串口通信控制LED、马达、蜂鸣器、风扇

1.STM32U575RITx

设置引脚

编写main.c

//对fputc重写,方便调用printf函数
int fputc(int ch, FILE* F){
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 10);
	return ch;
}
//main函数的主要循环

  while (1)
  {
		char whole_buf[128];
		memset(whole_buf, 0, sizeof(whole_buf));
		char *p = whole_buf;
		//字符实时输出,方便查看
		while(1){
			char signal_ch;
			HAL_UART_Receive(&huart1, (uint8_t*)&signal_ch, 1, 1000000);
			//这里通过重写fputc函数重写了printf,使其可以直接输出
			//也可以通过HAL_UART_Transmit函数进行输出
			printf("%c", signal_ch);
			//判断是否为回车键
			if(signal_ch == '\r'){
				printf("\n\r");
				break;
			}
			//因为是单字符,所以只能挨个赋值
			*p = signal_ch;
			p++;
		}
		//LED1的控制
		if(strcmp(whole_buf, "LED1_ON") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET);
		}else if(strcmp(whole_buf, "LED1_OFF") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
		}
		//LED2的控制
		if(strcmp(whole_buf, "LED2_ON") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET);
		}else if(strcmp(whole_buf, "LED2_OFF") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET);
		}
		//LED3的控制
		if(strcmp(whole_buf, "LED3_ON") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
		}else if(strcmp(whole_buf, "LED3_OFF") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
		}
		//风扇的控制
		if(strcmp(whole_buf, "FAN_ON") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
		}else if(strcmp(whole_buf, "FAN_OFF") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
		}
		//马达的控制
		if(strcmp(whole_buf, "MOTOR_ON") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
		}else if(strcmp(whole_buf, "MOTOR_OFF") == 0){
			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
		}
  }

2、STM32MP157AAA

module.h

#ifndef __MODULE_H_

#define __MODULE_H_

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"

typedef enum{
    LED_1,
    LED_2,
    LED_3
}Led_t;

typedef enum{
    CMD_ON,
    CMD_OFF
}Cmd_t;

void module_init();
void module_led_ctrl(Led_t led, Cmd_t cmd);
void module_fan_ctrl(Cmd_t cmd);
void module_motor_ctrl(Cmd_t cmd);
void module_buzzer_ctrl(Cmd_t cmd);


#endif

module.c

#include "module.h"

void module_init(){
    //时钟使能
    RCC->MP_AHB4ENSETR |= (0X1 << 1); //PB
    RCC->MP_AHB4ENSETR |= (0X1 << 4); //PE
    RCC->MP_AHB4ENSETR |= (0X1 << 5); //PF
    //模式选择
    //模式位复位
    GPIOE->MODER &= (~(0X3 << 20)); //LED1
    GPIOF->MODER &= (~(0X3 << 20)); //LED2
    GPIOE->MODER &= (~(0X3 << 16)); //LED3
    GPIOE->MODER &= (~(0X3 << 18)); //FAN
    GPIOF->MODER &= (~(0X3 << 12)); //MOTOR
    GPIOB->MODER &= (~(0X3 << 12)); //BUZZER
    //模式位置位
    GPIOE->MODER |= (0X1 << 20); //LED1
    GPIOF->MODER |= (0X1 << 20); //LED2
    GPIOE->MODER |= (0X1 << 16); //LED3
    GPIOE->MODER |= (0X1 << 18); //FAN
    GPIOF->MODER |= (0X1 << 12); //MOTOR
    GPIOB->MODER |= (0X1 << 12); //BUZZER
    
    //推挽输出设置
    GPIOE->OTYPER &= (~(0X3 << 10)); //LED1
    GPIOF->OTYPER &= (~(0X3 << 10)); //LED2
    GPIOE->OTYPER &= (~(0X3 << 8));  //LED3
    GPIOE->OTYPER &= (~(0X3 << 9));  //FAN
    GPIOF->OTYPER &= (~(0X3 << 6));  //MOTOR
    GPIOB->OTYPER &= (~(0X3 << 6));  //BUZZER

    //低速输出设置    
    GPIOE->OSPEEDR &= (~(0X3 << 20)); //LED1
    GPIOF->OSPEEDR &= (~(0X3 << 20)); //LED2
    GPIOE->OSPEEDR &= (~(0X3 << 16)); //LED3
    GPIOE->OSPEEDR &= (~(0X3 << 18)); //FAN
    GPIOF->OSPEEDR &= (~(0X3 << 12)); //MOTOR
    GPIOB->OSPEEDR &= (~(0X3 << 12)); //BUZZER
    
    //无上下拉电阻设置
    GPIOE->PUPDR &= (~(0X3 << 20)); //LED1
    GPIOF->PUPDR &= (~(0X3 << 20)); //LED2
    GPIOE->PUPDR &= (~(0X3 << 16)); //LED3
    GPIOE->PUPDR &= (~(0X3 << 18)); //FAN
    GPIOF->PUPDR &= (~(0X3 << 12)); //MOTOR
    GPIOB->PUPDR &= (~(0X3 << 12)); //BUZZER
}
//LED灯模组
void module_led_ctrl(Led_t led, Cmd_t cmd){
    switch(led){
        case LED_1:
        if(cmd == CMD_ON){
            GPIOE->ODR |= (0X1 << 10);
        }else if(cmd == CMD_OFF){
            GPIOE->ODR &= (~(0X1 << 10));
        }
        break;
        case LED_2:
        if(cmd == CMD_ON){
            GPIOF->ODR |= (0X1 << 10);
        }else if(cmd == CMD_OFF){
            GPIOF->ODR &= (~(0X1 << 10));
        }
        break;
        case LED_3:
        if(cmd == CMD_ON){
            GPIOE->ODR |= (0X1 << 8);
        }else if(cmd == CMD_OFF){
            GPIOE->ODR &= (~(0X1 << 8));
        }
        break;
    }
}
//风扇模组
void module_fan_ctrl(Cmd_t cmd){
    if(cmd == CMD_ON){
        GPIOE->ODR |= (0X1 << 9);
    }else if(cmd == CMD_OFF){
        GPIOE->ODR &= (~(0X1 << 9));
    }
}
//马达模组
void module_motor_ctrl(Cmd_t cmd){
    if(cmd == CMD_ON){
        GPIOF->ODR |= (0X1 << 6);
    }else if(cmd == CMD_OFF){
        GPIOF->ODR &= (~(0X1 << 6));
    }
}
//蜂鸣器模组
void module_buzzer_ctrl(Cmd_t cmd){
    if(cmd == CMD_ON){
        GPIOB->ODR |= (0X1 << 6);
    }else if(cmd == CMD_OFF){
        GPIOB->ODR &= (~(0X1 << 6));
    }
}

