|
用是STCD 15W404AS 做主控,片內(nèi)資源用到了,可調(diào)PWM,ADC , 串口(用來(lái)讀取計(jì)量模塊的數(shù)據(jù)),具體功能,可按鍵調(diào)充電功率,1602顯示實(shí)時(shí)電壓,電流,功率,電能累計(jì),
設(shè)計(jì)有1602顯示,但是不知道時(shí)序?qū)懙倪有些問(wèn)題還是干擾問(wèn)題,充電的時(shí)候就白屏了或者亂碼了,,不充電有時(shí)候有時(shí)候是正常的,這里還需要調(diào)試,目前已經(jīng)正常充電,電流30A
單片機(jī)源程序如下:
- #include <reg52.h>
- #include "intrins.h"
- sfr AUXR = 0x8E; //0000,0000 輔助寄存器
- sfr T2H = 0xD6; //0000,0000 T2高字節(jié)
- sfr T2L = 0xD7; //0000,0000 T2低字節(jié)
- sfr P0M1 = 0x93;
- sfr P0M0 = 0x94;
- sfr P1M1 = 0x91;
- sfr P1M0 = 0x92;
- sfr P2M1 = 0x95;
- sfr P2M0 = 0x96;
- sfr P3M1 = 0xb1;
- sfr P3M0 = 0xb2;
- sfr P4M1 = 0xb3;
- sfr P4M0 = 0xb4;
- sfr P5M1 = 0xC9;
- sfr P5M0 = 0xCA;
- sfr P6M1 = 0xCB;
- sfr P6M0 = 0xCC;
- sfr P7M1 = 0xE1;
- sfr P7M0 = 0xE2;
- /////////////////////////////////////////////////////////////////////////////////////////////
- //PWM模塊寄存器定義
- sfr P_SW1 = 0xA2; //外設(shè)功能切換寄存器1 針腳選擇功能寄存器
- #define CCP_S0 0x10 //P_SW1.4 選擇針腳功能
- #define CCP_S1 0x20 //P_SW1.5 選擇針腳功能
- #define S1_S1 0x80 //P_SW3.6 選擇針腳功能
- #define S1_S0 0x40 //P_SW3.7 選擇針腳功能
- sfr ADC_CONTR = 0xBC; //ADC控制寄存器
- sfr ADC_RES = 0xBD; //ADC高8位結(jié)果
- sfr ADC_LOW2 = 0xBE; //ADC低2位結(jié)果
- sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
- #define ADC_POWER 0x80 //ADC電源控制位
- #define ADC_FLAG 0x10 //ADC完成標(biāo)志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540個(gè)時(shí)鐘
- #define ADC_SPEEDL 0x20 //360個(gè)時(shí)鐘
- #define ADC_SPEEDH 0x40 //180個(gè)時(shí)鐘
- #define ADC_SPEEDHH 0x60 //90個(gè)時(shí)鐘
-
- sfr CCON = 0xD8; //PCA控制寄存器
- sbit CCF0 = CCON^0; //PCA模塊0中斷標(biāo)志
- sbit CCF1 = CCON^1; //PCA模塊1中斷標(biāo)志
- sbit CR = CCON^6; //PCA定時(shí)器運(yùn)行控制位
- sbit CF = CCON^7; //PCA定時(shí)器溢出標(biāo)志
- sfr CMOD = 0xD9; //PCA模式寄存器
- sfr CL = 0xE9; //PCA定時(shí)器低字節(jié)
- sfr CH = 0xF9; //PCA定時(shí)器高字節(jié)
- sfr CCAPM0 = 0xDA; //PCA模塊0模式寄存器
- sfr CCAP0L = 0xEA; //PCA模塊0捕獲寄存器 LOW
- sfr CCAP0H = 0xFA; //PCA模塊0捕獲寄存器 HIGH
- sfr CCAPM1 = 0xDB; //PCA模塊1模式寄存器
- sfr CCAP1L = 0xEB; //PCA模塊1捕獲寄存器 LOW
- sfr CCAP1H = 0xFB; //PCA模塊1捕獲寄存器 HIGH
- sfr CCAPM2 = 0xDC; //PCA模塊2模式寄存器
- sfr CCAP2L = 0xEC; //PCA模塊2捕獲寄存器 LOW
- sfr CCAP2H = 0xFC; //PCA模塊2捕獲寄存器 HIGH
- sfr PCA_PWM0 = 0xf2; //PCA模塊0的PWM寄存器
- sfr PCA_PWM1 = 0xf3; //PCA模塊1的PWM寄存器
- sfr PCA_PWM2 = 0xf4; //PCA模塊2的PWM寄存器
- ///////////////////////////////////////////////////////////函數(shù)列表、、、、、、、、、、、、、、、、、、、、、、、、、、、
- void UartInit(); //初始化串口
- void Timer0Init(); //初始化T0
- void UartWxd(); //發(fā)送數(shù)據(jù)查詢實(shí)時(shí)信息
- void jiexibuf(); //解析接受到的數(shù)據(jù)
- void pwm(); //解析接受到的數(shù)據(jù)
- void InitADC(); //初始化ADC
- void GetADCResult(); //讀取ADC的值存儲(chǔ)在變量adc里面
- void Delay(unsigned int n); //軟件延時(shí) 1.6毫秒左右
- void chongdian(); // 充電流程
- void diannengjisuan();//J計(jì)算初始電能并計(jì)算已用電能
- void dianliuxuanze(); //按鈕選項(xiàng)電流
- ///////////////////////////////////////////////////////////定義的一些變量、、、、、、、、、、、、、、、、、、、、、、、、、、、
- bit flagTxd = 0; //單字節(jié)發(fā)送完成標(biāo)志,用來(lái)替代 TXD 中斷標(biāo)志位
- sbit s1 = P3^3; //切換繼電器
- sbit km = P3^2; //功率繼電器接觸器
- sbit pwmdip = P1^1;
- sbit k1 = P3^0; //按鈕
- //sbit LED = P1^2;
- unsigned char cntRxd = 0; //接收字節(jié)計(jì)數(shù)器
- unsigned char pdata bufRxd[30]; //接收字節(jié)緩沖區(qū)
- unsigned char code bufWxd[8] ={0x01,0x03,0x00,0x48,0x00,0x0A,0x45,0xDB,};//發(fā)送的數(shù)據(jù) 增加了code關(guān)鍵字,此數(shù)組寫在程序區(qū)減少使用內(nèi)部?jī)?nèi)存128K
- unsigned long pdata cnt = 0; //毫秒計(jì)數(shù)
- unsigned long pdata sec; //秒計(jì)數(shù)
- //unsigned cha *but;// 發(fā)送指針
- unsigned int pdata vcc; // 電壓
- unsigned int pdata vci; // 電流
- unsigned int pdata power; // 功率
- unsigned long pdata kwh=0; // 電能
- unsigned long pdata kwh1; // 初始電能
- unsigned char pw; //設(shè)定的空占比%
- unsigned char cp; //充電樁PWM波形 cp電壓采集信號(hào) 120
- //// 關(guān)于LCD 1602 /////////////////LCD的一些定義
- sfr P5 = 0xC8;
- unsigned char pdata lcd1[16]; //LCD第一行
- unsigned char pdata lcd2[16]; //LCD第二行
- sbit LCD1602_RS = P5^5; //命令、數(shù)據(jù)選擇 H\L
- sbit LCD1602_E = P5^4; //使能
- unsigned char pdata ki; //電流顯示1表示16A 2表示32A
- #define LCD1602_DATAPINS P1 //定義P1口為數(shù)據(jù)端
- void LcdWriteCom(unsigned char com); /*LCD1602寫入8位數(shù)據(jù)子函數(shù)*/
- void LcdWriteData(unsigned char dat); /*LCD1602寫入8位數(shù)據(jù)子函數(shù)*/
- void LcdInit(); /*LCD1602初始化子程序*/
- void lcd1602(); //1602顯示刷新
- void Lcd1602_Delay5ms();
- void Lcd1602_Delay1ms();
- void main(){
- P0M0 = 0x00;
- P0M1 = 0x00;
- P1M0 = 0x00;
- P1M1 = 0x00;
- P2M0 = 0x00;
- P2M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P4M0 = 0x00;
- P4M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P6M0 = 0x00;
- P6M1 = 0x00;
- P7M0 = 0x00;
- P7M1 = 0x00;
- P_SW1=P_SW1|S1_S0;
- EA = 1; //使能總中斷
- ES = 1; //使能串口1中斷
- UartInit(); //初始化串口
- pwm(); //初始化pwm模塊設(shè)置
- InitADC(); //初始化ADC
-
- Timer0Init(); //初始化T0
- LcdInit();//初始化lcd
-
- while (1){
- chongdian(); //充電流程
- dianliuxuanze(); //電流選擇函數(shù)
-
- if(TF0==1){ //t0溢出的次數(shù)
- cnt++;}
- if(pwmdip==1){ //檢測(cè)
- GetADCResult(); //讀取刷新ADC的值 cp就是讀取的8位電壓信號(hào)
-
- }
- if(cnt>=20000){ //大概1秒鐘,還可以調(diào)整
-
- cnt=0;
- sec++;
-
- UartWxd(); //發(fā)送電能模塊讀取命令
- jiexibuf(); //解析接受到的數(shù)據(jù)
- diannengjisuan(); //電能計(jì)算函數(shù)
- lcd1602(); //lcd顯示
- }
-
- } }
- void chongdian(){ //、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、充電流程
- if(cp>111){ //當(dāng)cp電壓大于11.1時(shí) 狀態(tài)1
- s1=1; //小接觸器不吸合 常閉點(diǎn)12V s1
- km=1;
- } //主接觸器不吸合
- if(98>cp && cp>81){ //當(dāng)cp電壓大于8.1V小于9.8時(shí) 狀態(tài)2 與車輛已連接
- s1=0; //小接觸器吸合 切換至PWM
- km=1; } //主接觸器不吸合
- if(66>cp && cp>51){ //當(dāng)cp電壓大于5.1小于6.6時(shí) 狀態(tài)3 充電中
- s1=0; //小接觸器吸合 切換至PWM
- km=0; //主接觸器吸合 開(kāi)始充電
-
- }
- }
- void dianliuxuanze(){ //電流選擇初始值16A
- bit i=0; //電流選擇初始值16A
- if (i==1){ //不切換電流16A
- pw=33;
- ki=1;}
- else{pw=60;
- ki=2;} // 切換電流32A
- if(k1==0)
- { Lcd1602_Delay5ms();
- Lcd1602_Delay5ms();
- if(k1==0){
- i=!i;//k1按下置反i
- }
-
- }
- }
- void pwm(){ //PWM程序、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
-
- ACC = P_SW1; //累加器 等于外設(shè)寄存器
- ACC &= ~(CCP_S0 | CCP_S1); //CCP_S0=0 CCP_S1=0
- P_SW1 = ACC; //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2) 讀取累加器的值寫進(jìn)外設(shè)寄存器
- CCON = 0; //初始化PCA控制寄存器
- //PCA定時(shí)器停止
- //清除CF標(biāo)志
- //清除模塊中斷標(biāo)志
- CL = 0; //復(fù)位PCA寄存器
- CH = 0;
- CMOD = 0x04;
- // CMOD = 0x04; //設(shè)置PCA時(shí)鐘源 t0定時(shí)器
- //禁止PCA定時(shí)器溢出中斷
- PCA_PWM0 = 0x00; //PCA模塊0工作于8位PWM
- CCAP0H = CCAP0L =255-255*60/100; //PWM0的占空比為87.5% ((100H-20H)/100H) 255-255*設(shè)定空占比 /100
- CCAPM0 = 0x42; //00101010 PCA模塊0允許比較功能 使用CCP0腳為可調(diào)脈沖輸出 P1.1
- }
- void Timer0Init() //T0作為PWM頻率基準(zhǔn)發(fā)生
- {
-
- AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- TL0 = 0xd5; //設(shè)置定時(shí)初值 計(jì)算方法,65536-晶振/(256*需要頻率)
- TH0 = 0xFf; //設(shè)置定時(shí)初值
- TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- ET0 =0; // 禁止T0中斷
- TF0 = 0; //清除TF0標(biāo)志
- // EA =0; 關(guān)閉總總中斷
- CR = 1; } //PCA定時(shí)器開(kāi)始工作
- ///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
- // TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- // TL0 = 0xff; //設(shè)置定時(shí)初值
- // TH0 = 0xf6; //設(shè)置定時(shí)初值
- // TF0 = 0; //清除TF0標(biāo)志
- // TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- /*----------------------------
- 初始化ADC
- ----------------------------*/
- void InitADC() //初始化ADC
- {
- P1ASF = 0x01; //設(shè)置P1.0口為AD口
- ADC_RES = 0; //清除結(jié)果寄存器
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
- Delay(2); //ADC上電并延時(shí)
- }
- /*----------------------------
- 讀取ADC結(jié)果
- ----------------------------*/
- void GetADCResult()
- { unsigned long y;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | 0 | ADC_START; //ADC電源 540個(gè)時(shí)鐘ADC_SPEEDHH ADC_SPEEDLL 通道號(hào) 啟動(dòng)
- _nop_(); //等待4個(gè)NOP
- _nop_();
- _nop_();
- _nop_();
- while (!(ADC_CONTR & ADC_FLAG));//等待ADC轉(zhuǎn)換完成
- ADC_CONTR &= ~ADC_FLAG; //Close ADC
-
- //實(shí)際濾波測(cè)得4.6V一下不予處理
- if(ADC_RES>0x64){
- y=12000000/256*(ADC_RES+1); //ADC結(jié)果轉(zhuǎn)換 單位是最大12000毫伏
- cp=y/100000; //結(jié)果轉(zhuǎn)換120v 放大10倍最大電壓
- }
- }
- void jiexibuf() //解析接受到的數(shù)據(jù)
- { unsigned long h;
- unsigned long j;
- unsigned long l;
- unsigned long o;
- vcc = (bufRxd[3]<<8)| bufRxd[4]; //電壓 int16位
- vci = (bufRxd[5]<<8)| bufRxd[6]; //電流 int16位
- power = (bufRxd[7]<<8)| bufRxd[8]; //功率 int16位
- h = (bufRxd[9]<<8)| bufRxd[10];//電能 32位數(shù)據(jù)高16位
- j = (bufRxd[11]<<8)|bufRxd[12];//電能 32位數(shù)據(jù)低16位
- l = h<<16;
- o = (l|j)*100;
- kwh = o/3200;
- }
- void diannengjisuan() //計(jì)算電能顯示函數(shù)
- { unsigned long x;
- static bit p=1;
-
- if(p==1){ //開(kāi)始初始電能記錄
- if(s1==0){ //刷新是否有電能數(shù)據(jù)
- x=kwh1; // 初始電能傳給x
- p=0; //退出初始電能記錄
- }
- }
- // kwh=kwh1-x;
- }
- void UartInit() //4800bps@11.0592MHz
- {
- // P_SW1=P_SW1|S1_S0;
- SCON = 0x50; //8位數(shù)據(jù),可變波特率
- AUXR |= 0x01; //串口1選擇定時(shí)器2為波特率發(fā)生器
- AUXR |= 0x04; //定時(shí)器2時(shí)鐘為Fosc,即1T
- T2L = 0xC0; //設(shè)定定時(shí)初值
- T2H = 0xFD; //設(shè)定定時(shí)初值
- AUXR |= 0x10; //啟動(dòng)定時(shí)器2
- }
- void UartWxd(){
- unsigned char u; //數(shù)據(jù)位置 bufWxd[u]
- for(u=0;u<=7;u++)
- {
- flagTxd=0;
- SBUF=bufWxd[u]; // SBUF=bufWxd[u];
- while(!flagTxd);
-
- }
- }
- /*----------------------------
- 軟件延時(shí)
- ----------------------------*/
- void Delay(unsigned int n)
- {
- unsigned int x;
- while (n--)
- {
- x = 5000;
- while (x--);
- }
- }
- void InterruptUART() interrupt 4{
- if (RI){ //接收到字節(jié)
- RI = 0; //手動(dòng)清零接收中斷標(biāo)志位
- bufRxd[cntRxd++] = SBUF; //接收的數(shù)據(jù)存到接收緩沖區(qū),數(shù)組
- if(cntRxd==25){ //接收24幀數(shù)據(jù),然后復(fù)位接收計(jì)數(shù)器,下次從0開(kāi)始接收
- cntRxd=0;
- }
- }
- if (TI){ //字節(jié)發(fā)送完畢
- TI = 0; //手動(dòng)清零發(fā)送中斷標(biāo)志位
- flagTxd = 1; //設(shè)置字節(jié)發(fā)送完成標(biāo)志
- }
- }
- //清中斷標(biāo)志/清中斷標(biāo)志
- //void PCA_isr() interrupt 7
- //{
- // CCF0 = 0; //清中斷標(biāo)志
- // CCAP0L = value;
- // CCAP0H = value >> 8; //更新比較值
- // value += T100Hz;
- // if (cnt-- == 0)
- // {
- // cnt = 100; //記數(shù)100次
- // PCA_LED = !PCA_LED; //每秒閃爍一次
- // }
- //}
- //// 關(guān)于LCD 1602 LCD 1602 LCD 1602 LCD 1602 LCD 1602 LCD 1602 LCD 1602 /////////////////LCD的一些定義
- void LcdWriteCom(unsigned char com) //寫入命令
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 0; //選擇寫入命令
- LCD1602_DATAPINS = com >>2; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
- Lcd1602_Delay1ms();
- LCD1602_E = 1; //寫入時(shí)序
- Lcd1602_Delay5ms();
- LCD1602_E = 0;
- LCD1602_DATAPINS = com << 2; //發(fā)送低四位
- Lcd1602_Delay1ms();
- LCD1602_E = 1; //寫入時(shí)序
- Lcd1602_Delay5ms();
- LCD1602_E = 0;
- }
- void LcdWriteData(unsigned char dat) //寫入數(shù)據(jù)
- {
- LCD1602_E = 0; //使能清零
- LCD1602_RS = 1; //選擇寫入數(shù)據(jù)
- // LCD1602_RW = 0; //選擇寫入
-
-
- LCD1602_DATAPINS = dat >>2; //由于4位的接線是接到P0口的高四位,所以傳送高四位不用改
- Lcd1602_Delay1ms();
- LCD1602_E = 1; //寫入時(shí)序
- Lcd1602_Delay5ms();
- LCD1602_E = 0;
- LCD1602_DATAPINS = dat << 2; //寫入低四位
- Lcd1602_Delay1ms();
- LCD1602_E = 1; //寫入時(shí)序
- Lcd1602_Delay5ms();
- LCD1602_E = 0;
- }
- void LcdInit() //LCD初始化子程序
- {
- Delay(20);
- LcdWriteCom(0x32); //將8位總線轉(zhuǎn)為4位總線
- LcdWriteCom(0x28); //在四位線下的初始化
- LcdWriteCom(0x0c); //開(kāi)顯示不顯示光標(biāo)
- LcdWriteCom(0x06); //寫一個(gè)指針加1
- LcdWriteCom(0x01); //清屏
- //LcdWriteCom(0x80); //設(shè)置數(shù)據(jù)指針起點(diǎn)
- }
- void lcd1602()
- { LcdWriteCom(0x80); //設(shè)置數(shù)據(jù)指針起點(diǎn)
- LcdWriteData('V');
- LcdWriteData(':');
- LcdWriteData('0'+vcc/10000%10);
- LcdWriteData('0'+vcc/1000%10);
- LcdWriteData('0'+vcc/100%10);
- LcdWriteData('.');
- LcdWriteData('0'+vcc/10%10);
- LcdWriteData('0'+vcc%10);
- LcdWriteData(' ');
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
51hei截圖20210116100025.png (120.18 KB, 下載次數(shù): 56)
下載附件
2021-1-16 10:00 上傳
51hei.png (5.02 KB, 下載次數(shù): 55)
下載附件
2021-1-16 16:06 上傳
所有程序51hei提供下載:
485 - 通訊程序加顯示.zip
(53.37 KB, 下載次數(shù): 131)
2021-1-16 09:49 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|