一、通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作
1.例如在串口输入led1on,开饭led1灯点亮
2.例如在串口输入led1off,开饭led1灯熄灭
3.例如在串口输入led2on,开饭led2灯点亮
4.例如在串口输入led2off,开饭led2灯熄灭
5.例如在串口输入led3on,开饭led3灯点亮
6.例如在串口输入led3off,开饭led3灯熄灭
二、检测中断到来时,让LED灯状态取反,并且在串口工具上打印一句话
例如:当按键1按下之后,让LED1状态取反,并打印“LED1 down”
当按键2按下之后,让LED2状态取反,并打印“LED2 down”
当按键3按下之后,让LED3状态取反,并打印“LED3 down”
火焰传感器/人体红外/光电开关实验要求如上
作业一:
uart_led.h:
#ifndef __UART_LED_H__ #define __UART_LED_H__ #include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h" #include
"stm32mp1xx_exti.h" #include "stm32mp1xx_gic.h" //重写strcmp函数 int strcmp(const
char *s1, const char *s2); //对LED灯初始化 void hal_led_init(); //对GPIO引脚初始化函数 void
hal_gpio_init(gpio_t* gpiox, gpio_init_t* init, unsigned int pin);
//对GPIO引脚写操作函数 void hal_led_gpio_write(gpio_t* gpiox, unsigned int pin,
gpio_status_t state); //初始化串口 void hal_uart_init(); //发送一个字节 void
uart_put_char(const char str); //发送一个字符串 void uart_put_string(const char* str);
//接受一个字符 char uart_get_char(); //接收一个字符串 char* uart_get_string(); #endif
uart_led.c:
#include "uart_led.h" extern void printf(const char *fmt, ...); extern void
delay_ms(int ms); //重写strcmp函数 int strcmp(const char *s1, const char *s2) { int
t = 0; while(*s1 || *s2) { if(*s1 != *s2) { t = *s1 - *s2; return t; } *s1 ++;
*s2 ++; } return t; } //对LED灯初始化 void hal_led_init() { //RCC时钟初始化
RCC->MP_AHB4ENSETR |= (0x3 << 4); //结构体初始化 gpio_init_t init = {Output,
Push_pull, Low_speed, No_up_down}; //GPIO初始化 hal_gpio_init(GPIOE, &init,
GPIO_PIN_10); hal_gpio_init(GPIOF, &init, GPIO_PIN_10); hal_gpio_init(GPIOE,
&init, GPIO_PIN_8); } //对GPIO引脚初始化函数 void hal_gpio_init(gpio_t* gpiox,
gpio_init_t* init, unsigned int pin) { //GPIO输出模式初始化 gpiox->MODER &= (~(0x3 <<
(pin * 2))); gpiox->MODER |= (init->moder << (pin * 2)); //GPIO输出类型初始化
gpiox->OTYPER &= (~(0x1 << pin)); gpiox->OTYPER |= (init->otyper << pin);
//GPIO输出速度初始化 gpiox->OSPEEDR &= (~(0x3 << (pin * 2))); gpiox->OSPEEDR |=
(init->ospeedr << (pin * 2)); //GPIO是否需要上下拉 gpiox->PUPDR &= (~(0x3 << (pin *
2))); gpiox->PUPDR |= (init->pupdr << (pin * 2)); } //对GPIO引脚写操作函数 void
hal_led_gpio_write(gpio_t* gpiox, unsigned int pin, gpio_status_t state) {
if(gpio_reset_t == state) gpiox->ODR &= (~(0x1 << pin)); else gpiox->ODR |=
(0x1 << pin); } //初始化串口 void hal_uart_init() { /*********RCC章节初始化********/
RCC->MP_AHB4ENSETR |= (0x1 << 1); RCC->MP_AHB4ENSETR |= (0x1 << 6);
RCC->MP_APB1ENSETR |= (0x1 << 16); /*********GPIO章节初始化*******/ gpio_init_t init
= {0}; init.moder = Alternate; //设置GPIO模式为复用模式 hal_gpio_init(GPIOB, &init,
GPIO_PIN_2); hal_gpio_init(GPIOG, &init, GPIO_PIN_11); GPIOB->MODER |= (0x1 <<
5); GPIOB->AFRL &= (~(0xF << 8)); GPIOB->AFRL |= (0x1 << 11); GPIOG->MODER |=
(0x1 << 23); GPIOG->AFRH &= (~(0xF << 12)); GPIOG->AFRH |= (0x3 << 13);
/*********UART章节初始化*******/ if(USART4->CR1 & (0x1 << 0)) //判断UE位是否为0 {
delay_ms(500); USART4->CR1 &= (~(0x1 << 0)); } USART4->CR1 &= (~(0x1 << 28));
//设置数据位宽度为8位 USART4->CR1 &= (~(0x1 << 12)); USART4->CR1 &= (~(0x1 << 15));
//设置串口采样率 USART4->CR1 &= (~(0x1 << 10)); //设置无奇偶校验位 USART4->CR2 &= (~(0x3 <<
12)); //设置串口1位停止位 USART4->PRESC &= (~(0x3 << 3)); //设置串口不分频 USART4->BRR |=
0x22B; //设置串口波特率 USART4->CR1 |= (0x1 << 2); //串口发送器使能 USART4->CR1 |= (0x1 <<
3); //串口接收器使能 USART4->CR1 |= (0x1 << 0); //串口使能 } //发送一个字节 void
uart_put_char(const char str) { //1.判断发送数据寄存器是否为空,为空才可以发送下一个字节 //ISR[7]
//读0:发送数据寄存器满,需要等待 //读1:发送数据寄存器空,才可以发送下一个字节数据 while(!(USART4->ISR & (0x1 <<
7))); //2.将要发送的字符写到发送数据寄存器中 USART4->TDR = str; //3.判断发送数据是否完成 ISR[6]
while(!(USART4->ISR & (0x1 << 6))); } //发送一个字符串 void uart_put_string(const
char* str) { //判断是否为'\0',一个字符一个字符发 for(int i = 0; str[i] != '\0'; i++) {
uart_put_char(str[i]); } printf("\n"); } //接受一个字符 char uart_get_char() { char
ch; //1.判断接收数据寄存器是否有数据可读 ISR[5] while(!(USART4->ISR & (0x1 << 5)));
//2.将接收到的数据读出来 ch = USART4->RDR; return ch; } char buff[50] = {0}; //接收一个字符串
char* uart_get_string() { int i = 0; //for循环 //当键盘的回车键'\r'按下之后,字符串输入完成 for(i =
0; i < 48; i++) { buff[i] = uart_get_char(); if(buff[i] == '\r') break;
uart_put_char(buff[i]); } //字符串补'\0' buff[i] = '\0'; printf("\n");
//对接收到的字符串进行判断 if(strcmp(buff,"led1on") == 0) { hal_led_gpio_write(GPIOE,
GPIO_PIN_10, gpio_set_t); return "LED1_ON success"; } else
if(strcmp(buff,"led1off") == 0) { hal_led_gpio_write(GPIOE, GPIO_PIN_10,
gpio_reset_t); return "LED1_OFF success"; } else if(strcmp(buff,"led2on") == 0)
{ hal_led_gpio_write(GPIOF, GPIO_PIN_10, gpio_set_t); return "LED2_ON success";
} else if(strcmp(buff,"led2off") == 0) { hal_led_gpio_write(GPIOF, GPIO_PIN_10,
gpio_reset_t); return "LED2_OFF success"; } else if(strcmp(buff,"led3on") == 0)
{ hal_led_gpio_write(GPIOE, GPIO_PIN_8, gpio_set_t); return "LED3_ON success";
} else if(strcmp(buff,"led3off") == 0) { hal_led_gpio_write(GPIOE, GPIO_PIN_8,
gpio_reset_t); return "LED3_OFF success"; } return "invalid instruction!"; }
main.c:
#include "uart_led.h" extern void printf(const char *fmt, ...); void
delay_ms(int ms) { int i,j; for(i = 0; i < ms;i++) for (j = 0; j < 1800; j++);
} int main() { hal_led_init(); //LED灯初始化 hal_uart_init(); //串口初始化 while(1) {
uart_put_string(uart_get_string()); } return 0; }
测试结果如下:
作业二:
实验现象如下: