使用访问寄存器方式实现串口控制3盏灯亮灭
main.c
#include"led.h"
//#include "fan.h"
#include "uart4.h"
//封装延时函数
void delay(int ms)
{
int i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<2000;j++)
{}
}
}
int main()
{
all_led_init();
/*
fan_init();
*/
uart4_init();
while(1)
{
/*
LED1_ON();
delay(500);
LED1_OFF();
delay(500);
fan_ON();
delay(500);
fan_OFF();
*/
char c = getchar();
if(c == '\r'){
putchar('\r');
putchar('\n');
}
putchar(c);
if(c == 'a'){
LED1_ON();
LED2_OFF();
LED3_OFF();
}else if(c == 'b'){
LED2_ON();
LED1_OFF();
LED3_OFF();
}else{
LED3_ON();
LED1_OFF();
LED2_OFF();
}
}
return 0;
}
uart4.h
#ifndef __UART4_H__
#define __UART4_H__
#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
void uart4_init();
char getchar();
void putchar(char c);
#endif
uart4.c
#include "uart4.h"
void uart4_init(){
// set relevent bits in RCC to enable GPIOB GPIOG UART4 clock
/*
UART4_TX --> PG11
UART4_RX --> PB2
GPIOB GPIOG --> AHB4
PB2 -->set RCC_MP_AHB4ENSETR[1] to 1
PG11 -->set RCC_MP_AHB4ENSETR[6] to 1
UART4 --> APB1 -->set RCC_MP_APB1ENSETR[16] to 1
*/
RCC->MP_AHB4ENSETR |= (0x1<<0x1);
RCC->MP_AHB4ENSETR |= (0x1<<0x6);
RCC->MP_APB1ENSETR |= (0x1<<0x10);
//set GPIO alternate function
//PB2 AF8
GPIOB->MODER &=(~(0x3<<0x4));
GPIOB->MODER |=(0x2<<0x4);
GPIOB->AFRL &=(~(0xF<<0x8));
GPIOB->AFRL |=(0x8<<0x8);
//PG11 AF6
GPIOG->MODER &=(~(0x3<<0x16));
GPIOG->MODER |=(0x2<<0x16);
GPIOG->AFRH &=(~(0xF<<0xC));
GPIOG->AFRH |=(0x6<<0xC);
//disable uart4
USART4->CR1 &= (~(0x1));
//function : set data word length
//register : USART_CR1
//bits name : M1
//bits fieled : [28]
//bits name : M0
//bits fieled : [12]
//value : M1=0 and M0=0: 1 start bit, 8 Data bits
USART4->CR1 &= (~(0x1<<0xC));
USART4->CR1 &= (~(0x1<<0x1C));
//function : set number of stop bits
//register : USART_CR2
//bits name : stop
//bits fieled : [13:12]
//value : 00: 1 stop bit
USART4->CR2 &= (~(0x3<<0xC));
//function : set uart4 oversampling by 16
//register : USART_CR1
//bits name : OVER8
//bits fieled : [15]
//bits name :
//bits fieled : []
//value : 0: Oversampling by 16
// 1: Oversampling by 8
USART4->CR1 &= (~(0x1<<0xF));
//function : set Parity control enable
//register : USART_CR1
//bits name : PCE
//bits fieled : [10]
//value : 0: Parity control disabled
// 1: Parity control enabled
USART4->CR1 &= (~(0x1<<0xA));
//function : set baud rate to 115200
//register : USART_BRR
//bits name : BRR
//bits fieled : [15:0]
//value : =64000000/115200
USART4->BRR=64000000/115200;
//function : set no prescale
//register : USART_PRESC
//bits name : PRESCALER
//bits fieled : [3:0]
//value : 0000: input clock not divided
// 0001: input clock divided by 2
// 0010: input clock divided by 4
// 0011: input clock divided by 6
// 0100: input clock divided by 8
// 0101: input clock divided by 10
// 0110: input clock divided by 12
// 0111: input clock divided by 16
// 1000: input clock divided by 32
// 1001: input clock divided by 64
// 1010: input clock divided by 128
// 1011: input clock divided by 256
USART4->PRESC=0;
//function : enable transmitter
//register : USART_CR1
//bits name : TE
//bits fieled : [3]
//value : 0: Transmitter is disabled
// 1: Transmitter is enabled
USART4->CR1 |= (0x1<<0x3);
//function : enable Receiver
//register : USART_CR1
//bits name : RE
//bits fieled : [2]
//value : 0: Receiver is disabled
// 1: Receiver is enabled
USART4->CR1 |= (0x1<<0x2);
//function : enable USART
//register : USART_CR1
//bits name : UE
//bits fieled : [0]
//value : 0: USART prescaler and outputs disabled, low-power mode
// 1: USART enabled
USART4->CR1 |= (0x1);
}
char getchar(){
//function : check if the read data register is empty
//register : USART_ISR
//bits name : RXNE
//bits fieled : [5]
//value : 0: Data is not received
// 1: Received data is ready to be read.
while((USART4->ISR&(0x1<<0x5)) == 0);
return USART4->RDR;
}
void putchar(char c){
//function : check if the transmit data register is empty
//register : USART_ISR
//bits name : TXE
//bits fieled : [7]
//value : 0: Data register full
// 1: Data register not full
while((USART4->ISR&(0x1<<0x7)) == 0);
USART4->TDR = c;
//function : check if the data transmission complete
//register : USART_ISR
//bits name : TC
//bits fieled : [6]
//value : 0: Transmission is not complete
// 1: Transmission is complete
while((USART4->ISR&(0x1<<0x6)) == 0);
}
led.h
#ifndef __LED_H__
#define __LED_H__
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
void all_led_init();
void LED1_ON();
void LED2_ON();
void LED3_ON();
void LED1_OFF();
void LED2_OFF();
void LED3_OFF();
#endif
led.c
#include "led.h"
void all_led_init()//led灯的初始化
{
//GPIOE/GPIOF时钟使能
RCC->MP_AHB4ENSETR |= (0x3<<4);
//PE10设置为输出
GPIOE->MODER &= (~(0X3<<20));
GPIOE->MODER |= (0X1<<20);
//PF10设置为输出
GPIOF->MODER &= (~(0X3<<20));
GPIOF->MODER |= (0X1<<20);
//PE8设置为输出
GPIOE->MODER &= (~(0X3<<16));
GPIOE->MODER |= (0X1<<16);
//PE10设置为推挽输出
GPIOE->OTYPER &= (~(0X1<<10));
//PF10设置为推挽输出
GPIOF->OTYPER &= (~(0X1<<10));
//PE8设置为推挽输出
GPIOE->OTYPER &= (~(0X1<<8));
//PE10设置为低速输出
GPIOE->OSPEEDR &= (~(0X3<<20));
//PF10设置为低速输出
GPIOF->OSPEEDR &= (~(0X3<<20));
//PE8设置为低速输出
GPIOE->OSPEEDR &= (~(0X3<<16));
//PE10无上拉下拉电阻
GPIOE->PUPDR &= (~(0X3<<20));
//PF10无上拉下拉电阻
GPIOF->PUPDR &= (~(0X3<<20));
//PE8无上拉下拉电阻
GPIOE->PUPDR &= (~(0X3<<16));
//三盏灯默认输出低电平
GPIOE->ODR &= (~(0X1<<10));
GPIOF->ODR &= (~(0X1<<10));
GPIOE->ODR &= (~(0X1<<8));
}
//led1亮
void LED1_ON()
{
GPIOE->ODR |= (0X1<<10);
}
//led2亮
void LED2_ON()
{
GPIOF->ODR |= (0X1<<10);
}
//led1亮
void LED3_ON()
{
GPIOE->ODR |= (0X1<<8);
}
//LED1灭
void LED1_OFF()
{
GPIOE->ODR &= (~(0X1<<10));
}
//LED2灭
void LED2_OFF()
{
GPIOF->ODR &= (~(0X1<<10));
}
//LED3灭
void LED3_OFF()
{
GPIOE->ODR &= (~(0X1<<8));
}