GD32H759是一款功能丰富的微控制器,它支持多个通信接口,包括通用同步异步收发器(USART)。根据您提供的信息,GD32H759拥有最多8个USART,并且这些USART被挂载在不同的APB(先进外设总线)上。
- USART0 和 USART5:这两个USART接口被挂载在APB2总线上。APB2总线通常用于连接高速外设,因为它的时钟频率较高。因此,USART0和USART5可能具有更高的数据传输速率或更低的延迟,适用于需要高性能通信的应用。
- 其余6个USART:除了USART0和USART5之外,其余6个USART接口被挂载在APB1总线上。APB1总线通常用于连接低速或中速外设。虽然它们的性能可能不如APB2总线上的外设,但APB1总线上的外设通常具有更低的功耗,适用于对功耗有严格要求的应用。
下面开始。
原理图:要知道串口是哪几个脚才好办事。
查看规格书,了解一下PA9,PA10的引脚功能:
代码:
/**
* @brief 将一个字符写入文件(这里实际上是发送到USART0)
*
* 此函数模拟了标准C库中的fputc函数的行为,但实际上是通过USART0接口发送字符。
*
* @param ch 要发送的字符
* @param f 文件指针(在此实现中未使用,因为直接发送到USART0)
*
* @return 返回发送的字符
*/
int fputc(int ch, FILE *f)
{
// 将字符转换为uint8_t类型,并通过usart0_data_transmit函数发送
usart0_data_transmit((uint8_t)ch);
// 等待USART0的发送缓冲区为空,以确保字符已发送
while(RESET == ((LU_USART0_STAT >>6) & 0x01));
// 返回发送的字符
return ch;
}
复制代码uint32_t uclk = 0U; // 定义一个32位无符号整数变量uclk,并初始化为0
// 打开USART0总线时钟
LU_RCU_APB2EN |= ((uint32_t)0x01 << 4); // 将APB2总线上的USART0时钟使能位设置为1
// 使能GPIOA的时钟
LU_RCU_AHB4EN |= (uint32_t)0x01 << 0; // 将GPIOA的时钟使能位设置为1
// 配置GPIOA9、GPIOA10的复用模式为高速推挽输出
LU_GPIOA_AFSEL1 &= ~((uint32_t)0b1111 << 4); // 清除GPIOA9的复用功能选择位
LU_GPIOA_AFSEL1 |= ((uint32_t)0b0111 << 4); // 设置GPIOA9的复用功能为USART0_TX
LU_GPIOA_AFSEL1 &= ~((uint32_t)0b1111 << 8); // 清除GPIOA10的复用功能选择位
LU_GPIOA_AFSEL1 |= ((uint32_t)0b0111 << 8); // 设置GPIOA10的复用功能为USART0_RX
// 配置GPIOA9和GPIOA10为推挽输出模式,最大输出速度60MHz,上拉模式
LU_GPIOA_CTL &= ~((uint32_t)0b11 << (2U * 9)); // 清除GPIOA9的控制位
LU_GPIOA_CTL |= ((uint32_t)0b10 << (2U * 9)); // 设置GPIOA9为推挽输出模式
LU_GPIOA_OMODE &= ~((uint32_t)0x01 << 9); // 清除GPIOA9的输出模式位(设置为0表示推挽输出)
LU_GPIOA_OSPD &= ~((uint32_t)0b11 << (2U * 9)); // 清除GPIOA9的输出速度控制位
LU_GPIOA_OSPD |= ((uint32_t)0b01 << (2U * 9)); // 设置GPIOA9的输出速度为最大速度60MHz
LU_GPIOA_PUD &= ~((uint32_t)0b11 << (2U * 9)); // 清除GPIOA9的上拉/下拉控制位
LU_GPIOA_PUD |= ((uint32_t)0b01 << (2U * 9)); // 设置GPIOA9为上拉模式
// 重复上述配置过程,但这次是配置GPIOA10
LU_GPIOA_CTL &= ~((uint32_t)0b11 << (2U * 10)); // 清除GPIOA10的控制位
LU_GPIOA_CTL |= ((uint32_t)0b10 << (2U * 9)); // 这里应该是一个错误,应该是 |= ((uint32_t)0b10 << (2U * 10))
LU_GPIOA_OSPD &= ~((uint32_t)0b11 << (2U * 9)); // 清除GPIOA10的输出速度控制位,这里同样有错误,应为(2U * 10)
LU_GPIOA_OSPD |= ((uint32_t)0b01 << (2U * 9)); // 设置GPIOA10的输出速度为最大速度60MHz,这里也有错误,应为(2U * 10)
LU_GPIOA_PUD &= ~((uint32_t)0b11 << (2U * 9)); // 清除GPIOA10的上拉/下拉控制位,这里也有错误,应为(2U * 10)
LU_GPIOA_PUD |= ((uint32_t)0b01 << (2U * 9)); // 设置GPIOA10为上拉模式,这里也有错误,应为(2U * 10)
// 开始配置USART0
// 关闭在休眠模式下的USART0时钟使能,由软件置位或复位
// USART0SPEN位用于控制休眠模式下USART0的时钟是否使能
LU_RCU_ADDAPB2SPEN |= ((uint32_t)0x01 << 4U); // 启用休眠模式下的USART0时钟
复制代码// 清除USART_CTL1的STB位(停止位长度)
LU_USART0_CTL1 &= ~((uint32_t)0b11 << 12); // 清除第13和12位,用于设置停止位长度
LU_USART0_CTL1 |= ((uint32_t)0b00 << 12); // 设置停止位长度为1位(00表示1个停止位)
// 清除USART_CTL0的第9和第10位(校验位控制)
LU_USART0_CTL0 &= ~(((uint32_t)0x01 << 9) | (uint32_t)0x01 << 10); // 无校验位
LU_USART0_CTL0 |= (((uint32_t)0x00 << 9) | (uint32_t)0x00 << 10); // 不启用校验位
// 设置波特率,这里波特率被设置为115200,总线频率为300MHz
// 注意:波特率的计算通常涉及多个寄存器位和时钟源,这里直接写入了计算好的值
LU_USART0_BAUD = 0x00000A2C;
// 清除USART_CTL0的REN位(接收使能)
LU_USART0_CTL0 &= ~((uint32_t)0x01 << 2); // 先清除REN位
LU_USART0_CTL0 |= ((uint32_t)0x01 << 2); // 启用接收功能
// 注意:这里似乎有一个重复的代码块,可能是错误或者复制粘贴时的疏忽
LU_USART0_CTL0 &= ~((uint32_t)0x01 << 3); // 清除第3位(可能是另一个功能位,但注释有误,应为REN位)
LU_USART0_CTL0 |= ((uint32_t)0x01 << 3); // 启用接收功能(这里同样有误,因为REN位是第2位)
LU_USART0_CTL0 |= 0x01; // 启用USART0(通常这一位用于启用整个USART模块)
// 注释:这里缺少对LU_USART0_CTL0 |= 0x01; 这行代码的注释
// 应该是启用USART0传输或者类似的功能
复制代码输出结果:
printf("\r\n GD32H759I \r\n\r\n");
printf("\r\n eet-china \r\n\r\n");
复制代码