[百问网 7Day物联网智能家居实战训练]Day4 串口
串口通讯:RS232、RS422、RS485
|
场景 |
传输距离 |
传输电平 |
|
|
微处理器、板载蓝牙模块通信 |
几厘米 |
TTL电平,引脚直接连接 |
|
|
微处理器在工业现场 |
几十米 |
TTL电平转换为RS232、RS422、RS485 |
|
通讯接口标准:
|
接口 |
电平 |
特点 |
|
TTL |
1:2.4V~5V;0:0V~0.4V |
引脚直连 |
|
RS232 |
1:-3~-15V;0:3V~15V |
电平转换,距离15m |
|
RS422/RS485 |
1:压差2V~6V;0:压差-2V~6V |
电平转换,距离1200m |
TTL接口硬件连接:

基本概念:
|
波特率 |
每秒传输这么多个比特位数bit |
有9600,19200,115200等选项 |
|
起始位 |
表示传输数据开始 |
先发出一个逻辑”0”的信号 |
|
数据位 |
5~8位逻辑”0”或”1” |
|
|
校验位 |
校验数据传送的正确性【可选】 |
“1”的位数: 偶校验:偶数 奇校验:奇数 |
|
停止位 |
一个字符数据的结束标志 |
数据线变回逻辑”1” |
数据发送:
- 接受、发送方约定波特率、数据格式。【假设数据位是8,停止位是1,校验位是1】
- 准备
- 发送方:输出逻辑0,并保持1位的时间
- 接收方:检测到逻辑0【确定发送法开始发送数据】
- 数据发送:
- 发送方:根据数据的bit 0设置引脚电平,并保持1位的时间
- 接收方:读取引脚电平,得到bit 0;
- 循环发送8位数据。
- 校验【可省】:
- 发送方:计算出校验值,设置引脚,并保持1位的时间;
- 接收方读取引脚电平,得到校验值;
- 传输结束:
- 发送方:输出逻辑1,并保持1位的时间;
- 接收方:读取引脚电平,直到数据传输结束;
这步可以省略

STM32串口
STM32F103系列最多有3个通用同步异步收发器(Universal synchronous asynchronous receiver transmitter,USART),2个通用异步收发器(Universalasynchronous receiver transmitter,UART)。USART和UART的主要区别在于,USART支持同步通信,该模式有一根时钟线提供时钟。
串口在嵌入式中经常使用,一般使用UART就足够了,常见的用途如下:
1. 作为调试口,打印程序运行的状态信息;
2. 连接串口接口的模块(比如GPS模块),传输数据;
3. 通过电平转换芯片变为RS232/RS485电平,连接工控设备;
STM32F103C8T6只有USART1/2/3

USART内部结构:

USART组成:
1.引脚
|
TX |
数据发送 |
|
|
RX |
数据接收 |
|
|
SW_RX |
在单线和智能卡模式下接收数据 |
内部引脚,没有具体外部引脚 |
|
RTS |
在硬件流控制时,用于指示本设备准备好可接收数据 |
低电平说明本设备可以接收数据 |
|
CTS |
在硬件流控制时,用于指示本设备准备好可发送数据 |
低电平说明本设备可以发送数据; |
|
CK |
在同步模式时,用于输出时钟 |
2.波特率发生器
设置USART_BRR寄存器的值,实现串口通信数据传输速率的设置。
计算公式:

|
|
波特率 |
|
|
外设USART的时钟频率, |
|
USARTDIV |
USART_BRR 寄存器的值。 |
在利用寄存器配置USART的波特率的时候需要依据此公式计算USART_BRR的值,而在HAL库中无需
计算
假设所需波特率为115200,当前USART时钟为72MHz:USARTDIV=72000000/(115200*16)=39.0625。
USART_BRR寄存器使用高12位[15:4]存放整数部分,低4位[3:0]存放小数部分,小数部分每一位对应1/2 4 =0.0625。
因此,整数39对应16进制为0x27,左移4位为0x270,小数0.0625,对应0x1,USART_BRR=0x271
即可。
3.发送器/接收器控制单元
通过向控制寄存器CR1、CR2、CR3和状态寄存器SR写入相应的位,可实现对USART数据的发送和接收
控制。
|
CR1 |
配置USART的数据位、校验位和中断使能 |
|
CR2 |
配置USART的停止位和SCLK时钟控制 |
|
CR3 |
CTS硬件流控制、DMA多缓冲控制等。 |
|
SR |
查询USART的状态。 |
4.数据收发器单元
实现数据在传输时,是一位一位的发送和接收。
组成:由发送数据寄存器(TDR)、发送移位寄存器、接收数据寄存器(RDR)、接收移位寄存器。
|
发送移位寄存器 |
发送数据并串转换 |
|
接收移位寄存器 |
接收数据串并转换 |
补充:串/并行通讯

全双工、半双工、单工传输:

同步、异步通讯:时钟信号

