STM32的USART讲解
来源:互联网 发布:网络连接错误 编辑:程序博客网 时间:2024/05/20 21:49
一,串口相关寄存器
USART_SR 状态寄存器USART_DR 数据寄存器USART_BRR 波特率寄存器USART_CR1 控制寄存器
USART_SR-状态寄存器:
状态寄存器USART_SR,描述串口寄存器的一些状态:
如位5:读数据寄存器非空
通过读取这个位的值,判断是否收到了完整的数据
串口已经接收到了数据,并且已经写入到了USART_DR寄存器
USART_DR-数据寄存器:
数据寄存器USART_DR,只使用了位0-8,其他位保留
读寄存器:读取该寄存器获取接收到的数据值
写寄存器:向该寄存器写入发送的数据对数据进行发送
USART_BRR-波特率寄存器:
波特率寄存器USART_BRR,只用到了低16位,高16位保留
0-3位[3:0] : USART分频器的小数部分DIV_Fraction
4-15位[15:4] : USART分频器的整数部分DIV_Mantissa
USART_CR1-控制寄存器:
USART_BRR波特率寄存器,设置串口寄存器使能位
如:接收使能,发送使能
二,波特率的计算方法
波特率发生器:
如图: 波特率由波特率发生器和PCLKx共同产生 PCLKx的值由串口本身决定 通过配置USART_BRR寄存器确定波特率发生器的值 经过USARTDIV分频器除以16得到最终的波特率
波特率计算方法:
设置串口1波特率为115200MHz
串口1的时钟来自PCLK2=72MHz由公式得到: USARTDIV=72000000/(115200*16)=39.0625整数部分DIV_Mantissa=39=0x27小数部分DIV_Fraction=16*0,0625=1=0x01所以设置USART->BRR=0x0271,就可以实现设置串口1的波特率为115200MHz
三,串口操作相关库函数
获取状态标志位函数-操作USART_SR寄存器
// 获取状态标志位FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);// 清除状态标志位void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);// 获取中断状态标志位ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);// 清除中断状态标志位void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
接收发送数据函数-操作USART_DR寄存器
// 发送数据到串口(通过写USART_DR寄存器发送数据)void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);// 接收数据(从USART_DR寄存器读取接收到的数据)uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
- 1
- 2
- 3
- 4
串口配置函数
// 串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);// 使能串口void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);// 使能相关中断void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
- 1
- 2
- 3
- 4
- 5
- 6
四,串口硬件连接
PA9-RXDPA10-TXDCH340 USB转串口 将USB虚拟为串口使用
五,串口配置的步骤
1,串口时钟使能,GPIO时钟使能 RCC_APB2PeriphClockCmd()2,串口复位 USART_DeInit();3,GPIO端口模式设置 GPIO_Init();4,串口参数初始化 USART_Init()5,开启中断并初始化NVIC NVIC_Init(); USART_ITConfig();6,使能串口 USART_Cmd();7,中断函数逻辑 USARTx_IRQHandler();8,串口数据发送 void USART_SendData(USART_TypeDef* USARTx, uint16_t Data); uint16_t USART_ReceiveData(USART_TypeDef* USARTx);9,串口传输状态获取 ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
六,串口测试程序设计
程序功能:
电脑通过USB线连接开发板,开发板通过USB转串口实现和电脑的通信 电脑使用串口工具想单片机发送数据,单片机收到数据后返回给电脑 注:以串口1为例实现
七,串口测试程序实现分析
1,使能GPIO时钟
串口1的发送,接收引脚为PA9和PA10所以我们要使能GPIOA和串口1的时钟串口1和GPIOx时钟源为APB2所以使用RCC_APB2PeriphClockCmd函数进行初始化
stm32f10x_rcc.c找到RCC_APB2PeriphClockCmd函数源码:
/** * @brief Enables or disables the High Speed APB (APB2) peripheral clock. * @param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock. * This parameter can be any combination of the following values: * @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, * RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE, * RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1, * RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1, * RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3, * RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17, * RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 * @param NewState: new state of the specified peripheral clock. * This parameter can be: ENABLE or DISABLE. * @retval None */void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState){ /* Check the parameters */ assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph)); assert_param(IS_FUNCTIONAL_STATE(NewState)); if (NewState != DISABLE) { RCC->APB2ENR |= RCC_APB2Periph; } else { RCC->APB2ENR &= ~RCC_APB2Periph; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
stm32f10x_rcc.h找到IS_RCC_APB2_PERIPH函数声明:
/** @defgroup APB2_peripheral * @{ */#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001)#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008)#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020)#define RCC_APB2Periph_GPIOE ((uint32_t)0x00000040)#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080)#define RCC_APB2Periph_GPIOG ((uint32_t)0x00000100)#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000200)#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000400)#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000800)#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000)#define RCC_APB2Periph_TIM8 ((uint32_t)0x00002000)#define RCC_APB2Periph_USART1 ((uint32_t)0x00004000)#define RCC_APB2Periph_ADC3 ((uint32_t)0x00008000)#define RCC_APB2Periph_TIM15 ((uint32_t)0x00010000)#define RCC_APB2Periph_TIM16 ((uint32_t)0x00020000)#define RCC_APB2Periph_TIM17 ((uint32_t)0x00040000)#define RCC_APB2Periph_TIM9 ((uint32_t)0x00080000)#define RCC_APB2Periph_TIM10 ((uint32_t)0x00100000)#define RCC_APB2Periph_TIM11 ((uint32_t)0x00200000)#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
从参数定义验证了GPIOA-GPIOG 和串口1(USART1)的时钟使能由RCC_APB2PeriphClockCmd()控制
所以使能GPIOA和串口1时钟代码为:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟源RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能串口1时钟源
- 1
- 2
2,初始化GPIOA的工作模式
通过查找STM32中文参考手册确定串口1引脚工作模式配置:
如图:串口1接收发送引脚配置 发送端PA9配置为推挽复用输出 接收端PA10配置为浮空输入或上拉输入
代码:
GPIO_InitTypeDef GPIO_InitStrue;//发送端PA9配置GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9; //发送端-TXDGPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; //推挽输出GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA, &GPIO_InitStrue);//接收端PA10配置GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10; //接收端-RXDGPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA, &GPIO_InitStrue);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
3,串口初始化
stm32f10x_usart.h头文件找到USART_Init函数声明:
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
- 1
stm32f10x_usart.h找到入参USART_InitTypeDef结构体声明
/** * @brief USART Init Structure definition */typedef struct{ uint32_t USART_BaudRate; // 设置波特率 uint16_t USART_WordLength; // 字长8或9(停止位) uint16_t USART_StopBits; // 停止位 uint16_t USART_Parity; // 奇偶校验 uint16_t USART_Mode; // 发送接收使能 uint16_t USART_HardwareFlowControl; // 硬件流控制} USART_InitTypeDef;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
USART_HardwareFlowControl-硬件流参数有效性验证
/** @defgroup USART_Hardware_Flow_Control * @{ */#define USART_HardwareFlowControl_None ((uint16_t)0x0000)#define USART_HardwareFlowControl_RTS ((uint16_t)0x0100)#define USART_HardwareFlowControl_CTS ((uint16_t)0x0200)#define USART_HardwareFlowControl_RTS_CTS ((uint16_t)0x0300)#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\ (((CONTROL) == USART_HardwareFlowControl_None) || \ ((CONTROL) == USART_HardwareFlowControl_RTS) || \ ((CONTROL) == USART_HardwareFlowControl_CTS) || \ ((CONTROL) == USART_HardwareFlowControl_RTS_CTS))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
USART_Mode-使能参数有效性验证
/** @defgroup USART_Mode * @{ */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
USART_Parity-奇偶校验参数有效性
/** @defgroup USART_Parity * @{ */
#define USART_Parity_No ((uint16_t)0x0000)#define USART_Parity_Even ((uint16_t)0x0400)#define USART_Parity_Odd ((uint16_t)0x0600)#define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ ((PARITY) == USART_Parity_Even) || \ ((PARITY) == USART_Parity_Odd))- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
USART_StopBits-停止位参数有效性
/** @defgroup USART_Stop_Bits * @{ */#define USART_StopBits_1 ((uint16_t)0x0000)#define USART_StopBits_0_5 ((uint16_t)0x1000)#define USART_StopBits_2 ((uint16_t)0x2000)#define USART_StopBits_1_5 ((uint16_t)0x3000)#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \ ((STOPBITS) == USART_StopBits_0_5) || \ ((STOPBITS) == USART_StopBits_2) || \ ((STOPBITS) == USART_StopBits_1_5))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
USART_WordLength-字长参数有效性
/** @defgroup USART_Word_Length * @{ */
#define USART_WordLength_8b ((uint16_t)0x0000)#define USART_WordLength_9b ((uint16_t)0x1000)#define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ ((LENGTH) == USART_WordLength_9b))- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
串口初始化代码:
USART_InitTypeDef USART_InitStrue;USART_InitStrue.USART_BaudRate=115200; //设置波特率-115200MHzUSART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制-不使用USART_InitStrue.USART_Mode=USART_Mode_Rx| USART_Mode_Tx; //使能设置-发送接收都使能USART_InitStrue.USART_Parity=USART_Parity_No; //奇偶校验-不使用奇偶校验USART_InitStrue.USART_StopBits=USART_StopBits_1; //停止位-一个停止位USART_InitStrue.USART_WordLength=USART_WordLength_8b //字长-8位字长USART_Init(USART1, &USART_InitStrue);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
4,使能串口1:
stm32f10x_usart.h头文件找到USART_Cmd函数定义
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);USART_Cmd(USART1, ENABLE);
- 1
- 2
5,由于使用了中断首先要配置中断优先级分组-在主函数
misc.h头文件中找到NVIC_PriorityGroupConfig函数声明:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
- 1
misc.c中找到NVIC_PriorityGroupConfig函数实现:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup){ /* Check the parameters */ assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup)); /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */ SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
查看参数IS_NVIC_PRIORITY_GROUP有效性校验-misc.h
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 4 bits for subpriority */#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 3 bits for subpriority */#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 2 bits for subpriority */#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 1 bits for subpriority */#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 0 bits for subpriority */#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ ((GROUP) == NVIC_PriorityGroup_1) || \ ((GROUP) == NVIC_PriorityGroup_2) || \ ((GROUP) == NVIC_PriorityGroup_3) || \ ((GROUP) == NVIC_PriorityGroup_4))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
中断分组配置代码:
//配置中断分组为2,即2位抢占优先级和2位响应优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)
- 1
- 2
6,开启接收中断
stm32f10x_usart.h头文件中找到USART_ITConfig函数声明:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
- 1
stm32f10x_usart.c中找到USART_ITConfig函数实现:
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState){ uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00; uint32_t usartxbase = 0x00; /* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_CONFIG_IT(USART_IT)); assert_param(IS_FUNCTIONAL_STATE(NewState)); /* The CTS interrupt is not available for UART4 and UART5 */ if (USART_IT == USART_IT_CTS) { assert_param(IS_USART_123_PERIPH(USARTx)); } usartxbase = (uint32_t)USARTx; /* Get the USART register index */ usartreg = (((uint8_t)USART_IT) >> 0x05); /* Get the interrupt position */ itpos = USART_IT & IT_Mask; itmask = (((uint32_t)0x01) << itpos); if (usartreg == 0x01) /* The IT is in CR1 register */ { usartxbase += 0x0C; } else if (usartreg == 0x02) /* The IT is in CR2 register */ { usartxbase += 0x10; } else /* The IT is in CR3 register */ { usartxbase += 0x14; } if (NewState != DISABLE) { *(__IO uint32_t*)usartxbase |= itmask; } else { *(__IO uint32_t*)usartxbase &= ~itmask; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
第二个参数USART_IT的有效性校验IS_USART_CONFIG_IT:
stm32f10x_usart.h头文件找到IS_USART_CONFIG_IT声明:
#define USART_IT_PE ((uint16_t)0x0028)#define USART_IT_TXE ((uint16_t)0x0727)#define USART_IT_TC ((uint16_t)0x0626)#define USART_IT_RXNE ((uint16_t)0x0525)#define USART_IT_IDLE ((uint16_t)0x0424)#define USART_IT_LBD ((uint16_t)0x0846)#define USART_IT_CTS ((uint16_t)0x096A)#define USART_IT_ERR ((uint16_t)0x0060)#define USART_IT_ORE ((uint16_t)0x0360)#define USART_IT_NE ((uint16_t)0x0260)#define USART_IT_FE ((uint16_t)0x0160)#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \ ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \ ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \ ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
串口1初始化代码:
//打开串口1的接收中断,当串口1接收到数据时会触发此中断USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
- 1
- 2
6,中断优先级的设置
初始化NVIC,设置中断的抢占优先级和响应优先级
参考:NVIC
NVIC_InitTypeDef NVIC_InitTypeStrue;NVIC_InitTypeStrue.NVIC_IRQChannel=USART1_IRQn; // 哪个通道-stm32f10x.h顶层头文件包含参数定义NVIC_InitTypeStrue.NVIC_IRQChannelCmd=ENABLE; // 是否开启中断通道-使能NVIC_InitTypeStrue.NVIC_IRQChannelPreemptionPriority=1; // 抢占优先级NVIC_InitTypeStrue.NVIC_IRQChannelSubPriority=1; // 响应优先级,子优先级NVIC_Init(&NVIC_InitTypeStrue);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
7,编写中断服务函数
格式: USARTx_IRQHandler();
在启动文件startup_stm32f10x_hd.s中找到串口123的中断服务函数 DCD USART1_IRQHandler ; USART1 DCD USART2_IRQHandler ; USART2 DCD USART3_IRQHandler ; USART3
- 1
- 2
- 3
- 4
中断服务函数代码
void USART1_IRQHandler(void){ u8 res; //判断中断类型 //参数1:哪个串口 参数2:中断类型 if(USART_GetITStatus(USART1, USART_IT_RXNE)){//接收数据中断 res = USART_ReceiveData(USART1);//读取串口1接收到的数据 //回发 USART_SendData(USART1, res); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
八,串口程序完整代码
USER文件夹新建main.c函数:
#include "stm32f10x.h"// 主函数int main(void){ // 设置中断优先级分组位2 - 2位抢占2位相应 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 调用函数 初始化USART1相关引脚配置 My_USART1_Init(); while(1);}// 串口初始化函数void My_USART1_Init(void){ GPIO_InitTypeDef GPIO_InitStrue; USART_InitTypeDef USART_InitStrue; NVIC_InitTypeDef NVIC_InitStrue; // 1,使能GPIOA,USART1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); // 2,设置PGIO工作模式-PA9 PA10复用为串口1 GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9; GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10; GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz; GPIO_Init(GPIOA,&GPIO_InitStrue); // 3,串口1初始化配置 USART_InitStrue.USART_BaudRate=115200; USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; USART_InitStrue.USART_Parity=USART_Parity_No; USART_InitStrue.USART_StopBits=USART_StopBits_1; USART_InitStrue.USART_WordLength=USART_WordLength_8b; USART_Init(USART1,&USART_InitStrue); // 4,打开串口1 USART_Cmd(USART1,ENABLE); // 5,使能串口1中断-接收数据完成中断 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); // 6,设置中断优先级-主函数中设置中断优先级分组 NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn; NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1; NVIC_InitStrue.NVIC_IRQChannelSubPriority=1; NVIC_Init(&NVIC_InitStrue);}// 中断服务函数void USART1_IRQHandler(void){ u8 res; if(USART_GetITStatus(USART1,USART_IT_RXNE))// 接收到数据 { res= USART_ReceiveData(USART1); // 获得串口1接收到的数据 USART_SendData(USART1,res); // 通过串口1发送数据 }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
以上代码实现: 电脑通过串口助手发送数据给单片机 单片机接收数据进入接收数据串口中断 读取DR寄存器中接收到的数据 将接收到的数据再通过串口回写给电脑
(function () {('pre.prettyprint code').each(function () { var lines = - ').addClass('pre-numbering').hide();
- STM32的USART讲解
- STM32 USART的使用
- STM32的USART
- STM32的USART注意
- STM32的USART
- STM32的USART
- STM32的USART
- STM32串行通信USART讲解笔记
- STM32中USART的使用方法
- 20130408-[转]STM32的USART
- STM32中USART的使用方法
- STM32 USART
- STM32 USART
- STM32-USART
- stm32的usart操纵超级终端(usart 操纵串口)
- stm32的USART的初级使用
- STM32笔记---DMA(USART)的演示
- STM32-USART DMA_Interrupt例程的学习
- Linux下的Minicom
- 【算法题】KMP算法应用:二叉树结构匹配
- 用户密码MD5和SHA加密
- 超详细Retrofit源码解析(二)
- Java——HashMap原理
- STM32的USART讲解
- 判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。(回溯法)
- 优先级队列
- DNS主从服务器配置及案例解析
- 新装MySQL的一系列问题
- android开发之路(1)-- 支付宝SDK集成
- vb.net 教程 3-13 动态创建控件3
- android studio 7.0 FileProvider问题详解及相机示例
- js模块化之sea.js