STM32
直播中

李秀兰

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

如何通过串口控制LED的亮灭?

如何通过串口控制LED的亮灭?

回帖(1)

王峥

2021-12-16 10:38:04
  五一假期,博主闲着没事,想起之前自己调试串口控制LED的亮灭问题尚未解决,便开始调试,再调试了一会时间后,觉得应该把它记录下来。  

这一切问题的起源还得怪之前调试不认真,太浮躁了。


  前言

其中使用USART串口的一些配置方法在我之前的博客有粗略带过,纯小白看不懂建议看看其他csdn大佬们写的配置USART的方法和步骤。
我写这篇博客的目的是通过USART串口控制LED的亮灭问题,记录下我所调试过程中遇到的问题,和对于串口的一些自己的理解。

  一、配置串口

由于我之前的博客有带过,就那几个步骤,注意下需要和电脑进行通信所配置的串口号、波特率、奇偶校验位、停止位、数据位那几个特殊注意下,以方便和电脑的串口调试助手进行通信。
我所使用的是XCOM的串口调试助手。














这里就贴下我所配置的串口代码吧

二、主要操作
我试过了两种方法来控制LED亮灭,一种是通过串口中断从而使LED的状态翻转,另外一种则是跳过中断,在主函数中使LED的状态翻转。


1.通过串口中断
基于配置好的串口,我们需要加上一个串口中断初始化的配置函数和串口中断处理函数


串口中断初始化的配置函数如下:


void NVIC_Init()
{
        NVIC_InitTypeDef NVIC_InitStructure;
       
        //Usart1 NVIC 配置
  
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
         
          USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
}


对于中断的相应问题日后的会特意写一篇博客来分析。


font color=#256AAA >串口中断处理函数如下:


void USART1_IRQHandler(void)  
{
        u8 Res;
       
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
        {
                Res =USART_ReceiveData(USART1);        //读取接收到的数据
                printf("Receive Succsed: %2x rn", Res);//回复接收完成
        if(Res==0x01)
          LED0=!LED0;
                //USART_ClearFlag(USART1,USART_IT_RXNE);
        }
}


分析:在该段函数中,我先定义了一个Res的变量来储存串口接收到的数值,再通过printf函数(使用的是原子哥所重写的函数)将其打印到串口。
使用得到Res的函数与对应的数值进行比较,从而翻转LED0的状态。


2.通过主函数
char ReceivedData = NULL;


int main( void )
{
        u8 Receive_Data = 0;
       
        NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 );       /* 设置NVIC中断分组2:2位抢占优先级,2位响应优先级 */
        uart_init( 115200 );                                      /* 串口初始化为9600 */
        delay_init();                                           /* 延时函数初始化 */
        LED_Init();
        BEEP_Init();
       
       


       
        while ( 1 )
        {
                delay_ms(1000);
                printf("开始测试rn");


               
                if(USART_GetITStatus(USART1, USART_IT_RXNE))        //若接收到数据
        {
            Receive_Data = USART_ReceiveData(USART1);        //读取数据后,RXNE标志位自动清零;
            printf("Receive Succsed: %d rn", Receive_Data);
            if(Receive_Data == '1')
                        {
                LED0 = !LED0;
                        }
                        else
                        {
                                printf("runingrn");
                                delay_ms(2000);
                        }
                }
               


        }
}


分析:在该段函数中,同样也是使用了一个中间变量来储存串口接收的数据。


———————————————————————————————————————


要注意的是:用此方法,轮询接收stm32发送的时候,只能接收一个字符,而不能接收多个字符,接收多个字符就会出问题,同时在串口调试助手的时候,要将“发送新行”取消勾选,否则也是会出问题的。


三、库函数分析

在这几段代码中我都使用到了库函数,下面将其列出来:


  • USART_GetITStatus(USART1, USART_IT_RXNE)
  • USART_ReceiveData(USART1)
    对于通过串口控制LED状态翻转的实现中,这些库函数格外重要。

1.USART_GetITStatus(USARTx, USART_IT_RXNE)










该函数可以用于获取中断信息,并返回1或者0.
在这个功能的实现中,使用了USART_IT_RXNE这个状态标记位。
2.USART_ReceiveData(USART1)






该函数可以将接收到的数据赋值给另外一个变量。
Receive_Data = USART_ReceiveData(USART1);        //读取数据后,RXNE标志位自动清零; 总结

注意USB转TTL接口的接线问题,确保它正确接线。
同时,各位读者还可以基于这篇博客的基础,自己外扩串口控制其他模块的功能。举一反三。


写这篇博客主要还是想告诉自己戒骄戒躁,调试程序的时候需要耐心。
举报

更多回帖

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