就像前面提到的,我用的板子是一款stm32f107系列的板子,在这块板子上,已经开发出了一套比较成熟的库函数,这也就意味着你可以不用直接去操作存储器来实现某些功能。比方说对于USART来说可以直接通过void STM_EVAL_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct)实现对usart始终初始化,复用端口的定义和设置,usart功能的配置及使能。那么后面的寄存器是怎么操作的呢?这是我比较关心的问题,为了能更详细的了解这些东西,我选择了自己通过对那些寄存器操作来实现USART串口打印功能。

首先我们要知道做USART(我使用的是默认端口USART2)的一些基本配置:

  1. 使用pd5做发送端口,使用PD6做接收端口。通过阅读相关的文档可以知道usart2的默认输入输出端口是PA2和PA3 ,但是这两个端口已经被许多功能所使用,于是我们使用PD5,pd6作为输入输出端口,这里就要使用到端口的复用(AFIO)
  2. 波特率设置为115200
  3. 字长设置为8B
  4. 模式为发送/接收
  5. 停止位为1位
  6. 无错误校验

接下来就是跟着要完成的东西的顺序,开始配置寄存器。

1.首先第一个端口复用功能。需要使用到AFIO功能的RMAP寄存器。如图,

那么RMAP的配置应该为0x00000008;

2.设置pd5,pd6的端口配置,这里和之前做过的LED灯的配置差不多,只不过两个端口的模式有些不同,pD5端口的模式需要配置为:复用推免输出,50MHz,PD6的配置为浮空输入

3.设置波特率要通过BRR寄存器,DIV_Mantissa[11:0]是整数部分,DIV_Fraction[3:0]是小数部分。

计算公式如下

Tx/Rx波特率就是我们输入的115200,我们需要的结果是通过计算得到的,具体的计算方法将会在下面详述。

4.字长为8位,模式为发送接收,这些都可以在CR1 寄存器中设置。M为0表示字长为8,为1表示字长为9,PCE为1表示有错误校验,TE和RE分别为1.这里有一个需要特别注意的地方就是UE代表USART EnABLE就是usart功能的使能,将他置为1才可以使用usart功能。表示可以接受可以发送。即CR1的配置为0x0000200C

5.在CR2中Stop[1:0]中设置停止位,00为1位,01为0.5位,10为2位,11为1.5位

则CR2的配置为0x00000000

到现在为止,我们已经完成了对USART通信的基本原理叙述完毕,并且完成基础配置,剩下的就是用程序去实现功能。接下来就是用程序去实现。

1.引用stm32f10x.h文件,因为这个文件中包含了我们要用到的对GPIOD,USART2,AFIO,RCC寄存器的描述GPIO_TypeDef,USART_TypeDef,AFIO_TypeDef,RCC_TypeDef。

2.初始化GPIOD,USART2,AFIO的时钟,通过查看手册,可以知道USART2在APB1总线上,AFIO和GPIOD在APB2总线上。于是初始化时钟就是,

/*初始化USART2时钟*/

RCC->APB1ENR|=RCC_APB1Periph_USART2;
/*初始化GPIOD的RCC时钟*/
/*初始化AFIO的rcc时钟*/
RCC->APB2ENR|=RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO;

2.usart2的功能重映射

//usart2重映射
AFIO->MAPR|=0x00000008 ;//GPIO_Remap_USART2

3.pd5,pd6管脚的设置

GPIOD->CRL&=0x00000FFF;
GPIOD->CRL|=0x01E00000;

4.USART2的使能,字长为8,可接受发送,停止位为1

//字长为8,可接收,可发射
USART2->CR1|=0x0000000c; USART2->CR2|=0x00000000;

5.波特率的设置

从上面的公式可以得知,BRR中的最终的DIV=fclk/(波特率*16),然后得到一个实数,其中,他的整数部分写入到BRR的DIV_Man提撒,小数部分*16(取整)的值放入到DIV_Fraction中。于是

/*获取RCC时钟状态*/
RCC_GetClocksFreq(&RCC_ClocksStatus);
/*获取flck1的频率*/
apbclock=RCC_ClocksStatus.PCLK1_Frequency;
/*获取100倍的DIV*/
integerdivider=(*apbclock)/(*);
/*获取DIV的整数部分并且左移四位*/
tmpreg=(integerdivider/)<<;
/*获取小数部分的100值*/
fractionaldivider=integerdivider-(*(tmpreg>>));
/*存放整数的值*/
integerdivider=tmpreg;
/*小数值的100倍乘16,+50(完成四舍五入的功能),然后除100得到小数值,&0x0f防止溢出*/
fractionaldivider=(((fractionaldivider*)+)/)&(uint8_t)0x0f;
/*将整数和小数写入到BRR寄存器*/
USART2->BRR|=integerdivider|fractionaldivider;

