【优秀课设】51单片机LCD1602显示的温度控制系统设计 包括时间显示 校时、设置最值温度报警功能
前言
1、将DS18B20温度传感器的温度读出来,并在LCD1602上显示出来。
2、在LCD上分别切换显示,软件设计时钟(时、分、秒),和当前温度值,和温度上下控制值。并可以通过按键进行修改设置,温度高于上限,或下线都由蜂鸣器发出报警声。
3、实现校时、校分、校秒功能。
download.csdn.net/download/weixin_53403301/13724845
附件里附带所有程序、工程以及仿真图,仿真图为T-LCD2,程序工程为T-LCD,主程序是main.c
附件链接:
download.csdn.net/download/weixin_53403301/13724845
实验原理图:(用的protues仿真 C代码用keil编译器所写)
硬件实物图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zj6JwAx1-1622607997660)(https://img-bbs.csdn.net/upload/202012/18/1608303045_346176.jpg#pic_center)]
模式0为显示温度 时间 模式123分别为调个位、十位、十分位 按对应的按键就能实现调最高或最低 模式45显示最高、最低温度
570行主程序+100温度传感器+70行1602显示 实现单片机温度时间显示 精确到十分位 并且有校时、设置最值温度报警功能 精确到十分位
#include<reg52.h> //µ÷ÓÃ52µ¥Æ¬»ú¿â
#include"1602.h" //µ÷ÓÃLCD1602¿â
#include"ds18b20.h" //µ÷ÓÃds18b20ζȴ«¸ÐÆ÷
#define uint unsigned int
#define uchar unsigned char
uchar hour,min,sec,count,hour1,hour2, //¶¨ÒåСʱ ·ÖÖÓ Ãë ¶ÔÓ¦µÄʮλ¸öλ ÒÔ¼° count¼ÆÊý
sec1,sec2,min1,min2;
sbit speaker=P2^1; //¶¨Òå·äÃùÆ÷
sbit key1=P1^0; //×îµÍζÈÉèÖÃ
sbit key2=P1^1; //×î¸ßζÈÉèÖÃ
sbit key3=P1^2; //Á¬½ÓÇл»Ä£Ê½µÄ±¸Óÿª¹Ø P33ºÍP12¿Ú¶Ì½Ó ÓÃÓÚÇл»Ä£Ê½ºÍÍ˳ö±¨¾¯ÖжÏ
sbit keyh=P1^5; //Уʱ
sbit keym=P1^6; //У·Ö
sbit keys=P1^7; //УÃë
//¶¨Òåʱ¼ä°´¼ü
uint tem; //¶¨Òå²É¼¯Î¶È
int htem,htem2,time,time2,x,y,z,dot,dot2,maxtem,mintem; //¶¨ÒåζÈʮλÊý¡¢¸öλÊý¡¢Ð¡Êý£¬ÒÔ¼°ÆäÈýÖÖģʽµÄ±ê¼ÇÖµ
int cnt1=1,cnt2=1,cnt3=1,cnt4=1,cnt5=1,cnt6=1,cnt7=1; //¶¨Òå¼ÆÊý±äÁ¿
int i;
uchar mode=0; //¶¨Òåģʽ±äÁ¿
uchar code t3[]={" H/L=0/1: C"}; //ÏÔʾµ÷×îֵζȵÄʮλ
uchar code t4[]={"O/D: C"}; //ÏÔʾµ÷×îֵζȵĸöλ/СÊýλ×ÖÄ£
uchar code table2[]={
'0','1','2','3','4','5','6','7','8','9',':'}; //ÏÔʾʱ¼äµÄ×ÖÄ£
uchar code t5[]={"Max . CD"}; //ÏÔʾ×î¸ßζȵÄ×ÖÄ£
uchar code t6[]={"Min . CD"}; //ÏÔʾ×îµÍζȵÄ×ÖÄ£
//ÑÓʱº¯Êý
void delay1(uint i)
{
while(i--);
}
//ÏÔʾº¯Êý1 ³õʼÏÔʾ
void display(uint dat,uchar add)
{
uchar bai,shi ,ge;
bai=dat/100;
shi=dat%100/10;
ge=dat%10;
writelcd_cmd(add);
writelcd_dat(bai+0x30);
writelcd_dat(shi+0x30);
writelcd_cmd(add+3);
writelcd_dat(ge+0x30);
}
void lcd_min() //¶¨Òå×îСζÈÏÔʾ
{
uchar l;
writelcd_cmd(0x38); //³õʼ»¯ÆÁÄÇåÆÁ»
delay(5);
writelcd_cmd(0x38);
delay(5);
writelcd_cmd(0x38);
writelcd_cmd(0x08);
writelcd_cmd(0x01);
writelcd_cmd(0x06);
writelcd_cmd(0x0c);
writelcd_cmd(0x80);
writelcd_cmd(0xc0);
for(l=0;l<16;l++) //ÒÀ´Î¶ÁÈ¡t6²¢ÏÔʾ
{
writelcd_dat(t6[l]);
}
display(mintem,0xca);
delay1(5000000000); //ÑÓʱÏÔʾ
}
void lcd_max() //¶¨Òå×î´óζÈÏÔʾ
{
uchar k;
writelcd_cmd(0x38); //³õʼ»¯ÆÁÄ»ÇåÆÁ
delay(5);
writelcd_cmd(0x38);
delay(5);
writelcd_cmd(0x38);
writelcd_cmd(0x08);
writelcd_cmd(0x01);
writelcd_cmd(0x06);
writelcd_cmd(0x0c);
writelcd_cmd(0x80);
writelcd_cmd(0xc0);
for(k=0;k<16;k++) //ÒÀ´Î¶ÁÈ¡t5²¢ÏÔʾ
{
writelcd_dat(t5[k]);
}
display(maxtem,0xca);
delay1(5000000000);
}
void write_Char(unsigned char a,unsigned char b,unsigned char dat) //ÏÔʾʱ¼ä³ÌÐòĸ³ÌÐò ¶¨Î»
{
if (b == 0)
{
writelcd_cmd(0x80 + a);
}
else
{
writelcd_cmd(0xC0 + a);
}
writelcd_dat(dat);
}
void display4(uchar hour1,uchar hour2,uchar min1,uchar min2,uchar sec1,uchar sec2) //ÏÔʾʱ¼ä×Ó³ÌÐò È¡Öµ
{
write_Char(4,0,table2[hour1]); //ÏÔʾСʱ
write_Char(5,0,table2[hour2]);
write_Char(6,0,table2[0x0a]); //ÏÔʾðºÅ
write_Char(7,0,table2[min1]); //·ÖÖÓ
write_Char(8,0,table2[min2]);
write_Char(9,0,table2[0x0a]); //ÏÔʾðºÅ
write_Char(10,0,table2[sec1]); //Ãë
write_Char(11,0,table2[sec2]);
}
//ÏÔʾº¯Êý2 µ÷×îֵζȵÍʮλ ÔÚLCDÉÏÅÅÏÔʾ
void display2(uint dat,uchar add)
{
uchar bai,shi ;
bai=dat/100;
shi=dat%100/10;
//ge=dat%10;
writelcd_cmd(add);
writelcd_dat(shi+0x30);
writelcd_dat(bai+0x30);
writelcd_cmd(add+3);
//writelcd_dat(ge+0x30);
}
//ÏÔʾº¯Êý3 µ÷×îֵζȵĸöλ/СÊý ÔÚLCDÏÂÅÅÏÔʾ
void display3(uint dat,uchar add)
{
uchar ge;
//bai=dat/100;
//shi=dat%100/10;
ge=dat%10;
writelcd_cmd(add);
//writelcd_dat(shi+0x30);
//writelcd_dat(bai+0x30);
//writelcd_cmd(add+3);
writelcd_dat(ge+0x30);
}
//°´¼üɨÃ躯Êý
void keyscan()
{ uchar i,j; //¶¨Òåi/j
writelcd_cmd(0x80); //ÏÔʾº¯Êý±íʾÒÔ´ËÏÔʾt3×ÖÄ£ÀïÃæµÄ×Ö·û
for(i=0;i<16;i++)
{writelcd_dat(t3[i]);}
writelcd_cmd(0xc0);
for(j=0;j<16;j++) //ÏÔʾº¯Êý±íʾÒÔ´ËÏÔʾt4×ÖÄ£ÀïÃæµÄ×Ö·û
{writelcd_dat(t4[j]);}
while(mode!=0) //µ±mode²»Îª0ʱ
{
display2(htem,0x8b); //ÏÔʾµ÷ʮλ
display3(time,0xca); //ÏÔʾµ÷¸öλСÊýλ
while(mode!=0)
{
switch(mode) //Çл»Ä£Ê½caseÓï¾äÑ»· 5¸öģʽ 5¸öÑ»· 6¸ö±äÁ¿ ³õʼģʽΪ0 Çл»ºó¶ÔÓ¦µØ·½µÄ¹â±êÉÁ˸
{
case 1:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break; //µ÷¸öλ
case 2:writelcd_cmd(0x80+11);writelcd_cmd(0x0f);break; //µ÷ʮλ
case 3:writelcd_cmd(0xc0+10);writelcd_cmd(0x0f);break; //µ÷СÊýλ
case 4:lcd_max();break; //ÏÔʾ×î´óζÈ
case 5:lcd_min();break; //ÏÔʾ×îСζÈ
default:mode=0;break;
}
if(key2==0&&mode==1) //ģʽΪ1 key2Ϊ0ʱ µ÷×î¸ßλµÄ¸öλ
{
delay(50); //°´¼üÏû¶¶
y=0;display3(y,0x80);writelcd_cmd(0xca+11); //max one ÔÚ×óÉϽÇÏÔʾ0 ±íʾµ÷×î¸ßζÈ
if(key2==0)
{
delay(10); //Ê®¸öÑ»· ¶ÔÓ¦0-9Êý×Ö
cnt1++; //¼ÆÊý+1
while(key2==0);
switch(cnt1%11) //°´¼üµ½10ÒÔºóÇåÁã
{
case 1:time=0;display3(time,0xca);writelcd_cmd(0xca+11);break; //ÔÚ0xcaµÄµØ·½ÏÔʾ¸öλֵ ¹â±êÉÁ˸
case 2:time=1;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 3:time=2;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 4:time=3;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 5:time=4;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 6:time=5;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 7:time=6;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 8:time=7;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 9:time=8;display3(time,0xca);writelcd_cmd(0xca+11);break;
case 10:time=9;display3(time,0xca);writelcd_cmd(0xca+11);break;
default:break;
}
}
}
if(key1==0&&mode==1) //ÀàËÆ ×îµÍ¸öλ
{
delay(50);
y=1;display3(y,0x80);writelcd_cmd(0xca+11); //min one ÔÚ×óÉϽÇÏÔʾ1 ±íʾµ÷×îµÍζÈ
if(key1==0)
{
delay(10);
cnt4++;
while(key1==0);
switch(cnt4%11)
{
case 1:time2=0;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 2:time2=1;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 3:time2=2;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 4:time2=3;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 5:time2=4;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 6:time2=5;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 7:time2=6;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 8:time2=7;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 9:time2=8;display3(time2,0xca);writelcd_cmd(0xca+11);break;
case 10:time2=9;display3(time2,0xca);writelcd_cmd(0xca+11);break;
default:break;
}
}
}
if(key2==0&&mode==2) //×î¸ßʮλ
{
delay(10);
x=00;display2(x,0x80);writelcd_cmd(0x80+11); //max ten ÔÚ×óÉϽÇÏÔʾ00 ±íʾµ÷×î¸ß
if(key2==0)
{
cnt2++;
while(key2==0);
switch(cnt2%11)
{
case 1:htem=00;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 2:htem=10;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 3:htem=20;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 4:htem=30;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 5:htem=40;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 6:htem=50;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 7:htem=60;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 8:htem=70;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 9:htem=80;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
case 10:htem=90;display2(htem,0x8b);writelcd_cmd(0x80+11);break;
default:break;
}
}
}
if(key1==0&&mode==2)
{
delay(10);
x=10;display2(x,0x80);writelcd_cmd(0x80+11); //min ten ÔÚ×óÉϽÇÏÔʾ10±íʾ µ÷×îµÍ
if(key1==0)
{
cnt3++;
while(key1==0);
switch(cnt3%11)
{
case 1:htem2=00;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 2:htem2=10;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 3:htem2=20;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 4:htem2=30;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 5:htem2=40;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 6:htem2=50;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 7:htem2=60;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 8:htem2=70;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 9:htem2=80;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
case 10:htem2=90;display2(htem2,0x8b);writelcd_cmd(0x80+11);break;
default:break;
}
}
}
if(key2==0&&mode==3) //×î¸ßСÊý
{
delay(50);
z=00;display2(z,0x80);writelcd_cmd(0xca+11); //max dot
if(key2==0)
{
delay(10);
cnt5++;
while(key2==0);
switch(cnt5%11)
{
case 1:dot=0;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 2:dot=1;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 3:dot=2;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 4:dot=3;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 5:dot=4;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 6:dot=5;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 7:dot=6;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 8:dot=7;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 9:dot=8;display3(dot,0xca);writelcd_cmd(0xca+11);break;
case 10:dot=9;display3(dot,0xca);writelcd_cmd(0xca+11);break;
default:break;
}
}
}
if(key1==0&&mode==3) //×îµÍСÊý
{
delay(50);
z=10;display2(z,0x80);writelcd_cmd(0xca+11); //min dot
if(key1==0)
{
delay(10);
cnt6++;
while(key1==0);
switch(cnt6%11)
{
case 1:dot2=0;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 2:dot2=1;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 3:dot2=2;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 4:dot2=3;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 5:dot2=4;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 6:dot2=5;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 7:dot2=6;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 8:dot2=7;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 9:dot2=8;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
case 10:dot2=9;display3(dot2,0xca);writelcd_cmd(0xca+11);break;
default:break;
}
}
}
if(mode==4) //ģʽ4 ÏÔʾ×î´óζÈ
{
maxtem=htem*10+time*10+dot;
lcd_max();
}
if(mode==5) //×îµÍζÈ
{
mintem=htem2*10+time2*10+dot2;
lcd_min();
}
}
}
lcd_init(); //ģʽΪ0ʱִÐÐLCD³õʼ»¯º¯Êý
}
//Öжϳõʼ»¯º¯Êý
void init()
{
lcd_init(); //lcd³õʼ»¯
speaker=1; //·äÃùÆ÷¿ÚĬÈϸߵçƽ
mode=0; //ģʽĬÈÏ0
htem=80; //×î¸ßζÈĬÈÏ80
time=0;
htem2=10; //×îµÍζÈĬÈÏ10
time2=0;
dot=0;
dot2=0;
EA=1; //×ÜÖжϿªÆô
EX1=1; //ÍⲿÖжÏ1ÔÊÐí
ET1=1; //¶¨Ê±Æ÷1ÔÊÐí
TMOD=0X01; //¶¨Ê±ÖжÏ1£¬Ä£Ê½1
IT1=1; //ÖжÏ1 ϽµÑØ´¥·¢
TH1=0Xee; //¶¨Ê±ÖжÏ1 0.5us
TL1=0X00;
TR1=0; //¶¨Ê±ÖжÏ1ĬÈϹرÕ
count=0; //ʱ¼ä¼ÆÊýĬÈÏΪ0
hour=00; //Сʱ00
min=00; //·ÖÖÓ00
sec=00; //Ãë00
TH0=(65536-50000)/256; //ÄÚ²¿ÖжÏT0³õʼ»¯
TL0=(65536-50000)%256;
TR0=1; //ÄÚ²¿ÖжÏT0¿ªÆô
ET0=1;
}
//Ö÷º¯Êý
void main()
{
P1=0xe7; //³õʼP1¿Ú£¬P14£¬P13ΪµÍµçƽ ʹS1 S5 S9 S14 S15 S16±äΪ½ÓµØµÄÆÕͨ¿ª¹Ø S9ÓëP33¶Ì½Ó ÓÃÓÚÇл»Ä£Ê½ºÍÍ˳ö±¨¾¯ÖжÏ
init(); //Öжϳõʼ»¯
while(1)
{
if(mode!=0) //µ±Ä£Ê½²»Îª0
{keyscan();} //Ö´Ðа´¼üɨÃè ÒÔ¼°µ÷ζȵijÌÐò
else if(mode==0) //ģʽΪ0ʱ
{
delay(100);
tmpchange(); //ÔÚds18b20È¡Êý¾Ý
tem=tmp(); //ζÈÖµ»ñÈ¡ ΪÕûÊý ÇÒСÊýλʵ¼ÊÉÏÊǸöλ Èç35.5ÉãÊ϶ȶÔÓ¦µÄÖµÊÇ355
if(keyh==0) //µ±S14±ÕºÏʱ ʵÏÖСʱ¼ÓÒ»
{
delay(5);
if(keyh==0)
{
if(hour!=23) hour++; //hour=23ºóÇåÁã
else hour=0;
}
while(!keyh); //¼ì²âËÉÊÖ
}
if(keym==0) //ʵÏÖ·ÖÖÓ¼ÓÒ»
{
delay(5);
if(keym==0)
{
if(min!=59) //59ºóÇåÁã
{
min++;
}
else
{
min=0;
}
}
while(!keym); //ËÉÊÖ¼ì²â
}
if(keys==0) //ʵÏÖÃë¼ÓÒ»
{
delay(5);
if(keys==0)
{
if(sec!=59) //59ºóÇåÁã
{
sec++;
}
else
{
sec=0;
}
}
while(!keys);
}
hour1=hour/10; //Сʱʮλ
hour2=hour%10; //Сʱ¸öλ
min1=min/10; //·ÖÖÓʮλ
min2=min%10; //·ÖÖÓ¸öλ
sec1=sec/10; //Ãëʮλ
sec2=sec%10; //Ãë¸öλ
maxtem=htem*10+time*10+dot;
mintem=htem2*10+time2*10+dot2;
if(tem>=maxtem) //¸ßÓÚ×î¸ß
{
TR1=1; //T1ÖжϿªÆô
}
else if(tem<=mintem) //µÍÓÚ×îµÍ
{
TR1=1; //T1ÖжϿªÆô
}
else //´¦ÓÚÖмä
{
TR1=0; //T1ÖжϹرÕ
//±¨¾¯µÆÃð
}
delay(10);
display(tem,0xca); //Ò»Ö±ÏÔʾζÈ
display4(hour1,hour2,min1,min2,sec1,sec2); //Ò»Ö±ÏÔʾʱÖÓ
delay(100);
}
}
}
//ÍⲿÖжϷþÎñº¯Êý
void exter()interrupt 2 //ÍⲿÖжÏ2
{
delay(50); //°´¼üÏû¶¶
if(P3^3==0) //Á¬½ÓP12ºÍP33µÄ¿ª¹ØS9±ÕºÏ
delay(50); //Ïû¶¶
mode++; //ģʽ+1
mode=mode%7 ; //ÿ°´4´ÎºóÖÃÁã
delay(50);
}
//¶¨Ê±ÖжϷþÎñº¯Êý
void timer0()interrupt 3 //¶¨Ê±ÖжÏT1
{
TH1=0Xee; //ÖØ×°ÔØ
TL1=0X00;
speaker=~speaker; //·äÃùÆ÷²»¶ÏÈ¡·´
delay1(1); //·äÃùÆ÷±¨¾¯ÆµÂÊÑÓʱ
TR1=1; //¶¨Ê±ÖжÏ1Ò»Ö±¿ªÆô
if(key3==0) //µ±±ÕºÏ¿ª¹ØS9ʱ P12ºÍP33ΪµÍµçƽ ¹Ø±ÕÖжÏT1 ²¢ÇÒÇл»µ½µ÷×îֵζȵÄģʽ1
TR1=0;
}
void count0() interrupt 1 //T0ÖÐ¶Ï Ê±¼ä¼Æʱ³ÌÐò
{
TH0=(65536-50000)/256; //ÖØгõʼ»¯T0
TL0=(65536-50000)%256;
count++; //count+1
if(count==20) //ÿ20´Î»úÆ÷Ñ»·ÊµÏÖÃë½ø1
{
count=0;
sec++;
if(sec==60) //Ãëµ½60ʱÇåÁã
{
sec=0;
min++; //·Ö+1
if(min==60) //·Öµ½60ʱÇåÁã
{
min=0;
hour++; //Сʱ+1
if(hour==24) //Сʱµ½24ʱÇåÁã
{
hour=0;
}
}
}
}
}
#include <reg52.h> //µ¼Èë52¿â
#include"1602.h" //µ¼Èë1602¿â
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^7; //¶¨ÒåζȽӿÚ
void dsreset()
{
uint i;
DS=0;
i=103;
while(i>0)i--; //ÑÓʱ´óÔ¼480us~960us
DS=1;
i=4;
while(i>0)i--; //ÑÓʱ´óÔ¼60us~240us
}
bit tmpreadbit() //18b20¶ÁһλÊý¾Ý
{
uint i;
bit dat;
DS=0;i++; //ÀµÍ´óÔ¼1us×óÓÒ
DS=1;i++;i++;
dat=DS; //¶Á»ØÊý¾Ý
i=8;while(i>0)i--; //ÑÓʱ45ms×óÓÒ
return (dat);
}
uchar tmpread() //18b20¶ÁÒ»¸ö×Ö½Úº¯Êý
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1);
}
return(dat);
}
void tmpwrite1() //Ïò18b20дÈë1
{ uint i;
DS=0;
i++;i++; //ÑÓʱ15us×óÓÒ
DS=1;
i=8;while(i>0)i--;
}
void tmpwrite0() //Ïò18b20дÈë0
{ uint i;
DS=0;
i=8;while(i>0)i--; //ÑÓʱ60us×óÓÒ
DS=1;
i++;i++;
}
void tmpwritebyte(uchar dat)//18b20дһ¸ö×Ö½Úº¯Êý
{
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb)
{
tmpwrite1();
}
else
{
tmpwrite0();
}
}
}
void tmpchange() //18b20ζÈת»»º¯Êý
{ //18b20Ö´ÐÐÐòÁУº
dsreset(); //1¡¢³õʼ»¯
delay(1); //
tmpwritebyte(0xcc); //2¡¢rom²Ù×÷Ö¸Áî
tmpwritebyte(0x44); //3¡¢18b20¹¦ÄܲÙ×÷Ö¸Áî
}
uint tmp() //ζÈÈ¡Öµ tempֵΪÎÞ·ûºÅÕûÊý ¿ÉΪ¸ºÊý
{
uint temp;
float tt;
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe);
a=tmpread();
b=tmpread();
temp=b;
temp<<=8;
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5; //¼Ó0.5ËÄÉáÎåÈë
return temp;
}
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit rs=P3^0; //¶¨ÒåLCD½Ó¿Ú
sbit rw=P3^1;
sbit en=P3^2;
uchar code t1[]={"TX ZZN"}; //³õʼLCDÆÁÄ»ÉÏÐÐÏÔʾ °à¼¶ ÐÕÃû
uchar code t2[]={"181105035 . CD"}; //ÏÂÐÐÏÔʾ ѧºÅ СÊýµã ÉãÊ϶ȼòдCD
void delay(uint ms) //ÑÓʱ
{
uint i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}
void writelcd_cmd(uchar cmd)//Ïò1602Òº¾§ÏÔʾÆ÷ÀïдÈëÃüÁîµÄº¯Êý
{
en=0;
rs=0;
rw=0;
delay(1);
P0=cmd; //P0¿ÚÊä³ö
en=1;
delay(1);
en=0;
}
void writelcd_dat(uchar dat)//Ïò1602Òº¾§ÏÔʾÆ÷ÀïдÈëÊý¾ÝµÄº¯Êý
{
en=0;
rs=1;
rw=0;
delay(1);
P0=dat;
en=1;
delay(1);
en=0;
}
void lcd_init() //³õʼ»¯1602Òº¾§ÏÔʾÆ÷µÄº¯Êý
{
uchar i,j;
writelcd_cmd(0x38); //ÇåÆÁÏÔʾ
delay(5);
writelcd_cmd(0x38);
delay(5);
writelcd_cmd(0x38);
writelcd_cmd(0x08);
writelcd_cmd(0x01);
writelcd_cmd(0x06);
writelcd_cmd(0x0c);
writelcd_cmd(0x80);
for(i=0;i<16;i++)
{
writelcd_dat(t1[i]); //ÿһλÒԴ˶ÁÈ¡×ÖÄ£t1²¢ÏÔʾ×Ö·û
}
writelcd_cmd(0xc0);
for(j=0;j<16;j++) //ÒÀ´Î¶ÁÈ¡t2²¢ÏÔʾ
{
writelcd_dat(t2[j]);
}
}
具体的代码功能在附件程序里都有标注 代码就不放了 keil里面的标注会识别成特殊字符
附录:压缩字符串、大小端格式转换
压缩字符串
首先HART数据格式如下:
重点就是浮点数和字符串类型
Latin-1就不说了 基本用不到
浮点数
浮点数里面 如 0x40 80 00 00表示4.0f
在HART协议里面 浮点数是按大端格式发送的 就是高位先发送 低位后发送
发送出来的数组为:40,80,00,00
但在C语言对浮点数的存储中 是按小端格式来存储的 也就是40在高位 00在低位
浮点数:4.0f
地址0x1000对应00
地址0x1001对应00
地址0x1002对应80
地址0x1003对应40
若直接使用memcpy函数 则需要进行大小端转换 否则会存储为:
地址0x1000对应40
地址0x1001对应80
地址0x1002对应00
地址0x1003对应00
大小端转换:
void swap32(void * p)
{
uint32_t *ptr=p;
uint32_t x = *ptr;
x = (x << 16) | (x >> 16);
x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);
*ptr=x;
}
压缩Packed-ASCII字符串
本质上是将原本的ASCII的最高2位去掉 然后拼接起来 比如空格(0x20)
四个空格拼接后就成了
1000 0010 0000 1000 0010 0000
十六进制:82 08 20
对了一下表 0x20之前的识别不了
也就是只能识别0x20-0x5F的ASCII表
压缩/解压函数后面再写:
//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_ASCII_to_Pack(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
if(str_len%4)
{
return 0;
}
uint8_t i=0;
memset(buf,0,str_len/4*3);
for(i=0;i<str_len;i++)
{
if(str[i]==0x00)
{
str[i]=0x20;
}
}
for(i=0;i<str_len/4;i++)
{
buf[3*i]=(str[4*i]<<2)|((str[4*i+1]>>4)&0x03);
buf[3*i+1]=(str[4*i+1]<<4)|((str[4*i+2]>>2)&0x0F);
buf[3*i+2]=(str[4*i+2]<<6)|(str[4*i+3]&0x3F);
}
return 1;
}
//传入的字符串和数字必须提前声明 且字符串大小至少为str_len 数组大小至少为str_len%4*3 str_len必须为4的倍数
uint8_t Trans_Pack_to_ASCII(uint8_t * str,uint8_t * buf,const uint8_t str_len)
{
if(str_len%4)
{
return 0;
}
uint8_t i=0;
memset(str,0,str_len);
for(i=0;i<str_len/4;i++)
{
str[4*i]=(buf[3*i]>>2)&0x3F;
str[4*i+1]=((buf[3*i]<<4)&0x30)|(buf[3*i+1]>>4);
str[4*i+2]=((buf[3*i+1]<<2)&0x3C)|(buf[3*i+2]>>6);
str[4*i+3]=buf[3*i+2]&0x3F;
}
return 1;
}
大小端转换
在串口等数据解析中 难免遇到大小端格式问题
什么是大端和小端
所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
简单来说:大端——高尾端,小端——低尾端
举个例子,比如数字 0x12 34 56 78在内存中的表示形式为:
1)大端模式:
低地址 -----------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
2)小端模式:
低地址 ------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12
可见,大端模式和字符串的存储模式类似。
数据传输中的大小端
比如地址位、起止位一般都是大端格式
如:
起始位:0x520A
则发送的buf应为{0x52,0x0A}
而数据位一般是小端格式(单字节无大小端之分)
如:
一个16位的数据发送出来为{0x52,0x0A}
则对应的uint16_t类型数为: 0x0A52
而对于浮点数4.0f 转为32位应是:
40 80 00 00
以大端存储来说 发送出来的buf就是依次发送 40 80 00 00
以小端存储来说 则发送 00 00 80 40
由于memcpy等函数 是按字节地址进行复制 其复制的格式为小端格式 所以当数据为小端存储时 不用进行大小端转换
如:
uint32_t dat=0;
uint8_t buf[]={0x00,0x00,0x80,0x40};
memcpy(&dat,buf,4);
float f=0.0f;
f=*((float*)&dat); //地址强转
printf("%f",f);
或更优解:
uint8_t buf[]={0x00,0x00,0x80,0x40};
float f=0.0f;
memcpy(&f,buf,4);
而对于大端存储的数据(如HART协议数据 全为大端格式) 其复制的格式仍然为小端格式 所以当数据为小端存储时 要进行大小端转换
如:
uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
memcpy(&dat,buf,4);
float f=0.0f;
swap32(&dat); //大小端转换
f=*((float*)&dat); //地址强转
printf("%f",f);
或:
uint8_t buf[]={0x40,0x80,0x00,0x00};
memcpy(&dat,buf,4);
float f=0.0f;
swap32(&f); //大小端转换
printf("%f",f);
或更优解:
uint32_t dat=0;
uint8_t buf[]={0x40,0x80,0x00,0x00};
float f=0.0f;
dat=(buf[0]<<24)|(buf[0]<<16)|(buf[0]<<8)|(buf[0]<<0)
f=*((float*)&dat);
总结
固 若数据为小端格式 则可以直接用memcpy函数进行转换 否则通过移位的方式再进行地址强转
对于多位数据 比如同时传两个浮点数 则可以定义结构体之后进行memcpy复制(数据为小端格式)
对于小端数据 直接用memcpy写入即可 若是浮点数 也不用再进行强转
对于大端数据 如果不嫌麻烦 或想使代码更加简洁(但执行效率会降低) 也可以先用memcpy写入结构体之后再调用大小端转换函数 但这里需要注意的是 结构体必须全为无符号整型 浮点型只能在大小端转换写入之后再次强转 若结构体内采用浮点型 则需要强转两次
所以对于大端数据 推荐通过移位的方式来进行赋值 然后再进行个别数的强转 再往通用结构体进行写入
多个不同变量大小的结构体 要主要字节对齐的问题
可以用#pragma pack(1) 使其对齐为1
但会影响效率
大小端转换函数
直接通过对地址的操作来实现 传入的变量为32位的变量
中间变量ptr是传入变量的地址
void swap16(void * p)
{
uint16_t *ptr=p;
uint16_t x = *ptr;
x = (x << 8) | (x >> 8);
*ptr=x;
}
void swap32(void * p)
{
uint32_t *ptr=p;
uint32_t x = *ptr;
x = (x << 16) | (x >> 16);
x = ((x & 0x00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF);
*ptr=x;
}
void swap64(void * p)
{
uint64_t *ptr=p;
uint64_t x = *ptr;
x = (x << 32) | (x >> 32);
x = ((x & 0x0000FFFF0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF0000FFFF);
x = ((x & 0x00FF00FF00FF00FF) << 8) | ((x >> 8) & 0x00FF00FF00FF00FF);
*ptr=x;
}