[百问网 7Day物联网智能家居实战训练]Day4 中断
行过程中,如果遇到其它紧急的事件需要处理,则先暂停当前任务,执行紧急事件,待紧急事件处理完后,再恢复到刚才暂停的地方继续执行。
中断和复位控制寄存器的Bits[10:8]PRIGROUP)将优先级分组。
分组决定可编程中断的PRI_n的Bits[7:0]的高低位分配,从而影响抢占优先和子优先级的级数
|
|
|
|
抢占优先级决定:是否可以产生中断嵌套,子优先级决定中断响应顺序,
|
|
|
|
|
|
|
|
|
两种优先级一样:则看中断在中断异常表中的位置,越靠前越先响应。
抢占优先级高(值小):中断可以中断抢占优先级低(值大)的中断处理函数,进而执行高优先级的中
断处理函数,执行完毕后再继续执行被中断的低优先级的处理函数。
当一个中断到来后,若CPU正在处理另一个中断,则这个后到来的中断就要等到前一个中断处理函数处理完毕后才能被处理,
当这两个中断同时到达,则中断控制器会根据它们的子优先级决定先处理哪个。
HAL库启动文件“startup_stm32f103xb.s”,可以看到定义的中断向量表
__Vectors DCD
__initial_sp ; Top
of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0
; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD WWDG_IRQHandler ; Window Watchdog
DCD PVD_IRQHandler ; PVD through EXTI Line detect
DCD TAMPER_IRQHandler ; Tamper
DCD RTC_IRQHandler ; RTC
DCD FLASH_IRQHandler ; Flash
DCD RCC_IRQHandler ; RCC
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
DCD ADC1_2_IRQHandler ; ADC1_2
DCD USB_HP_CAN1_TX_IRQHandler ; USB High Priority or CAN1 TX
DCD USB_LP_CAN1_RX0_IRQHandler ; USB Low Priority or CAN1 RX0
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD TIM1_BRK_IRQHandler ; TIM1 Break
DCD TIM1_UP_IRQHandler ; TIM1 Update
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
DCD I2C1_EV_IRQHandler ; I2C1 Event
DCD I2C1_ER_IRQHandler ; I2C1 Error
DCD I2C2_EV_IRQHandler ; I2C2 Event
DCD I2C2_ER_IRQHandler ; I2C2 Error
DCD SPI1_IRQHandler ; SPI1
DCD SPI2_IRQHandler ; SPI2
DCD USART1_IRQHandler ; USART1
DCD USART2_IRQHandler ; USART2
DCD USART3_IRQHandler ; USART3
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTC_Alarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
__Vectors_End
可以看到第2~16行,为10个系统异常,剩下的全为外部中断。同时这里还定义了所有的中断处理函数名
字,当外设产生中断时,则跳到中断向量表中对应中断处理函数位置,比如发生RTC中断事件,则跳到22行
STM32F103的异常和中断,基于Cortex-M3修改而来,前面的系统异常部分几乎没有变化,外部中断则
同样,STM32F103也继承了Cortex-M3的中断优先级规则,因为中断少了很多,中断优先级也用不了那
么多,只使用了PRI_n的Bits[7:0]中的Bits[7:4]设置优先级,因此优先级分组
可见STM32F103系列有16级可编程优先级,STM32F103不使用PRIGROUP来命名分组,而采用
NVIC_PRIORITYGROUP_x 的 方 式 命 名 , 即 NVIC_PRIORITYGROUP_0 对 应 PRIGROUP 为 7 , 在
#define
NVIC_PRIORITYGROUP_0 0x00000007U
/*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1
0x00000006U /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PRIORITYGROUP_2
0x00000005U /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PRIORITYGROUP_3
0x00000004U /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PRIORITYGROUP_4
0x00000003U /*!< 4 bits for pre-emption priority
0
bits for subpriority */
中断优先级分组:只会设置一次,它针对的是系统中所有的中断。后续设置某个中断的中断优先级
时,只需要在这个组规定的抢占优先级数和子优先级级数范围内分配优先级级数。后续代码中,不应该再修
改中断优先级分组,否则导致中断顺序不按预期触发。将设置中断优先级分组放在了“HAL_Init()”里,如代码段 10.2.3 的第5行,调用“HAL_NVIC_SetPriorityGrouping()”函数设置中断优先级.
HAL_StatusTypeDef HAL_Init(void)
{
...
/* Set Interrupt Group Priority */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
...
}
这里默认设置的优先级分组为NVIC_PRIORITYGROUP_4,则后续使用“HAL_NVIC_SetPriority()”函
数设置优先级时,抢占优先级的范围是0~15,子优先级的值只能选择0。
“HAL_NVIC_SetPriority()”函数需要传入三个参数,参数IRQn是中断号,如表 10.2.1 所示的中断号。
后两个是抢占优先级级数和子优先级级数,注意结合中断分组设置范围。
/**
* @brief Sets the priority of an interrupt.
* @param IRQn: External interrupt number.
* This parameter can be an enumerator of
IRQn_Type enumeration
* (For the complete STM32 Devices IRQ
Channels list, please refer to the appropriate CMSIS device file
(stm32f10xx.h))
* @param PreemptPriority: The preemption priority for
the IRQn channel.
* This parameter can be a value between
0 and 15
* A lower priority value indicates a
higher priority
* @param SubPriority: the subpriority level for the
IRQ channel.
* This parameter can be a value between
0 and 15
* A lower priority value indicates a
higher priority.
* @retval None
*/
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t
SubPriority)
{
uint32_t prioritygroup = 0x00U;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup =
NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn,
NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}
1.先使用“HAL_NVIC_SetPriorityGrouping()”函数设置中断优先级分组,
2.再使用“HAL_NVIC_SetPriority()”函数设置不同中断的抢占优先级级数和子优先级级数。





浙公网安备 33010602011771号