6.配置完成,现在开始输入内容,这里为了满足不同的输入要求,定义了不同的输出函数

/*!< STM32F10x Standard Peripheral Library old types (maintained for legacy purpose) */

#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

7.每次调用Printf函数的时候,将输出到在屏幕的数据流改到串口,调用PUTCHAR_PROTOTYPE函数

PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USARTx->DR = (Data & (uint16_t)0x01FF); /* Loop until the end of transmission */
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
{} return ch;
}

到这里基本完成了USAT的串口打印的功能。

直接对寄存器操作,实现usart的串口输出寄存器的配置的更多相关文章

  1. STM32串口寄存器操作(转)

    源:STM32串口寄存器操作 //USART.C /************************************************************************** ...

  2. STM32 下的库函数和寄存器操作比较

    以 led闪烁中的flashLed函数例子: 库函数操作简单,但是效率不如寄存器操作的高: 寄存器操作很复杂,因为要熟悉上百个寄存器,但是程序效率很高 /**下面是通过直接操作库函数的方式实现IO控制 ...

  3. STM8L外部中断 为何 死循环 寄存器操作

    STM8L 系列单片机是 ST公司推出的低功耗单片机,与STM8S系列相比功耗降低了很多,但内部结构也删减了很多,使用时一定要仔细阅读手册.  这是第一次使用STM8,实现功能不是很复杂就没想研究库函 ...

  4. I.MX6 AR8031 寄存器操作

    /*************************************************************************** * I.MX6 AR8031 寄存器操作 * ...

  5. STM32---初学者用库函数好还是直接对寄存器操作比较好

    引用:http://blog.csdn.net/u010349006/article/details/416 首先,两个都是C语言.从51过渡过来的话,就先说寄存器操作.每个MCU都有自己的寄存器,5 ...

  6. tiny4412 串口驱动分析四 --- 修改默认的串口输出

    作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...

  7. STM32串口程序的一般配置方法

    #include "stm32f10x.h" /************************************************ 该程序讲解串口程序的一般配置方法: ...

  8. Minicom串口工具安装及配置

    Minicom串口工具安装及配置 1. 简述 嵌入式开发多采用串口线连接电脑进行开发及调试. 2 安装及配置串口工具(以Minicom为例) Tiny4412开发板提供的有RS232电平的DB9公头接 ...

  9. 串口调试利器--Minicom配置及使用详解.md

    因为现在电脑基本不配备串行接口,所以,usb转串口成为硬件调试时的必然选择.目前知道的,PL2303的驱动是有的,在dev下的名称是ttyUSB*. Minicom,是Linux下应用比较广泛的串口软 ...

随机推荐

  1. PHPCMS数据筛选功能实现

    第一步:添加模型字段,这个模型可以是官方的,也可以是你自定义的模型,以单选字段形式添加就好了; 第二步:就是添加栏目和内容: 第三步:模板如下,照着改就好了. {template "cont ...

  2. Linux环境变量(小马哥推荐)

    /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d目录的配置文件中搜集shell的设置. /etc/bashrc:为每一 ...

  3. html5 canvas 移动小方块

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. SharePoint咨询师之路:备份和恢复系列二 - 备份服务器场

    本系列包括: 备份服务器场和配置 备份web和服务应用程序 备份内容数据库 备份网站集 备份自定义项 根据“SharePoint咨询师之路:备份和恢复系列--制定备份计划”我们制定了一下备份计划如下: ...

  5. [翻译]创建ASP.NET WebApi RESTful 服务(9)

    一旦成功的发布API后,使用者将依赖于你所提供的服务.但是变更总是无法避免的,因此谨慎的制定ASP.NET Web API的版本策略就变得非常重要.一般来说,新的功能需要无缝的接入,有时新老版本需要并 ...

  6. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  7. jQuery在updatepanel中使用造成内存泄露

    wijmo用户反馈了一个RadialGauge控件内存泄露的bug,采用chrome监控内存使用情况,发现明显的内存泄露,在前面的文章中我就发现了jQuery内存泄露的问题,这次再次发现此问题,自然就 ...

  8. MySQL重置密码(OSX)

    1.停止MySQL的服务 sudo /Library/StartupItems/MySQLCOM/MySQLCOM stop   2.cd /usr/local/mysql/bin ./mysqld_ ...

  9. jsp页面加载readyState的五种状态根据我们状态添加进度条

    这段代码放在页面最下面 原文如下: document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法. function subSomet ...

  10. Spring REST实践之客户端和测试

    RestTemplate 可参考spring实战来写这部分. RestTemplate免于编写乏味的样板代码,RestTemplate定义了33个与REST资源交互的方法,涵盖了HTTP动作的各种形式 ...