资讯专栏INFORMATION COLUMN

身价过亿的妖媚子对小码农说串口能传送我的爱吗?

iOS122 / 2572人阅读

摘要:目前,所有型号串口的输入是输出是。串口全双工通信是没有时钟脉冲的,只能依靠晶振脉冲定时器的溢出脉冲。中断中读取,清标志,然后返回给计算机,等待发送完毕防重叠最少时间次位定时器时间。实现烧录程序的目的。

文章目录


小码农不敢接受妖媚子(想多活几年),但是串口还是可以传送数据的

并行通信

多位数据同时传输

通讯介质通常为TTL,差分(低压差分芯片)

例如:LCO1602,ADC0804,LVDS(液晶显示)等

串行通信

多位数据排队传输,任意IO口都可以做数据收发

通信介质通常为TTL,差分(485),无线电

同步:

74HC595(单工),IIC(半双工),SPI

异步:

单线归零、1- Wire 、 CAN 总线、无线电、UART (含 DMX512 、 modbus )。

​ UART 是单片机的独立模块。我们设置好模块的参数,需要发送什么内容,扔给串口模块就行。 CPU 不需要按位读写。该模块是指定的管脚输入输出。目前, STC 所有型号串口1 的输入是 RxD1=P3.0, , 输出是 TxD1=P3.1 。
​ STC15 开发板使用 STC15W4K16S4 芯片,串口有4个,其中串口3的输入是 RxD3= P0.0, , 输出是 TxD3= P0.1 。与矩阵键盘共用了两个 IO

串口通信:收发一个字节(只能用时间来同步)

CPU 往 SBUF 中写入一个 byte , CPU 可以跑去执行其他函数。如果发送完成,串口模块向 CPU 申请中断(T1);

串口收发一位数据,依靠严格的时间来保证收发同步

如果串口模块接收完一个字节,也向 CPU 申请中断( RI ),CPU 可以从 SBUF 中读取数据。

串口通讯的相关术语

**1.位采样脉冲:**接收器把每个 bit 的时间平均等份,对线路电平进行采样,确定接收到的是高电平还是低电平,才能进行下一位数据的采样。 STC89 是 16 等份判断7、8 、9(三选二)。STC15W 和 STC8 系列是4等份(四选三,官方资料写错成 16 了)

2.波特率:: 是指1秒钟的时间内,串口通信线路上面,发送的数据位数, , 简单理解成1秒钟内电平跳变多少次
常用的波特率有 9600 等, STC 下载软件里面可以选择的就有很多种波特率。我们后面要学的 DMX512 就是 250000bps .

**波特率的本质,是设置信号时间点。**到点就按时发送或者接收一位。串口全双工通信是没有时钟脉冲的,只能依靠晶振脉冲、定时器的溢出脉冲。

==3.波特率哪里来:==波特率来自定时器的溢出,独立波特率发生器,以及系统时钟分频

STC串口1通信的寄存器

1.方式设置以及中断标志寄存器

2.电源控制寄存器中的波特率加倍功能寄存器

3.数据收发缓存寄存器SBUF

4.辅助寄存器AUXR控制定时器分频,独立波特率发3生器以及串口2的相关控制

5.独立波特率发生器寄存器BRT,用于保存该定时器的初值

6.与串口通信相关的中断寄存器IE,中断优先级IPH,IP

串行口1工作模式1:8位UART,波特率可变

收发波特率需要一致

收发波特率不一致,导致RX端不能正常接收:

串口1

1.配置 SCON ,选择方式1,8 位可变波特率,允许接收。

SM0 = 0;SM1 = 1;REN = 1;

PCON &= 0x3f;

2.配置定时器2为 :16 位自动重装模式, 不申请中断 AUXR |= 0x01;AUXR |= 0x14; 实际上也可以写成AUXR |= 0x15;

3.计算定时器2的溢出率:

波特率是 9600 ,每位采样4次。就需要定时器2每秒钟溢出 9600*4 次 =38400

4.配置定时器2初值

定时器2溢出需要的脉冲数是:24000000 ÷ 38400=625. 那么,定时器2的预装初值就是:65536-625=64911=0xFD8F

5.启动定时器2、闭合串口1中断开关、闭合总中断开关。ES = 1

6.中断中读取SBUF,清 RI 标志,然后返回给计算机,等待发送完毕,防重叠最少时间=4 次*10 位* 定时器时间 。再清除 TI

