STM32F10x USART串口映射功能实现串口通讯 485初始化

发布者:心连心意最新更新时间:2018-08-12 来源: eefocus关键字:STM32F10x  USART  串口映射  串口通讯  485初始化 手机看文章 扫描二维码
随时随地手机看文章

篇文章很有用!新手不要自以为是,STM32串口管脚重映射小样你会吗???


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 = 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 );   


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


[cpp] view plain copy

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)  

{  

    while (0 != *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 = 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_Cmd(USART2, ENABLE);  

}  


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


关键字:STM32F10x  USART  串口映射  串口通讯  485初始化 引用地址:STM32F10x USART串口映射功能实现串口通讯 485初始化

上一篇:STM32 UART/USART初始化时钟使能
下一篇:stm32 485串口数据的收发

推荐阅读最新更新时间:2024-03-16 16:10

ATMEGA16单片机usart通信(主从多机通信)proteus仿真与源码
部分单片机源程序如下: /***************************************************** This program was produced by the CodeWizardAVR V2.05.1b Evaluation Automatic Program Generator ?Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l. Project : Version : Date : 2017/12/21 Author : Freeware, for evaluation and non-commercial use only
[单片机]
ATMEGA16单片机<font color='red'>usart</font>通信(主从多机通信)proteus仿真与源码
STM32 USART库函数介绍2
USART_Cmd函数的功能是使能或失能USART串口外设。 例:使能USART1 USART_Cmd(USART1,ENABLE); USART_ITConfig函数的功能是使能或者失能指定的USART串口中断。 USART_IT_PE 奇偶错误中断 USART_IT_TXE 发送中断 USART_IT_TC 传输完成中断 USART_IT_RXNE 接收中断 USART_IT_IDLE 空闲总线中断 USART_IT_LBD LIN中断检测中断 USART_IT_CTS CTS中断 USART_IT_ERR 错误中断 例:使能USART1接收中断 USART_Cmd(USAR
[单片机]
实现STM32中USART的DMA
对于没玩过DMA 的朋友,这里简单说一下DMA,用自己的语言说吧,那就是,从某个位置 传输数据到某个位置,如果不用DMA,那要CPU参与操作,一个字节一个字节地搬,效率高 点的,就一个字一个字地搬.但当你用了DMA 后,那就是只需要设置:A.从哪里开始搬; B, 搬到哪里去;C以字节方式搬还是半字还是字;D:一共搬多少个.之后,启动DMA.CPU内部 就会开始搬数据了,整个搬数据的过程都不需要指令的参与,唯一要做的,就是检测什么时 候搬完.你可以扫描寄存器,也可以用中断.这里,我使用了中断. 具体设置功能看注释就可以明白了.注意一点就是,有一个设置: DMA_InitStructure.DMA_PeripheralInc = DMA
[单片机]
STM32F207Cube库函数USART中断接收
USART初始化部分就不介绍了,直接看官方给的例程就能知道,现在主要将自己在学习过程中遇到的问题以及解决方法记录一下。 首先,如果使用了串口接收中断,就需要在初始化中打开中断以及设定中断优先级等常规操作。 HAL_UART_Init(&UartHandle) - HAL_UART_MspInit(huart)- /* Set Interrupt Group Priority */ HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1); /* Enable the TIMx global Interrupt */ HAL_NVIC_EnableIRQ(USARTx_IRQn); 然后需要调用串口接收终端初
[单片机]
基于PIC16F73的下位机串口通讯设计备忘
基本功能要求: 接收上位机所给的设定命令,并根据命令进行相应的操作,同时下位机将采集到的信息上传给上位机处理显示等。 具体细节设计: 由于本设计主要针对本公司的高压电源的,关于采集到的输出高压反馈值的模拟量可以利用单片机内部集成的8位AD转换模块, 而电源的设定电压采用单片机内部的PWM模块来实现8位的DA转换, 具体程序如下:(初稿) //*********************************************************** //-------------- 源文件名为:RS232.c----- //监控高压源71520的工作,开启高压,上位机可以设定高压值 //同时可以监控反馈高
[单片机]
51单片机串口通讯之中断法
程序讲解: /*---------------------------------------------------------------*/ //串口通讯 //按下按钮,单片机发送数据 Come On!\r\n 给主机 //单片机晶振:11.0592MHz //波特率: 9600bps /*-------------------------------------------------------------*/ //包含头文件 #include at89x52.h unsigned char co de tab ={ Come On!\r\n }; #define k1 P3_2 //对应开发板
[单片机]
STM32中USART 串口简单使用
  使用查询方式的USART:   设置时钟:   RCC_APB2Periph_AFIO 功能复用IO时钟   RCC_APB2Periph_GPIOA GPIOA时钟   RCC_APB2Periph_USART1 USART1时钟   你可以用   //使能串口1,PA,AFIO总线 RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1 ,ENABLE);   或直接   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL,ENABLE); //全部APB
[单片机]
用汇编语言实现STM32的LED和USART
; AREA RESET, DATA, READONLY DCD 0x20000000 + 1024 ;0 DCD UserMain ;1 DCD 0 ;NMI 2 DCD 0 ;HardFault 3 DCD 0 ;MemManage 4 DCD 0 ; 5 DCD 0 ; 6 DCD 0 ; 7 DCD 0 ; 8 DCD 0 ; 9 DCD 0 ; 10 DCD 0 ; 11 DCD 0 ; 12 DCD 0 ; 13 DCD 0 ; 14 DCD SysTick_Handler ; 15 HelloString DCB Hello Wordn HelloEnd HexTable DC
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved