参考资料:
蓝桥杯嵌入式备赛手册
蓝桥杯嵌入式开发经验分享(5.串口的配置)
总目录:目录
硬件连接
- 首先看线路板介绍
- USART1连接了RS232的DB9接口,UART2连接外部串行接口,即可以直接使用UART2与上位机通信(也不用专门串口线了,我们的程序下载线就能用)
- 查看连接关系
- 查看电路原理图,找到连接串口的引脚,可以看到,连接到了PA口
uart.c
- 库函数在STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Interrupt中
- 以及,要加上时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- 把接收引脚改成PA3,发送引脚改成PA2,中断IRQChannel改成USART2_IRQn,再使能对应的时钟即可
- "stm32f10x_it.c"中接收中断函数相关代码:
- 串口的接收需要用到串口中断,首先我们需要定义了一些变量:
RXBUF
是用来储存串口的接收数据的,RXOVER
为接收串口结束标志位,RXCUNT
为串口接收计数值
这一段中断函数的改写理解后考虑背下来
u8 buffer_u2[20]={"\0"}, cnt=0;
void USART2_IRQHandler(void)
{
u8 data;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
buffer_u2[cnt++] = USART_ReceiveData(USART2);
}
}
- 串口的发送函数
void SendString(char *str)
{
while(*str)
{
USART_SendData(USART2,*str++);
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
}
- 注意,要把misc.c和 stm32f10x_usart.c文件也加进来(路径:Libraries->STM32F10x_StdPeriph_Driver->src)
- uart.c如下:
#include "uart.h"
void uart_Init()
{
//串口/GPIO/中断结构体
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
//时钟使能,能背下来就背,背不下来之前的库函数里面也有,自己学会改写
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//串口配置,注意后面用串口调试助手时,里面的设置要和这里一致
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
//这句不能写!因为是“发送寄存器空”的中断,所以发完字符串后必须关掉,否则只要空了,就会进中断
//因此,只用写上一句RXNE的即可
//USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
USART_Cmd(USART2, ENABLE);
/* Configure USARTy Rx as input floating */
//RX为浮空输入
//RX2连接PA3引脚,因此把原句中USARTy_RxPin改成具体引脚:GPIO_Pin_3
//GPIO_InitStructure.GPIO_Pin = USARTy_RxPin;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USARTy Tx as alternate function push-pull */
//Tx为推挽复用
//TX2连接PA2引脚,因此把原句中USARTy_RxPin改成具体引脚:GPIO_Pin_2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//上面GPIO这一段直接复制,改改引脚即可
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
//注:这个的配置库函数没有,但是EXIT中断那边有,所以还是写上
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
u8 buffer_u2[20]={"\0"}, cnt=0;
void USART2_IRQHandler(void)
{
u8 data;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
buffer_u2[cnt++] = USART_ReceiveData(USART2);
}
}
void SendString(char *str)
{
while(*str)
{
USART_SendData(USART2,*str++);
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
}
uart.h
#include "stm32f10x.h"
void uart_Init(void);
void SendString(char *str);
main.c
#include "stm32f10x.h"
#include "uart.h"
#include "lcd.h"
u32 TimingDelay = 0;
extern u8 buffer_u2[20];
void Delay_Ms(u32 nTime);
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
uart_Init();
while(1)
{
SendString("test:string");
LCD_DisplayStringLine(Line4,buffer_u2);
Delay_Ms(500);
}
}
//
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
串口调试
- WIN+R键运行,输入devmgmt.msc打开设备管理器,查看USART是哪个串口
- 推荐使用官方给的AccessPort.exe作为串口调试助手
- 根据查询的串口选择,注意波特率为9600(uart.c初始化中写了)
- 发现串口调试助手可以接受到我们写的语句
- 同样,利用串口调试助手可以发送数据到LCD屏