微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 串行口通信 上位机发送字符x,单片机返回上位机“I get x“

串行口通信 上位机发送字符x,单片机返回上位机“I get x“

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

上位机上用串口调试助手发送一个字符X, 单片机收到字符后返回给上位机"I get X",串口波特率设为9600bps.

二.程序源码

1) 法1 (头文件法, 适用于老手)

#include

#define uchar unsigned char

#define uint unsigned int

uchar flag, a, i;

uchar code table[] = "I get "; //定义一个字符类型编码数组

void init();

void main()

{

init(); //初始化

while (1)

{

//若检测到flag为1, 说明程序已经执行过串口中断服务程序, 即收到了数据.

if (flag == 1)

{

//手动将flag清0,方便标志位检测

flag = 0;

//检测到flag为1后,即串口中断发生,先将ES清0, 原因是接下来要发送数据, 若不关闭串口中断, 发送完数据后,

//单片机同样会申请串口中断,再次进入中断服务程序,flag又为1,又再此发送数据,一直重复

//因此我们在发送数据前把串口中断关闭,等发送完数据再打开串口中断,这样可以安全地发送数据

ES = 0;

//通过for循环将前面数组中字符依次发送出去

//由于数组table中共有6个字符,所以循环中以6作为结束个数

for (i = 0; i < 6; i++)

{

//发送字符

SBUF = table[i];

//当向SBUF中写入一个数据后,使用while(!TI)等待发送完毕, 因为发送完毕后TI会由

//硬件置1,然后退出while(!TI)

while (!TI);

//再将TI手动清0

TI = 0;

}

//向SBUF中写入从中断服务程序读回来的数据

SBUF = a;

while (!TI); //同上

TI = 0; //同上

ES = 1; //重新开启串口中断

}

}

}

void init()

{

TMOD = 0x20; //设定定时器1为工作方式2: 8位初值自动重装的8位定时器(设定定时器1目的是其溢出率决定串口波特率)

TH1 = 0xfd; //定时器1装初值(波特率为9600)

TL1 = 0xfd; //定时器1装初值(波特率为9600),注意:TH1,TL1初值必须相同

//ET1 = 1; 这里不需要开启定时器1中断,因为定时器1工作在方式2,为8位自动重装方式,进入中断也无事可做

REN = 1; //容许串行口接收数据

SM0 = 0; //设定串口工作方式1

SM1 = 1; //设定串口工作方式1(10位异步收发,波特率可变,且由定时器1的溢出率决定)

EA = 1; //开总中断

ES = 1; //开串口中断

TR1 = 1; //启动定时器1

}

//串口中断服务程序

void ser() interrupt 4

{

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

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

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

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

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

//产生下一次中断.

RI = 0;

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

a = SBUF;

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

flag = 1;

}

2) 法2 (完整寄存器地址法)

//中断允许寄存器IE,字节地址位0xA8

//单片机复位时, IE中所有位被清0

sfr IE = 0xA8;

//EA为全局中断允许位

//EA = 1时打开全局中断控制,在这样条件下,由各个中断控制位打开或关闭相应的中断

//EA = 0时关闭所有中断

sbit EA = IE^7;

//ET2为定时器/计数器2中断允许位

//ET2 = 1时打开T2中断, ET2 = 0时关闭T2中断

sbit ET2 = IE^5; //8052 only

//ES为串行口中断允许位

//ES = 1时打开串行口中断, ES = 0时关闭串行口中断

sbit ES = IE^4;

//ET1为定时器/计数器1中断允许位

//ET1 = 1时打开T1中断, ET1 = 0时关闭T1中断

sbit ET1 = IE^3;

//EX1为外部中断1中断允许位

//EX1 = 1时打开外部中断1中断, EX1 = 0时关闭外部中断1中断

sbit EX1 = IE^2;

//ET0为定时器/计数器0中断允许位

//ET0 = 1时打开T0中断, ET0 = 1时关闭T0中断

sbit ET0 = IE^1;

//EX0为外部中断0中断允许位

//EX0 = 1时打开外部中断0中断, EX0 = 0时关闭外部中断0中断

sbit EX0 = IE^0;

//SBUF为串行数据缓冲寄存器

//51单片机中含有两个SBUF,其中一个为发送缓冲寄存器,另一个为接收缓冲寄存器

//这两个寄存器共有一个地址0x99, 但物理上是两个独立的寄存器,有指令操作决定访问哪个寄存器

//执行写指令时, 访问串行发送寄存器, 执行读指令时, 访问串行接收寄存器

//接收器具有双缓冲结构, 即

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

网站地图

Top