STM32串口控制LED灯的亮灭

STM32中的串口控制LED灯的亮灭,分为两种方式,一种是直接发送数字0和1来控制灯的亮灭,另一种是通过发送字符串来控制。

我所使用的开发板主控芯片是STM32F401RET6,主频84MHz,

首先要进行串口的初始化:

/*
函数功能:串口的初始化
函数名:Usart_Init
返回值:无
参数:u32 brr
备注:
USART1_TXD->PA9
USART1_RXD->PA10

*/
void Usart_Init(u32 brr)
{
	float div;
	u16 div_m;
	u16 div_f;
	//1.打开GPIOA,USART1的时钟
	RCC->AHB1ENR	|= (1<<0);
  RCC->APB2ENR	|= (1<<4);
	
	//2.把PA9配置为复用推挽输出,把PA10配置为浮空输入模式
	GPIOA->MODER &= ~(3<<18);//清零
	GPIOA->MODER |= (2<<18);//复用功能模式
	GPIOA->OTYPER &= ~(1<<9);//输出推挽
	GPIOA->OSPEEDR &= ~(3<<18);//清零
	GPIOA->OSPEEDR |=(3<<18);//输出高速
	
	GPIOA->MODER &= ~(3<<20);//输入模式
	GPIOA->MODER |= (2<<20);//复用功能
	
	GPIOA->PUPDR &= ~(3<<20);//无上下拉
	
	//3.把USART1映射复用到PA9,PA10上
	GPIOA->AFR[1] |=(0x7<<4);//USART1映射到PA9
	GPIOA->AFR[1] |=(0x7<<8);//USART1映射到PA10
	
	//4.配置串口:
	1.打开接收器和发送器
	USART1->CR1 |= (3<<2);
	
	2.禁止奇偶校验
	USART1->CR1 &= ~(1<<10);
	3.选择字长
	USART1->CR1 &= ~(1<<12);
	4.选择过采样
	USART1->CR1 &= ~(1<<15);
	5.配置停止位
	USART1->CR2 &= ~(3<<12);
	
	6.计算波特率寄存器
	div = 84000000.0/16/brr;
	div_m = (int)div;
	div_f = (div-div_m)*16+0.5f;
	USART1->BRR |= div_f|(div_m<<4);
	7.打开USART1模块使能
	USART1->CR1 |= (1<<13);
	
}

由于用到了printf函数,需要添加以下代码段,取消半主机状态:

/************************printf支持函数****************************/
#pragma import(__use_no_semihosting_swi) //取消半主机状态

struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;

int fputc(int ch, FILE *f) {
	while((USART1->SR &(0X01<<7))==0){};
		USART1->DR=ch;
  return (ch);
}
int ferror(FILE *f) {
  /* Your implementation of ferror */
  return EOF;
}

void _ttywrch(int ch) {
  while((USART1->SR &(0X01<<7))==0);
		USART1->DR=ch;
}

void _sys_exit(int return_code) {
label:  goto label;  /* endless loop */
}

方式一:

/*
函数名:Usart_Cont1
函数功能:串口的控制方式
返回值:无
形参:无
备注:
发送31,使LED3亮;发送30,使LED3灭;
发送41,使LED4亮;发送40,使LED4灭;

*/

void Usart_Cont1(void)
{
	u8 value[2];
	u8 i;
	for(i=0;i<2;i++)
	{
		while(!(USART1->SR & (1<<5))){};//等待数据接收完成
		value[i]=USART1->DR;
		
	}
	switch(value[0])
	{
		case '3':
			if(value[1]=='1')
			{
				LED3_ON;
			}
			else if(value[1]=='0')
			{
				LED3_OFF;
			}
			break;
		case '4':
			if(value[1]=='1')
			{
				LED4_ON;
			}
			else if(value[1]=='0')
			{
				LED4_OFF;
			}		
			break;
	}
}

方式二:

/*
函数名:Usart_Cont2
函数功能:串口的控制方式
返回值:无
形参:无
备注:
发送LED3_ON,使LED3亮;发送LED3_OF,使LED3灭;
发送LED4_ON,使LED4亮;发送LED4_OF,使LED4灭;

*/


void Usart_Cont2(void)
{
	u8 value1[8]={0};
	u8 i;
	for(i=0;i<7;i++)
	{
		while(!(USART1->SR & (1<<5))){};//等待数据接收完成
		value1[i]=USART1->DR;
	}
	value1[7]='\0';
	if(!(strcmp((const char *)value1,"LED3_ON")))
	{
		LED3_ON;
	}
	else if(!(strcmp((const char *)value1,"LED3_OF")))
	{
		LED3_OFF;
	}
	else if(!(strcmp((const char *)value1,"LED4_ON")))
	{
		LED4_ON;
	}	
	else if(!(strcmp((const char *)value1,"LED4_OF")))
	{
		LED4_OFF;
	}
}

调试时要注意的一些问题:

(1)串口调试助手XCOM V2.6部分字符会乱码,需要使用低版本的串口调试助手,如XCOM V1.4

(2)使用多条发送时,需要取消勾选“发送新行”,将间隔改为1ms,使用单条发送无此问题

(3)STM32串口的调试需要明确芯片的主频,选择正确的波特率,否则会出现乱码

(4)有些开发板还需要将拨码开关拨上才能进行串口调试实验,如我之前使用的主控芯片为STM32F411CEU6的智能手环开发板

完整工程源代码:https://download.csdn.net/download/qq_44678890/76737688

  • 8
    点赞
  • 137
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,使用STM32串口控制LED: ```c #include "stm32f10x.h" void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); } void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); 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_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } int main(void) { GPIO_Configuration(); USART_Configuration(); while (1) { if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) { char ch = USART_ReceiveData(USART1); if (ch == '1') { GPIO_SetBits(GPIOC, GPIO_Pin_13); } else if (ch == '0') { GPIO_ResetBits(GPIOC, GPIO_Pin_13); } } } } ``` 这个示例代码将USART1的TX引脚配置为复用推挽输出模式,将PC13引脚配置为输出模式。在主循环中,判断USART1是否有接收到数据,如果有,则读取数据,如果是字符'1',则点PC13引脚对应的LED,如果是字符'0',则关闭LED。您可以通过串口终端程序向STM32发送字符'1'或'0'来控制LED

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值