当前位置: 首页 > article >正文

单片机串口控制

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

main.c

#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

#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.单片机串口控制风扇开关

 

 

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);
		}


http://www.kler.cn/a/472034.html

相关文章:

  • docker优雅停止容器
  • Linux中rsync命令使用
  • Android布局layout的draw简洁clipPath实现圆角矩形布局,Kotlin
  • 『SQLite』如何使用索引来查询数据?
  • matlab编写Newton插值多项式
  • 旷视科技C++面试题及参考答案
  • 关于FPGA中添加FIR IP核(采用了GOWIN EDA)
  • 使用宝塔面板,安装 Nginx、MySQL 和 Node.js
  • 后端Java开发:第十天
  • 【Linux】进程概念(PCB)与进程创建(fork)
  • 策略模式(Stragety Pattern)
  • PostgreSQL 运维的难与“难” --上海PG大会主题记录
  • Cloudflare IP 优选工具:轻松找到最快的 CDN 节点
  • Unity 3D游戏开发从入门进阶到高级
  • 【蓝桥真题练习】蓝桥杯 2021 国赛 A 组 E 题
  • 云商城--业务+架构学习和环境准备
  • php 多进程那点事,用 swoole 如何解决呢 ?
  • 【Cocos TypeScript 零基础 5.1】
  • win下搭建elk并集成springboot
  • 未来趋势:电商平台API接口的智能化与自动化发展