通过串口控制LED的亮灭

USART 系列文章目录

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


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



前言

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


一、配置串口

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

void uart_init(u32 bound){
 	//GPIO端口设置
 	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
  
	//USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  


   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	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(USART1, &USART_InitStructure); //初始化串口1
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

二、主要操作

我试过了两种方法来控制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 \r\n", 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("开始测试\r\n");

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

	}
}

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

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

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

三、库函数分析

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

  1. USART_GetITStatus(USART1, USART_IT_RXNE)
  2. 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接口的接线问题,确保它正确接线。
同时,各位读者还可以基于这篇博客的基础,自己外扩串口控制其他模块的功能。举一反三。


写这篇博客主要还是想告诉自己戒骄戒躁,调试程序的时候需要耐心。
  • 32
    点赞
  • 185
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
### 回答1: 首先,你需要连接一个LEDSTM32的一个引脚上,然后使用STM32串口模块来控制该引脚的电平状态。 下面是一个简单的示例代码: ```c #include "stm32f10x.h" #include "stdio.h" // 定义LED引脚 #define LED_PIN GPIO_Pin_13 #define LED_PORT GPIOC // 定义串口 #define USART USART1 #define USART_TX_PIN GPIO_Pin_9 #define USART_RX_PIN GPIO_Pin_10 void init_led(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOC时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 配置LED引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); } void init_usart(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // 使能USART1和GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置USART1的TX引脚为复用推挽输出 GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART1的RX引脚为浮空输入 GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART1的参数 USART_InitStructure.USART_BaudRate = 115200; 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(USART, &USART_InitStructure); // 使能USART1 USART_Cmd(USART, ENABLE); } int main(void) { char ch; // 初始化LED和USART init_led(); init_usart(); while (1) { // 从串口读取一个字符 if (USART_GetFlagStatus(USART, USART_FLAG_RXNE) == SET) { ch = USART_ReceiveData(USART); // 如果收到字符 '1',则点LED if (ch == '1') { GPIO_SetBits(LED_PORT, LED_PIN); } // 如果收到字符 '0',则熄LED if (ch == '0') { GPIO_ResetBits(LED_PORT, LED_PIN); } } } } ``` 在该示例代码中,我们使用串口USART1来读取输入字符,并根据收到的字符控制LED。当接收到字符 '1' 时,点LED;当接收到字符 '0' 时,熄LED。 需要注意的是,在使用串口时,需要先初始化串口的GPIO引脚,然后配置串口的参数,最后使能串口。除此之外,还需要使用USART_GetFlagStatus()函数判断是否有数据可读,然后使用USART_ReceiveData()函数读取数据。 ### 回答2: 要使用STM32串口控制LED,可以按照以下步骤进行编程实现: 首先,在Keil等集成开发环境中创建一个新工程,并选择对应的STM32单片机型号。 然后,需要在代码中包含相应的头文件,包括对串口和GPIO的定义和配置。 接着,配置串口的波特率、数据位、停止位和校验位等参数,并初始化串口。 接下来,在代码中配置LED所连接的GPIO口,并设置该引脚为输出模式。 在主函数中,可以使用一个循环来不断接收串口数据并进行判断。当串口接收到特定的指令时,根据指令的内容控制LED。 在接收到控制指令后,可以使用if语句或switch语句来判断指令的具体内容。例如,当接收到字符"A"时,可以将LED引脚置高从而使LED起;当接收到字符"B"时,可以将LED引脚置低从而使LED。 最后,记得在循环中加入延时函数,以便观察LED效果。 需要注意的是,为了能够正确接收和发送串口数据,可能还需要配置中断和DMA等相关功能。 以上是使用STM32串口控制LED的基本步骤,具体的代码实现可以根据自己的需求灵活调整。 ### 回答3: STM32是一种广泛应用于嵌入式系统的微控制器,它可以通过串口控制LED串口是一种通信接口,可用于将数据发送或接收到外部设备。以下是如何使用STM32控制器和串口实现LED控制: 首先,需要配置STM32串口。选择合适的串口引脚作为发送和接收端口,并配置串口的波特率、校验位和停止位。 然后,编写STM32控制器的程序。在主程序中,通过串口接收数据。当接收到特定的命令时,根据命令设置相应的IO口来控制LED。 例如,当接收到字节“1”时,可以将LED所连接的IO口设置为高电平,从而使LED。当接收到字节“0”时,将IO口设置为低电平,从而使LED。 程序定期检查串口是否有新的数据到达,并根据接收到的数据执行相应的操作。这样,当用户通过串口发送特定的命令时,可以实现对LED控制。 需要注意的是,通过串口控制LED的前提是正确连接STM32LED,并正确配置引脚。此外,还需要确保串口接收的数据正确且互不冲突,以避免误操作。 通过以上步骤,我们可以利用STM32控制器和串口实现对LED控制。这种方法不仅简洁高效,而且灵活性强,可以根据需要对LED进行灵活的控制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值