——基于STC高性能单片机温度采集控制器设计
目录
1. 课程设计目的
2. 硬件设计
3. 软件设计
4. 安装调试
5. 结果分析
6. 体会
7. 参考文献
(一)课程设计目的
通过基于STC高性能单片机温度采集控制器 的硬件设计和软件编程,了解STC单片机硬 件电路设计的一般方法和软件编程的思路及 方法,巩固单片机课程的理论知识,提高单片机小系统设计和调试的技巧,增强对基于 项目的课题设计的本领。
(二)硬件设计
???????????????
(一)软件设计
#include"reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include"lcd.h"
#include"temp.h"
#include
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit beep=P1^5;
void LcdDisplay(int);
void UsartConfiguration();
u8 Disp[]="170030153WELCOME";
u8 Disp_1[]=" ZHAOZIQIANG ";
u8 CNCHAR[6] = "摄氏度";
void Lcdprint()//显示姓名,学号
{
u16 i;
for(i=0;i<16;i++)
{
LcdWriteData(Disp[i]);
}
}
void Lcdprint_1()//只显示学号
{
u16 i;
for(i=0;i<16;i++)
{
LcdWriteData(Disp_1[i]);
}
}
void delay(u16 i)//延时
{
u16 j;
for(j=0;j<10;j++)
{
while(i--);
}
}
void main(void)
{
LcdInit();
Lcdprint_1(); //第1次,第一行显示姓名
delay(150000);//延时
UsartConfiguration();
LcdInit(); //初始化LCD1602
LcdWriteCom(0x00+0x80);//写地址 80表示初始地址
Lcdprint(); //第2次,第一行显示学号,和欢迎
LcdWriteCom(0x40+0x87);
LcdWriteData('C'); //第2次,第二行显示温度
while(1)
{
LcdDisplay(Ds18b20ReadTemp());
Delay1ms(1);//1s钟刷一次
//调整延时时间得到不同频率的响声
}
}
void LcdDisplay(int temp) //lcd显示
{
unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
float tp;
if(temp< 0)//当温度值为负数
{
LcdWriteCom(0x80+0x40);//写地址 80表示初始地址
SBUF='-';//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
LcdWriteData('-'); //显示负
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算由?.5,还是在小数点后面。
}
else
{
LcdWriteCom(0x80+0x40);//写地址 80表示初始地址
LcdWriteData('+'); //显示正
SBUF='+';//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
datas[0] = temp / 10000;
datas[1] = temp % 10000 / 1000;
datas[2] = temp % 1000 / 100;
datas[3] = temp % 100 / 10;
datas[4] = temp % 10;
LcdWriteCom(0x81+0x40); //写地址 80表示初始地址
LcdWriteData('0'+datas[0]); //百位
SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x82+0x40); //写地址 80表示初始地址
LcdWriteData('0'+datas[1]); //十位
SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x83+0x40);//写地址 80表示初始地址
LcdWriteData('0'+datas[2]); //个位
SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x84+0x40);//写地址 80表示初始地址
LcdWriteData('.'); //显示 ‘.’
SBUF = '.';//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x85+0x40); //写地址 80表示初始地址
LcdWriteData('0'+datas[3]); //显示小数点
SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x86+0x40); //写地址 80表示初始地址
LcdWriteData('0'+datas[4]); //显示小数点
SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
for(i=0; i<6; i++)
{
SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
}
}
void UsartConfiguration()//函 数 名 :UsartConfiguration()函数功能 :设置串口
{
SCON=0X50;//设置为工作方式1
TMOD=0X20;//设置计数器工作方式2
PCON=0X80;//波特率加倍
TH1=0XF3;//计数器初始值设置,注意波特率是4800的
TL1=0XF3;
//ES=1;//打开接收中断
//EA=1;//打开总中断
TR1=1;//打开计数器
}
!!!!!!!!!!!!!!!!!!
上面是主函数,temp.c也进行了更改,不懂的直接复制进去就好。
int Ds18b20ReadTemp()
{ float fmq=0;
int temp = 0;
uchar tmh, tml;
Ds18b20ChangTemp(); //先写入转换命令
Ds18b20ReadTempCom();//然后等待转换完后发送读取温度命令
tml = Ds18b20ReadByte();//读取温度值共16位,先读低字节
tmh = Ds18b20ReadByte();//再读高字节
temp = tmh;
temp <<= 8;
temp |= tml;
fmq=temp*0.0625*100+0.5;
if( fmq>=2600)
{
beep=~beep;
}
return temp;
}
(四)安装调试
将普中科技开发板与电脑相连,并将lcd正确插入开发板里,利用烧录软件将程序烧录进芯片里即可观察到现象。 Lcd显示屏首先显示ZHAOZIQIANG字符串6秒,随后lcd第一行显示170030153WELCOME字符串,第二行显示实时温度。当温度升至26.00°c时,蜂鸣器发出报警声。 (五) 结果分析 正确输出了实时温度,当温度超出26°c发出滴滴的报警声。程序无报错,实验现象符合预期。 (六)体会开始我想用数码管进行显示,但没有办法显示我姓名,数码管只能显示0-F,只能换用lcd1602,拿到普中科技lcd1602源程序后,将程序研究后更改显示内容,成功显示出170030153,或者zhaoziqiang字符串,但是只可以显示一行,没办法在第二行显示,查找之后发现第一行地址为0x80,第二行地址为0x80+0x40,虽然找到了入口地址,但怎末调用函数进行显示成了难题。
因为lcd1602源程序并没有写第一行入口地址,直接就是初始化,写入命令。经过漫长的对比查找后,大概3个小时吧,才发现调用入口地址函数在lcd.h里,至此,成功的在第二行显示出了内容。
可以在第二行显示内容后,接下来就是将DS18B20温度传感器采集的内容传到显示屏显示即可。一开始我想把读到的温度拆成位后读出来像字符串一样进行显示,但无论如何都没办法显示出内容。后来研究了普中科技的代码,他的是串口接受温度,把得到的位一位一位的通过发送寄存器发出去,,,没有理解,但不妨碍我借用,果然出结果了,真神奇啊!
项目进入尾声,只差报警函数了,只有一个蜂鸣器能出声,led能闪瞎眼,果断弃用,就决定是你了,蜂鸣器!将蜂鸣器函数放在主函数里,处理的温度转了2轮才到蜂鸣器,这样太慢了,请小伙伴和我一起改进吧,将蜂鸣器函数放在温度处理函数里,这样就可以立即判断温度是否超标。缺点就是响的频率与lcd刷新频率也有关系了。
最后优化了lcd 刷新频率,使得蜂鸣器也可以清脆的哒哒哒哒哒哒哒哒,项目结束。
(7)参考资料 普中科技,实验17:DS18B20温度传感器源程序 普中科技,实验23:LCD12864液晶源程序 普中科技,中级实验7. LCD1602显示温度+串口接收温度源程序