STM32F103串口中断接收和空闲中断接收

因为要使用可替代芯片,之前用DMA配置的串口在某些国产pin to pin的MCU上无法使用,所以得改回中断方式进行收发,就最近修改的心得与各位分享一下。
标志位USART_IT_RXNE触发,一次获取一字节数据,中断里需要使用数组将接收数据存起来,因为是一个字节一个字节存,这就有可能导致存较长数据的时候数据分段了,协议无法校验。
然后我上网搜到了USART_IT_IDLE空闲中断,它一次存一帧数据,就很少会出现丢失数据的情况了。其实,在今天之前,我一直以为串口的IDLE空闲中断是必须配置DMA才能使用,大意了。
1. 串口3初始化配置

在这里插入代码片
void USART3_Config(uint32_t baudRate)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;             
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                    
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;                
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = baudRate;               
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;    
    USART_InitStructure.USART_StopBits = USART_StopBits_1;       
    USART_InitStructure.USART_Parity = USART_Parity_No;           
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; 
    USART_Init(USART3, &USART_InitStructure);

    USART_Cmd(USART3, ENABLE);
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;         
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
    NVIC_Init(&NVIC_InitStructure);

    USART_ITConfig(USART3, USART_IT_RXNE ,ENABLE);
    USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); //空闲中断
}

2. 中断处理函数
这里我使用了空闲中断接收+中断发送
我想发送函数放在中断里完成速度会更快点吧

u16 com3_rx_len=0;//接收长度
u8 com3_recv_end_flag=0;//接收完成标志
u8 com3_rx_buffer[100]={0};//接收缓存数组

void USART3_IRQHandler(void)  //串口3中断服务程序
{
    u8 i;
    if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)     //接收中断触发
    {
        com3_rx_buffer[com3_rx_len++]=USART_ReceiveData(USART3); //清除中断标志位(接收函数有清标志位的作用)
    }
    else if(USART_GetITStatus(USART3,USART_IT_IDLE) != RESET)//接收到一帧数据 空闲中断触发
    {
        USART3->SR;//先读SR
        USART3->DR;//再读DR
        com3_recv_end_flag=1;//接收完成标志位
    }
    if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET)//主循环开启发送中断
    {
        uart3_SendBuff(send_buf,send_buf_len);        //串口3数据处理完,返回上位机
        USART_ITConfig(USART3, USART_IT_TXE, DISABLE); //关闭发送中断
        for(i=0;i<send_buf_len;i++) send_buf[i]=0;    //清除发送缓存
    }
}

3. 发送函数

void uart3_SendBuff(uint8_t * buf, u16 len)
{
    while(len--)
    {
        while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET); //等待发送结束
        USART_SendData(USART3, *buf++);
    }
    while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);
}
  • 0
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值