stm32 开启接收中断 PC 发送两次 为啥串口只接收到一次

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32 开启接收中断 PC 发送两次 为啥串口只接收到一次相关的知识,希望对你有一定的参考价值。

你可能忘了清除串口中断接收标志位,或者是你的中断里的处理程序太占时间了,你试试吧~ 参考技术A 我的串口接收也出现和你一样的问题,请问你的问题是怎么解决。

STM8S系列基于IAR开发串口中断接收和发送示例

STM8S系列基于IAR开发串口中断接收和发送示例


🔖本示例基于STM8S903K3T6单片机。没有启用字节配置选项下,串口引脚PD5(TXD)、PD6(RXD)。

usart.c

📑串口初始化配置以及printf重定向

/*************************************

 * 文件名  :uart.c
 * 描述    :串口通信配置函数库     
 * 实验平台: STM8S

    |--------------------|
    |  USART1_RX-PD6    |
    |  USART1_TX-PD5   |
    |--------------------|

******************************************/

#include "uart.h"
/**************************************************************************
 * 函数名:uart_conf
 * 描述  :uart配置函数
 * 输入  :无
 *
 * 输出  :无
 * 返回  :无 
 * 调用  :外部调用 
 *************************************************************************/
void uart_conf(void)

    unsigned int baud_div=0;
    
    UART1_CR1 = (0<<4)|(0<<3)|(0<<2)|(0<<1)|(0<<0); 
    /*1位起始位 8位数据位 结束位由CR3设置 不使用奇偶校验 不使能奇偶校验中断*/
    UART1_CR2 = (0<<7)|(0<<6)|(1<<5)|(0<<4)|(1<<3)|(1<<2); 
    /*使能发送和接收 接收中断使能 禁止发送中断*/
    UART1_CR3 = (0<<6)|(0<<4)|(0<<3); /*设置1位停止位 不使能SCLK*/        
    UART1_CR5 = (0<<2)|(0<<1);     
    /*使用智能卡模式需要设置的,基本上保持默认就行了 */ 
    
    /*设置波特率*/
    baud_div =HSIClockFreq/BaudRate;  /*求出分频因子*/
    UART1_BRR2 = baud_div & 0x0f;
    UART1_BRR2 |= ((baud_div & 0xf000) >> 8);
    UART1_BRR1 = ((baud_div & 0x0ff0) >> 4);    /*先给BRR2赋值 最后再设置BRR1*/
    
    UART1_CR1 |= (0<<5);         /*使能UART*/


/**************************************************************************
 * 函数名:UART1_SendByte
 * 描述  :uart发送一个字节
 * 输入  :u8 data
 *
 * 输出  :无
 * 返回  :无 
 * 调用  :外部调用 
 * 举例  :UART1_SendByte('a')
 *************************************************************************/
void UART1_SendByte(u8 data)

    
    UART1_DR=data;
   /* Loop until the end of transmission */
   while (!(UART1_SR & UART1_FLAG_TXE));


/**********************************************************************************
 * 函数名:UART1_SendByte
 * 描述  :uart发送字符串
 * 输入  :u8* Data,u16 len
 *
 * 输出  :无
 * 返回  :无 
 * 调用  :外部调用 
 **********************************************************************************/
void UART1_SendString(u8* Data,u16 len)

  u16 i=0;
  for(;i<len;i++)
    UART1_SendByte(Data[i]);
  

/**********************************************************************************
 * 函数名:UART1_ReceiveByte
 * 描述  :uart查询接收一个字节
 * 输入  :无
 *
 * 输出  :无
 * 返回  :一个字节 
 * 调用  :外部调用 
 * 举例  :temp=UART1_ReceiveByte()
 **********************************************************************************/
u8 UART1_ReceiveByte(void)

     u8 USART1_RX_BUF; 
     while (!(UART1_SR & UART1_FLAG_RXNE));
     USART1_RX_BUF=(uint8_t)UART1_DR;
     return  USART1_RX_BUF;
    



/***********************************************
 * 函数名:fputc
 * 描述  :重定向c库函数printf到USART1
 * 输入  :无
 * 输出  :无
 * 调用  :由printf调用
 ***********************************************/
int fputc(int ch, FILE *f)
  
 /*将Printf内容发往串口*/ 
  UART1_DR=(unsigned char)ch;
  while (!(UART1_SR & UART1_FLAG_TXE));
  return (ch);


stm8s_interruput.c

🔰串口中断接收服务函数

/**************************************
 * 文件名  :
 * 描述    :中断服务子函数库   
 * 实验平台: STM8S

*****************************************************/

#include "uart.h"

u8 RxBuffer[RxBufferSize];
u8 UART_RX_NUM=0;

#pragma vector=1
__interrupt void TRAP_IRQHandler(void)

  

