前言:作者想要帮助一些童鞋和爱好者进行项目构建,但自知能力有限,不喜可论,创作不易,勿喷。
系统采用stc89c51芯片进行的单片机由pt100测温,根据温度大小控制充点电流大小。

项目包含主要器件stc89c51 lcd1602 PCF8591 PT100
项目包含程序 仿真
main.c

#include <reg51.h>
#include <math.h>
extern float log (float val);
#include <ds1602.c>
uchar cp1,pwm,cp2,current;
uint cp,ad0,pwm1;
float tem,aa;
float temp1;


#include <pcf8591.c>
#include <display.c>
#define temp_R 20000
#define temp_B 4050
#define temp_in 298
//float Ad_to_T(uchar ad)
//{


// return tem-273;
//}
sbit P15 = P1^5;
sbit P17 = P1^7;

void Timer_isr(void)interrupt 1
{
TH0 =64535/256;
TL0 =64535%256;
cp++;
if(cp >= 50)
{
cp = 0;
ad0 = read_pcf8591(0x40);
aa = 298*log(((float)255.0/ad0)-1)+4050;
temp1 = (1206900)/aa-273;
}
if(temp1 >= 100)
{
P17 = 1;
}
else P17 =0;

}
void Timer_isr1(void)interrupt 3
{
TH1 =65435/256;
TL1 =65435%256;
cp1++;
if(cp1 <= pwm1) P15 = 1;
if((cp1 > pwm1)&&(cp1 <= 200)) P15 = 0;

}
void Timer_Init()
{
TMOD = 0x11;
TH0 =63535/256;
TL0 =63535%256;
TH1 =65435/256;
TL1 =65435%256;
TR1 = 1;
TR0 = 1;
ET1 = 1;
ET0 = 1;

EA =1;
}

void main()
{

Timer_Init();
init_1602();
LCD_clr1602();
delayus(20000);
init_24c04();

while(1)
{
// temp1 = Ad_to_T(ad0);
if(ad0 >= 226)
{
pwm1 = 0;
}
if((ad0 >= 217)&&(ad0 < 226))
{
pwm1 = 25;
}
if((ad0 >= 191)&&(ad0 < 217))
{
pwm1 = 50;
}
if((ad0 >= 151)&&(ad0 < 191))
{
pwm1 = 100;
}
if(ad0 < 151)
{
pwm1 = 200;
}
display();

}
}

DS1602.c

#define uchar unsigned char 
#define uint unsigned int

sbit RS = P3^0;//数据/命令
sbit RW = P3^1;//读/写
sbit E = P3^2;//使能
uchar i;
uchar str[] = {"Internet of Things00"};
uchar num[] = {"0123456789"};

void delayus(uint x) //延时函数
{
while(x--);
}

void write_com(uchar com)//写命令
{
RW = 0;
RS = 0;
E = 1;
P0 = com;
delayus(100);
E = 0;
}
void write_data(uchar da)//写入数据
{
RW = 0;
RS = 1;
E = 1;
P0 = da;
delayus(100);
E = 0;
}


void init_1602() //LCD1602 初始化
{
write_com(0x3c);//设定数据总线的个数4/8,显示一行/两行
write_com(0x0c);// //光标不显示
write_com(0x06);// //光标随字符右移
}
void LCD_clr1602() //LCD1602 清屏
{
write_com(0x01); // 对字符串清0
write_com(0x02); //对光标清0
}

void goto_xy(uchar y,uchar x) //定位显示位置
{
if(y == 1)
write_com(x + 0x80); //定位第一行
else
write_com(x + 0x80 + 0x40); //定位第二行
}

void display_num(unsigned char x) //显示数字
{
write_data(num[x / 10]);
write_data(num[x % 10]);
}

void display_num1(unsigned int x) //显示数字
{
write_data(num[x / 1000 % 10]);
write_data(num[x / 100 % 10]);
write_data(num[x / 10 % 10]);
write_data(num[x % 10]);
}

void display_string(uchar *p) //显示字符
{
while(*p)
{
write_data(*p);
p++;
}
}
void display_xnum2(float x) //显示数字
{
uint y,x1;

y = (int)x;
write_data(num[y / 1000%10]);
write_data(num[y / 100%10]);
write_data(num[y / 10%10]);
write_data(num[y % 10]);
x1 = (int)((x -(float)y)*1000);
display_string(".");
write_data(num[x1 / 100 % 10]);
write_data(num[x1 / 10 % 10]);
write_data(num[x1 % 10]);
}

PCF8591.c

#include<intrins.h>
sbit scl = P2^0;
sbit sda = P2^1;

/*************起始信号**************/
//工作条件sda 产生下降沿 scl 为高电平;
void star_24c04 ()
{
sda = 1;
scl = 1;
sda = 0;
scl = 0; //时钟信号复位
}
/*************终止信号**************/
//终止条件sda数据信号产生下降沿 scl 时钟信号为高电平
void stop_24c04()
{
sda = 0;
scl = 1;
sda = 1;
}
/**************应答信号**************/
void ack_24c04()
{
uchar i= 255;
scl = 1;
while(sda && i--);
scl = 0;
}
/**************I2C总线初始化*********/
void init_24c04(void)
{
sda = 1;
scl = 1;
}
/**************读取一个字节**************/
uchar read_onebyte_24c04(void)
{
uchar i ,dat;
sda = 1;//释放总线
for(i = 0;i < 8;i++)
{
scl = 1;
dat = dat<<1;
if(sda)dat = dat|0x01;//先读取高位,放到dat 的低位;
scl = 0;
}
sda = 1;
scl = 0;
return (dat);
}
/*************写入一个字节**************/
void write_onebyte_24c04(uchar dat)
{
uchar i;
for(i = 0;i < 8;i++)
{
sda = (bit)(dat & 0x80);
dat = dat << 1;
scl = 1;
scl = 0;
}
sda = 1;
scl = 0;
}

//读地址、数据函数
//0x40表示0号通道;0x41表示1号通道;
uchar read_pcf8591(uchar sh)
{
uchar temp;

star_24c04(); //发出开始信号
write_onebyte_24c04(0x90);//PCF8591地址 相当于握手信号
ack_24c04(); //响应
write_onebyte_24c04(sh);//0x40表示0号通道;//0x43 滑变 //0x40 光敏 //0x41 热敏
ack_24c04(); //响应

star_24c04(); //再次发出开始信号
write_onebyte_24c04(0x91);//发出读取对应8951模块AD的信号
ack_24c04(); //响应
temp=read_onebyte_24c04();//读取数据
stop_24c04(); //停止
return(temp); //返回数据
}
//void DA_PCF8591(uchar dat) /// DA转换
//{
// star_24c04();
// write_onebyte_24c04(0x90);
// ack_24c04();
// write_onebyte_24c04(0x40);
// ack_24c04();
// write_onebyte_24c04(dat);
// ack_24c04();
// stop_24c04();
//}

DISPLAY.c

void display()
{
goto_xy(1,0);
display_string("AD:");
goto_xy(1,4);
display_num1(ad0);
goto_xy(2,0);
display_string("temp:");
display_xnum2(temp1);

}

仿真

项目七 基于stc89c52系列单片机安全充电仿真_c语言