STM32F1 配置串口1重映射端口(PB6、PB7)
初始化程序
void USART1_Init(u32 bound)
{
// 转换波特率
float temp;
u16 mantissa, fraction;
temp = SystemCoreClock/(16*bound); // 计算得USARTDIV,SystemCoreClock是时钟频率72000000
mantissa = temp; // USARTDIV整数部分
fraction = (temp-mantissa)*16; // 转换得USARTDIV小数部分
mantissa <<= 4; // 左移,空出4位小数部分
mantissa += fraction; // 组合BRR波特率值
// 启动时钟:GPIO USART AFIO
RCC->APB2ENR |= 1<<3; // 开启GPIOB时钟
RCC->APB2ENR |= 1<<14; // 开启USART1时钟
RCC->APB2ENR |= 1; // 开启AFIO时钟
// 初始化GPIO
AFIO->MAPR |= 1 << 2; // USART1重映射
GPIOB->CRL &= ~(0x000000ffu << 24);// 清空 USART1 IO口状态
GPIOB->CRL |= 0xB << 24; // PB6:TX 推挽复用
GPIOB->CRL |= 0x4 << 28; // PB7:RX 浮空输入
// 配置USART PA9:TX 10:RX;PB6:TX 7:RX
RCC->APB2RSTR |= 1<<14; // 复位USART1配置
RCC->APB2RSTR &= ~(1<<14); // 结束复位
USART1->CR1 |= 1<<13 | 1<<2 | 1<<3; // 使能、接收、发送
USART1->BRR = mantissa; // 波特率
USART2->CR2 &= ~(0x11<<12);// 1位停止位
// 中断
USART1->CR1 |= 1<<4 | 1<<5; // 开启空闲中断、接收中断
MY_NVIC_Init(3,3,USART1_IRQn,2); // 中断优先级
}
中断服务函数
#define BUFFERSIZE1 255 // 接收缓冲区大小
static uint8_t ubRx1Index = 0x00; // 作为接收缓冲区的计数器,相当于数组下标
static uint8_t U1_RX_BUF[BUFFERSIZE1]; // 作为接收缓冲区
//串口1中断服务程序
void USART1_IRQHandler(void)
{
// 触发接收中断
if(USART1->SR & (1<<5))
{
USART1->SR &= ~(0x01<<5); // 清除中断标志位
// 判断是否溢出缓冲区
if(ubRx1Index < BUFFERSIZE1)
{
// 搬运接收的消息
U1_RX_BUF[ubRx1Index++] = USART1->DR;
}
}
// 触发空闲中断
if(USART1->SR & (1<<4))
{
u8 temp;
temp = USART1->SR; temp = USART1->DR;// 清除中断标志位
U1_RX_BUF[ubRx1Index] = '\0'; //最后一个字节放'0’
printf("rec:%s\n", U1_RX_BUF);
memset(U1_RX_BUF, 0, sizeof(U1_RX_BUF));
ubRx1Index=0;
// u1_instruction_parse(); // 指令解析
}
}
讲解
1. 开启总线时钟
以下位置
2. 配置GPIO
2.1 开启重映射,AFIO_MAPR第2位置1
2.2 GPIO配置
PA9 :TX 推挽复用
PA10:RX 浮空输入
3. 串口配置
3.1状态寄存器
3.2数据寄存器
收、发数据存储。读取数据字节读取此寄存器,发送数据字节写入1字节到此寄存器。
3.3波特比率寄存器
具体计算过程看初始化代码
3.4控制寄存器1
配置串口使能、字长、发送、接收、接收中断、空闲中断。
3.5控制寄存器2
设置停止位。