收藏 分销(赏)

STM学习重点笔记USART程序解释原子.docx

上传人:天**** 文档编号:3027551 上传时间:2024-06-13 格式:DOCX 页数:10 大小:219.41KB 下载积分:8 金币
下载 相关 举报
STM学习重点笔记USART程序解释原子.docx_第1页
第1页 / 共10页
STM学习重点笔记USART程序解释原子.docx_第2页
第2页 / 共10页


点击查看更多>>
资源描述
USART程序分析 一 .H文献 #ifndef __USART_H #define __USART_H #include <stm32f10x_lib.h> #include "stdio.h" 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 <stdio.h> int BASE=2; //变量定义 int exe(int x); //外部函数提前声明 int main(int argc,char *agrv[]) { int a=10; printf("%d^%d = %d\n",BASE,a,exe(a)); return 0; } 文献b.c内容: #include <stdio.h> extern BASE; //外部变量声明 int exe(int x) { int i; int ret=1; for(i=0;i<x;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 "sys.h" #include "usart.h" //加入如下代码,支持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 通过上述分析,程序便可以理解。 //初始化IO 串口1 //pclk2:PCLK2时钟频率(Mhz) //bound:波特率 //CHECK OK //091209 void uart_init(u32 pclk2,u32 bound) { float temp; u16 mantissa; u16 fraction; temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV mantissa=temp; //得到整数某些 fraction=(temp-mantissa)*16;//得到小数某些 mantissa<<=4; mantissa+=fraction; RCC->APB2ENR|=1<<2; //使能PORTA口时钟 RCC->APB2ENR|=1<<14; //使能串口时钟 GPIOA->CRH&=0XFFFFF00F; GPIOA->CRH|=0X000008B0;//IO状态设立 RCC->APB2RSTR|=1<<14; //复位串口1 RCC->APB2RSTR&=~(1<<14);//停止复位 //波特率设立 USART1->BRR=mantissa;// 波特率设立 USART1->CR1|=0X200C; //1位停止,无校验位. #ifdef EN_USART1_RX //如果使能了接受 //使能接受中断 USART1->CR1|=1<<8; //PE中断使能 USART1->CR1|=1<<5; //接受缓冲区非空中断使能 MY_NVIC_Init(2,3,USART1_IRQChannel,2);//组2,最低优先级 #endif } 解释:STM32每个串口均有一种自己独立波特率寄存器USART_BRR,通过设立该寄存器就可以达到配备不同波特率目。其各位描述如下图所示: 前面提到STM32分数波特率概念,其实就是在这个寄存器(USART_BRR)里面体现。USART_BRR最低4位(位[3:0])用来存储小数某些DIV_Fraction,紧接着12位(位[15:4])用来存储整数某些DIV_Mantissa,最高16位未使用。 这里,咱们简朴简介一下波特率计算,STM32串口波特率计算公式如下: 上式中,是给串口时钟(PCLK1用于USART2、3、4、5,PCLK2用于USART1);USARTDIV是一种无符号定点数。咱们只要得到USARTDIV值,就可以得到串口波特率寄存器USART1->BRR值,反过来,咱们得到USART1->BRR值,也可以推导出USARTDIV值。但咱们更关怀是如何从USARTDIV值得到USART_BRR值,由于普通咱们懂得是波特率,和PCLKx时钟,规定就是USART_BRR值。 下面咱们来简介如何通过USARTDIV得到串口USART_BRR寄存器值。假设咱们串口1要设立为9600波特率,而PCLK2时钟为72M。这样,咱们依照上面公式有: USARTDIV=7000/(9600*16)=468.75 那么得到: DIV_Fraction=16*0.75=12=0X0C; DIV_Mantissa= 468=0X1D4; 这样,咱们就得到了USART1->BRR值为0X1D4C。只要设立串口1BRR寄存器值为 0X1D4C就可以得到9600波特率。 固然,并不是任何条件下都可以随便设立串口波特率,在某些波特率和PCLK2频率下,还是会存在误差,详细可以参照《STM32参照手册》第525页表176。 接下来,咱们就可以初始化串口了,需要注意是这里初始化串口是按8位数据格式,1位停止位,无奇偶校验位。 RCC->APB2ENR|=1<<14; //使能串口时钟 寄存器位如下: 位14 USART1EN:USART1时钟使能 由软件置’1’或清’0’ 0:USART1时钟关闭; 1:USART1时钟启动。 GPIOA->CRH&=0XFFFFF00F; GPIOA->CRH|=0X000008B0;//IO状态设立 IO设立成上啦或下拉模式,一种输入一种输出。 RCC->APB2RSTR|=1<<14; //复位串口1 RCC->APB2RSTR&=~(1<<14);//停止复位 详细查看RCC->APB2RSTR寄存器定义。 USART1->CR1|=0X200C; //1位停止,无校验位. USART1->CR1|=1<<8; //PE中断使能 USART1->CR1|=1<<5; //接受缓冲区非空中断使能 参照控制寄存器1(USART_CR1) 参照手册496页。 MY_NVIC_Init(2,3,USART1_IRQChannel,2);//组2,最低优先级 USART1_IRQChannel是中断编号。 //#define USART1_IRQChannel ((u8)0x25) /* USART1 global Interrupt */
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服