Proteus 8 C51单片机仿真_串口
  RGE9SaKkXr6k 2023年12月06日 16 0

1.首先查看规格书和芯片引脚标识确定串口的RX/TX引脚分别是P3.0和P3.1:

Proteus 8 C51单片机仿真_串口_proteus仿真

Proteus 8 C51单片机仿真_串口_proteus仿真_02

点击虚拟仪器中的虚拟示波器,放置在桌面上:

Proteus 8 C51单片机仿真_串口_波特率_03

将虚拟示波器的RX接到单片机的TX,将虚拟示波器的TX接到单片机的RX:

Proteus 8 C51单片机仿真_串口_波特率_04

接下来打开keil编写串口收发的程序:

在stc-isp的范例程序中,找到STC89Cxx,找到串口的C语言范例,复制到keil中,做进一步的修改:

Proteus 8 C51单片机仿真_串口_串口_05

在了解了串口关于硬件的知识后,我们应该熟悉与串口相关的寄存器,软件方面主要是配置好寄存器:

Proteus 8 C51单片机仿真_串口_串口_06

当串口需要接收数据时,REN需要配置为1:

Proteus 8 C51单片机仿真_串口_波特率_07

Proteus 8 C51单片机仿真_串口_proteus仿真_08

发送数据结束时硬件自动将TI置1,向主机请求中断,在中断中我们必须使用软件将TI置为0:换句话说就是将标志位重新置为0:

Proteus 8 C51单片机仿真_串口_串口_09

接收数据结束时硬件自动将RI置1,向主机请求中断,在中断中我们必须使用软件将RI置为0:换句话说就是将标志位重新置为0:

Proteus 8 C51单片机仿真_串口_波特率_10

总结:将SCON配置为:01000000,十六进制表示为:SCON = 0x40;

Proteus 8 C51单片机仿真_串口_波特率_11

接下来是SBUF寄存器,不需要配置。只需要了解其内部本质是两个寄存器但共用一个地址即可:

Proteus 8 C51单片机仿真_串口_串口_12

接下来是PCON寄存器的前两位,这个寄存器的前两位也是与串口有关的,我们只需要关注SMOD寄存器即可,它决定了波特率是否加倍:在初始化中我们配置为1:PCON = 0x80; (1000 0000);

Proteus 8 C51单片机仿真_串口_51单片机_13

Proteus 8 C51单片机仿真_串口_串口_14

接下来配置定时器,根据手册中的说明,串口使用的是专用定时器1,所以接下来开始配置定时器1:

在TMOD寄存器中,高八位部分配置的是定时器1,低八位配置的是定时器0;

所以我们要配置寄存器TMOD的高八位部分:

Proteus 8 C51单片机仿真_串口_串口_15

其中TMOD的M1和M0用来做定时器/计数器模式选择,配置串口时需要选择自动重装载模式(Aotu Reload模式),双八位自动重装载模式是指将十六位寄存器分开,高八位存放初值,低八位计数,由低八位CNT完成计数,处理效率更快,精度更高。但只用八位来记录的数据更短(0-255);

Proteus 8 C51单片机仿真_串口_波特率_16

因此我们配置TMOD寄存器为:TMOD |= 0x20; (0010 0000);

接下来配置定时器的初值:通过stc-isp的波特率计算器中生成的代码来计算:

计算得到: TL1 = 0xF3; TH1 = 0xF3;

Proteus 8 C51单片机仿真_串口_proteus仿真_17

接下来由于我们不需要定时器1中断,

所以配置:

ET1 = 0;   //禁止定时器1中断

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

至此,串口初始化配置完成:(定时器初值由于时钟频率选择不同有一些差异):

Proteus 8 C51单片机仿真_串口_波特率_18


接下来写发送数据的函数,串口操作相对简单,在函数给要发送的数据,串口内部会帮我们完成发送:

定义发送函数,参数为要发送的数据,将数据发送给SBUF,同时检测当发送完成后TI等于1即跳出循环,再通过软件将TI置为0;发送函数如下示例:

Proteus 8 C51单片机仿真_串口_波特率_19

至此,串口初始化和发送串口数据就写好了,通过调用UART_SenByte就可以完成串口数据的发送了,

我们将串口部分的代码封装成模块方便调用:

Proteus 8 C51单片机仿真_串口_波特率_20

Proteus 8 C51单片机仿真_串口_波特率_21


接下来继续丰富代码,添加串口接收部分功能,串口接收需要用到中断功能,当接收的时候我们要进入到中断函数中;

接收数据需要将串行控制寄存器中的REN寄存器置1:SCON = 0x50;   (0101 0000)

Proteus 8 C51单片机仿真_串口_proteus仿真_22

另外开启中断寄存器:

ES:ES = 1;     //串口中断使能 

EA:  EA = 1;     //全局中断使能

中断之后会跳转到中断服务函数里面,查询手册可知中断号:

Proteus 8 C51单片机仿真_串口_串口_23

写一个URAT中断的函数,使用中断号4,当UART产生中断的时候,就会进入到这个函数:

我们要在函数中作判断,判断进入到中断的是接收还是发送,因为接收和发送是共用中断的:

如果是接收中断则保存数据,同时将接收标志位手动由软件置0;

Proteus 8 C51单片机仿真_串口_串口_24

最后,将接收中断函数也封装成模块放在UART模块中,在需要使用到的main.c函数中调用即可。

那么串口的接收和发送功能都实现了。


总结一下:发送数据只需要配置好UART相关的寄存器,再将寄存器的配置封装成初始化模块,需要用到串口时调用就好了。

而接收串口数据需要用到中断,配置串口的专用中断寄存器,然后编写中断函数,在中断函数中判断串口的接收数据,将SBUF中的缓存数据保存到定义的变量中即可,最后将接收标志位RI置0。



最后附上仿真实现示例:

Proteus 8 C51单片机仿真_串口_串口_25


拓展知识:波特率的计算:

一、0xF3 对应的十进制是243

二、每隔256溢出一次,256-243=13

三、12M晶振在12T模式下1us计数一次,13次计数等于13us,13us溢出一次

四、1/13=0.07692MHz   0.07692是T1的溢出率

五、0.07692 / 16 =0.00480769MHz    换算位4807.69Hz  波特率≈4800(这里选择了波特率加倍,即0.07692 / 16,如果波特率不加倍0.07692 / 2 / 16)

Proteus 8 C51单片机仿真_串口_51单片机_26



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月06日 0

暂无评论

推荐阅读
RGE9SaKkXr6k