1. 实验目的
学习STC12C5A单片机串口通信USART知识和ADC转换。
2. 实验原理
STC12C5A16S2系列单片机串口工作原理
USART是一个高度灵活的串行通讯设备。主要特点为:全双工操作 (独立的串行接收和发送寄存器)、异步或同步操作、主机或从机提供时钟的同步操作、高精度的波特率发生器、支持 5, 6, 7, 8,或 9个数据位和 1个或 2个停止位、硬件支持的奇偶校验操作、数据过速检测、帧错误检测、噪声滤波,包括错误的起始位检测,以及数字低通滤波器、三个独立的中断:发送结束中断、发送数据寄存器空中断,以及接收结束中断、多处理器通讯模式、倍速异步通讯模式。
STC12C5A16S2系列单片机具有2个采用UART工作方式的全双工串行通讯接口串口1(对应芯片引脚为:TXD/P3.1和RXD/P3.0)串行口2(对应的芯片引脚为:TXD2和RXD2)。每一个串口有4种工作方式,其中2种的工作方式波特率是可变的,另两种是不可变的。芯片可以通过查询或者中断方式来接收和发送数据。
STC12C5A16S2系列单片机在串口通信中经常使用到的寄存器主要是SCON(串行口控制寄存器)、PCON(电源控制寄存器)、AUXR(辅助寄存器)、BRT(独立波特率发生器寄存器)、SBUF(串行口缓冲寄存器)、IE(中断允许寄存器)。
3. 主要仪器设备
硬件:IOT-L01-05型物联网综合实验箱1台,串口线。
软件:Keil u Vision4编译软件,STC下载软件STC_ISP_V479,串口调试工具。
4. 实验内容及步骤
4.1.1 编译工程文件,生成可执行Timer.hex文件。
4.1.2 使用串口线将电脑与物联网综合实验箱中带有STC单片机的底板连接,拨打好串口控制开关。
4.1.3 将可执行Timer.hex文件通过STC_ISP串口下载软件下载进STC单片机中。
4.1.4 将下载完程序的开发板从新上电。
Main函数代码:主要通过修改波特率的定义来改变波特率的值
/**************************************************************
* 晶振频率 :选取用RC 11.0592MHz
* 文件名 :STC12C5A16S2_UART.c
* 功能说明 :STC12C5A16S2单片机的串口通信演示实验
* 制作 :www.frotech.com
* 变更记录 :2013.04.27
* 变更内容 :新建造
**************************************************************/
#include <STC12C5A60S2.h>
#define BUF_LENTH 128 //定义串口接收缓冲长度
unsigned char uart1_wr; //写计数器
unsigned char uart1_rd; //读计数器
unsigned char xdata RX0_Buffer[BUF_LENTH]; //接收缓冲
unsigned char flag; //定义串口是否有接收到数据的标志位
unsigned char i; //普通的循环变量
bit B_TI; //定义B_TI为bit类型
void uart1_init(void); //串口初始化函数声明
void Uart1_TxByte(unsigned char dat); //串口发送单个字符函数声明
void Uart1_String(unsigned char code *puts); //串口发送字符串函数函数声明
void delay_ms(unsigned char ms); //延时函数声明
#define MAIN_Fosc 11059200UL //定义外部晶振的频率
#define Baudrate0 38400UL //定义串口波特率频率
#define BRT_Reload (256 - MAIN_Fosc / 16 / Baudrate0) //装入定时器1工作在1倍模式下的益出数
/*************************************************************
* 函数名:main( void )
* 输入:无
* 输出:无
* 功能描述:串口初始化参数为9600 8 N 1.
程序一开始执行输出"www.frotech.com",然后将
串口接收到的数据原样返回
**************************************************************/
void main(void)
{
uart1_init(); //调用串口初始化函数
Uart1_String("www.frotech.com"); //一开始就输出"www.frotech.com"
while(1)
{
if(flag == 1) //是否有串口中断
{
for(i = 0; i < uart1_wr; i++)
{
Uart1_TxByte(RX0_Buffer[i]); //将接收到的字符串原样输出
}
uart1_wr = 0; //将写计数器0
flag = 0; //将中断判断读清0
}
}
}
/*************************************************************
* 函数名:uart1_init(void)
* 输入:无
* 输出:无
* 功能描述:串口初始化参数为9600 8 N 1.
**************************************************************/
void uart1_init(void)
{
PCON |= 0x80; //SMD=1 串行通讯的波特率加倍 P265
SCON = 0x50; //当SM0/FE=0 SM1=1时组成工作方式1(8位UART,波特率可变) P264
AUXR |= 0x01; //S1BRS=1 使用独立波特率发生器作为串行口的波特率发生器 P266
AUXR |= 0x04; //BRTx12=1 波特率发生器每一个时钟计数一次
BRT = BRT_Reload; //把根据波特率计算的 定时器的值,装入波特率发生器 P267
//BRT =0xB8;
AUXR |= 0x10; //BRTR=1 开启独立波特率发生器运行 P266
ES = 1; //IE寄存器的ES位为1 串口1中断开 P192
EA = 1; //IE寄存器的EA位为1 CPU开中断
}
/*************************************************************
* 函数名:Uart1_TxByte(unsigned char dat)
* 输入:发送字符
* 输出:无
* 功能描述:将单个字符通过串口发送.
**************************************************************/
void Uart1_TxByte(unsigned char dat) //串口1发送单个字符函数
{
B_TI = 0; //将B_TI置0
SBUF = dat; //将发送的数据写入SBUF缓冲器中
while(!B_TI); //等待发送 缓冲器发送完数据
B_TI = 0; //将B_TI置位0
}
/*************************************************************
* 函数名:Uart1_String(unsigned char code *puts)
* 输入:发送字符串
* 输出:无
* 功能描述:将字符串通过调用单个字符函数发送.
**************************************************************/
void Uart1_String(unsigned char code *puts)
{
for(; *puts != 0; puts++)
{
Uart1_TxByte(*puts); //以指针的形式将字符串分解为单个字符,调用上面的单个字符发送函数发送
}
}
/*************************************************************
* 函数名:UART1_RCV (void)
* 输入:无
* 输出:无
* 功能描述:定义串口的中断处理函数,串口中断号为4.
当串口接受完或者发送完一帧数据
时产生中断,告知CPU进行中断处理
**************************************************************/
void UART1_RCV (void) interrupt 4 //中断接收函数 中断号为4 P188
{
if(RI) //判断接收的数据是否接收完,当接收到第8位时 接收结束 RI会置1 P265
{
RI = 0; //接收中断使能位清0
RX0_Buffer[uart1_wr++] = SBUF; //将串口缓冲器SBUF的数据放到数据接收缓冲器RX0_Buffer[]中
flag = 1; //将标志位置1方便主函数判断
}
if(TI) //判断发送的数据是否发送完,当发送到第8位时 发送结束 TI会置1 P265
{
TI = 0; //将发送结束标志位 TI清0
B_TI = 1; //将B_TI 置1 方便上面的Uart1_TxByte 函数判断
}
}
/*************************************************************
* 函数名:delay_ms(unsigned char ms)
* 输入:延时时间
* 输出:无
* 功能描述:产生毫秒级别延时.
**************************************************************/
void delay_ms(unsigned char ms) //毫秒级延时函数
{
unsigned int i;
do{
i = MAIN_Fosc /1400;
while(--i);
}while(--ms);
}
代码流程图:
5. 实验结果与分析
在波特率为9600情况下输出组员学号:
在波特率为38400情况下输出组员学号:
6. 问题与讨论
ADC转换实验效果图:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。