無錯誤,無警告,編譯通過。
- #include <STC12C5A60S2.H>
- #include <intrins.h> /*use _nop_() function*/
- #define uchar unsigned char
- #define uint unsigned int
- #define ADC_FLAG 0X10
- /*****************************************
- 端口功能設定
- *****************************************/
- sbit PWM_1 = P1^4; //PWM1_Boost/Buck
- sbit SD_1 = P1^5; //SD1_Boost_Buck
- sbit LED = P0^0; //SD1_Boost_Buck
- uint ADC_value;
- uchar PWM_temp=2;
- uchar last_key; //按鍵變量
- uchar channel=0; //第一通道
- uchar Caes=0; //菜單
- uint OUT_Current=300;
- uint Battery_voltage; //輸入電壓
- uint Boost_voltage; //Boost電壓
- uint Boost_Buck_current; //Buck_Boost電流8位
- uint O_current; //輸出電流
- uint A_value=90;
- bit lock=0; //PWM輸出鎖定
- bit ADC_ready=0; //ADC完畢
- bit K=0;
- bit Charge=0;
- void delay(uchar);
- void Key_0_();
- void Key_1_();
- void Key_2_();
- void Key_3_();
- void init_pca();
- void init_timer();
- /**********************************************************
- 函數說明: 延時程序
- **********************************************************/
- void delay(uchar t)
- {
- uint j;
- uchar i;
- for(i=0;i<t;i++)
- for(j=0;j<1000;j++);
- }
- /**********************************************************
- 函數說明: PWM初始化
- **********************************************************/
- void init_pwm()
- {
- CCON = 0;
- CL = 0;
- CH = 0;
- CMOD = 0X08; //0X08:43KHZ // 0X02,22KHZ // 0X0A,10KHZ //
- CCAPM1 =0x42;//8位PWM輸出,無中斷
- CCAP1L =CCAP1H =250;//初始化spwm輸出的占空比
- CR=1;
- }
- /**********************************************************
- 函數說明: 中斷 始化函數
- **********************************************************/
- void InitADC()
- {
- P1M1=0x87;
- P1M0=0x00;
- P1ASF=0X87; //選擇ADC通道0127
- ADC_RES=0;
- ADC_CONTR=0X88; //1110 0000 E8 開電源,最高速
- EA=1;
- EADC=1;
- }
- /**************************************
- 12864液晶
- | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
- vss vdd vo rs r/w en d0 d1 d2 d3 d4 d5 d6 d7 psb nc rst vee led+ led-
- **************************************/
- #define dataPort P2 //數據口
- sbit rs = P0^4; //寄存器選擇輸入
- sbit rw = P0^3; //液晶讀/寫控制
- sbit en = P0^2; //液晶使能控制
- sbit psb = P0^7; //串/并方式控制
- sbit LCD_RST = P0^5; //液晶復位端口
- /**************************************
- 短延時
- **************************************/
- /*
- void delay5ms()
- {
- uchar i,v,k;
- for(i=1;i>0;i--)
- for(v=168;v>0;v--)
- for(k=22;k>0;k--);
- }*/
- void delayms(unsigned int n)
- {
- unsigned char i;
- for(;n>0;n--)
- for(i=0;i<100;i++);
- }
- void checkBusy(void)
- {
- rs=0;
- rw=1;
- en=1;
- dataPort=0xff;
- while(dataPort & 0x80);
- en=0;
- }
- void writeCommand(unsigned char cmd)
- {
- checkBusy();
- rs=0;
- rw=0;
- en=1;
- dataPort=cmd;
- _nop_();
- en=0;
- }
- void writeData(unsigned char adata)
- {
- checkBusy();
- rs=1;
- rw=0;
- en=1;
- dataPort=adata;
- _nop_();
- en=0;
- }
- /*
- unsigned char readData(void)
- {
- unsigned char RData;
- dataPort=0xff;
- checkBusy();
- rs=1;
- rw=1;
- en=0;
- en=1;
- RData=dataPort;
- en=0;
- return RData;
- }*/
- /***********************************************************
- 函 數 名:ClrGDRAM
- 函數說明:
- 傳入參數:無
- 傳出參數:無
- 返 回 值:無
- **********************************************************/
- void ClrGDRAM(void)
- {
- unsigned char x,y;
- for(y=0;y<64;y++)
- for(x=0;x<16;x++)
- {
- writeCommand(0x34);
- writeCommand(y+0x80); //行地址
- writeCommand(x+0x80); //列地址
- writeCommand(0x30);
- writeData(0x00);
- writeData(0x00);
- }
- //writeCommand(0x30);
- }
- /***********************************************************
- 函 數 名:LcmInit
- 函數說明:液晶初始化
- 傳入參數:無
- 傳出參數:無
- 返 回 值:無
- **********************************************************/
- void LcmInit(void)
- {
- writeCommand(0x30);
- delayms(50);
- writeCommand(0x01);
- delayms(50);
- writeCommand(0x06);
- delayms(50);
- writeCommand(0x0c);
- ClrGDRAM();
- psb=1;
- }
- /***********************************************************
- 函 數 名:clr_screen
- 函數說明:清屏
- 傳入參數:無
- 傳出參數:無
- 返 回 值:無
- **********************************************************/
- /*
- void clr_screen(void)
- {
- writeCommand(0x34); //擴充指令操作
- delayms(1);
- writeCommand(0x30); //基本指令操作
- delayms(1);
- writeCommand(0x01); //清屏
- delayms(1);
- }*/
- /***********************************************************
- 函 數 名:address_w
- 函數說明:寫入數據位置
- 傳入參數:無
- 傳出參數:無
- 返 回 值:無
- **********************************************************/
- void address_w(unsigned char x,unsigned char y)
- {
- /***設定顯示位置 ******/
- unsigned char address;
- switch (y)
- {
- case 0:address=0x80+x;break;
- case 1:address=0x90+x;break;
- case 2:address=0x88+x;break;
- case 3:address=0x98+x;break;
- default:break;
- }
- writeCommand(address);
- }
- /***********************************************************
- 函 數 名:LcmPrint
- 函數說明:在坐標(x,y)處顯示字符串
- 傳入參數:x,y,*adata
- 傳出參數:無
- 返 回 值:無
- **********************************************************/
- void hz_dis(unsigned char x,unsigned char y,unsigned char *adata)
- {
- unsigned char i=0;
- address_w(y,x);
- while(*(adata+i))
- {
- writeData(*(adata+i));
- i++;
- }
- delay(3);
- }
- /***********************************************************
- 函 數 名:num_dis
- 函數說明:在坐標(x,y)處顯示數字
- 傳入參數:x,y,num,n
- 傳出參數:無
- 返 回 值:無
- **********************************************************/
- unsigned char num_buffer[10];
- void num_dis(unsigned char x,unsigned char y,unsigned int num,unsigned char n)//數字顯示 X為行,Y為列 num為顯示數據 n為顯示位數
- {
- unsigned char i=0;
- address_w(y,x);
- for(i=0;i<n;i++)
- {
- num_buffer[n-1-i]=num%10+0x30;
- num/=10;
- }
- for(i=0;i<n;i++) writeData(num_buffer[i]);
- delay(3);
- }
- /**********************************************************
- 函數說明: 平均濾波函數
- **********************************************************/
- #define N 50
- uint Filter(uint adc_data)
- {
- uint value=0;
- uchar count,count_ADC;
- for(count=0;count<N;count++)
- {
- for(count_ADC=0;count_ADC<3;count_ADC++)
- {
- while(!ADC_ready){}
- ADC_ready=0;
- }
- value+=adc_data;
- }
- return (value);
- }
- /**********************************************************
- 函數說明:按鍵延時防抖動
- P3^5 Key_1
- P3^6 Key_2
- P3^7 Key_3
- **********************************************************/
- void key_scan()
- {
- uchar temp;
- temp = P3&0xF0;
- if(temp != 0xF0)
- {
- delay(10);
- temp = P3&0xF0;
- if(temp!= 0xF0)
- {
- switch(temp)
- {
- case 0xE0: Key_0_(); break; //20
- case 0xD0: Key_1_(); break; //21
- case 0xB0: Key_2_(); break; //22
- case 0x70: Key_3_(); break; //23
- default:break;
- }
- }
- }// last_key = temp;
- }
- /**********************************************************
- 函數說明: 按鍵程序
- **********************************************************/
- void Key_0_()
- {
- Charge=~Charge;
- if(Charge) {CCAP1L =CCAP1H =100; SD_1=1; hz_dis(2,7,"放");} //hz_lcdDis(1,14,"Bo");
- else {SD_1=0; hz_dis(2,7,"充");} //hz_lcdDis(1,14," ");
- delay(50);
- }
- void Key_1_()
- {
- if(K) {SD_1=0; lock=1; CCAP1L =CCAP1H =128; hz_dis(3,7,"關"); }// hz_lcdDis(0,14,"oF");
- else {SD_1=1; lock=0; hz_dis(3,7,"開");LED=1; }//hz_lcdDis(0,14,"oN");
- K=~K;
- delay(50);
- }
- void Key_2_()
- {
- OUT_Current=OUT_Current+6;
- if(OUT_Current>630)OUT_Current=630;
- }
- void Key_3_()
- {
- OUT_Current=OUT_Current-6;
- if(OUT_Current<270)OUT_Current=270;
- }
- /**********************************************************
- 函數說明: 主函數
- **********************************************************/
- void main(void)
- {
- uint U1,U2,I1,S;
- SD_1=0;LED=1;
- LcmInit();
- ClrGDRAM();
- hz_dis(0,0,"輸入電壓 . V");
- hz_dis(1,0,"輸出電壓 . V");
- hz_dis(2,0,"設定電流 . A 充");
- hz_dis(3,0,"輸出電流 . A 關");
- init_pwm();
- InitADC();
- delay(50);
- EA=1;//開總中斷
- while(1)//主循環
- {
- U1=Filter(Boost_voltage)/92; //輸入電壓 1:10采樣電阻 93,
- U2=Filter(Battery_voltage)/92; //輸出電壓 1:10采樣電阻 93
- I1=Filter(O_current)/150; //輸出電流
- // if(I1>30) I1=I1+7;//輸出電流顯示校準
- if(U2>242)
- {
- SD_1=0; lock=1; CCAP1L =CCAP1H=128;
- hz_dis(3,7,"保"); LED=0;
- }//hz_lcdDis(0,14,"Pt");
- num_dis(0,4,U1/10,3);
- num_dis(0,6,U1%10,1);
- num_dis(1,4,U2/10,3);
- num_dis(1,6,U2%10,1);
- S=OUT_Current/3;
- num_dis(2,4,S/100,1);
- num_dis(2,5,S%100,2);
- num_dis(3,4,I1/100,1);
- num_dis(3,5,I1%100,2);
- // num_lcdDis(0,2,U1/10,2);
- // num_lcdDis(0,5,U1%10,1);
- // num_lcdDis(0,8,U2/10,2);
- // num_lcdDis(0,11,U2%10,1);
- // num_lcdDis(1,2,S/100,1);
- // num_lcdDis(1,4,S%100,2);
- // num_lcdDis(1,8,I1/100,1);
- // num_lcdDis(1,10,I1%100,2);
- // if((u2-u1)<40) hz_lcdDis(0,10,"Error!");
- // else hz_lcdDis(0,10,"OK ");
- key_scan();
- }
- }
- /****************************************************************
- 函數說明: ADC中斷
- 實現功能:執行ADC采集并做電壓和電流的調整。
- ****************************************************************/
- void ADC_interrupt()interrupt 5 //ADC轉換完后ADC_FLAG由硬件自動置位,須由軟件清零
- {
- uint ADC_value; //ADC轉換結果 10位
- ADC_CONTR&=!ADC_FLAG; //clear ADCflag
- ADC_value=(ADC_RES<<2)+ADC_RESL; //
- ADC_value=(ADC_RES<<2)+ADC_RESL;
- switch(channel)
- {
- case 0: Boost_voltage=ADC_value;
- channel=1;
- break;
- case 1: Boost_Buck_current=ADC_value;
- if(!Charge)
- {
- if(!lock)
- {
- if((Battery_voltage<480)&&(Boost_Buck_current<OUT_Current)) //442
- {
- PWM_temp--;
- if(PWM_temp<1) PWM_temp=1;
- }
- else
- {
- PWM_temp++;
- if(PWM_temp>250) PWM_temp=250;
- }
- CCAP1H = CCAP1L =PWM_temp;
- }
- }
- else
- {
- if(Boost_voltage<542)
- {
- PWM_temp++;
- if(PWM_temp>250) PWM_temp=250;
- }
- else
- {
- PWM_temp--;
- if(PWM_temp<1) PWM_temp=1;
- }
- CCAP1H = CCAP1L =PWM_temp;
- }
- channel=2;
- break;
- case 2:Battery_voltage=ADC_value;
- channel=7;
- break;
- case 7:O_current=ADC_value;
- channel=0;
- break;
- default:break;
- }
- ADC_CONTR=0xE8|channel;
- ADC_ready=1;
- }
復制代碼 |