微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 串行口通信 发送0~255数据,单片机再将数据发送回上位机

串行口通信 发送0~255数据,单片机再将数据发送回上位机

时间:11-22 来源:互联网 点击:
一. 程序功能

上位机以波特率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[] = {

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71

};

void delayms(uint xms);

void display(uchar, uchar, uchar);

void init();

void main()

{

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);

}

}

void init()

{

//设置定时器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;

}

void delayms(uint xms)

{

uint i, j;

for (i = xms; i > 0; i--)

for (j = 110; j > 0; j--)

;

}

void display(uchar bai, uchar shi, uchar ge)

{

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);

}

void ser() interrupt 4

{

//RI为接收中断标志位, 在方式0时, 当串行接收第8位数据结束时, 或在其他方式, 串行接收停止位的

//中间时, 由内部硬件使RI置1, 向CPU发出中断申请, 也必须在中断服务程序中, 用软件将其清0,取消

//此中断申请, 以方便下一次中断申请检测, 即这样才能产生下一次中断.

//这里RI清0, 因为程序既然产生了串口中断, 肯定是收到或发送了数据, 在开始时没有发送任何数据

//那必然是收到了数据, 此时RI会被硬件置1, 所以进入串口中断服务程序后必须由软件清0, 这样才能

//产生下一次中断.

if (RI)

{

RI = 0;

//将SBUF中的数据读走给a, 这是此中断服务程序最重要的目的

a = SBUF;

//将标志位flag置1, 以方便在主程序中查询判断是否已经收到数据

flag = 1;

}

}

三. 程序小结

1. 因为SBUF中每次只能存储8位字节数据, 所以该程序每次只能发送8位字节数据.

2. 当以十六进制发送FF时, 单片机接收上位机发送的数据后, 会将FF当成一个8位字节数据发送给上位机,

如果以字符格式发送FF时, 单片机接收数据后, 会把FF分成0F 0F当成两个8位字节数据发送给上位机.

3. 程序缺陷

1)程序下载到单片机后, 一上电数码管就显示为255, 怎么也想不通,没有发生串口中断的情况下, bai, shi, ge怎么能由0,0,0

变成2, 5, 5

2)如果将主函数中的display放入到if判断中,发送数据后数码管只会显示最后一位数据, 不知道为什么

有哪位前辈可以指点一下, 在下先谢过了.


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top