🚩write in front🚩
🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~作者周榜89﹣作者总榜832~阿里云专家博主 & 阿里云星级博主~掘金优秀创作者⇿InfoQ创作者⇿51CTO红人⇿全网访问量40w+🏅
🆔本文由 謓泽 原创 CSDN首发🙉如需转载还请通知⚠
📝个人主页-謓泽的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏-【51单片机】系列_謓泽的博客-CSDN博客🎓
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩💬本系列哔哩哔哩江科大51单片机的视频为主以及博主自己的总结梳理📚
目录
⒈串口向电脑发送数据
配置串口
串口相关寄存器
SM0和SM1工作模式
SCON串行控制寄存器
PCON电源控制寄存器
定时器1&工作模式二
STC-ISP波特率计算
发送
串口向电脑发送数据 - 代码
main.c
Delay.c & Delay.h
UART.c & UART.h
接收
接收中断
⒉电脑通过串口控制LED灯 && 将接收到的数据发送到串口当中里面去 - 代码
main.c
Delay.c & Delay.h
UART.c & UART.h
数据显示模式
⒈串口向电脑发送数据
配置串口
串口相关寄存器
串口这个寄存器就是相当于按钮,也可以是指示灯或者是数据的什么。
SCON是控制这个电路如何运转开关怎么拨。里面有很多位可以。控制这个电路
SBUF是串口数据缓存寄存器,发送的数据存储到这里。
PCON是电源管理寄存器其中有SMOD和SMOD0这两位是控制串口的,之所以放在电源这里可能是单片机当中资源有点紧张。然后串口又多了所以分配到电源管理寄存器当中去了。
IE是允许中断标志当种有EA和ES是这个中断控制的东西与串口有关。
SM0和SM1工作模式
在这里由于我们只讲述最常用的模式一。
SCON串行控制寄存器
注→串行控制寄存器为可位寻址:可以单独的对一位寄存器进行赋值。
B7→FE:检测帧错误,也就是说它有一个奇校验和偶校验。如果错误的话就会在这一位当中检测FE这个帧错误。注:当我们去使用⒏位串口的时候就不需要来检测这个帧错误了。这里所说的是『模式1:8位UART[⒈个字节],波特率可变』— 最常用的一个模式。
B7→SM0 = 0
B6→SM1 = 1 [决定工作模式,在这里我们是工作模式⒈]
B5→SM2 = 0 [多机通信是方式⒉和方式⒊的,如果是这两个的话设置SM2 = 1反之SM2 = 0]
B4→REN = 1||0 [是否允许它进行接收RXD,如果REN = 0的话就是不允许接收 REN = 1的话就是允许接收。想让单片机接收数据的话就置为1,不想让单片机接收就置为0]
B3→TB8 = 0 [方式三和方式二置1用于发送第⑨位数据,方式一置0]
B2→RB8 = 0 [方式三和方式二置1用于发送第⑨位数据,方式一置0]
B1→TI = 0 [初始化配置给0]
B0→RI = 0 [初始化配置给0]
串行口数据缓冲器SBUF
PCON电源控制寄存器
注→PCON电源控制寄存器:不可位寻址就是它的寄存器只能进行整体的进行赋值。
对应着串口逻辑图当中的SMOD控制波特率是否加倍的。
在上述图当中说明了SMOD=⒈的时候波特率就会加倍。一般来说不会进行波特率的加倍。
SMOD0:帧错误我们在这里是不需要的所以不用进行配置。
注→ 【在串口向电脑发送数据】单片机只是需要给电脑发送就行。所以没有必要开启中断。
定时器1&工作模式二
注→这个串口只能配置定时器⒈这是它专用的。
★模式2→8位自动重装模式,这个算是第二个最常用的一个模式。第二种模式主要用于串口通信产生波特率来用的『在电子通信领域,波特(Baud)即调制速率,指的是有效数据讯号调制载波的速率,即单位时间内载波调制状态变化的次数』
STC-ISP波特率计算
在这里要注意下你的晶振频率如果是12MHZ的话可以选择波特率倍速使误差更小。
AUXR→在五一单片机当中是不需要的这个是如何确定高系列的单片机里面有可选择的东西因为在我们的89C52当中是不可选的所以是不需要的。
下面我们来说说它的波特率计算方式如下
SMOD 是决定要不要进行波特率加倍的。
fosc 晶振频率。51单片机的晶振频率一般为12或11.0592(MHZ) 注:在串口通信上我们一般都是用11.0592(MHZ)因为用12MHZ它会产生百分之五的一个误差算出的结果会有小数。
发送
在发送当中内部的移位的过程还是比较复杂的,但是在我们编写程序当中的操作还是比较容易的。我们只需要把数据写到SBUF当中去,一旦我们写进去的时候它就会发送出去。
当SBUF被赋值为左值的时候就带表它是写入SBUF被写入的话它就是发送的。
//例如↓ SBUF = Byte;//发送-单片机向电脑发送数据 P2 = SBUF; //接收-单片机接收电脑的数据
注→当我们发送完成之后是还需要进行检测的。TI = 发送控制位。
//例如↓ while(TI==0); TI == 0;
当 TI == 0 时候就一直循环下去,直到TI == 1的时候就会跳出循环,然后再用软件复位置0。
串口向电脑发送数据 - 代码
代码的内容→单片机每隔⒈s向电脑发送一次数据。
main.c
#include <REGX52.H> #include "Delay.h" #include "UART.h" int main() { unsigned char Sec = 0; UART_Init(); //串口初始化 while(1) { UART_SendByte(Sec); //串口发送一个字节 Sec+=2; //Sec自增 Delay(1000); //延时1秒 准确精准,防止有误差! } }
Delay.c & Delay.h
//Delay.c void Delay(unsigned int xms) { unsigned char i, j; while(xms--) { i = 2; j = 239; do { while (--j); } while (--i); } } //Delay.h #ifndef __DELAY_H__ #define __DELAY_H__ void Delay(unsigned int xms); #endif
UART.c & UART.h
//UART.c #include <REGX52.H> void UART_Init() { SCON = 0x40; TMOD &= 0x0F;//0000 0000 & 0000 1111 定时器1的话高四位清0 定时器0的话低四位清0 TMOD |= 0x20;//0000 0000 | 0010 0000 TL1 = 0xFA; TH1 = 0xFA; ET1 = 0; TR1 = 1; } void UART_SendByte(unsigned char Byte) { SBUF=Byte;//TX发送 SBUF被赋值为左值 while(TI==0);//发送到了数据置TI == 1 TI=0;//软件复位 } //UART.h #ifndef __UART_H__ #define __UART_H__ void UART_Init(); void UART_SendByte(unsigned char Byte); #endif
接收
注:一般发送数据是不需要中断号的,但是接收数据的话是需要中断号的。发送是因为是我们的单片机来进行发送到电脑端当中去的。
接收的话之所以要中断系统是因为我们并不清楚电脑什么时候发送过来,我们也不能一直检测所以我们就可以利用中断电脑发送过来的时候(单片机接收)触发这个中断在中断函数当中进行处理。
注→SCON串行控制寄存器当中REN现在我们是要进行接收了所以需要REN置1的值。
接收中断
接收的时候需要中断所以我们需要在串口初始化当中加上ES = 1 和 EA = 1 的值,优先级默认。 其实无论在发送还是接收只要有一个条件满足了它就会触发中断。当中断使能[EA]之后程序会跳转到中断服务函数里面 — void UART_Routine interrupt4 表示(串口中断)
⒉电脑通过串口控制LED灯 && 将接收到的数据发送到串口当中里面去 - 代码
main.c
#include <REGX52.H> #include "Delay.h" #include "UART.h" void main() { UART_Init(); //串口初始化 while(1) { } } //中断服务子函数 void UART_Routine() interrupt 4 // interrupt 4 中断的入口-中断服务子函数 { if(RI==1) //如果接收标志位为1,接收到了数据.[之所以需要判断是因为我们要区分接收RI=TXD和发送TI=RXD] { P2=~SBUF; //读取数据,取反后输出到LED SBUF在等号的右边说明它是接收位 UART_SendByte(SBUF); //将接收到的数据发回串口 RI=0; //接收标志位清0 软件复位 } }
Delay.c & Delay.h
//Delay.c void Delay(unsigned int xms) { unsigned char i, j; while(xms--) { i = 2; j = 239; do { while (--j); } while (--i); } } //Delay.h #ifndef __DELAY_H__ #define __DELAY_H__ void Delay(unsigned int xms); #endif
UART.c & UART.h
//UART.c #include <REGX52.H> void UART_Init(void) //9600bps@11.0592MHz { PCON &= 0x7F; //波特率不倍速 SCON = 0x50; //8位数据,可变波特率 TMOD &= 0x0F; //清除定时器1模式位 TMOD |= 0x20; //设定定时器1为8位自动重装方式 TL1 = 0xFD; //设定定时初值 TH1 = 0xFD; //设定定时器重装值 ET1 = 0; //禁止定时器1中断 TR1 = 1; //启动定时器1 ES=1; EA=1; } void UART_SendByte(unsigned char Byte) { SBUF=Byte;//发送-单片机向电脑发送数据 while(TI==0); TI=0; } //UART.h #ifndef __UART_H__ #define __UART_H__ void UART_Init(); void UART_SendByte(unsigned char Byte); #endif
数据显示模式
HEX模式/十六进制模式/二进制模式→都以原始数据的形式进行显示。
文本模式/字符模式→以原始数据编码后的形式进行显示。