版权声明:让结局不留遗憾,让过程更加完美。 https://blog.csdn.net/Xiaomo_haa/article/details/87632959
这都半个月没弄了,马上就要开学了,抓紧把模块搞完。
UART串口通信初步认识
51单片机内部存在UART模块,要想正确使用还需要配置相应的寄存器。
51单片机的UART串口通信的结构由串行口控制寄存器SCON、发送(P30—RXD)和接收(P31—TXD)电路组成。
SCON
以下是STC15手册里的关于SCON和PCON的资料。
波特率
关于波特率,波特率就是发送二进制数据位的速率,一般使用baud表示,就是发送一位二进制数据的持续时间为1/baud。
在通信之前,通信双方的波特率需要设置相同,才能实现正常通信。
在51单片机中,波特率发生器只能由定时器1和定时器2产生,不能使用定时器0。如果使用定时器2需要配置额外的定时器,默认是使用定时器1,而且使用的是定时器1的8位自动重载模式。
定时器的重载值计算公式为:
TH1 = TL1 = 256 - FOSC / 12 / 2 / 16 / baud (12T模式)
如果程序中写了
PCON |= 0x80;
这时PCON的最高位将波特率提高一倍,计算公式就变成了:
TH1 = TL1 = 256 - FOSC / 12 / 16 / baud (12T模式)
串口发送和接收
串口的发送和接收电路在物理上有两个相同的SBUF寄存器,它们的地址都是0x99,但是一个用来做发送缓冲,一个用来做接收缓冲。
但是如何判断到底是发送还是接收,就看SBUF是在 = 前面,还是在 = 后面。如下所示:
SBUF = 1; //发送
/*———————————————————————————————————————————————————————————————————————————————————————*/
temp = SBUF; //接收并存入temp变量中
UART程序
main.c
/*******************************************************************************
* 文件名:main.c
* 描 述:
* 作 者:小默haa
* 版本号:v1.0.0
* 日 期:
* 备 注:
*
*******************************************************************************/
#include <STC15F2K60S2.H>
#include "sys.h"
void main(void)
{
All_Init();
UartInit(9600);
EA = 1;
while(1);
}
sys.c
/*******************************************************************************
* 文件名:sys.c
* 描 述:系统文件
* 作 者:小默haa
* 版本号:v1.0.0
* 日 期: 2019年1月15日
* 备 注:系统中必要的一些程序放在这里
*
*******************************************************************************/
#include "sys.h"
/*******************************************************************************
* 函数名 :All_Init
* 输入值 :无
* 返回值 :无
* 作者 :小默haa
* 时间 :2019年1月15日
* 功能描述:外设初始化
* 备注 :关闭所有外设
*******************************************************************************/
void All_Init(void)
{
P2 = (P2 & 0x1f) | 0x80; //打开Y4C(LED)
P0 = 0xff; //关闭LED
P2 = (P2 & 0x1f) | 0xe0; //打开Y7C(数码管)
P0 = 0xff; //关闭数码管
P2 = (P2 & 0x1f) | 0xa0; //打开Y5C
P0 = 0x00; //关闭蜂鸣器、继电器
P2 = P2 & 0x1f; //关闭所有使能
}
sys.h
#ifndef _SYS_H_
#define _SYS_H_
typedef signed char int8;
typedef signed int int16;
typedef signed long int32;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
#include <stc15f2k60s2.h>
//全局变量定义
#define FOSC 11059200L //系统时钟 11.0592MHz
//sys.c
void All_Init(void);
//uart.c
void UartInit(uint16 baud);
#endif
uart.c
/*******************************************************************************
* 文件名:uart.c
* 描 述:UART程序
* 作 者:小默haa
* 版本号:v1.0.0
* 日 期: 2019年2月18日
* 备 注:
*
*******************************************************************************/
#include "sys.h"
/*******************************************************************************
* 函数名 :UartInit
* 输入值 :uint16 baud
* 返回值 :none
* 作者 :小默haa
* 时间 :2019年2月18日
* 功能描述:设置波特率
* 备注 :
*******************************************************************************/
void UartInit(uint16 baud)
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为FOSC/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 256 - (FOSC / 12 / 32) / baud; //设定定时初值
TH1 = TL1; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES = 1; //使能串口中断
}
/*******************************************************************************
* 函数名 :UART_Interrupt
* 输入值 :none
* 返回值 :none
* 作者 :小默haa
* 时间 :2019年2月18日
* 功能描述:串口中断服务程序
* 备注 :
*******************************************************************************/
void UART_Interrupt(void) interrupt 4
{
if(RI) //如果接收到
{
RI = 0; //手动清零接收中断标志位
SBUF = SBUF + 1; //接收到后+1再发送回去
}
if(TI) //如果发送完毕
{
TI = 0; //手动清零发送中断标志位
}
}
这是最简单的实现串口通信的程序。