STM32
直播中

h1654155275.5669

7年用户 1028经验值
私信 关注
[问答]

STM32串口接收不定长数据的实现方法

STM32串口接收不定长数据的实现方法

回帖(1)

龙献益

2021-12-9 10:40:05

1.配置串口


void USART1_Config(void)
{
        //初始化使用的端口 A9->TX   A10->Rx
        //初始化GPIO
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART1_InitStructure;       
        //使能时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        //配置波特率等
        USART1_InitStructure.USART_BaudRate = 115200;
        USART1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//None
        USART1_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//
        USART1_InitStructure.USART_Parity = USART_Parity_No;//No
        USART1_InitStructure.USART_StopBits = USART_StopBits_1;//1
        USART1_InitStructure.USART_WordLength = USART_WordLength_8b;//8b
        //配置
        USART_Init(USART1,&USART1_InitStructure);
//        USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
        //使能
        USART_Cmd(USART1,ENABLE);
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
}


2.配置串口中断


void NVIC_Config(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//配置串口中断       
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_Init(&NVIC_InitStructure);
        //DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);



3.配置串口中断响应函数


/************定义联合体的意义是接收字节数>1的数,如浮点数**************/
/***********对于一帧多个字节数据可以直接使用数组来接受就OK了,不需要用联合体****/
union DataType{
        unsigned char s[4];
        unsigned int data;
}RxDataType;//共用内存地址思想,详见C语言


void USART1_IRQHandler(void)
{
        GPIO_WriteBit(GPIOB,GPIO_Pin_0 ,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_0)));
        if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//是否接受到一个字节
        {
                RxDataType.s[RxCounter++] = USART1->DR;
        }
        if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)//是否接受到一帧
        {
                USART1->SR;
                USART1->DR;                                               
                RxCounter=0;
        }
}


代码解释如上注释


以下为测试使用代码


串口发送代码


        GPIO_WriteBit(GPIOB,GPIO_Pin_0 ,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_0)));//LED闪烁辅助观察
        if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//是否接受到一个字节
        {
                RxDataType.s[RxCounter++] = USART1->DR;
        }
        if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)//是否接受到一帧
        {
                USART1->SR;
                USART1->DR;//这两句是清除状态位的,必须加上。如果提示未使用,定义一个uint8_t变量存储返回值即可                                               
                RxCounter=0;//一帧数据存储完毕,清零


STM32串口发送代码:


/***************这里我是定义外部中断使能发送的,可以直接发这段代码放在主函数while循环中也可以***/


void EXTI1_IRQHandler(void)
{
        GPIO_WriteBit(GPIOB,GPIO_Pin_1 ,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_1)));
        USART_SendData(USART1,0xAA);
        delay_ms(1);
        USART_SendData(USART1,RxDataType.s[0]);
        delay_ms(1);
        USART_SendData(USART1,RxDataType.s[1]);
        delay_ms(1);
        USART_SendData(USART1,RxDataType.s[2]);
        delay_ms(1);
        USART_SendData(USART1,RxDataType.s[3]);
        delay_ms(1);
        USART_SendData(USART1,0xFF);
        delay_ms(1);
        for(c = 0;c < 4;++c)
        {
                RxDataType.s[c] = 0;
        }
        EXTI_ClearITPendingBit(EXTI_Line1);
}


演示效果:
默认情况下,STM32发送给电脑的数据应该是0,对应的16进制应该是


AA 00 00 00 00 FF



  

  

当电脑1111STM32,STM32接收到给电脑发送数据
  接收到AA 11 00 00 00 FF后,数据变成了AA 00 00 00 00 FF,是我设置了一次发送之后即将所有位设置为0,代码见“发送代码” for(c = 0;c < 4;++c) { RxDataType.s[c] = 0; }   
  

  

当电脑发送22 22给STM32之后,STM32接收到数据并回传给电脑:


  

  

当电脑发送88 88 88 88给STM32之后,STM32接收到数据并回传给

  

  

其他
  上位机和下位电脑之间发送和接收浮动、双类型的数据使用联合体统计**
举报

更多回帖

发帖
×
20
完善资料,
赚取积分