单片机温度测量及双机通信.docx
《单片机温度测量及双机通信.docx》由会员分享,可在线阅读,更多相关《单片机温度测量及双机通信.docx(15页珍藏版)》请在冰豆网上搜索。
单片机温度测量及双机通信
(1)主机程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
uchartable[30]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
0x77,0x7C,0x39,0x5E,0x79,0x71,
0x3F,0x40,
0x06,0x37,
0x5c,0x1c,0x78};//0-9,数码管代码
//a-f,
//0,-,16,17
//in,18,19
//out,20,21,22
ulongsaved_data[10]={0,0,0,0,0,0,0,0,0,0};//保存的十个四位数据,默认为零
uchardisplay[6];//分别保存六位数码管的数值
uchars_diplay[6];//保存串口通信时显示值
//uchardis_buf;//显示缓存
uchartemp1;//
ucharkey;//键顺序码
ucharkeydown_flag=0;//有键按下标志
ucharback_flag=0;//返回菜单标志,为1时返回菜单
/*延时子程序*/
voiddelay(ucharx)
{
ucharj;
while((x--)!
=0)
{
for(j=0;j<125;j++);
}
}
/*键扫描子程序*/
voidkeyscan(void)
{
uchartemp;//临时保存端口值
P1=0x0F;//低四位输入
delay
(1);
temp=P1;//读P1口
temp=temp&0x0F;
temp=~(temp|0xF0);
if(temp==1)
key=0;
elseif(temp==2)
key=4;
elseif(temp==4)
key=8;
elseif(temp==8)
key=12;
else
key=16;
P1=0xF0;//高四位输入
delay
(1);
temp=P1;//读P1口
temp=temp&0xF0;
temp=~((temp>>4)|0xF0);
if(temp==1)
key=key+0;
elseif(temp==2)
key=key+1;
elseif(temp==4)
key=key+2;
elseif(temp==8)
key=key+3;
else
key=16;
}
/*判断键是否按下*/
voidkeydown(void)
{
ucharktemp;
keydown_flag=0;
P1=0xF0;
ktemp=P1;
if(ktemp!
=0xF0)
{
delay(20);//去抖
ktemp=P1;
if(ktemp!
=0xF0)
{
keyscan();
keydown_flag=1;
while(P1!
=0xF0);//等待键释放
}
}
}
voidmenu(void);//函数声明
/*显示函数*/
voidlcd_display(uchara[6])
{
uchari;
ucharb[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
for(i=0;i<6;i++)
{
P2=b[i];//各位轮流置低电平
P0=table[a[i]];
delay
(2);
P0=0x00;//消影
}
}
/*数据输入函数*/
voiddata_input(void)
{
uchari,number;//循环变量,序号
display[0]=18;
display[1]=19;
display[2]=17;
display[3]=17;
display[4]=17;
display[5]=17;
while(keydown_flag==0)
{
lcd_display(display);//显示“in-----”
keydown();//等待输入数据序号或返回菜单
}
keydown_flag=0;
if(key!
=12&&key<10)//序号必须在0——9内
{
number=key;//保存序号
display[0]=key;
display[1]=17;
display[2]=0;
display[3]=0;
display[4]=0;
display[5]=0;
keydown_flag=0;
while(keydown_flag==0)
{
lcd_display(display);//显示“序号-0000”
keydown();//等待输入数据或清除键或返回菜单
}
keydown_flag=0;
if(key!
=12&&key!
=14)//按菜单键返回菜单,按清除键重新输入
{
for(i=0;i<4;i++)
{
if(key==13)//输入回车,保存数据
{
saved_data[number]=display[5]+10*display[4]+100*display[5]+1000*display[5];
}
elseif(key==14);//输入清除键,重新输入
elseif(key<10)
{
display[2]=display[3];
display[3]=display[4];
display[4]=display[5];
display[5]=key;
while(keydown_flag==0)
{
lcd_display(display);//显示“序号-000x”“序号--00xx”...
keydown();//等待输入数据,清除键或回车键
}
keydown_flag=0;
}
}
if(key!
=14)//输完四位若没有按清除键,则保存数据
{
saved_data[number]=display[5]+10*display[4]+100*display[3]+1000*display[2];
}
if(key==13)//输入回车
{
;//进入下次循环,重新输入序号
}
if(key==12)
{
back_flag=1;//返回主菜单
}
}
elseif(key==12)//返回主菜单
{
back_flag=1;
}
elseif(key==14)//重新输入
{;
}
}
elseback_flag=1;
}
/*数据输出函数*/
voiddata_output(void)
{
ucharnumber;//保存输入的序号
display[0]=20;
display[1]=21;
display[2]=22;
display[3]=17;
display[4]=17;
display[5]=17;
while(keydown_flag==0)
{
lcd_display(display);//显示“out----”
keydown();//等待输入数据序号
}
keydown_flag=0;
if(key!
=12&&key<10)
{
number=key;//保存序号
display[0]=key;
display[1]=17;
display[2]=saved_data[number]/1000;//取千位
display[3]=(saved_data[number]/100)%10;//取百位
display[4]=(saved_data[number]/10)%10;//取十位
display[5]=saved_data[number]%10;//取个位
while(keydown_flag==0)
{
lcd_display(display);//显示“序号-xxxx”
keydown();//继续输出或返回主菜单
}
keydown_flag=0;
if(key==13)//输入回车,重新输入序号
{
;
}
elseback_flag=1;//若不是回车,返回主菜单
}
elseback_flag=1;
}
/*串口初始化函数*/
voidinit_usart(void)
{
SCON=0x50;//REN=1允许串行接受状态,串口工作模式2
TMOD=0x20;//定时器工作方式2
PCON=0x80;//波特率提高一倍
//TH1=0xFD;//baud*2/*reloadvalue19200、数据位8、停止位1。
效验位无(11.0592)
TH1=0xF3;////baud*2/*8波特率4800、数据位8、停止位1。
效验位无(12M)
TL1=0xF3;
TR1=1;//开启定时器1
ES=1;//开串口中断
EA=1;//开总中断
}
/*串口通信函数*/
voidserial(void)
{
display[5]=display[4];
display[4]=display[3];
display[3]=display[2];
display[2]=display[1];
display[1]=display[0];
display[0]=key;//装入全局数组
SBUF=key;//发送键值
while(TI==0);//当发送标志位为0,即未完成发送,则一直等待,直到发送完成
TI=0;//发送完成之后,将发送中断标志TI置0
if(key!
=12)//按菜单键返回菜单
{
while(keydown_flag==0)
{
lcd_display(display);//显示输入数据
keydown();//等待输入数据
}
}
elseback_flag=1;
}
/*菜单函数,选择不同功能*/
voidmenu(void)
{
while
(1)
{
uchari;
back_flag=0;//返回菜单标志清零
for(i=0;i<6;i++)
{
display[i]=17;//显示"------"
}
lcd_display(display);
keydown();//等待输入功能序号
if(keydown_flag==1&&key>0&&key<4)
{
temp1=key;//获得键值
keydown_flag=0;
while(keydown_flag==0)
{
display[0]=temp1;
lcd_display(display);//显示“键值-----”
keydown();//等待输入回车
}
keydown_flag=0;
if(key==13)//按回车键进入选择的功能
{
switch(temp1)
{
case1:
while(back_flag==0)
{
data_input();
}
break;
case2:
while(back_flag==0)
{
data_output();
}
break;
case3:
display[0]=5;
display[1]=14;
display[2]=17;
display[3]=17;
display[4]=17;
display[5]=17;
while(keydown_flag==0)
{
lcd_display(display);//显示“se-----”
keydown();//等待输入数据
}
display[0]=17;
display[1]=17;
while(back_flag==0)
{
keydown_flag=0;
serial();
}
break;
default:
break;
}
}
}
}
}
/*主程序*/
main()
{
P0=0x00;//置P0口
P2=0xFF;//置P2口
init_usart();//串口初始化
while
(1)
{
menu();
//lcd_display(display);
}
}
(2)从机程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
uchartable[30]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
0x77,0x7C,0x39,0x5E,0x79,0x71,
0x3F,0x40,
0x06,0x37,
0x5c,0x1c,0x78};//0-9,数码管代码
//a-f,
//0,-,16,17
//in,18,19
//out,20,21,22
//ulongsaved_data[10]={0,0,0,0,0,0,0,0,0,0};//保存的十个四位数据,默认为零
uchardisplay[6]={17,17,17,17,17,17};//分别保存六位数码管的数值
//uchars_diplay[6];//保存串口通信时显示值
ucharcount=0;//记录串口输入数据个数
ucharflag;//
/*延时子程序*/
voiddelay(ucharx)
{
ucharj;
while((x--)!
=0)
{
for(j=0;j<125;j++);
}
}
/*显示函数*/
voidlcd_display(uchara[6])
{
uchari;
ucharb[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
for(i=0;i<6;i++)
{
P2=b[i];//各位轮流置低电平
P0=table[a[i]];
delay
(2);
P0=0x00;//消影
}
}
/*串口初始化函数*/
voidinit_usart(void)
{
SCON=0x50;//REN=1允许串行接受状态,串口工作模式1
TMOD=0x20;//定时器工作方式2
PCON=0x80;//波特率提高一倍
//TH1=0xFD;//baud*2/*reloadvalue19200、数据位8、停止位1。
效验位无(11.0592)
TH1=0xF3;//baud*2/*8波特率4800、数据位8、停止位1。
效验位无(12M)
TL1=0xF3;
TR1=1;//开启定时器1
ES=1;//开串口中断
EA=1;//开总中断
}
voidmain(void)
{
init_usart();
while
(1)
{
if(flag==1)
{
lcd_display(display);
}
else
{
display[0]=17;
display[1]=17;
display[2]=17;
display[3]=17;
display[4]=17;
display[5]=17;
lcd_display(display);
}
}
}
/*串口中断*/
voidser_int(void)interrupt4using1
{
uchartemp;
if(RI==1)//若RI接受中断标志为1,即收到数据
{
RI=0;//清除RI接受中断标志
temp=SBUF;//SUBF接受/发送缓冲器
if(temp==12)//如果是菜单键,
{
flag=0;
}
else
{
flag=1;
display[5]=display[4];
display[4]=display[3];
display[3]=display[2];
display[2]=display[1];
display[1]=display[0];
display[0]=temp;
}
}
}