📄 serial.c
字号:
#include <reg52.h>
#define uchar unsigned char
bit receive; //接收标志
bit re_finish;//接收一串字符完成标志
sbit lck = P3^5;//HC574锁存信号
sbit LED = P1^3;//串口通信指示
sbit addr0 = P1^4;//系统片选地址线0
sbit addr1 = P1^5;//系统片选地址线1
sbit addr2 = P1^6;//系统片选地址线2
sbit addr3 = P1^7;//系统片选地址线3
uchar i,buffer[8];//串口缓冲区
uchar cash[8]; //数码管显示缓冲区
uchar sbuffer,number;//发送字符个数
uchar sendFINS ; //发送完成标志
uchar copyOK , cmd_numb ;//发送缓冲区填充完成标志
//数码管位扫描数据
uchar code scan[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//row0--row7
//数码管数字码表
uchar code table[18] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,//0,1,2,3,4,5
0x82,0xf8,0x80,0x90,0x88,0x83,//6,7,8,9,a,b
0xc6,0xa1,0x86,0x8e,0xbf,0xff};//c,d,e,f,-,空格
void delay(unsigned int loop); //延时函数声明
/********************************系统初始化函数************************/
void initial(void)
{ uchar j;
SCON=0x50; //串口工作方式1,允许接收
PCON=0x80; //波特率翻倍
TCON=0;
TMOD=0x26; //T1用于串口波特率控制
TL1=0xfa; //初始化T1,波特率为9600(晶振11.0592M)
TH1=0xfa;
TR1=1; //开定时器
EA=1; //开总中断
ES=1; //开串口中断
copyOK = 0; //缓冲区准备好标志清零
receive = 0; //接收标志清零
re_finish = 0; //接受完成标志清零
cmd_numb = 0; //接受计数器清零
P1 = 0xb0; //RS485允许接收
for(j=0; j<8; j++) //串口缓冲区清空
buffer[j] = 17; //table[18]为空显示
for(j=0; j<8; j++) //串口缓冲区清空
cash[j] = 17; //table[18]为空显示
cash[0] = 15;
}
/************************向串口发送字符串*************************/
void send(void)
{
P1 = 0xf0;
if(copyOK) //串口准备好且缓冲区准备好
{
i = 0;
REN = 0; //发送过程中禁止接收数据
copyOK = 0; //清缓冲区准备好标志
SBUF = cash[i++]; //发送字符串首字符
number = 7; //置发送计数器
}
else
return; //没准备好则返回
}
/*****************************串口中断响应处理函数***********************/
void serial(void) interrupt 4
{ uchar k;
if(RI)//为接收中断
{
RI=0; //清接收中断标志
LED = ~LED; //闪串口指示LED
sbuffer = SBUF; //读取串口缓冲区数据
if((sbuffer == 's') && (receive == 0)) //判断是否为数据头 ,是数据头则准备接收
{
receive = 1; //开始接收标志
cmd_numb = 0; //清接收计数器
re_finish = 0; //清接收完成标志
}
else if(sbuffer == 'e') //判断数据尾
{
if(cmd_numb<8)//接收到的字符少于8个
for(k=cmd_numb;k<8;k++)//则空位填空显示
buffer[k] = 17;
re_finish = 1; //置接收完成标志
receive =0; //清接收标志
}
else if(receive){ //判断当前是否处于接收状态
buffer[cmd_numb++] = sbuffer-'0'; //当前字符送缓冲区
}
else //无效命令则返回
return;
}
else{
TI=0; //为单个字符发送完中断
if(!number) //字符串发送完
{ REN = 1; //单片机允许接收
P1 = 0xbf; //RS485允许接收
}
else{ //字符串未发送完
SBUF = cash[i++]; //发送下一字符
number--; //发送字符数减一
}
}
}
/*****************************延时函数**********************/
void delay(unsigned int loop)
{ unsigned int i ; //loop 为执行空指令的次数,改变它可一改变延时时长
for(i=0;i<loop;i++); //循环执行空指令loop次,达到延时目的
}
/******************************数码管显示扫描*************************/
void ledscan()
{ uchar i;
for(i=0;i<8;i++){
P2 = 0xff;//关闭所有数码管
addr3 = 0;
addr0 = 0;
addr1 = 1;
addr2 = 0;//开发板上U4(74HC574)的片选地址
P0 =table[cash[i]]; //取一行显示数据
addr3 = 1;
addr3 = 0;//在U4的11脚(锁存信号)产生上升沿
P2 = scan[i];//取row0--row7行扫描数据
delay(50); //延时50us
}
}
/********************************主函数****************************/
main()
{
initial();
while(1){//主循环
if(re_finish){//把串口缓冲区的内容送到显示缓冲区
cash[0] = buffer[0];
cash[1] = buffer[1];
cash[2] = buffer[2];
cash[3] = buffer[3];
cash[4] = buffer[4];
cash[5] = buffer[5];
cash[6] = buffer[6];
cash[7] = buffer[7];
re_finish = 0;//接收完成标志
copyOK=1;//发送缓冲区填充完成标志
send(); //把显示缓冲区的内容发送给电脑
}
ledscan(); //循环扫描数码管
}
}
/**********************************结束****************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -