- #ifndef __UART4_H__
- #define __UART4_H__
-
- #include "stm32mp1xx_rcc.h"
- #include "stm32mp1xx_gpio.h"
- #include "stm32mp1xx_uart.h"
-
- //PB2 ---> UART4_RX
- //PG11 ---> UART4_TX
-
- //RCC/GPIO/UART4章节初始化
- void hal_uart4_init();
- //发送一个字符
- void hal_put_char(const char ch);
- //发送一个字符串
- void hal_put_string(const char* string);
- //接收一个字符
- char hal_get_char();
- //接收一个字符串
- char* hal_get_string();
-
- #endif
- #include "uart4.h"
- extern void delay_ms(int ms);
- //RCC/GPIO/UART4章节初始化
- void hal_uart4_init()
- {
- //RCC章节初始化
- //1.使能GPIOB组控制器 MP_AHB4ENSETR[1] = 1 0x50000A28[1]
- RCC->MP_AHB4ENSETR |= (0X1 << 1);
- //2.使能GPIOG组控制器 MP_AHB4ENSETR[6] = 1 0x50000a28[6]
- RCC->MP_AHB4ENSETR |= (0X1 << 6);
- //3.使能UART4组控制器 MP_AHB4ENSETR[11] = 1 PB2 PG11---> 0x500000A00[16]
- RCC->MP_APB1ENSETR |= (0X1 << 16);
-
- //GPIO章节初始化
- //1.设置PB2引脚为复用功能模式 MODER[5:4] = 10
- GPIOB->MODER &= (~(0x1 << 4));
- GPIOB->MODER |= (0x1 << 5);
- //2.设置PB2引脚复用功能为UART4_RX功能 AFRL[11:8] = 1000
- GPIOB->AFRL &= (~(0xf << 8));
- GPIOB->AFRL |= (0x1 << 11);
- //设置PG11引脚为复用功能模式 MODER[23:22] = 10
- GPIOG->MODER &= (~(0x1 << 22));
- GPIOG->MODER |= (0x1 << 23);
- //设置PG11引脚复用功能为UART4_TX功能 AFRH[15:12] = 0110
- GPIOG->AFRH &= (~(0xf << 12));
- GPIOG->AFRH |= (0x6 << 12);
-
- //UART4章节初始化
- //8N1 115200 使能位 代码编写逻辑
- //0.设置串口UE=0 CR1[0] = 0
- if(USART4->CR1 & (0x1 << 0))
- {
- delay_ms(500);
- USART4->CR1 &= (~(0x1 << 0));
- }
- //1.设置1位起始位,8位数据位 CR1[28][12] = 00
- USART4->CR1 &= (~(0x1 << 12));
- USART4->CR1 &= (~(0x1 << 28));
- //2.设置串口1位停止位 CR2[13:12] = 00
- USART4->CR2 &= (~(0x3 << 12));
- //3.设置串口无校验位 CR1[10] = 0
- USART4->CR1 &= (~(0x1 << 10));
- //4.设置串口16倍采样率 CR1[15] = 0
- USART4->CR1 &= (~(0x1 << 15));
- //5.设置串口不分频 PRESC[3:0] = 0000
- USART4->PRESC &= (~(0xf << 0));
- //6.设置串口波特率为115200 BRR = 0X22b
- //USART4->BRR &= (~(0xffff)); //可以不清零
- USART4->BRR |= (0x22b); //直接置0x22b // |= :按位赋值, = 直接赋值
- //7.设置串口发送位使能 CR1[3] = 1
- USART4->CR1 |= (0x1 << 3);
- //8.设置串口接受位使能 CR1[2] = 1
- USART4->CR1 |= (0x1 << 2);
- //9.设置串口使能 CR1[0] = 1
- USART4->CR1 |= (0x1 << 0);
- }
- //发送一个字符
- void hal_put_char(const char ch)
- {
- //1.判断发送数据寄存器是否为空 ISR[7]
- //读0:发送数据寄存器满,需要等待 for while
- //读1:发送数据寄存器空,可以发送数据
- while(!(USART4->ISR & (0X1 << 7)));
- //2.将参数ch传递过来的内容,赋值给TDR寄存器
- USART4->TDR = (volatile unsigned int)ch;
- //3.判断一帧数据是否发送完成 ISR[6]
- //读0:一帧数据没有发送完成,需要等待 for while
- //读1:一帧数据发送完成,可以发送下一帧数据
- while(!(USART4->ISR & (0x1 << 6)));
- }
-
- //发送一个字符串
- void hal_put_string(const char* string)
- {
- //判断字符串是否为\0
- while(*string)
- {
- //一个字符一个字符进行发送
- hal_put_char(*string++);
- }
- hal_put_char('\r');
- hal_put_char('\n');
- }
-
- //接收一个字符
- char hal_get_char()
- {
- char ch;
- //1.判断接收数据寄存器是否不为空 ISR[5]
- //读0:没有接收到数据,需要等待 for while
- //读1:接收到数据,可以将数据读出
- while(!(USART4->ISR & (0x1 << 5)));
- //2.将接收数据寄存器中RDR,读出来
- ch = (char)USART4->RDR;
- return ch;
- }
-
- char buffer[50] = {0};
- //接收一个字符串
- char* hal_get_string()
- {
- int i=0;
- for(i=0;i<49;i++)
- {
- buffer[i] = hal_get_char(); //开发板接收一个字符
- hal_put_char(buffer[i]); //发送一个字符显示串口工具
- if(buffer[i] == '\r')
- break;
- }
- buffer[i] = '\0';
- hal_put_char('\n');
- return buffer;
- }
- #include "uart4.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_uart4_init();
-
- hal_put_string("hello");
-
- while(1)
-
- {
- //单个字符
-
- //hal_put_char(hal_get_char() + 1);
-
- //字符串
-
- hal_put_string(hal_get_string());
-
- }
- return 0;
- }