【STM32】(3) 串口通信实验

串口通信实验

一、实验目的

从电脑串口助手发送长度为200以内任意长度的字符串给STM32串口1(字符串以回车换行标识结束),STM32接收到字符串之后,一次性通过串口1把所有数据返回给电脑。

二、硬件连接

引脚连接
PA9(USART1_TX)USB-TTL串口RXD
PA10(USART1_RX)USB-TTL串口TXD

三、代码及分析

( 1 )定义函数uart_init用来调用HAL_UART_Init初始化串口参数配置:

UART_HandleTypeDef UART1_Handler;//UART句柄

void uart_init(u32 bound)

{     

       //UART 初始化设置

       UART1_Handler.Instance=USART1;                                                     //USART1

       UART1_Handler.Init.BaudRate=bound;                                                 //波特率

       UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;           //字长为8位数据格式

       UART1_Handler.Init.StopBits=UART_STOPBITS_1;                           //一个停止位

       UART1_Handler.Init.Parity=UART_PARITY_NONE;                            //无奇偶校验位

       UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;          //无硬件流控

       UART1_Handler.Init.Mode=UART_MODE_TX_RX;                              //收发模式

       HAL_UART_Init(&UART1_Handler);                                                    //HAL_UART_Init()会使能UART1

       HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量。

}

( 2 ) 串口MSP函数HAL_UART_MspInit函数我们自定义了其内容。

在串口初始化函数HAL_UART_Init内部,会调用串口MSP函数HAL_UART_MspInit来设置与MCU相关的配置。函数HAL_UART_Init主要用来初始化与串口相关的参数(这些参数与MCU无关),包括波特率,停止位等。而串口MSP函数HAL_UART_MspInit用来设置GPIO初始化,NVIC配置等于MCU相关的配置。

代码如下:

void HAL_UART_MspInit(UART_HandleTypeDef *huart)

{

      GPIO_InitTypeDef GPIO_Initure;

       if(huart->Instance==USART1)                                      //如果是串口1,进行串口1 MSP初始化

       {

              __HAL_RCC_GPIOA_CLK_ENABLE();                  //使能GPIOA时钟

              __HAL_RCC_USART1_CLK_ENABLE();               //使能USART1时钟

              GPIO_Initure.Pin=GPIO_PIN_9;                             //PA9

              GPIO_Initure.Mode=GPIO_MODE_AF_PP;          //复用推挽输出

              GPIO_Initure.Pull=GPIO_PULLUP;                       //上拉

              GPIO_Initure.Speed=GPIO_SPEED_FAST;         //高速

              GPIO_Initure.Alternate=GPIO_AF7_USART1;      //复用为USART1

              HAL_GPIO_Init(GPIOA,&GPIO_Initure);               //初始化PA9

              GPIO_Initure.Pin=GPIO_PIN_10;                        //PA10

              HAL_GPIO_Init(GPIOA,&GPIO_Initure);             //初始化PA10

#if EN_USART1_RX

              HAL_NVIC_EnableIRQ(USART1_IRQn);           //使能USART1中断通道

              HAL_NVIC_SetPriority(USART1_IRQn,3,3);     //抢占优先级3,子优先级3

#endif  

       }

}

( 3 )函数HAL_UART_IRQHandler实现串口1中断服务程序

void USART1_IRQHandler(void)                     

{

HAL_UART_IRQHandler(&UART1_Handler);    //调用HAL库中断处理公用函数

}

串口接收中断流程图

串口接收中断的一般流程进行概括:当接收到一个字符之后,在函数UART_Receive_IT()中会把数据保存在串口句柄的成员变量pRxBuffPtr缓存中,同时RxXferCount计数器减1。如果我们设置RxXferSize=10,那么当接收到10个字符之后,RxXferCount会由10减到0(RxXferCount 初始值等于RxXferSize),这个时候再调用接收完成回调函数HAL_UART_RxCpltCallback进行处理。

首先,我们回到用户函数uart_init定义可以看到,在uart_init 函数中调用完HAL_UART_Init后我们还调用了HAL_UART_Receive_IT开启接收中断,并且初始化串口句柄的缓存相关参数。

代码如下:

HAL_UART_Receive_IT(&UART1_Handler,(u8*)aRxBuff,RXBUFFERSIZE);而aRxBuffer是我们定义的一个全局数组变量,RXBUFFERSIZE是我们定义的一个标识符: #define RXBUFFERSIZE 1

u8 aRxBuffer[RXBUFFERSIZE];所以,调用HAL_UART_Receive_IT函数后,除了开启接收中断外还确定了每次接收RXBUFFERSIZE个字符后标示接收结束从而进入回调函数HAL_UART_RxCpItCalback进行相应处理。

( 4 ) HAL_UART_RxCpltCallback函数定义:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

       if(huart->Instance==USART1)//如果是串口1

       {

            if((USART_RX_STA&0x8000)==0)//接收未完成,判断USART_RX_STA的最高位bit15是否为1 ,若为1,则接收完成

              {

                     if(USART_RX_STA&0x4000)//接收到了0x0d

                     {

                            if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始

                            else USART_RX_STA|=0x8000;  //接收完成了

                     }

                     else //还没收到0X0D

                     {    

                            if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;

                            else

                            {

                                   USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;

                                   USART_RX_STA++;

                                   if(USART_RX_STA>(USART_REC_LEN1))USART_RX_STA=0;//接收数据错误,重新开始接收  

                            }           

                     }

              }

       }

}

( 5 ) 主函数

int main(void)

{

    u8 len;

     u16 times=0;

    Cache_Enable();                        //打开L1-Cache

    HAL_Init();                                  //初始化HAL库

    Stm32_Clock_Init(432,25,2,9);   //设置时钟,216Mhz

    delay_init(216);                             //延时初始化

       uart_init(115200);                     //串口初始化

    LED_Init();                                  //初始化LED

    while(1)

    {

       if(USART_RX_STA&0x8000)

              {                                    

                     len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度

                     printf("\r\n您发送的消息为:\r\n");

                   HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);      //发送接收到的数据

              while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);          //等待发送结束

                     printf("\r\n\r\n");               //插入换行

                     USART_RX_STA=0;

              }else

              {

                     times++;

                     if(times%5000==0)

                     {

                            printf("\r\nALIENTEK STM32F7开发板 串口实验\r\n");

                            printf("正点原子@ALIENTEK\r\n\r\n\r\n");

                     }

                     if(times%200==0)printf("请输入数据,以回车键结束\r\n"); 

                     if(times%30==0)LED0_Toggle;//闪烁LED,提示系统正在运行.

                     delay_ms(10);  

              }

       }

}

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值