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功能//PB2GPIOB->MODER &= (~(0x3<<4));GPIOB->MODER |= (0x2<<4);GPIOB->AFRL &= (~(0xf<<8));GPIOB->AFRL |= (0x8<<8);//PG11GPIOG->MODER &= (~(0x3<<22));GPIOG->MODER |= (0x2<<22);GPIOG->AFRH &= (~(0xf<<12));GPIOG->AFRH |= (0x6<<12);//禁用串口UE=0USART4->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);}