STM32F10x 系列单片机中都包含了USART 模块,所谓USART,就是通用同步异步收发器。通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。它支持同步单向通信半双工单线通信,也支持LIN(局部互连网),智能卡协议IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。

  从前面的介绍可知USART模块功能非常的强大。这里我只简单讲讲如何用USART模块来实现标准EIA-232 串口通讯。

  用过单片机的人肯定都接触过串口,设置串口无非就是设置波特率、数据位、停止位、奇偶校验位。发送接收也就三种基本方式,轮询、中断和DMA。STM32F10x 的USART 模块也不过如此。所以我重点讲讲我在调试代码时犯得各种错误,那些很容易得到的代码就不详细的讲解了。

  首先说说我的硬件环境。还是那块神舟4号开发板,用的是串口2,对应的是USART2。默认情况下USART2是连接到IO端口A的,但是我这里需要将USART的管腿重定向到IO端口D上。具体的管腿的关系参见下表。这个表是从STM32参考手册上拷下来的。

  初始化USART的代码很简单。USART2 连接到APB1 总线上了,先要打开USART2的时钟,然后设置波特率一类的参数。

USART_InitTypeDef USART_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
USART_InitStructure.USART_BaudRate = ;
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 ); 

  这样设置了还不能使用。因为我们将USART2 重定向了。重定向操作需要写复用重映射和调试I/O配置寄存器(AFIO_MAPR)。GPIO_PinRemapConfig() 可以完成这项任务。

GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

  光这样操作还不够。STM32参考手册上有这么一段话:对寄存器AFIO_EVCR,AFIO_MAPR和AFIO_EXTICRX进行读写操作前,应当首先打开AFIO的时钟。参考第6.3.7节APB2外设时钟使能寄存器(RCC_APB2ENR)。

所以需要先打开AFIO的时钟。因此,USART2的重定向需要两步操作:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);

我原以为这样就能工作了,可是结果还是什么都没有输出。没办法只能继续研究。在读GPIO的相关章节时看到下图让我恍然大悟。

USART2的输入输出都是借用PD口管腿,PD 口的时钟却还没给。用到的几个IO 端口也没有设置相应的输入输出状态。在读到8.1.9 复用功能配置这一小节时发现了如下的表格。

按照上面给出的配置,写好程序:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

/* Configure USART Rx as input floating */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOD, &GPIO_InitStructure);

再次测试,一切正常。

发送一个字符的函数可以这么写:

void UART_PutChar(USART_TypeDef* USARTx, uint8_t Data)
{
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET ) {};
    USART_SendData (USARTx, Data);
}

这个函数可以手工优化一下,里面的两个函数调用都可以去掉,甚至于这个函数可以用汇编来实现或者写成inline 函数。不过这里只是个示例代码,没有考虑这些。

发送字符串的函数如下:

void UART_PutStr (USART_TypeDef* USARTx, uint8_t *str)
{
     != *str)
    {
        UART_PutChar(USARTx, *str);
        str++;
    }
}

上面串口初始化的代码可以放到一个函数中:

void USART2_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);

    /* Configure USART Tx as alternate function push-pull */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    /* Configure USART Rx as input floating */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    USART_InitStructure.USART_BaudRate = ;
    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_Cmd(USART2, ENABLE);
}

今天先写这么多。接收字符的函数与发送字符的函数差不多,但是这种轮询方式效率很低,不建议使用。下次写一篇介绍如何用中断方式发送接收串口数据,中断方式的效率会高很多。如果有时间再写一篇DMA方式发送接收数据的文章。

