单片机电梯控制系统代码分析:LED显示和串口通信
单片机电梯控制系统代码分析:LED显示和串口通信
本代码实现了一个简单的单片机电梯控制系统,通过串口接收目标楼层信息,并控制LED显示当前楼层,同时模拟电梯的上升、下降和停止状态。
代码如下:
uint r= 0; //定义一个无符号整型变量r,初始值为0
char offset = 0; //定义一个字符型变量offset,初始值为0
uchar Current_Level = 1,Dest_Level=1,x=0,t =0; //定义三个无符号字符型变量Current_Level、Dest_Level、x和一个无符号整型变量t,初始值都为1或0
void main() //主函数
{
P1 = 0x80; //将P1口设置为高电平
Current_Level = 1; //设置初始楼层为1
TMOD = 0x21; //设置定时器1和定时器0的工作方式
TH0 = (65536-4000)/256; //设置定时器0的初值为4ms
TL0 = (65536-4000)%256;
TR0=1; //启动定时器0
SCON=0x50; //设置串口模式为模式1
TH1=0xFD;TL1=0xFD; //设置波特率为9600
TR1=1; //启动定时器1
IE = 0x92; //开启中断
EA =1; //开启总中断
while(1); //进入死循环
}
void Serial_Receive() interrupt 4 //串口接收中断函数
{
unsigned char val=0; //定义一个无符号字符型变量val,初始值为0
val=SBUF; //将接收到的数据存入val中
P2=val; //将val的值输出到P2口
if (Dest_Level == Current_Level && val != 0xff) //如果目标楼层等于当前楼层且接收到的数据不为0xff
{
if (val ==0x09)Dest_Level =9; //如果接收到的数据为0x09,将目标楼层设置为9
if (val ==0x08)Dest_Level =8; //如果接收到的数据为0x08,将目标楼层设置为8
if (val ==0x07)Dest_Level =7; //如果接收到的数据为0x07,将目标楼层设置为7
if (val ==0x06)Dest_Level =6; //如果接收到的数据为0x06,将目标楼层设置为6
if (val ==0x05)Dest_Level =5; //如果接收到的数据为0x05,将目标楼层设置为5
if (val ==0x04)Dest_Level =4; //如果接收到的数据为0x04,将目标楼层设置为4
if (val ==0x03)Dest_Level =3; //如果接收到的数据为0x03,将目标楼层设置为3
if (val ==0x02)Dest_Level =2; //如果接收到的数据为0x02,将目标楼层设置为2
if (val ==0x01)Dest_Level =1; //如果接收到的数据为0x01,将目标楼层设置为1
}
RI = 0; //清除接收中断标志位
}
void Led_Dispaly() interrupt 1 //LED显示中断函数
{
uchar i; //定义一个无符号字符型变量i
//发送当前楼层信息
if (Dest_Level == Current_Level) //如果目标楼层等于当前楼层
{
SBUF = 0xff; //发送0xff
}
TH0 = -4000/256; //设置定时器0的初值为4ms
TL0 = -4000%256;
P1 =_crol_(P1,1); //P1口逐行扫描
i = Current_Level *8 + r + offset+1; //计算LED数字在表格中的位置
P0 = ~Table[i]; //将LED数字的值输出到P0口
//电梯上升
if (Current_Level < Dest_Level ) //如果电梯正在往上,电梯当前层数小于目标层数
{
if ( ++r ==8) //偏移量r按照顺序从0~7
{
r =0;
if( ++x ==4) //x代表LED的行数
{
x = 0;
if(++offset ==8) //offset代表LED的列数
{
offset = 0;
Current_Level++; //当前楼层加1
}
}
}
}
//电梯下降
else if(Current_Level > Dest_Level ) //如果电梯正在往下,电梯当前层数大于目标层数
{
if ( ++r ==8) //偏移量r按照顺序从0~7
{
r =0;
if( ++x ==4) //x代表LED的行数
{
x = 0;
if(--offset == -8) //offset代表LED的列数
{
offset = 0;
Current_Level--; //当前楼层减1
}
}
}
}
//电梯停止
else //如果电梯没有移动
{
if ( ++r ==8) r =0; //偏移量r每次加1,r增加到8时,复位为0
}
}
代码分析:
- 变量定义
uint r= 0;: 定义一个无符号整型变量r,用于控制LED显示的偏移量。char offset = 0;: 定义一个字符型变量offset,用于控制LED显示的列数。uchar Current_Level = 1,Dest_Level=1,x=0,t =0;: 定义三个无符号字符型变量Current_Level、Dest_Level、x和一个无符号整型变量t,分别表示当前楼层、目标楼层、LED显示的行数和一个临时变量。
- 主函数
P1 = 0x80;: 将P1口设置为高电平。Current_Level = 1;: 设置初始楼层为1。TMOD = 0x21;: 设置定时器1和定时器0的工作方式,定时器1用于串口通信,定时器0用于控制LED显示的刷新频率。TH0 = (65536-4000)/256;和TL0 = (65536-4000)%256;: 设置定时器0的初值为4ms,用于控制LED显示的刷新频率。TR0=1;: 启动定时器0。SCON=0x50;: 设置串口模式为模式1。TH1=0xFD;TL1=0xFD;: 设置波特率为9600。TR1=1;: 启动定时器1。IE = 0x92;: 开启中断,包括串口接收中断和定时器0中断。EA =1;: 开启总中断。while(1);: 进入死循环,等待中断事件发生。
- 串口接收中断函数
Serial_Receive() interrupt 4;: 定义串口接收中断函数,当串口接收到数据时触发。unsigned char val=0;: 定义一个无符号字符型变量val,用于存储接收到的数据。val=SBUF;: 将接收到的数据存入val中。P2=val;: 将val的值输出到P2口,用于调试。if (Dest_Level == Current_Level && val != 0xff) ...: 如果目标楼层等于当前楼层且接收到的数据不为0xff,则根据接收到的数据设置目标楼层。RI = 0;: 清除接收中断标志位。
- LED显示中断函数
Led_Dispaly() interrupt 1;: 定义LED显示中断函数,由定时器0中断触发,每4ms执行一次。uchar i;: 定义一个无符号字符型变量i,用于存储LED数字在表格中的位置。if (Dest_Level == Current_Level) SBUF = 0xff;: 如果目标楼层等于当前楼层,则向串口发送0xff,通知上位机电梯已经到达目标楼层。TH0 = -4000/256;和TL0 = -4000%256;: 重新设置定时器0的初值为4ms,确保定时器0每4ms产生一次中断。P1 =_crol_(P1,1);: P1口逐行扫描,用于控制LED显示的刷新频率。i = Current_Level *8 + r + offset+1;: 计算LED数字在表格中的位置。P0 = ~Table[i];: 将LED数字的值输出到P0口,控制LED显示。if (Current_Level < Dest_Level ) ...: 如果电梯正在往上,电梯当前层数小于目标层数,则控制LED显示电梯上升过程。else if(Current_Level > Dest_Level ) ...: 如果电梯正在往下,电梯当前层数大于目标层数,则控制LED显示电梯下降过程。else ...: 如果电梯已经到达目标楼层,则控制LED显示电梯停止状态。
代码总结:
本代码通过串口接收目标楼层信息,并控制LED显示当前楼层,同时模拟电梯的上升、下降和停止状态。代码中使用了定时器、中断、串口通信和LED显示等技术,是一个简单实用的单片机控制系统示例。
需要注意的是,本代码只是简单示例,实际的电梯控制系统会更加复杂,需要考虑更多因素,例如安全、效率、可靠性等。
原文地址: https://www.cveoy.top/t/topic/gonY 著作权归作者所有。请勿转载和采集!