void Uart1_Init(){	SM0 = 0;	SM1 = 1;	REN = 1;	//上面三条语句就等于操作SCON |= 0x50;	PCON &= 0x3f;	AUXR |= 0x01;	AUXR |= 0x14;	T2H = 0xfd;	T2L = 0x8f;	ES = 1;}

串口1中断函数

串口1中断号

在中断里面我们干什么,进中断第一件事就是先把接收标志,发送标志给软件清零,然后再做一系列操作

void Uart1_Routine() interrupt 4{	if (RI) 	{		RI = 0;//先把接收标志给清零		Uart1_Data = SBUF;	}	if (TI) 	{		TI = 0;//先把发送标志给清零	}}

串口中断让单片机软复位,实现自动烧录 IAP_CONTR |= 0xe0

监控串口通信内容,如果在 9600 波特率下,连续收到 10 个字节都是 0x7f, 那么让单片机软复位,去支持 ISP 监控区域代码。实现烧录程序的目的。单片机不断电就可下载程序,方便项目调试

上面我们故意用最低波特率与最高波特率都是1200,小于9600,我就点了下载,(板子是上电的)没有用板子的开关复位,就是通过纯软件复位,等了几秒没有反应,说明我们用9600下载的方式是不支持1200下载的

9600很慢的(哈哈)下载了

我们发现只要最低波特率到9600就可以软复位了,越高会下载越快

void Uart1_Routine() interrupt 4{	//记录接收命令流变量	static char Uart1_ser_n = 0; 	if (RI) 	{		RI = 0;//先把接收标志给清零		Uart1_Data = SBUF;				if (SBUF == 0x7f) //9600波特率		{			//接收命令为0x7f时就++			Uart1_ser_n++;			if(Uart1_ser_n > 10)//大于10基本就是确定是下载命令			{				Uart1_ser_n = 0;				//然后执行软复位				IAP_CONTR |= 0xe0;				}		}	}	if (TI) 	{		TI = 0;//先把发送标志给清零	}}

上面是发送一个字节,现在我们发送字符串

先了解一下SBUF

为什么一直是0xFF,眼看也不是1啊是不是 ,我们用逻辑分析仪来抓取看看

延时后

完美,为了让你直观的看到美,我采集一下给你们看看

我们调整上一个字节发送完成后马上发送下一个字节

我们给他一个标志位,前面一个字节发送完成后,标志位修改,然后发第二个字节,以此类推

//串口发送底层驱动的函数void Uart1_Up_Data_Drive(){		//串口1标志为1才能发送字节,	//可以让数据有效的发送	if(Uart1_Flag)	{		Uart1_Flag = 0;		SBUF = 1;	}}//串口1中断void Uart1_Routine() interrupt 4{	//记录接收命令流变量	static char Uart1_ser_n = 0; 	if (RI) 	{		RI = 0;//先把接收标志给清零			if (SBUF == 0x7f) //9600波特率		{			//接收命令为0x7f时就++			Uart1_ser_n++;			if(Uart1_ser_n > 10)//大于10基本就是确定是下载命令			{				Uart1_ser_n = 0;				//然后执行软复位				IAP_CONTR |= 0xe0;				}		}	}	if (TI) 	{		TI = 0;//先把发送标志给清零		//数据全部发送完成后标志位置1		//置1后是准备发送后一个字节		Uart1_Flag = 1;		//调用串口发送函数		Uart1_Up_Data_Drive();	}}

发字符串

单片机没有数据接收,串口标志就不会置1,电压就发不出去

我们可以看到接收缓冲区啥也没有,那就是因为发送缓冲区没有数据发送,单片机也就没有数据接收,标志没置1,然后单片机发送数据就没有一个触发的引子

单片机有数据接收,串口标志就会置1,电压就发出去

我们发送任意数据都可以,只要单片机接收到数据就行,然后串口标志就会置1,使得串口发送函数有用,我们就可以看到电压显示出来,但是细心的同学会发现,我的发送汉字缓冲区明明是换行回车,你这也没看到啊,那是SPI软件有点小毛病,我们换个软件

发送汉字缓冲区有 /n/r换行回车

发送汉字缓冲区有 /n换行,无回车

发送汉字缓冲区无换行,有回车/r

发送汉字缓冲区无换行,无回车

所以知道为什么我在发送汉字缓冲区中写换行回车了吗

主要代码

Uart1_Drive.c

#include "all.h"//需要显示串口的临时变量bit Uart1_Flag = 1;//汉字是固定的 直接code//串口发送汉字数组缓存  先换行/n回车/ru8 code Uart1_Up_Symbol_Buffer[30] = {"/n/r电压:  "};//串口发送数字数组缓存   20个足够以后用的了u8 xdata Uart1_Up_Num_Buffer[20];//串口1初始化void Uart1_Init(){	SM0 = 0;	SM1 = 1;	REN = 1;	//上面三条语句就等于操作SCON |= 0x50;	PCON &= 0x3f;	AUXR |= 0x01;	AUXR |= 0x14;	T2H = 0xfd;	T2L = 0x8f;	ES = 1;}//串口发送底层驱动的函数void Uart1_Up_Data_Drive(){		static xdata u8 count = 0;	//串口1标志为1才能发送字节,	//可以让数据有效的发送	if(Uart1_Flag)	{		Uart1_Flag = 0;		count++; 		switch (count)		{			case 1: SBUF = Uart1_Up_Symbol_Buffer[0];break;						case 2: SBUF = Uart1_Up_Symbol_Buffer[1];break;			case 3: SBUF = Uart1_Up_Symbol_Buffer[2];break;			case 4: SBUF = Uart1_Up_Symbol_Buffer[3];break;			case 5: SBUF = Uart1_Up_Symbol_Buffer[4];break;						case 6: SBUF = Uart1_Up_Symbol_Buffer[5];break;			case 7: SBUF = Uart1_Up_Symbol_Buffer[6];break;			case 8: SBUF = Uart1_Up_Symbol_Buffer[7];break;			case 9: SBUF = Uart1_Up_Symbol_Buffer[8];break;			case 10:SBUF = Uart1_Up_Symbol_Buffer[9];break;			case 12:SBUF = Uart1_Up_Num_Buffer[0];break;			case 14:SBUF = Uart1_Up_Num_Buffer[1];break;			case 16:SBUF = Uart1_Up_Num_Buffer[2];break;			case 18:SBUF = Uart1_Up_Num_Buffer[3];break;			case 20:SBUF = Uart1_Up_Num_Buffer[4];break;			case 22:SBUF = Uart1_Up_Num_Buffer[5];break;			case 24:count=0;break;		}	}}//串口1中断void Uart1_Routine() interrupt 4{	//记录接收命令流变量	static char Uart1_ser_n = 0; 	if (RI) 	{		RI = 0;//先把接收标志给清零			//当接收到一个字节时,串口标志置1		Uart1_Flag = 1;		if (SBUF == 0x7f) //9600波特率		{			//接收命令为0x7f时就++			Uart1_ser_n++;			if(Uart1_ser_n > 10)//大于10基本就是确定是下载命令			{				Uart1_ser_n = 0;				//然后执行软复位				IAP_CONTR |= 0xe0;				}		}	}	if (TI) 	{		TI = 0;//先把发送标志给清零		//数据全部发送完成后标志位置1		//置1后是准备发送后一个字节		Uart1_Flag = 1;		//调用串口发送函数		Uart1_Up_Data_Drive();	}}

Uart_Drive.h

#ifndef Uart1_Drive#define Uart1_Drive//外部声明extern void Uart1_Init();extern bit Uart1_Flag;extern void Uart1_Up_Data_Drive();extern u8 xdata Uart1_Up_Num_Buffer[20];#endif

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123696.html

相关文章

  • 身价亿的女王对小码农说中断会了

    摘要:复位后初值是子函数调用,中断响应过程调用子函数处理中断响应的时候,程序计数器的值以及相关数据会先压入堆栈,然后去处理子函数中断服务。联动文章身家过亿的帝都富豪对小码农说你时空复杂度会了吗 ...

    Leck1e 评论0 收藏0
  • 身价亿的女总裁对小码农说你按键会了

    摘要:行列总共使用个口,可以扫描个按键的开关状态,这就是矩阵键盘的优势。口之间必须串联电阻。 文章目录 小码农为了总裁,咳咳,为了知识敢说按键不会吗?==**帝都富豪与...

    Doyle 评论0 收藏0
  • 身价亿的贤淑才女对小码农说PWM可以控制时间长短

    摘要:否则可能会导致电平颠倒完美的计数糟糕的线条再来一个测试组我们来实现一个呼吸灯的效果呼吸灯波形为了贤淑妻子,咳咳,贤淑才女,小码农必定让控制时间什么是脉宽调制中间动的线是电流线,电流通断,电流小就暗,电流大就亮。 ...

    不知名网友 评论0 收藏0
  • 身价亿的温柔萝莉对小码农说ADC会采集

    摘要:对于电压或者电流连续变化的信号,就需要通过模数转换电路,变成单片机可以识别的数字电平信号。目前来说,常见的有两种方式,一种是并行比较,一种是逐次比较。具有成本低元件简单等优势,而且容易做出高精度的转换器,所以被广泛使用。 ...

    gnehc 评论0 收藏0
  • 回怼文章《为什么甲骨文被裁员工不值得同情》

    摘要:前言今天下班突然看到一篇刷屏朋友圈的文章为什么甲骨文被裁员工不值得同情来自一个财经的微信公众号刚看题目我以为文章是会分析甲骨文公司内部的财经类问题所以就戳开看了毕竟本人不喜欢看打鸡血的文章。 为工薪层能合理取得报酬而发声,为大众选择不同生活状态都能获得尊重而发声,为不同职场层次的职场人都能有健康的工作环境而发声。 前言 今天下班突然看到一篇刷屏朋友圈的文章来自一个XX财经的微信公众号,...

    _ivan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<