uart4.h

#ifndef __UART4_H_

#define __UART4_H_

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"

void uart4_init();
void putchar(char ch);
char getchar();
void gets(char *s);
void puts(char *s);

#endif

uart4.c

#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 puts(char *s){
    while(*s){
        putchar(*s);
        s++;
    }
    putchar('\0');
    putchar('\n');
    putchar('\r');
}

void gets(char *s){
    while (1)
    {
        *s = getchar();
        if((*s) == '\r'){
            *s = '\0';
            break;
        }
        putchar(*s);
        s++;
    }
    putchar('\n');
    putchar('\r');
}

main.c

#include "uart4.h"
#include "module.h"

int my_strcmp(char *str1, char *str2){
	while(*str1 != '\0' && *str2 != '\0'){
		if(*str1 != *str2){
			return *str1 - *str2;
		}
		str1++;
		str2++;
	}
	return *str1 - *str2;
}

void my_bezero(char *buf, int len){
	int i = 0;
	while(i != len){
		*buf = '\0';
		buf++;
		i++;
	}
}

int my_strlen(char *str){
	int count = 0;
	while (*str != '\0')
	{
		count++;
		str++;
		putchar('c');
	}
	return count;
}

int main()
{
	//初始化TX和RX
    uart4_init();
	module_init();

	while (1)
	{
		char buf[128];
		my_bezero(buf, my_strlen(buf));
		gets(buf);
		//LED2的使能
		if(my_strcmp(buf, "LED1_ON") == 0){
			char info[] = "LED1 is on";
			puts(info);
			module_led_ctrl(LED_1, CMD_ON);
		}else if(my_strcmp(buf, "LED1_OFF") == 0){
			char info[] = "LED1 is off";
			puts(info);
			module_led_ctrl(LED_1, CMD_OFF);
		}
		//LED2的使能
		if(my_strcmp(buf, "LED2_ON") == 0){
			char info[] = "LED2 is on";
			puts(info);
			module_led_ctrl(LED_2, CMD_ON);
		}else if(my_strcmp(buf, "LED2_OFF") == 0){
			char info[] = "LED2 is off";
			puts(info);
			module_led_ctrl(LED_2, CMD_OFF);
		}
		//LED3的使能
		if(my_strcmp(buf, "LED3_ON") == 0){
			char info[] = "LED3 is on";
			puts(info);
			module_led_ctrl(LED_3, CMD_ON);
		}else if(my_strcmp(buf, "LED3_OFF") == 0){
			char info[] = "LED3 is off";
			puts(info);
			module_led_ctrl(LED_3, CMD_OFF);
		}

		//风扇的使能
		if(my_strcmp(buf, "FAN_ON") == 0){
			char info[] = "FAN is on";
			puts(info);
			module_fan_ctrl(CMD_ON);
		}else if(my_strcmp(buf, "FAN_OFF") == 0){
			char info[] = "FAN is off";
			puts(info);
			module_fan_ctrl(CMD_OFF);
		}
		//马达的使能
		if(my_strcmp(buf, "MOTOR_ON") == 0){
			char info[] = "MOTOR is on";
			puts(info);
			module_motor_ctrl(CMD_ON);
		}else if(my_strcmp(buf, "MOTOR_OFF") == 0){
			char info[] = "MOTOR is off";
			puts(info);
			module_motor_ctrl(CMD_ON);
		}
		//蜂鸣器的使能
		if(my_strcmp(buf, "BUZZER_ON") == 0){
			char info[] = "BUZZER is on";
			puts(info);
			module_buzzer_ctrl(CMD_ON);
		}else if(my_strcmp(buf, "BUZZER_OFF") == 0){
			char info[] = "BUZZER is off";
			puts(info);
			module_buzzer_ctrl(CMD_OFF);
		}
	}
	

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值