STM32学习笔记-USART程序解释(原子) 联系客服

发布时间 : 星期一 文章STM32学习笔记-USART程序解释(原子)更新完毕开始阅读01e643d3aa00b52acfc7ca3b

USART程序分析

一 .H文件

#ifndef __USART_H #define __USART_H

#include #include \

extern u8 USART_RX_BUF[64]; //接收缓冲,最大63个字节.末字节为换行符 extern u8 USART_RX_STA; //接收状态标记

//如果想串口中断接收,请不要注释以下宏定义 //#define EN_USART1_RX 使能串口1接收 void uart_init(u32 pclk2,u32 bound);

#endif

解释:extern 作用域:如果整个工程由多个文件组成,在一个文件中想引用另外一个文件中已经定义的外部变量时,则只需在引用变量的文件中用extern关键字加以声明即可。可见,其作用域从一个文件扩展到多个文件了。

例子:

文件a.c的内容: #include

int BASE=2; //变量定义 int exe(int x); //外部函数提前声明 int main(int argc, char *agrv[]) {

int a=10;

printf(\ return 0; }

文件b.c的内容: #include

extern BASE; //外部变量声明 int exe(int x) {

int i; int ret=1;

for(i=0;i

ret*=BASE; }

return ret; }

利用gcc工具编译gcc a.c b.c –o demo,再运行./demo,结果为2^10

= 1024。其中,在a.c文件中定义BASE=2,在b.c中引用BASE时,需要用extern关键字声明其为外部变量,否则编译会找不到该变量。

二 .C文件

#include \#include \

//加入以下代码,支持printf函数,而不需要选择use MicroLIB #if 1

#pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE {

int handle;

/* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ };

/* FILE is typedef’ d in stdio.h. */ FILE __stdout;

//定义_sys_exit()以避免使用半主机模式 _sys_exit(int x) {

x = x; }

解释:一些支持的函数。

//重定义fputc函数

int fputc(int ch, FILE *f) {

while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; }

#endif

解释:最后这里就是定义printf的输出执行单元了,比如现在是串口1输出,如果你要串口2,那么设置USART1为USART2即可。

#ifdef EN_USART1_RX //如果使能了接收 //串口1中断服务程序

//注意,读取USARTx->SR能避免莫名其妙的错误

u8 USART_RX_BUF[64]; //接收缓冲,最大64个字节. //接收状态

//bit7,接收完成标志 //bit6,接收到0x0d

//bit5~0,接收到的有效字节数目

u8 USART_RX_STA=0; //接收状态标记

void USART1_IRQHandler(void) {

u8 res;

if(USART1->SR&(1<<5))//接收到数据 {

res=USART1->DR;

if((USART_RX_STA&0x80)==0)//接收未完成 {

if(USART_RX_STA&0x40)//接收到了0x0d {

if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x80; //接收完成了 }else //还没收到0X0D {

if(res==0x0d)USART_RX_STA|=0x40; else {

USART_RX_BUF[USART_RX_STA&0X3F]=res; USART_RX_STA++;

if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收

} } } } }

#endif 解释:

void USART1_IRQHandler(void)函数是一个串口1 中断响应函数,当串口1 发生了相应的中断后,就会跳到该函数执行。这里我们设计了一个小小的接收协议:通过这个函数,配合一个数组USART_RX_BUF[64],一个接收状态寄存器USART_RX_STA 实现对串口数据的接收管理。USART_RX_BUF 的最大值为64,也就是一次接收的数据最大不能超过64 个字节。USART_RX_STA 是一个接收状态寄存器其各的定义如下表:

设计思路如下:

当接收到从电脑发过来的数据,把接收到的数据保存在USART_RX_BUF 中,同时在接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(0X0D,0X0A)的第一个字节0X0D 时,计数器将不再增加,等待0X0A 的到来,而如果0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如果顺利接收到0X0A,则标记USART_RX_STA的第七位,这样完成一次接收,并等待该位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到0X0D,那么在接收数据超过64 个了,则会丢弃前面的数据,重新接收。

USART1->SR的第5位:

USART1->DR

通过上述分析,程序便可以理解。