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