首先总结一下串口232,422,485
串口232:可双向传输,全双工,最大速率20Kbps,负逻辑电平,-15V~-3V逻辑“1”,+3V~+15V逻辑“0”。
串口422:可双向传输,4线全双工,2线单工。
串口485:可双向传输,4线全双工,2线单工,最大速率10Mb/s,差分信号,发送端:+2V~+6V逻辑“1”,-2V~-6V逻辑“0”,接收端:+200mV逻辑“1”,-200mV逻辑“0”。
对于串口的实现有以两个方案:
方案一,和原子的《例说STM32》一样,首先接收,然后处理,没有消息验证处理,这样就会出现消息覆盖,消息出错后死机,无法明确区分命令,无法及时应答握手信号。方案二,借鉴uC/OSII的消息队列,进入中断服务函数之后,关闭中断,接收数据,如果没有数据接收,等待一段时间(时间和波特率有关)后开中断,出中断,然后在对接收到的数据进行处理,下面看代码:
消息队列及其初始化函数:
/*osq结构体来管理消息队列*/
typedef struct os_q { /* QUEUE CONTROL BLOCK */
u8 *OSQStart; /* Pointer to start of queue data */
u8 *OSQEnd; /* Pointer to end of queue data */
u8 *OSQIn; /* Pointer to where next message will be inserted in the Q */
u8 *OSQOut; /* Pointer to where next message will be extracted from the Q */
u8 OSQSize; /* Size of queue (maximum number of entries) */
u8 OSQEntries; /* Current number of entries in the queue */
} OS_Q;
OS_Q *posq,osq;
u8 USART_RX_BUF[length_buff]; //循环队列,存储接受的信息.
void OS_QInit() //初始化结构体
{
posq=&osq;
posq->OSQStart=USART_RX_BUF;
posq->OSQEnd=&USART_RX_BUF[length_buff];
posq->OSQIn=USART_RX_BUF;
posq->OSQOut=USART_RX_BUF;
posq->OSQSize=length_buff;
posq->OSQEntries=0;
}
///*在中断函数中将一条消息的所有字节一次性得保存在消息队列中*/
u8 message_buff[20];
void USART1_IRQHandler(void)
{
u8 num=0;
// u8 i;
u8 time=0;//接受超时技术
USART1->CR1&=0XFFDF;
LED=!LED;
while(1)
{
if(USART1->SR&(1<<5)) //如果有数据收到的话,将消息存在消息队列中
{
message_buff[num]=(u8)USART1->DR;
num++;
*posq->OSQIn++=(u8)USART1->DR;
posq->OSQEntries++;
if(posq->OSQIn==posq->OSQEnd)
{
posq->OSQIn = posq->OSQStart;
}
time=0;
}
else
{
delay_us(10);
time++;
if(time>=50) break;
}
}
USART1->CR1|=0X0020;
}
这样就把数据一次性全部存储下来了,剩下的就是对消息缓冲器message_buff[]中的消息进行处理了,这样就解决了消息覆盖,消息出错无法纠正的问题,至于消息怎么处理就是依据不同的需求不同的处理,另外注意,握手信号好用定时器中断。
关键字:STM32 串口应用
引用地址:
STM32的串口应用总结
推荐阅读最新更新时间:2024-03-16 15:37
STM32使用I2C读写EEPROM流程总结
配置I/O端口,配置的模式,使能GPIO和时钟 写: 检测SDA是否空闲。 检测“事件”是否成功。 按协议发出起始信号 检测“事件”是否成功。 发出7位器件地址和写模式。 检测“事件”是否成功。 要写入的存储区首地址。 检测“事件”是否成功。 用页写入方式或字节写入方式写入数据。 检测EEPROM是否进入Standby状态。 检测“事件”是否成功。 发送通信结束信号。 读: 检测SDA是否空闲。 按协议发出起始信号。 发出7位器件地址和写模式。(伪写) 发出要读取的存储区的首地址。 重发起始信号。 发出7位器件地址和读模式。 接收数据。 类似写操作,每个操作后要检测“事件”是否成功。
[单片机]
关于STM32串口使用DMA的教程
1 前言 直接存储器访问(Direct Memory Access),简称DMA。DMA是CPU一个用于数据从一个地址空间到另一地址空间“搬运”(拷贝)的组件,数据拷贝过程不需CPU干预,数据拷贝结束则通知CPU处理。 因此,大量数据拷贝时,使用DMA可以释放CPU资源。DMA数据拷贝过程,典型的有: 内存— 内存,内存间拷贝 外设— 内存,如uart、spi、i2c等总线接收数据过程 内存— 外设,如uart、spi、i2c等总线发送数据过程 2 串口有必要使用DMA吗 串口(uart)是一种低速的串行异步通信,适用于低速通信场景,通常使用的波特率小于或等于115200bps。 对于小于或者等于
[单片机]
STM32-通用定时器基本定时功能
1. STM32的Timer简介 STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。 其中TIM1和TIM8是能够产生3对PWM互补输出的高级登时其,常用于三相电机的驱动,时钟由APB2的输出产生。TIM2-TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。由于STM32的TIMER功能太复杂了,所以只能一点一点的学习。因此今天就从最简单的开始学习起,也就是TIM2-TIM5普通定时器的定时功能。
[单片机]
MDK环境下 万利EK-STM32F STM32开发板在RAM中仿真
启动脚本RAM.ini中的内容: FUNC void Setup (void) { SP = _RDWORD(0x20000000); // 堆栈指针 PC = _RDWORD(0x20000004); // PC _WDWORD(0xE000ED08, 0x20000000); // 中断向量偏移地址 } LOAD .ObjBlinky.axf INCREMENTAL // Download,.axf 根据自己的文件名和目录修改 Setup(); // 调用Setup(); g, m
[单片机]
STM32 (Cortex-M3) 中NVIC(嵌套向量中断控制)的理解
一、STM32 (Cortex-M3) 中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和响应优先级,也把响应优先级称作“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先级。 1. 何为占先式优先级(pre-emption priority) 高占先式优先级的中断事件会打断当前的主程序/中断程序运行—抢断式优先响应,俗称中断嵌套。 2. 何为副优先级(subpriority) 在占先式优先级相同的情况下,高副优先级的中断优先被响应; 在占先式优先级相同的情况下,如果有低副优先级中断正在执行, 高副优先级的中断要等待已被响应的低副优先级中断执行结束后才能得到响应—非抢断式响应(
[单片机]
关于stm32HardFault_Handler异常(死机)的处理
在系统开发的时候,出现了HardFault_Handler硬件异常,也就是死机,尤其是对 于调用了os的一系统,程序量大,检测堆栈溢出,以及数组溢出等,找了半天发现什么都没有的情况下,估计想死的心都有了。如果有些程序开始的时候一切没有问题,但是运行几个小时候,会发现死机了,搞个几天下来估计蛋都碎了一地吧。。。 一般来说运行操作系统 是以下几个问题 1.开始的时候给ucos分配的堆栈太小了,随着项目做多了,这类问题一般很容易解决 #define TASK_IO_SIZE 300 #define TASK_IO_PRIO 6 OS_STK TASK_IO_STK ; 比如修改300到 1000,做开发的时候 如果ram允许,尽量大些,
[单片机]
STM32开发笔记18: STM32CubeMX中Debug Serial Wire的设置问题
单片机型号:STM32L053R8T6 使用STM32CubeMX时,可发现在SYS下,有Debug Serial Wire选项,如下图所示。 使能该选项后,相应的IO引脚,会变为调试引脚,如下图所示。 最初,认为必须选中该选项才能对STM32进行仿真调试,今天调试时,忽略了该选项,发现仿真调试依然正常,并不受影响。也就是说,勾选该选项与否,都可以进行仿真调试,那么该选项的作用时什么呢? 答案:将其显示指定为调试引脚,不可当作其它功能复用,如果将该引脚用做其它功能,则不再具有仿真功能。另外,再补充一点,我在项目中,由于引脚数目有限,将SWDIO复用为IO口使用,使用NUCLEO自带的仿真
[单片机]
STM32-(31):独立看门狗
在嵌入式系统中,由于MCU(微控制单元:Microcontroller Unit)的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状态进行实时监测的考虑,便产生了一种专门用于监测程序运行状态的模块,俗称 看门狗 (watchdog) 在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以在使用有看门狗的时候要注意清看门狗。 看门狗是恢复系统的正常运行及有效的监视管理器(具有锁定光驱,锁定
[单片机]