STM32串口通信 (缓冲区 发送不出数据&接收不到数据)
STM32串口通信流程附上代码注意事项一点心得:流程(简单的发送数据)GPIO时钟使能串口时钟使能串口的GPIO配置写初始化串口函数,配置串口USART_Init(USART1,&USART_InitStruct);开启(使能)串口USART_Cmd(USART1, ENABLE);附上代码void NVIC_Config_USART(){NVIC_InitTypeDefNVIC_Init
·
流程
(简单的发送数据)
- GPIO时钟使能
- 串口时钟使能
- 串口的GPIO配置
- 写初始化串口函数,配置串口USART_Init(USART1,&USART_InitStruct);
- 开启(使能)串口USART_Cmd(USART1, ENABLE);
附上代码
void NVIC_Config_USART()
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(& NVIC_InitStruct);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
}
void Init_UART()
{
GPIO_InitTypeDef GPIOInitstruct;
USART_InitTypeDef USART_InitStruct;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,ENABLE); //开启串口对应的GPIO时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1,ENABLE);//开启串口1的时钟 :Tx-A9 RX-A10,开
GPIOInitstruct.GPIO_Mode = GPIO_Mode_AF_PP; //设置串口GPIO模式(有两个)
GPIOInitstruct.GPIO_Pin = GPIO_Pin_9;
GPIOInitstruct.GPIO_Speed = GPIO_Speed_50MHz; //Tx GPIO配置
GPIO_Init(GPIOA,&GPIOInitstruct); //设置TX为推免输出模式
GPIOInitstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIOInitstruct.GPIO_Pin = GPIO_Pin_10;
GPIOInitstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIOInitstruct); //设置RX GPIO配置
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct); //配置好串口
NVIC_Config_USART(); //配置NVIC
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); // 使能接收中断
USART_Cmd(USART1, ENABLE); //开启串口
//串口接受,会引发中断
}
void UART_SendByte(USART_TypeDef * USARTx, uint8_t dat)
{
USART_SendData(USART1, dat);
while((USART_GetFlagStatus(USART1,USART_FLAG_TC))== RESET);
//发送缓冲区为空,状态置1, 写入一个数据,状态置0,灯数据发送借书,这个状态寄存器就变成1
//实现了串口发送一个字节
}
void UART_SendString(USART_TypeDef * USARTx, char* string)
{
char * str = string;//指向string
while(*str) //只要str不为0,表示字符串还没有结束
{
UART_SendByte(USARTx, *str);
str++;
}
}
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOE, ENABLE); //使能 PB,PE 端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED0-->PB.5 推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 推挽输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高
}
中断函数:
void USART1_IRQHandler(void)
{
uint16_t temp;
delay_init();
if(USART_GetITStatus(USART1,USART_IT_RXNE))
{
GPIO_ResetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高
temp = USART_ReceiveData(USART1);
USART_SendData(USART1,temp);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == SET);
}
}
注意事项
-
注意GPIO的使能时钟 RCC_APB2PeriphClockCmd
- RCC_APB2PeriphResetCmd
巧妙运用 USART_GetFlagStatus函数来确定发送/接受数据是否完成,避免因为程序执行太快而导致数据丢失。
以下是详细代码:
- @brief Checks whether the specified USART flag is set or not. *
@param USARTx: Select the USART or the UART peripheral. * This
parameter can be one of the following values: * USART1, USART2,
USART3, UART4 or UART5. * @param USART_FLAG: specifies the flag to
check. * This parameter can be one of the following values: -
@arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
-
@arg USART_FLAG_LBD: LIN Break detection flag
-
@arg USART_FLAG_TXE: Transmit data register empty flag
-
@arg USART_FLAG_TC: Transmission Complete flag
-
@arg USART_FLAG_RXNE: Receive data register not empty flag
-
@arg USART_FLAG_IDLE: Idle Line detection flag
-
@arg USART_FLAG_ORE: OverRun Error flag
-
@arg USART_FLAG_NE: Noise Error flag
-
@arg USART_FLAG_FE: Framing Error flag
-
@arg USART_FLAG_PE: Parity Error flag
- @retval The new state of USART_FLAG (SET or RESET).
/
FlagStatus USART_GetFlagStatus(USART_TypeDef USARTx, uint16_t USART_FLAG)
一点心得:
今天这个串口中断真的写了很久,最开始只有程序中的发送代码,但是都不能使我设置的GPIO的灯亮,原因是因为我的GPIO使能时钟函数写错了)(PS:细节决定成败)
第二步进阶: 发送的数据让串口返回 : 用到了NVIC中断函数
NVIC函数的步骤:
1.NVIC 初始化 NVIC_Init()
2.中断优先级 NVIC_PriorityGroupConfig
3. 使能(开启)接收中断USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献2条内容
所有评论(0)