2022-9-15实验二串口实现字符串的收发

头文件部分

#ifndef __UART4_H__
#define __UART4_H__

#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_gpio.h"
#define LEN  50
// 初始化的函数
void uart4_init();

// 发送一个字节的函数
void send_char(const char ch);

// 发送字符串的函数 
void send_string(const char *str);

// 接收一个字符的函数
char recv_char();

// 接收一个字符串的函数
char * recv_string(char str[]);


#endif // __UART4_H__

功能函数部分

#include "uart4.h"
extern void delay_ms(unsigned int ms);
// 初始化的函数
void uart4_init()
{
    // 1. 使能GPIOB,GPIOG外设的时钟 RCC_MP_AHB4ENSETR[1][6] = 0b1
    RCC->MP_AHB4ENSETR = (0x1 << 1) | (0x1 << 6);
    // 2. 设置PB2, 和 PG11引脚为复用的功能
            // GPIOB_MODER[5:4] = 0b10  GPIOG_MODER[23:22] = 0b10
    GPIOB->MODER &= (~(0x3 << 4));
    GPIOB->MODER |= (0x2 << 4);
    GPIOG->MODER &= (~(0x3 << 22));
    GPIOG->MODER |= (0x2 << 22);

    // 3. 设置PB2引脚为UART4_RX功能  GPIOB_AFRL[11:8] --> AF8 --> 0b1000
        // 设置PG11引脚为UART4_TX功能  GPIOG_AFRH[15:12] --> AF6 --> 0b0110
    GPIOB->AFRL &= (~(0xF << 8));
    GPIOB->AFRL |= (0x8 << 8);
    GPIOG->AFRH &= (~(0xF << 12));
    GPIOG->AFRH |= (0x6 << 12);

    // 4. 使能UART4外设的时钟  RCC_MP_APB1ENSETR[16] = 0b1
    RCC->MP_APB1ENSETR = (0x1 << 16);

    // 5. 判断UART4串口是否使能,如果使能则禁止串口
    if (USART4->CR1 & (0x1 << 0)) {
        delay_ms(2000);  // 等待之前的串口的数据发送完成之后在禁止串口
        USART4->CR1 &= (~(0x1 << 0));  // 禁止串口的使能
    }
    // 6. 设置数据位为8位的数据宽度 USART4_CR1[28][12] = 0b00
    USART4->CR1 &= ~((0x1 << 12) | (0x1 << 28));
    // 7. 禁止校验位,不使用校验  USART4_CR1[10] = 0b0
    USART4->CR1 &= (~(0x1 << 10));
    // 8. 设置串口的采样率为16倍或者8倍,最终会影响波特率的计算  USART4_CR1[15]
    USART4->CR1 &= (~(0x1 << 15));
    // 9. 设置停止位的个数为1位  USART4_CR2[13:12] = 0b00
    USART4->CR2 &= (~(0x3 << 12));
    // 10. 设置串口时钟的分频寄存器 USART4_PRERC[3:0]  最终也会影响波特率的计算
            // usart_ker_ck 时钟源的频率等于 64MHz
            // usart_ker_ck_pesc = usart_ker_ck / USART4_PRESC[3:0]
     USART4->PRESC &= (~(0xF << 0));
     // 11. 设置串口的波特率为115200bps  USART4_BRR[15:0]                    
     USART4->BRR = 0x22B;                                                    
     // 12. 使能串口发送器  USART4_CR1[3] = 0x1                              
     USART4->CR1 |= (0x1 << 3);                                              
     // 13. 使能串口接收器  USART4_CR1[2] = 0x1                              
     USART4->CR1 |= (0x1 << 2);                                              
     // 14. 使能串口        USART4_CR1[0] = 0x1                              
     USART4->CR1 |= (0x1 << 0);                                              
 }                                                                           
                                                                             
 // 发送一个字节的函数                                                       
 void send_char(const char ch)                                           
 {                                                                           
     // 1. 判断发送寄存器是否为空,如果为空发送下一个字节的数据,            
     // 如果不为空等待发送数据寄存器为空。  USART4_ISR[7]                    
     while(!(USART4->ISR & (0x1 << 7)));                                     
     // 2. 发送数据,向发送数据寄存器中写入数据 USART4_TDR[7:0]              
     USART4->TDR = ch;                                                       
     if (ch == '\n')                                                         
         send_char('\r');                                                
 }                                                                           
                                                                             
 // 发送字符串的函数                                                         
 void send_string(const char *str)                                       
 {                                                                           
     // 1. 调用发送字符的函数一个一个的发送,字符串的结尾为‘/0’              
     while (*str != '\0') {                                                  
         send_char(*str);                                                
         str++;                                                              
     }                                                                       
 }                                                                           
                                                                             
 // 接收一个字符的函数                                                         
 char recv_char()                                                      
 {                                                                             
     char ch;                                                                  
     // 1. 判断接收数据寄存器中是否有有效的数据,如果有数据则读取数据          
     //   如果没有有效的数据,则等待有有效的数据之后在读取。 USART4_ISR[5]     
     while(!(USART4->ISR & (0x1 << 5)));                                       
     // 2. 从接收数据寄存器中读取数据到ch变量中   USART4_RDR[7:0]              
     ch = (char)USART4->RDR;                                                   
     return ch;                                                                
 }                                                                             
                                                                               
 // 接收一个字符串的函数                                                       
                                                                               
 char  buffer[LEN] = {0};                                                      
 char * recv_string(char str[])                                            
 {                                                                             
     // 1 一个字符一个字符的接收,接收到之后将数据存到buffer缓冲区中,        
     // 最多接收49,接收结束之后结尾需要补'\0'.                                
     // 接收的情况,一种是接收49个字符结束,另一种是按下enter键之后结束        
     // enter键是一个字符'\r'.                                                 
     unsigned int i;                                                           
     for (i = 0; i < LEN -1 ;i++) {                                            
         // 接收一个字符                                                       
         buffer[i] = recv_char();                                          
         // 在串口工具上回显接收到的字符                                       
         send_char(buffer[i]);                                             
         if (buffer[i] == '\r')    // 按下enter键结束字符串的接收              
             break;                                                            
     }                                                                         
     buffer[i] = '\0';   // 字符串的结尾补0                                    
     send_char('\n');                                                      
     return buffer;                                                            
 }  

 主函数部分

#include "uart4.h"

void delay_ms(unsigned int ms)

{

	int i,j;

	for(i = 0; i < ms;i++)

		for (j = 0; j < 1800; j++);

}



extern char  buffer[LEN];

int main()

{

	char *str;

	uart4_init();  // 串口的初始化

	while(1)

	{

	 



		// 接收一个字符串

		str = recv_string(buffer);

		send_string(str);

		send_char('\n'); 

	}

	return 0;

}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值