STM32F10x 学习笔记5(USART实现串口通讯 1)的更多相关文章

  1. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

  2. STM32F10x 学习笔记6(USART实现串口通讯 2)

    这次讲讲利用串口收发中断来进行串口通讯.STM32 上为每个串口分配了一个中断.也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断.程序需在中断处理函数中读取状态寄存器(USART_SR) ...

  3. ARM-LINUX学习笔记-(虚拟机linux串口终端以及USB程序下载,基于TQ2440)

    昨天安装了ssh服务之后今天在windows上用xshell登陆发现登录不上,原因是使用了virtualbox的NAT模式,在NAT模式下,客户机可以很方便地上网,但是想要链接宿主机就需要打开网络地址 ...

  4. STM32学习笔记(二)——串口控制LED

    开发板芯片:STM32F407ZGT6 PA9-USART1_TX,PA10-USART1_RX; PF9-LED0,PF10-LED1; 一.串口1配置过程(不使用串口中断): 1.使能时钟,包括G ...

  5. 串口(USART)通信-串口通讯协议简介

    物理层:规定通讯系统中具有机械.电子功能部分的特性,确保原始数据在物理媒体的传输.其实就是硬件部分. 协议层:协议层主要规定通讯逻辑,统一收发双方的数据打包.解包标准.其实就是软件部分. 简单来说物理 ...

  6. STM32学习笔记(五) USART异步串行口输入输出(轮询模式)

    学习是一个简单的过程,只要有善于发掘的眼睛,总能学到新知识,然而如何坚持不懈的学习却很困难,对我亦如此,生活中有太多的诱惑,最后只想说一句勿忘初心.闲话不多扯,本篇讲诉的是异步串行口的输入输出,串口在 ...

  7. 【STM32学习笔记】USART 硬件流控

    流控的概念源于 RS232 这个标准,在 RS232 标准里面包含了串口.流控的定义.大家一定了解,RS232 中的"RS"是Recommend Standard 的缩写,即&qu ...

  8. CC2540开发板学习笔记(五)——串口通信

    (一)串口发送 一.实验现象: 开发板实现功能发送 二.实验过程 1.PL2303 USB转串口电路图 2.串口发送 (1)查看用户手册有: UART0 对应的外部设备 IO 引脚关系为: P0_2 ...

  9. Arduino101学习笔记(十)—— 串口通信

    //打开串口 Serial.begin(); //获取串口上可读取的数据的字节数.该数据是指已经到达并存储在接收缓存(共有64字节)中 Serial.available(); //读串口数据,串口上第 ...

随机推荐

  1. 海思android4.4 SDK编译Latin输入法

    原来的HiSTBAndroidV500R001C01SPC020\device\hisilicon\bigfish\packages\apps\HiLatinIME\Android.mk内容例如以下: ...

  2. android 54 播放音视频

    mainActivity: package com.sxt.day07_09; import java.util.ArrayList; import java.util.HashMap; import ...

  3. IOS-AssetsLibrary(相册)框架介绍

    AssetsLibrary框架介绍: AssetsLibrary框架包含了ALAssetsLibrary,ALAssetsGroup,ALAsset,ALAssetsFilter,ALAssetRep ...

  4. 基于Html5的兼容所有主流浏览器的在线视频播放器videoJs

    在一个新的项目上需要实现在线视频播放,原本打算借助优酷的视频存储和播放,但是发现这个需要用户注册优酷账户,严重影响用户体验,于是这个方案被毙掉了.于是开始了自己开发一个在线播放器的想法,当然尽量使用已 ...

  5. UVA - 11572 Unique Snowflakes

    /* STLsort离散化==T 手工sort离散化==T map在线==T map离线处理c==A 240ms */ #include<cstdio> #include<map&g ...

  6. 动态拼接 sql的时候 里面 如果有变量的话 按上面的方式进行处理

    set @Sql_Sql = N' select top 1 @m_zw=zw,@m_zh=temp from ket where zd=''ddd'' ' print @Sql_Sql EXEC s ...

  7. 知识点摸清 - - position属性值之relative与absolute

    两者共同特点是: 改变文档流 激活元素left.top.right.bottom.z-index属性 让元素”浮起来“,z-index>0 不同的是: 1.position:relative 会 ...

  8. PageMapAdapter MapAdapter (续webServices)

    public class PageMapAdapter extends XmlAdapter<PageMapConverter, IPage<Map<String, Object&g ...

  9. power desinger 学习笔记三<批量执行sql语句>

    使用sql脚本导入表结构,直接 附带表的 约束.列的注释.真的可以哦 sql语句如下: create table test01 (   ID                   VARCHAR2(10 ...

  10. Objective-C消息机制的原理

    http://desheng.me/2012/03/31/objective-c%E6%B6%88%E6%81%AF%E6%9C%BA%E5%88%B6%E7%9A%84%E5%8E%9F%E7%90 ...