打印
[活动专区]

【AT-START-F425测评】3、串口接收不定长数据

[复制链接]
572|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 freeelectron 于 2022-3-7 09:34 编辑

系列**:
AT-START-F425测评】1、初识AT32F425开发板(开箱)
【AT-START-F425测评】2、非阻塞方式点灯,blink,blink,blink…...

1、硬件连接

本文使用串口1,对应的引脚为PB6和PB7。

2、GPIO复用功能

可以看出,复用功能为MUX0。

[color=rgba(0, 0, 0, 0.75)]3、实现思路

利用串口接收相邻两个字符的时间来判断一串数据是否接收完成,如果超过设定的时间,还没有接收到下一个字符,则认为一串数据接收完成。


如果使用115200波特率,数据长度为8bit,停止位为1bit,那么接收一个字节大约需要,(1/115200)9=0.78ms。


那么就可以利用,接收完一个字符后,如果0.78ms之内没有下一个数据,那么就可以认为一串数据接收完成,考虑到单片机接收数据保存,这里设定超时时间为5ms。

4、核心代码

主要是利用串口接收中断和应用层超时。

#define UART_MAX_LEN  200

struct
{
        uint8_t Timeout;
        uint8_t RecvBuff[UART_MAX_LEN];
        uint8_t RecvLen;
} SerialStr;


void SerialInit(void)
{
        gpio_init_type gpio_init_struct;
  
        /* enable the usart1 and gpio clock */
        crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
           crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);  

        gpio_default_para_init(&gpio_init_struct);

        /* configure the usart1 tx/rx pin */
        gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
        gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
        gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
        gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7;
        gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
        gpio_init(GPIOB, &gpio_init_struct);

        /* config usart1 iomux */
        gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE6, GPIO_MUX_0);
        gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE7, GPIO_MUX_0);
  
        /* config usart1 nvic interrupt */
        nvic_irq_enable(USART1_IRQn, 3, 0);
  
        /* configure usart1 param */
        usart_init(USART1, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
        usart_parity_selection_config(USART1, USART_PARITY_NONE);
    usart_hardware_flow_control_set(USART1,USART_HARDWARE_FLOW_NONE);

        usart_transmitter_enable(USART1, TRUE);
        usart_receiver_enable(USART1, TRUE);
  
        usart_interrupt_enable(USART1, USART_RDBF_INT, TRUE);
        usart_enable(USART1, TRUE);  
}


void SerialRecvTimeout(void)
{
        if(SerialStr.Timeout>0)
        {
                SerialStr.Timeout--;
        }
}


void SerialRecv(uint8_t data)
{
        SerialStr.Timeout=5;
        
        if(SerialStr.RecvLen<UART_MAX_LEN)
        {
                SerialStr.RecvBuff[SerialStr.RecvLen++]=data;
        }
}


void SerialSend(uint8_t *data,uint8_t len)
{
        for(uint8_t i=0; i<len;i++)
        {
                while (RESET == usart_flag_get(USART1, USART_TDC_FLAG));

                usart_data_transmit(USART1, data[i]);
        }
}


void SerialPro(void)
{
        if(!SerialStr.Timeout&&SerialStr.RecvLen)
        {
                printf("Recv:%d,[",SerialStr.RecvLen);
#if 1                 
                SerialSend(SerialStr.RecvBuff,SerialStr.RecvLen);
#else
                for(uint8_t i=0;i<SerialStr.RecvLen;i++)
                {
                        printf(" %02d",SerialStr.RecvBuff[i]);
                }
#endif
                printf("]\r\n");

                SerialStr.RecvLen=0;
        }
}


void USART1_IRQHandler(void)
{
        uint16_t ch;
        
        if(usart_flag_get(USART1, USART_RDBF_FLAG) != RESET)
        {
                ch=usart_data_receive(USART1);
                SerialRecv(ch);
    }
}


/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
        while(usart_flag_get(USART1, USART_TDC_FLAG) == RESET);
        usart_data_transmit(USART1, (uint8_t) ch);
        
    return ch;
}
5、现象













使用特权

评论回复
沙发
freeelectron|  楼主 | 2022-3-4 17:42 | 只看该作者
好奇怪,编辑的超链接,怎么没有了,@21ic大掌柜

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:stm32/LoRa物联网:304350312

65

主题

785

帖子

11

粉丝