单片机串口控制

1.使用微控制器输入串口指令控制LED灯亮灭

main.c

cpp 复制代码
#include "uart4.h"


int main()
{
    led_init(); //初始化LED相关寄存器
    char buf[128];
    while(1){
        gets(buf);
        if(mystrcmp(buf,"LED1_on") == 0){
            led_ctl(1,1); //当在串口工具中输入"LED1_on"时控制LED1打开
            puts("灯已经打开\n");
        }else if(mystrcmp(buf,"LED1_off") == 0){
            led_ctl(1,0);当在串口工具中输入"LED1_off"时控制LED1关闭
            puts("灯已经关闭\n");
        }else{
            puts(buf);
        }
    }
}

uart4.h

cpp 复制代码
#include "uart4.h"

//串口初始化
void uart4_init()
{

    //使能UART4外设时钟
    RCC->MP_APB1ENSETR |= (0x1<<16);
    //使能GPIOB/GPIOG外设时钟
    RCC->MP_AHB4ENSETR |= (0x1<<1);
    RCC->MP_AHB4ENSETR |= (0x1<<6);

    //设置PB2/PG11复用为UART4功能
    //PB2
    GPIOB->MODER &= (~(0x3<<4));
    GPIOB->MODER |= (0x2<<4);
    GPIOB->AFRL &= (~(0xf<<8));
    GPIOB->AFRL |= (0x8<<8);
    //PG11
    GPIOG->MODER &= (~(0x3<<22));
    GPIOG->MODER |= (0x2<<22);
    GPIOG->AFRH &= (~(0xf<<12));
    GPIOG->AFRH |= (0x6<<12);

    //禁用串口UE=0
    USART4->CR1 &= (~(0x1<<0));
    //设置8bit数据位
    USART4->CR1 &= (~(0x1<<12));
    USART4->CR1 &= (~(0x1<<28));
    //设置没有校验位
    USART4->CR1 &= (~(0x1<<10));
    //设置不分频
    USART4->PRESC &= (~(0xf<<0));
    //设置16倍过采样
    USART4->CR1 &= (~(0x1<<15));
    //设置1bit停止位
    USART4->CR2 &= (~(0x3<<12));
    //设置115200波特率
    USART4->BRR =0x22b;
    //使能发送器
    USART4->CR1 |= (0X1<<3);
    //使能接收器
     USART4->CR1 |= (0X1<<2);
    //使能串口
    USART4->CR1 |= 0x1;

}
//封装单个字符的发送函数
void putchar(char ch)
{
    //判断发送数据寄存器是否为空
    //不为空则等待
    while (!(USART4->ISR&(0x1<<7)));
    //为空。向发送数据寄存器写入
    USART4->TDR=ch;
    //等待送完成
    while (!(USART4->ISR&(0x1<<6)));

    
}

//单个字符的接收
char getchar()
{
    //判断接收数据寄存器是否有数据
    //没有数据则等待
    while (!(USART4->ISR&(0x1<<5)));
    
    //有数据就将数据读取返回
    return USART4->RDR;
}

//封装字符串的输入
void gets(char *s)
{
    //循环调用单个字符接收
    while(1)
    {
        *s=getchar();
        if(*s == '\r')
        {
            //s++;
            *s='\0';
            break;
        }
        putchar(*s);
        s++;
    }
   //*s = '\0';
   putchar('\n');
   putchar('\r');

    //等待读取到回车键\r,字符串接收

}

//字符串输出
void puts(char *s)
{

    //循环调用单个字符的发送
    //直到遇到\0结束
    //最后末尾发送一个换行一个回车
    while(*s)
    {
        putchar(*s);
        s++;
    }
    putchar('\0');
    putchar('\n');
    putchar('\r');
}

int mystrcmp(char *s1,char *s2)
{
    while(*s1==*s2)
	{
		if(*s1=='\0'||*s2=='\0')
		{
			break;
		}
		s1++;
		s2++;
	}
	return (*s1 - *s2);
}

