在蓝桥杯嵌入式开发板上共有两个串口,在进行串口配置前,我们先查看原理图,知道串口的收发引脚。
可以看到串口1(接收引脚PA10,发送引脚PA9),串口2(接收引脚PA3,发送引脚PA2),有两个串口供我们选择,但是串口1连接在ST3232ECTR芯片上,需要使用RS232接口来连接,而串口2可以直接通过USB下载线连接,为了使用方便,我们就选择串口2。
在进行串口配置前,我们还需要从固件库中添加几个文件。
stm32f10x_usart.c中包含了关于串口的库函数,misc.c中包含了关于中断的库函数。
选中Library,点击上图红框中的按钮,选择目录为:工程文件->Libraries->STM32F10x_StdPeriph_Driver->src
做完准备工作,接下来我们就可以开始配置串口了,配置代码如下:
void Usart_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //中断分组
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//开启串口2中断
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//接收引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
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);
USART_InitStructure.USART_BaudRate = 9600;//波特率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); //开启接收中断
USART_Cmd(USART2, ENABLE); //使能串口2
}
1.串口时钟使能,GPIO时钟使能:串口 是挂载在APB1下面的外设,所以使能函数为:RCC_APB1PeriphClockCmd();GPIO是挂载在APB2下的外设,使能函数为:RCC_APB2PeriphClockCmd()
2.初始化NVIC:串口接收需要使用到接收中断,所以需要配置中断。
3.GPIO端口模式设置:使用GPIO_Init()函数对接收发送引脚进行初始化
4. 串口参数初始化:使用函数USART_Init()进行配置即可,波特率可以根据题目要求进行调整。
5.使能串口
6.使能串口接收中断
关于串口的配置代码,在蓝桥杯提供的固件库中可以直接复制粘贴,做很小的修改就可以使用。
串口发送函数需要我们自己编写:
//函数功能:串口发送字符串
void USART_SendString(u8 *buf)
{
u8 i = 0;
while(buf[i]!='\0')
{
USART_SendData(USART2,buf[i]); //发送数据
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
i++;
}
}
函数的传入参数为指针类型, 一般使用数组或字符串作为参数。
USART_SendData()每次发送一个字节的数据到串口,接下来要检测这个数据是否已经被发送完成了,USART_FLAG_TXE是宏定义的数据发送完成标识符,其实就是判断SR寄存器中的TXE标志位(STM32_CN手册489页)
TXE:为0时没有发送完成,为1时发送完成
编写完串口发送函数,接下来就要写串口2的中断响应函数,建议写在stm32f10x_it.c文件中。
extern u8 RxCounter; //接收计数
extern u8 RxBuffer[20]; //接收缓存
extern u8 Rx_Flag; //接收标志
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
RxBuffer[RxCounter++] = USART_ReceiveData(USART2);
if(RxBuffer[RxCounter-1]=='\n')
{
Rx_Flag=1;
}
}
}
当串口2发生了相应的中断后,就会跳到该函数执行,中断响应哈数的名字是不能随便定义的,一般我们都遵循MDK定义的函数名。这些函数名字在启动文件startuo_stm32f10x_md.s中可以找到。
函数体里面通过函数:
USART_GetITStatus(USART2, USART_IT_RXNE) != RESET
判断是否接收中断,如果是串口接收中断,则执行下面的内容,记住要清楚中断标志:
USART_ClearITPendingBit(USART2,USART_IT_RXNE)
每次进入中断响应函数,只能接收一个字节的数据,所以我们要把数据放入接收缓存数组中。
接收完成的标志可以随意定义,我定义为‘\n’,把接收到'\n'之前的数据都放入接收缓存数组中,当接收到'\n'的时候就说明数据接收完毕,我们就把接收完成标志位置1。在其他文件中就可以处理串口接收的数据了。
只是做简单的测试,我就直接在main.c中处理数据,代码如下:
#include "stm32f10x.h"
#include "io.h"
#include "lcd.h"
#include "string.h"
u32 TimingDelay = 0;
void Delay_Ms(u32 nTime);
u8 RxCounter=0;
u8 RxBuffer[20];
u8 Rx_Flag=0;
//Main Body
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
Usart_Init();
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
while(1)
{
if(Rx_Flag) //接收完成
{
Rx_Flag=0;
LCD_DisplayStringLine(Line1,RxBuffer);
USART_SendString(RxBuffer);
RxCounter = 0;
memset((u8*)RxBuffer,0,20);//清除接收缓存
}
}
}
//1ms延时函数
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
在while中,当接收标志为1时,就进行串口数据的处理,这里做最简单的显示处理,并返回数据给上位机,串口接收数据处理完毕后还需要清空接收缓存数组,准备下一次接收。
memset()的作用是将某一块内存中的内容全部设置为指定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
第一个参数为指针或是数组,第二个参数是赋给第一个参数的值,第三个参数是第一个参数的长度。
把以上程序烧录进开发板,就可以看到相应现象。
在蓝桥杯提供文件中,提供了两个串口助手,推荐使用AccessPort
在上图界面做简单的配置即可,注意:串口连接到电脑会有两个COM端口,只有一个端口可以正常发送数据,另一个则会发送乱码。