单片机串口控制

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);
		}
相关推荐
2301_805962931 小时前
NRF24L01模块STM32通信-通信初始化
stm32·单片机·嵌入式硬件
阳光宅男@李光熠3 小时前
【电子通识】PWM驱动让有刷直流电机恒流工作
单片机·嵌入式硬件
半个番茄4 小时前
STM32 : 奈奎斯特-香农采样定理
网络·stm32·单片机
IT信息技术学习圈6 小时前
CSP初赛知识学习计划(第二天)
单片机·嵌入式硬件·学习
硬件技术我知道9 小时前
产品 防尘防水IP等级 划分与实验方法
网络·人工智能·嵌入式硬件·物联网·计算机视觉·硬件工程·智慧城市
JoneMaster10 小时前
[读书日志]从零开始学习Chisel 第三篇:Scala面向对象编程——类和对象(敏捷硬件开发语言Chisel与数字系统设计)
开发语言·嵌入式硬件·学习·硬件架构·scala
分享大师11 小时前
【小制作】米家模拟手指点击
单片机·gitlab
qq_5719572612 小时前
通过串口通信控制led灯的亮灭
c语言·stm32·单片机
hfffhfh13 小时前
STM32CUBEMX+PLS_D1000激光测距模块+MT6701角度传感器,获取三角形第三边角度
stm32·单片机·嵌入式硬件
1101 110114 小时前
STM32-笔记34-4G遥控灯
嵌入式硬件