无错误,无警告,编译通过。
- #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;
- }
复制代码 |