|
50黑幣
系統(tǒng)主程序代碼controller.c:
#include <reg52.h>
#include <intrins.h> //庫(kù)函數(shù)頭文件,代碼中引用了_nop_()函數(shù)
#include "define.h" //變量定義和函數(shù)的聲明
#include "init.h" //初始化模塊
#include "AD.h" //AD轉(zhuǎn)換模塊
#include "yj1602.h" //液晶1602顯示模塊
#include "AT24C02.h" //數(shù)據(jù)存儲(chǔ)模塊
/*主函數(shù)*/
void main()
{
init();
init1602();
init24c02();
battery_v=get_ad();
yj1602();
if(battery_v<108) PWM=0; //首次要直接充電
else PWM=1;
while(1)
{
delay(5000);
battery_v=get_ad();
yj1602();
if(battery_v<0)//蓄電池反接,立刻關(guān)閉充放電電路,蜂鳴器報(bào)警
{
PWM=1;FuZai=1;buzzer();
}
if(battery_v>=108)//蓄電池電壓大于10.8V
{
if(145<=battery_v)
{
LED1=0; //開(kāi)啟過(guò)電壓指示燈
LED=1;
LED2=1;
PWM=1;//停止充電
buzzer(); //蜂鳴器報(bào)警
write=1;
AT24c02();
}
else if(120<=battery_v<145)//蓄電池電壓大于12v而且小于13.5v
{
LED=0;
LED1=1;LED2=1;
TR0=1; //開(kāi)啟固定PWM充電
if(count==4)
{
PWM=0;
}
if(count==12)
{
count=0;
PWM=1;
}
}
else if(battery_v<120)
{
LED=0;LED1=1;LED2=1;
TR0=0;
PWM=0;
}
}
else
{
LED=1;//開(kāi)啟欠壓指示燈
LED1=1;
LED2=0;
FuZai=1;//關(guān)閉負(fù)載
PWM=0;
buzzer();
write=1;
AT24c02();
}
}
}
/*****定時(shí)中斷函數(shù)*****/
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;//定時(shí)時(shí)間為50ms,每50ms中斷一次
count++;
}
以下代碼為define.h //變量定義和函數(shù)的聲明
#define uchar unsigned char
#define uint unsigned int
// 定義控制信號(hào)端口
//充放電控制端口
sbit PWM= P3^2;//蓄電池開(kāi)關(guān)
sbit FuZai=P3^3;//負(fù)載開(kāi)關(guān)
sbit LED=P2^3;//充電指示燈
sbit LED1=P2^4;//充電指示燈
sbit LED2=P2^5;//欠壓指示燈
sbit beep=P2^6;//蜂鳴器控制位
uchar count,battery_v;
//AD轉(zhuǎn)換
sbit csad=P2^7; //定義AD的片選位
sbit adwr=P3^6; //定義AD的WR端口
sbit adrd=P3^7; //定義AD的RD端口
unsigned char V1,V2,V3,adval,ad_vo;
//1602液晶顯示
sbit RS=P2^0; //P2.0
sbit RW=P2^1; //P2.1
sbit EN=P2^2; //P2.2
unsigned char code table1[]=" TYNCFDKZQXTSJ";
unsigned char code table2[]=" D:12.0 N:";
unsigned char code lcdd[]="0123456789";
uchar xs_vo,num;
//AT24c02保存數(shù)據(jù)
bit write=0; //寫(xiě)24C02的標(biāo)志;
sbit scl=P2^4;
sbit sda=P2^5;
uchar p=2,a1;
RS232串口通信
sbit RXD=P3^0;
sbit TXD=P3^1;
/*聲明調(diào)用函數(shù)*/
void init();//初始化主函數(shù)
void delay(unsigned int t); //可控延時(shí)函數(shù)
void delay1(); //軟件實(shí)現(xiàn)延時(shí)函數(shù),5個(gè)機(jī)器周期
void buzzer();
uchar get_ad(); // AD程序
//1602液晶顯示部分
void write_com(uchar com);
void write_data(uchar date);
void init1602();
void yj1602();
//AT24c02保存數(shù)據(jù)
void init24c02();
void start(); //啟動(dòng)
void stop(); //停止
void respons(); //應(yīng)答
void write_byte(uchar date);
//uchar read_byte();
void write_add(uchar address,uchar date);
//uchar read_add(uchar address);
void AT24c02();
以下代碼為init.h //初始化模塊
void init()//初始化主函數(shù)
{
TMOD=0x01;
TH0=(65536-50)/256;
TL0=(65536-50)%256;//定時(shí)時(shí)間為50ms,每50ms中斷一次
EA=1;
ET0=1;
PWM=1;//初始化時(shí)先關(guān)閉充電
LED=0;//開(kāi)啟正常工作指示燈
LED1=1;//關(guān)閉異常指示燈
LED2=1;
beep=1;
write=0;
}
/*延時(shí)函數(shù)*/
void delay(unsigned int t)
{
unsigned int j,i;
for(i=0;i<t;i++)
for(j=0;j<110;j++);
}
/*延時(shí)函數(shù)1*/
void delay1()
{
_nop_(); _nop_();
_nop_(); _nop_();
_nop_();
}
//蜂鳴器報(bào)警函數(shù)
void buzzer()
{
beep=0; delay(10);
beep=1;
}
以下代碼為AD.h //AD轉(zhuǎn)換模塊
//ad轉(zhuǎn)換程序
uchar get_ad() // AD程序
{
csad=0; //置CSAD為0,
adwr=1;
_nop_();
adwr=0; //啟動(dòng)AD轉(zhuǎn)換
_nop_();
adwr=1;
delay(2); //AD轉(zhuǎn)換時(shí)間
P1=0xff; //讀取P1口之前先給其寫(xiě)全1
adrd=1; //選通ADCS
_nop_();
adrd=0; //AD讀使能
_nop_();
adval=P1; //AD數(shù)據(jù)讀取賦給P1口,得到ad轉(zhuǎn)換的結(jié)果
adrd=1;
ad_vo=(float)adval*150.0/256.0;//得到蓄電池的電壓
return(ad_vo);
}
以下代碼為yj1602.h //液晶1602顯示模塊
/*LCD1602顯示部分子函數(shù)*/
void init1602() //LCD初始化函數(shù)
{
EN=0;
write_com(0x38);//設(shè)置16X2顯示,5X7點(diǎn)陣,8位數(shù)據(jù)接口
write_com(0x0c);//設(shè)置開(kāi)顯示,不顯示光標(biāo)
write_com(0x06);//寫(xiě)一個(gè)字符后地址指針加1
write_com(0x01);//顯示清零,數(shù)據(jù)指針清零
}
void write_com(uchar com)//1602寫(xiě)命令函數(shù)
{
RW=0; delay1();
RS=0; // RW=0,RS=0,寫(xiě)LCD命令字
delay1();
EN=1; //E端時(shí)序
delay1();
P0=com; //將com中的命令字寫(xiě)入LCD數(shù)據(jù)口
delay1();
EN=0; delay1();
delay(5);
}
void write_data(uchar date)//1602寫(xiě)數(shù)據(jù)函數(shù)
{
RW=0; delay1();
RS=1; // RW=1,RS=0,寫(xiě)LCD數(shù)據(jù)
delay1();
EN=1; // E端時(shí)序
delay1();
P0=date; // 將dat中的顯示數(shù)據(jù)寫(xiě)入LCD數(shù)據(jù)口
delay1();
EN=0; delay1();
delay(5);
}
void yj1602()
{ uchar xs_vo;
init1602();
xs_vo=battery_v;
V1=xs_vo/100;
V2=xs_vo%100/10;
V3=xs_vo%10;
write_com(0x80+0x10);
for(num=0;num<14;num++)
{
write_data(table1[num]);
delay(5);
}
write_com(0x80+0x50);
write_data(' ');
delay(5);
write_data('S');
delay(5);
write_data(':');
write_data(' ');
delay(5);
write_data(lcdd[1]);
delay(5);
write_data(lcdd[2]);
delay(5);
write_data('.');
delay(5);
write_data(lcdd[0]);
delay(5);
write_data(' ');
delay(5);
write_data(' ');
delay(5);
write_data('N');
delay(5);
write_data(':');
delay(5);
write_data(lcdd[V1]);
delay(5);
write_data(lcdd[V2]);
delay(5);
write_data('.');
delay(5);
write_data(lcdd[V3]);
delay(5);
for(num=0;num<16;num++)//移屏顯示
{
write_com(0x1c);
delay(1000);
}
}
以下代碼為AT24C02.h //數(shù)據(jù)存儲(chǔ)模塊
//at24c02部分子函數(shù)
void init24c02()//24c02初始化函數(shù)
{
sda=1; delay1();
scl=1; delay1();
}
void start() //開(kāi)始信號(hào)
{
sda=1; delay1();
scl=1; delay1();
sda=0; delay1();
}
void stop() //停止
{
sda=0; delay1();
scl=1; delay1();
sda=1; delay1();
}
void respons() //應(yīng)答
{
uchar i;
scl=1; delay1();
while((sda==1)&&(i<250)) i++;
scl=0; delay1();
}
void write_byte(uchar date)//串行發(fā)送字節(jié)函數(shù)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0; delay1();
sda=CY; delay1();
scl=1; delay1();
}
scl=0; delay1();
sda=1; delay1();
}
uchar read_byte()//串行讀字節(jié)函數(shù)
{
uchar i,k;
scl=0;
delay1();
sda=1;
delay1();
for(i=0;i<8;i++)
{
scl=1;
delay1();
k=(k<<1)|sda;
scl=0;
delay1();
}
return k;
}
void write_add(uchar address,uchar date)//24c02字節(jié)寫(xiě)入函數(shù)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_add(uchar address)//24c02字節(jié)讀操作函數(shù)
{
uchar date;
start();
write_byte(0xa0); respons();
write_byte(address); respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
void AT24c02()
{
init24c02();
a1=battery_v; //保存蓄電池過(guò)電壓數(shù)據(jù)
if(write==1) //判斷計(jì)時(shí)器是否計(jì)時(shí)一秒
{
write=0; //清零
write_add(p,a1); //在24c02的地址p中寫(xiě)入數(shù)據(jù)a1
p++;
}
}
|
|