#include "usart.h"
/* 初始化串口1 */
void usart1_init(void)
{
/* 1 开启时钟 1<<14 = 0x4000*/
/* 1.1 开启 usart1 时钟 */
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
/* 1.2 开启 GPIOA 时钟 */
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
/* 2 配置引脚: PA9(Tx)和PA10(Rx) */
/* 2.1 PA9 配置为推挽输出 mode=11 cnf=10*/
GPIOA->CRH |= (GPIO_CRH_MODE9 | GPIO_CRH_CNF9_1);
/* 2.2 PA10 配置为浮空输入 */
GPIOA->CRH |= GPIO_CRH_CNF10_0;
/* 3 配置波特率为:115200*/
USART1->BRR = 0x271;
/* 4 使能usart1的发送和接收 */
USART1->CR1 |= (USART_CR1_TE | USART_CR1_RE);
/* 5 使能usart1接收中断 */
USART1->CR1 |= USART_CR1_RXNEIE;
/* 6. 使能空闲中断 */
USART1->CR1 |= USART_CR1_IDLEIE; /* 空闲中断使能 */
/* 7. 设置NVIC */
NVIC_SetPriorityGrouping(4);
NVIC_SetPriority(USART1_IRQn, 2);
NVIC_EnableIRQ(USART1_IRQn);
/* 8.使能usart1 */
USART1->CR1 |= USART_CR1_UE;
}
/*
通过串口1发送数据:
参数1:要发送的数据
参数2:要发送的数据的长度
*/
void send_string(uint8_t *str, uint32_t len)
{
uint32_t i;
for (i = 0; i < len; i++)
{
send_char(str[i]);
}
}
/*
向串口1发送一个字符
*/
void send_char(uint8_t c)
{
/* 等待发送缓冲区为空。 SR_TXE为1表示已经移到移位寄存器, 0表示还没有 */
while ((USART1->SR & USART_SR_TXE) == 0)
{
}
/* 把要发送的数据写入到数据寄存器 */
USART1->DR = c;
}
/* 中断服务函数: 利用空闲中断接收变长数据 */
uint8_t buff[1000]; /* 缓存就收到的字节数据 */
uint8_t count = 0; /* 对接收到的字节计数 */
void USART1_IRQHandler(void)
{
if (USART1->SR & USART_SR_RXNE) // 接收到一个字节
{
uint8_t c = USART1->DR & 0xff;
buff[count] = c; // 把数据存入到缓冲区
count++; /* 计数加1 */
}
else if (USART1->SR & USART_SR_IDLE) // 产生了空闲中断
{
/* 先清除空闲中断位: 先读SR,再读DR */
USART1->SR;
USART1->DR;
send_string(buff, count); /* 发送给接收端 */
count = 0; /* 计数清除,用于下一个变长数据的接收 */
}
}
STM32使用串口接收变长数据(利用空闲中断)---寄存器版
于 2023-12-24 17:29:27 首次发布