串行口通信 发送0~255数据,单片机再将数据发送回上位机
一. 程序功能 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71 init(); while(1) { if (flag == 1) { //flag手动清0,便于下次检测 flag = 0; //关闭串口中断 ES = 0; //将8位数据分解成百,十,个位 dData = a; bai = dData / 100; shi = dData % 100 / 10; ge = dData % 10; //num1计数,达到满255清0 num1++; if (num1 == 255) num1 = 0; //发送字符(序号) SBUF = num1; //检测是否发送完毕 while(!TI); //TI手动清0 TI = 0; //发送字符(上位机发送过来的数据) SBUF = a; //检测是否发送完毕 while(!TI); //TI手动清0 TI = 0; //重新开启串口中断 ES = 1; } display(bai, shi, ge); } //设置定时器1为工作方式2 TMOD = 0x20; //波特率为2400bps,给计时器1初值 TH1 = 0xf4; TL1 = 0xf4; //启动定时器1 TR1 = 1; //ET1 = 1; 这里不需要开启定时器1中断,因为定时器1工作在方式2,为8位自动重装方式,进入中断也无事可做 //设置串口工作方式1 //10位异步收发(8位数据), 波特率可变(由定时器溢出率控制) SM0 = 0; SM1 = 1; //容许串口中断 REN = 1; //开启总中断 EA = 1; //开启串口中断 ES = 1; uint i, j; for (i = xms; i > 0; i--) for (j = 110; j > 0; j--) ; dula = 1; P0 = table[bai]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfe; wela = 0; delayms(5); dula = 1; P0 = table[shi]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfd; wela = 0; delayms(5); dula = 1; P0 = table[ge]; dula = 0; P0 = 0xff; wela = 1; P0 = 0xfb; wela = 0; delayms(5); //RI为接收中断标志位, 在方式0时, 当串行接收第8位数据结束时, 或在其他方式, 串行接收停止位的 //中间时, 由内部硬件使RI置1, 向CPU发出中断申请, 也必须在中断服务程序中, 用软件将其清0,取消 //此中断申请, 以方便下一次中断申请检测, 即这样才能产生下一次中断. //这里RI清0, 因为程序既然产生了串口中断, 肯定是收到或发送了数据, 在开始时没有发送任何数据 //那必然是收到了数据, 此时RI会被硬件置1, 所以进入串口中断服务程序后必须由软件清0, 这样才能 //产生下一次中断. if (RI) { RI = 0; //将SBUF中的数据读走给a, 这是此中断服务程序最重要的目的 a = SBUF; //将标志位flag置1, 以方便在主程序中查询判断是否已经收到数据 flag = 1; } 如果以字符格式发送FF时, 单片机接收数据后, 会把FF分成0F 0F当成两个8位字节数据发送给上位机.
上位机以波特率2400bps发送0~255的数据(十六进制发送),单片机先将数据发送到数码管,
再将数据加上序号发送回上位机,当序号超过255时归零.
二. 程序源码
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit dula = P2 ^ 6;
sbit wela = P2 ^ 7;
uchar flag, a, num, num1;
uchar bai = 0, shi = 0, ge = 0, dData = 0;
uchar code table[] = {
};
void delayms(uint xms);
void display(uchar, uchar, uchar);
void init();
void main()
{
}
void init()
{
}
void delayms(uint xms)
{
}
void display(uchar bai, uchar shi, uchar ge)
{
}
void ser() interrupt 4
{
}
三. 程序小结
1. 因为SBUF中每次只能存储8位字节数据, 所以该程序每次只能发送8位字节数据.
2. 当以十六进制发送FF时, 单片机接收上位机发送的数据后, 会将FF当成一个8位字节数据发送给上位机,
3. 程序缺陷
1)程序下载到单片机后, 一上电数码管就显示为255, 怎么也想不通,没有发生串口中断的情况下, bai, shi, ge怎么能由0,0,0
变成2, 5, 5
2)如果将主函数中的display放入到if判断中,发送数据后数码管只会显示最后一位数据, 不知道为什么
有哪位前辈可以指点一下, 在下先谢过了.
关键词: 串行口通信单片机再上位

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码