void led_init()
{
	//GPIO初始化
	//外设时钟
	//*((unsigned int *)0x50000A28) |= (0x3 <<4);
	RCC->MP_AHB4ENSETR |= (0x3 <<4);

	//*((unsigned int *)0x50006000) &= (~(0x3 << 20));
	//*((unsigned int *)0x50006000) |= (0x1 << 20);
	GPIOE->MODER &= (~(0x3 << 20));
	GPIOE->MODER |= (0x1 << 20);

	//*((unsigned int *)0x50007000) &= (~(0x3 << 20));
	//*((unsigned int *)0x50007000) |= (0x1 << 20);
	GPIOF->MODER &= (~(0x3 << 20));
	GPIOF->MODER |= (0x1 << 20);


	//*((unsigned int *)0x50006000) &= (~(0x3 << 16));
	//*((unsigned int *)0x50006000) |= (0x1 << 16);
	GPIOE->MODER &= (~(0x3 << 16));
	GPIOE->MODER |= (0x1 << 16);

	//*((unsigned int *)0x50006004) &= (~(0x1 << 10));
	//*((unsigned int *)0x50007004) &= (~(0x1 << 10));
	//*((unsigned int *)0x50006004) &= (~(0x1 << 8));
	GPIOE->OTYPER &= (~(0x1 << 10));
	GPIOF->OTYPER &= (~(0x1 << 10));
	GPIOE->OTYPER &= (~(0x1 << 8));


	//*((unsigned int *)0x50006008) &= (~(0x3 << 20));
	//*((unsigned int *)0x50007008) &= (~(0x3 << 20));
	//*((unsigned int *)0x50006008) &= (~(0x3 << 16));
	GPIOE->OSPEEDR &= (~(0x3 << 20));
	GPIOF->OSPEEDR &= (~(0x3 << 20));
	GPIOE->OSPEEDR &= (~(0x3 << 16));



	//*((unsigned int *)0x5000600c) &= (~(0x3 << 20));
	//*((unsigned int *)0x5000700c) &= (~(0x3 << 20));
	//*((unsigned int *)0x5000600c) &= (~(0x3 << 16));
	GPIOE->PUPDR &= (~(0x3 << 20));
	GPIOF->PUPDR &= (~(0x3 << 20));
	GPIOE->PUPDR &= (~(0x3 << 16));
}

void led_ctl(int which,int cmd)
{
	switch(which)
	{
		case 1:
			if(cmd == 0){
				GPIOE->ODR &= (~(0x1<<10));
			}
			else if(cmd == 1){
				GPIOE->ODR |= (0x1<<10);
			}
				break;
		case 2:
			if(cmd == 0){
				GPIOF->ODR &= (~(0x1<<10));
			}
			else if(cmd == 1){
				GPIOF->ODR |= (0x1<<10);
			}
				break;
		case 3:
			if(cmd == 0){
				GPIOE->ODR &= (~(0x1<<8));
			}
			else if(cmd == 1){
				GPIOE->ODR |= (0x1<<8);
			}
				break;
	}
}

2.单片机串口控制风扇开关

cpp 复制代码
char buf[32];
  while (1)
  {
		memset(buf,0,sizeof(buf));
		HAL_UART_Receive(&huart1,(uint8_t *)buf,10,10000);
		if(strcmp(buf,"fan_on")==0){
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,GPIO_PIN_SET);//风扇是PC6引脚
			printf("the fan is on\n\r");
		}else if(strcmp(buf,"fan_off")==0){
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_6,GPIO_PIN_RESET);
			printf("the fan is off\n\r");
		}else{
			HAL_UART_Transmit(&huart1,(uint8_t *)buf,strlen(buf),5);
		}
相关推荐
周周记笔记13 分钟前
GD32F450xx MCU Datasheet 解读:硬件测试工程师的测试方法论
单片机·嵌入式硬件
潘潘的嵌入式日记2 小时前
I²C 从机接收总被覆盖?双缓冲要在 STOP 时交接
c语言·开发语言·单片机
AOI小白新手上路4 小时前
江科协51单片机16-1 AD/DA ADC 三通道综合显示(LCD1602 版)改造说明
单片机·嵌入式硬件·51单片机
HUI-4744 小时前
EG1135|SSOP‑16 同步整流降压控制器,大功率外置 MOS 降压优选
单片机·嵌入式硬件·硬件工程
单片机仿真设计5 小时前
【proteus仿真】基于 STM32 单片机恒温箱控制系统设计(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·毕设
国科安芯5 小时前
星载CAN总线通信网络中抗辐射MCU的通信可靠性设计分析
网络·人工智能·分布式·单片机·嵌入式硬件·架构
新晨单片机设计6 小时前
S003A-基于STM32单片机温度计(数码管显示)【Proteus仿真+Keil程序+原理图】
stm32·单片机·stm32单片机功能定制
AOI小白新手上路7 小时前
江科协51单片机16-1 DA数模转换实验(PWM 呼吸灯)
单片机·嵌入式硬件·51单片机
hongmai6668887 小时前
告别Wi-Fi,专注Mesh:ESP32-H2-MINI-1U-H2S模组规格与应用
单片机·嵌入式硬件·物联网·5g·h.265
Yiran_G7 小时前
BLE通信距离怎么判断?从发射功率、PHY到天线设计分析
单片机·嵌入式硬件