嵌入式学习-ARM
STM32串口控制三盏灯亮灭
MAIN.C
c
#include "uart4.h"
int main()
{
uart4_init();
gpio_init();
char str[32];
while (1)
{
gets(str);
if (my_strcmp(str,"A") == 0)
{
led1();
}else if (my_strcmp(str,"B") == 0)
{
led2();
}else if (my_strcmp(str,"C") == 0)
{
led3();
}
puts(str);
}
return 0;
}
UART4.C
c
#include "uart4.h"
void uart4_init()
{
// 使能GPIOB GPIOP UART4
RCC->MP_AHB4ENSETR |= (0x1);
RCC->MP_AHB4ENSETR |= (0x1 << 6);
RCC->MP_APB1ENSETR |= (0x1 << 16);
// 设置PB2和PG11管脚复用
GPIOB->MODER &= (~(0X3 << 4));
GPIOB->MODER |= (0X1 << 5);
GPIOG->MODER &= (~(0X3 << 22));
GPIOG->MODER |= (0X1 << 23);
GPIOB->AFRL &= (~(0XF << 8));
GPIOB->AFRL |= (0X8 << 8);
GPIOG->AFRH &= (~(0XF << 12));
GPIOG->AFRH |= (0X6 << 12);
// 设置串口不使能 UE=0
USART4->CR1 &= (~(0X1));
// 设置8位数据位
USART4->CR1 &= (~(0X1 << 12));
USART4->CR1 &= (~(0X1 << 28));
// 设置没有奇偶校验位
USART4->CR1 &= (~(0X1 << 10));
// 设置1位停止位
USART4->CR2 &= (~(0X3 << 12));
// 设置16倍过采样
USART4->CR1 &= (~(0X1 << 15));
// 设置时钟不分频
USART4->PRESC &= (~(0XF));
// 设置波特率115200
USART4->BRR &= (~(0XF));
USART4->BRR |= (0X22b);
// 使能发送器
USART4->CR1 |= (0X1 << 3);
// 使能接收器
USART4->CR1 |= (0X1 << 2);
// 使能uart4
USART4->CR1 |= (0X1);
}
void gpio_init()
{
// GPIOE GPIOF时钟使能
RCC->MP_AHB4ENSETR |= (0X3 << 4);
// PE10 PF10 PE8设置为输出
GPIOE->MODER &= (~(0X3 << 20));
GPIOE->MODER |= (0X1 << 20);
GPIOF->MODER &= (~(0X3 << 20));
GPIOF->MODER |= (0X1 << 20);
GPIOE->MODER &= (~(0X3 << 16));
GPIOE->MODER |= (0X1 << 16);
// 设置为推挽输出
GPIOE->OTYPER &= (~(0X1 << 10));
GPIOF->OTYPER &= (~(0X1 << 10));
GPIOE->OTYPER &= (~(0X1 << 8));
// 设置为低速输出
GPIOE->OSPEEDR &= (~(0X3 << 20));
GPIOF->OSPEEDR &= (~(0X3 << 20));
GPIOE->OSPEEDR &= (~(0X3 << 16));
// 设置为无上拉电阻
GPIOE->PUPDR &= (~(0X3 << 20));
GPIOF->PUPDR &= (~(0X3 << 20));
GPIOE->PUPDR &= (~(0X3 << 16));
// 默认低电平
GPIOE->ODR &= (~(0X1 << 10));
GPIOF->ODR &= (~(0X1 << 10));
GPIOE->ODR &= (~(0X1 << 8));
//GPIOE->ODR |= ((0X1 << 10));
//GPIOF->ODR |= ((0X1 << 10));
//GPIOE->ODR |= ((0X1 << 8));
}
// 输出字符
void putchar(char a)
{
// 先判断发送数据寄存器是否为空
// 不为空阻塞等待
// 为空向发送数据寄存器写入a的数据
// 写入完成需要判断发送是否完成,不完成阻塞等待,完成了则函数结束
while (!(USART4->ISR & (0X1 << 7)))
;
USART4->TDR = a;
while (!(USART4->ISR & (0X1 << 6)))
;
}
// 获取字符
char getchar()
{
// 先判断接收数据寄存器种有没有准备好的数据
// 如果数据没有准备好则阻塞等到
// 如果数据准备好了则读取
// 读取完毕将读取到的数据返回
while (!(USART4->ISR & (0X1 << 5))) // 等待数据
;
return USART4->RDR;
}
// 获取字符串
void gets(char *str)
{
while (1)
{
*str = getchar();
putchar(*str); // 显示输入的字符
if (*str == '\r') // 回车退出
break;
str++;
}
*str = '\0';
putchar('\n'); // 换行
}
// 输出字符串
void puts(char *s)
{
while (*s)
{
putchar(*s);
s++;
}
putchar('\r');
putchar('\n');
}
void led1()
{
if (GPIOE->ODR & (0X1 << 10)) // 此时是亮 改为暗
GPIOE->ODR &= (~(0X1 << 10));
else
GPIOE->ODR |= (0X1 << 10);
}
void led2()
{
if (GPIOF->ODR & (0X1 << 10)) // 此时是亮 改为暗
GPIOF->ODR &= (~(0X1 << 10));
else
GPIOF->ODR |= (0X1 << 10);
}
void led3()
{
if (GPIOE->ODR & (0X1 << 8)) // 此时是亮 改为暗
GPIOE->ODR &= (~(0X1 << 8));
else
GPIOE->ODR |= (0X1 << 8);
}
int my_strcmp(const char *src, const char *dest)
{
while (*src == *dest)
{
if (*dest == '\0')
break;
src++;
dest++;
}
return *src - *dest;
}
UART4.H
c
#ifndef __UART4_H__
#define __UART4_H__
#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.H"
void uart4_init();
void gpio_init();
void putchar(char a);
char getchar();
void puts(char *s);
void gets(char *str);
void led1();
void led2();
void led3();
int my_strcmp(const char *src, const char *dest);
#endif