STM32串口通信 (缓冲区 发送不出数据&接收不到数据)

流程

(简单的发送数据)

  1. GPIO时钟使能
  2. 串口时钟使能
  3. 串口的GPIO配置
  4. 写初始化串口函数,配置串口USART_Init(USART1,&USART_InitStruct);
  5. 开启(使能)串口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);

  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值