STM32F1笔记(三)UART/USART

2019-10-12来源: eefocus关键字:STM32F1  UART  USART

UART:Universal Asynchronous Receiver/Transmitter(通用异步收/发器)


USART:Universal Synchronous/Asynchronous Receiver/Transmitter(通用同步/异步串行收/发器)


从命名即可看出USART就是UART的基础上添加了同步功能。通常把UART/USART称为串口。


串口包含TLL电平和232的串口,485等电气特性的串口。232、485通常应用于工业。


串口配置的一般步骤可以参考正点原子的总结:


1、串口时钟使能,GPIO时钟使能;


2、串口复位;(我不知道这一步的意义,去掉似乎也没影响,求大神指点)


3、GPIO端口模式的配置;


4、串口参数初始化;


5、初始化NVIC并开启中断;


6、使能串口;


7、编写中断服务函数。


配置示例:


void Usart3_Init(unsigned int 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);

    

    USART_DeInit(USART3);

  

    //USART3_TX   GPIOB.10

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

   

    //USART3_RX   GPIOB.11

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

 

    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_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_Rx | USART_Mode_Tx;

 

    USART_Init(USART3, &USART_InitStructure);

    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

    USART_Cmd(USART3, ENABLE);

}

注意:在此示例中GPIO的速率配置为50M,其实没必要那么高,可降低至2M。速率越高,噪声越大,功耗越高。


在配置代码中,开启了接收中断。在日常串口使用中,都会规定通信协议。通信协议的解析,通常在中断服务函数里进行。


通信协议通常由帧头,数据,帧尾三部分组成。


帧头不正确,不继续处理后续接收到的内容。


帧尾不正确,对数据不进行处理。


示例:

帧头由两部分组成,校验信息和数据长度。示例中断校验信息,赋值给unsigned char的变量,相加后为0。这是特殊的帧头。


    unsigned char chr = 0;

 

    chr += (0xAA + 0xBB + 0xCC + 0xDD + 0xEE + 0x04);

 

    printf("chr=%Xn", chr);

数据长度通常只指数据的长度,不包含帧头校验信息和帧尾的长度。


帧尾可以是CRC等校验方式。可包含长度也可不包含,计算数据的CRC。目的是确保数据的一致性。


串口中断服务函数示例:


void USART3_IRQHandler(void)

{       

    if(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET)

    {

        USART_ClearITPendingBit(USART3, USART_IT_RXNE);

        

        g_usart3_recv_data = USART_ReceiveData(USART3);

        

        switch(g_usart3_recv_state)

        {

            case USART3_RECV_FIRST_FRAME_HEAD:

                if(MKLM_FIRST_FRAME_HEAD == g_usart3_recv_data)

                {

                    g_usart3_recv_state = USART3_RECV_SECOND_FRAME_HEAD;   

                }

                else

                {

                    g_usart3_recv_state = USART3_RECV_FIRST_FRAME_HEAD;             

                }

                break;

            

            case USART3_RECV_SECOND_FRAME_HEAD:

                if(MKLM_SECOND_FRAME_HEAD == g_usart3_recv_data)

                {

                    g_usart3_recv_state = USART3_RECV_FIRST_LENGTH;

                }

                else

                {

                    g_usart3_recv_state = USART3_RECV_FIRST_FRAME_HEAD;             

                }

                break;

                

            case USART3_RECV_FIRST_LENGTH:

                g_Usart3_recv_struct.length = g_usart3_recv_data;

                g_Usart3_recv_struct.length <<= 8;

                g_usart3_recv_state = USART3_RECV_SECOND_LENGTH; 

                break;

            

            case USART3_RECV_SECOND_LENGTH:

                g_Usart3_recv_struct.length |= g_usart3_recv_data;

                g_usart3_recv_length = 0;

                g_usart3_recv_state = USART3_RECV_ADDRESS; 

                break;

            

            case USART3_RECV_ADDRESS:

                g_Usart3_recv_struct.address = g_usart3_recv_data;

                g_usart3_recv_length++;

                g_usart3_recv_state = USART3_RECV_ORDER;

                break;

            

            case USART3_RECV_ORDER:

                g_Usart3_recv_struct.order = g_usart3_recv_data;

                g_usart3_recv_length++;

                g_usart3_recv_state = USART3_RECV_ACTION; 

                break;

            

            case USART3_RECV_ACTION:

                g_Usart3_recv_struct.action = g_usart3_recv_data;

                g_usart3_recv_length++;

                g_usart3_recv_state = USART3_RECV_FIRST_CRC;

                break;

            

            case USART3_RECV_FIRST_CRC:

                g_Usart3_recv_struct.crc16 = g_usart3_recv_data;

                g_Usart3_recv_struct.crc16 <<= 8;

                g_usart3_recv_length++;

                g_usart3_recv_state = USART3_RECV_SECOND_CRC;

                break;

            

            case USART3_RECV_SECOND_CRC:

                g_Usart3_recv_struct.crc16 |= g_usart3_recv_data;

                g_usart3_recv_length++;

            

                if(g_usart3_recv_length == g_Usart3_recv_struct.length)

                {

                    g_recv_status = RECEIVE_OK;

                }

                else 

                {

                    g_recv_status = RECEIVE_LENGTH_ERROR;

                }

                                    

                g_usart3_recv_flag = USART3_RECV_SECCESS;

                g_usart3_recv_length = 0;

g_usar

[1] [2]
关键字:STM32F1  UART  USART 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic476930.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32-自学笔记(11.通过串口与PC通信,发Hello)
下一篇:STM32波特率设置

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32F0 ADC学习
开始时候使用的是stdlib的库,最近发现cube库用的越来越广泛了,遂开始使用cube库来完成ADC的多通道采集实验。ADC 的driver 在STM32F0XX_HAL_DRIVER当中,有stm32f0xx_hal_adc.c文件中,我们可以在stm32f0xx_hal_conf.h中开启 宏定义 ADC 模块。ADC有三种工作模式,polling interruptDMA我这里使用了polling的方式来获取多通道的数据。首先是要声明两个参数设置的结构体ADC_HandleTypeDef             AdcHandle
发表于 2019-10-09
STM32F030 使用内部时钟和外部时钟
p;  /* Wait till PLL is ready */  while((RCC->CR & RCC_CR_PLLRDY) == 0)  {  }   /* Select PLL as system clock source */  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;       /* Wait till PLL is
发表于 2019-10-09
STM32F030F4P6单片机由外部时钟改为内部时钟的步骤
一.看程序运行的时候初始化时钟部分: 二.查看systeminit定义如下: 这就是打开的函数内容这就是使用外部时钟的配置,也就是库函数的默认配置):static void SetSysClock(void){  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;    /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*//* Enable HSE */ //打开外部时钟开关&nbs
发表于 2019-10-09
STM32F030F4P6单片机由外部时钟改为内部时钟的步骤
STM32F4(Flash读保护)
1,目的在实际的产品发布中,如果不对储存在单片机Flash中的程序做一些保护的话,就有可能被一些不法公司,通过仿真器(J-Link,ST-Link等)把Flash中的程序读取回来,得到bin文件或hex文件,然后去山寨产品。所以我们需要对程序进行保护,一种比较简单可靠的方法就是把Flash设置成读保护。2,开发环境1,适用芯片:STM32F4全部芯片2,固件库:STM32F4xx_DSP_StdPeriph_Lib_V1.8.03,IDE:MDK5173,程序源码/**************************************************************** * Function
发表于 2019-10-09
stm32F103 DMA通道
发表于 2019-10-09
stm32F103 DMA通道
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved