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

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

时间:11-22 来源:互联网 点击:

CPU申请中断,当CPU响应中断,转向中断服务程序,该位由硬件清0

sbit IE1 = TCON^3;

//IT1为外部中断1触发方式选择位

//IT1=0,电平触发方式,引脚INT1上低电平有效

//IT1=1,跳变沿触发方式,引脚INT1上的电平从高到低的负跳变有效

sbit IT1 = TCON^2;

//IE0为外部中断0请求标志,功能及操作同IE1

sbit IE0 = TCON^1;

//IT0为外部中断0触发方式选择位,功能及操作同IT1

sbit IT0 = TCON^0;

//定时器1初值高8位

sfr TH1 = 0x8D;

//定时器1初值低8位

sfr TL1 = 0x8B;

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

}

三.程序小结

1) 操作串行口之前,需要对单片机的一些与串口有关的特殊功能寄存器进行初始化设置, 主要是设置产生波特率

的定时器1, 串行口控制和中断控制,其主要步骤包括:

a. 确定T1的工作方式(变成TMOD寄存器)

b. 计算T1的初值, 装载TH1,TL1

c. 启动T1(编程TCON中的TR1位)

d. 确定串行口工作方式(编程SCON寄存器)

e. 串行口工作在中断方式时, 要进行中断设置(变成IE, IP寄存器)

2) 51单片机可以通过特殊功能寄存器SBUF对串行接收或串行发送寄存器进行访问, 两个寄存器共用一个地址

99H,但在物理上是两个独立的寄存器, 由指令操作决定访问哪一个寄存器. 执行写指令时, 访问串行发送寄存器, 执行读指令时, 访问串行接收寄存器, 接收器具有双缓冲结构, 即在从接收寄存器中读出前一个已收到

的字节之前, 便能接收第二个字节, 如果第二个字节已经接收完毕, 第一个字节还没有读出, 则丢失其中

一个字节. 对于发送器, 因为数据由CPU控制和发送的, 所以不需要考虑.

a=SBUF;代表单片机自动将串口接收寄存器中的数据取走给a.

SB

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

网站地图

Top