单片机串口控制

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);
		}
相关推荐
LS_learner2 小时前
基于CanMV IDE 开发软件对K210图像识别模块的开发
嵌入式硬件
wmq1633 小时前
嵌入式经常用到串口,如何判断串口数据接收完成?
单片机·串口
木燚垚4 小时前
物联网水质监测系统设计与实现/基于STM32的水产养殖云监控系统设计
stm32·嵌入式硬件·物联网·智能家居
Ronin-Lotus4 小时前
嵌入式硬件篇---原码、补码、反码
嵌入式硬件·十六进制·八进制·计算机硬件·原码·反码·补码
zd8451015006 小时前
单片机复杂项目的软件分层设计
arm开发·单片机·嵌入式硬件
云山工作室6 小时前
基于单片机的电子式单项智能电表设计(论文+源码)
stm32·单片机·嵌入式硬件·毕业设计·毕设
勿忘初心917 小时前
Android车机DIY开发之软件篇(十二) AOSP12下载编译
android·大数据·arm开发·嵌入式硬件·elasticsearch
phoenixlxl7 小时前
常用电路(过压保护、电流/电压采集)
单片机·嵌入式硬件
派阿喵搞电子8 小时前
在freertos中,事件组的用途,相比与信号量有什么优势,事件组适合应用于什么场合,而这种场合却是信号量无法实现的
单片机·学习·系统架构
微信1532379424310 小时前
AFE 户外储能 家用储能 安全性强 KA49702/KA49701 高低边
单片机·嵌入式硬件