#pragma vector=2
__interrupt void TLI_IRQHandler(void)

  

#pragma vector=3
__interrupt void AWU_IRQHandler(void)

  

#pragma vector=4
__interrupt void CLK_IRQHandler(void)

  
  

#pragma vector=5
__interrupt void EXTI_PORTA_IRQHandler(void)

  

#pragma vector=6
__interrupt void EXTI_PORTB_IRQHandler(void)

  

#pragma vector=7
__interrupt void EXTI_PORTC_IRQHandler(void)

  

#pragma vector=8
__interrupt void EXTI_PORTD_IRQHandler(void)

 
  

#pragma vector=9
__interrupt void EXTI_PORTE_IRQHandler(void)

   



#pragma vector=0xC
__interrupt void SPI_IRQHandler(void)

  

#pragma vector=0xD
__interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)

  


#pragma vector=0xE
__interrupt void TIM1_CAP_COM_IRQHandler(void)

  


#pragma vector=0xF
__interrupt void TIM2_UPD_OVF_BRK_IRQHandler(void)

     

#pragma vector=0x10
__interrupt void TIM2_CAP_COM_IRQHandler(void)

  



#pragma vector=0x11
__interrupt void TIM3_UPD_OVF_BRK_IRQHandler(void)

  

#pragma vector=0x12
__interrupt void TIM3_CAP_COM_IRQHandler(void)

  



#pragma vector=0x13
__interrupt void UART1_TX_IRQHandler(void)

  

#pragma vector=0x14
__interrupt void UART1_RX_IRQHandler(void)
 
   u8 Res;
    if(UART1_SR & UART1_FLAG_RXNE)  
    /*接收中断(接收到的数据必须是0x0d 0x0a结尾)*/
	Res =(uint8_t)UART1_DR;
        /*(USART1->DR);读取接收到的数据,当读完数据后自动取消RXNE的中断标志位*/
	if(( UART_RX_NUM&0x80)==0)/*接收未完成*/
	
	    if( UART_RX_NUM&0x40)/*接收到了0x0d*/
		
		  if(Res!=0x0a) UART_RX_NUM=0;/*接收错误,重新开始*/
		  else  UART_RX_NUM|=0x80;	/*接收完成了 */
		
            else /*还没收到0X0D*/
              	
                if(Res==0x0d) UART_RX_NUM|=0x40;
                else
                  
                    RxBuffer[ UART_RX_NUM&0X3F]=Res ;
                     UART_RX_NUM++;
                      if( UART_RX_NUM>63) UART_RX_NUM=0;/*接收数据错误,重新开始接收*/  
                  		 
	      
	   		 
      


#pragma vector=0x15
__interrupt void I2C_IRQHandler(void)

  



#pragma vector=0x16
__interrupt void UART3_TX_IRQHandler(void)

  

#pragma vector=0x17
__interrupt void UART3_RX_IRQHandler(void)

  



#pragma vector=0x18
__interrupt void ADC2_IRQHandler(void)

   



#pragma vector=0x19
__interrupt void TIM4_UPD_OVF_IRQHandler(void)

  


#pragma vector=0x1A
__interrupt void EEPROM_EEC_IRQHandler(void)

  



main.c


/***********************************
 * 文件名  :main.c
 * 描述    :串口通信   
 * 实验平台:STMS开发板

***************************************/

/* Includes ------------------------------------------------------------------*/
#include "clk_conf.h"
#include "uart.h"



/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
extern u8 RxBuffer[RxBufferSize];
extern u8 UART_RX_NUM;
int main(void)

  /* Infinite loop */
   u8 len ;
  /*设置内部高速时钟16M为主时钟*/ 
  Clk_conf();
  uart_conf();
  EnableInterrupt;
  printf("\\r\\n硬件平台为:%s\\r\\n","STM8S903K3");

  while(1)
  
      if(UART_RX_NUM&0x80)
      
        len=UART_RX_NUM&0x3f;/*得到此次接收到的数据长度*/
        UART1_SendString("SentData:",sizeof("SentData"));
        UART1_SendString(RxBuffer,len);
        printf("\\r\\n数据长度:%d Byte\\r\\n",len);
        UART_RX_NUM=0;
      

  
  


#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\\r\\n", file, line) */

  /* Infinite loop */
  while (1)
  
  

#endif



⛳工程源码

链接:https://pan.baidu.com/s/1WaDs_zOFOq81-28CWUZIlA 
提取码:3ile

以上是关于stm32 开启接收中断 PC 发送两次 为啥串口只接收到一次的主要内容,如果未能解决你的问题,请参考以下文章

stm32串口通信

STM32Cube IDE配置串口发送与接收

stm32串口发送正常,接受只能收到一个字符,求解,急

stm32h750串口发送中断关掉

stm32啥触发串口接收中断

STM32串口通讯程序