stm32之USART通信

  任何USART通信,需要用到2个对外连接的引脚:RxD,TxD;

 RxD是输入引脚,用于串行数据接收;

 TxD是输出引脚,用于串行数据发送;

SCLK引脚:发生器时钟输出(同步模式下,异步模式下不需要)

  在IrDA模式(红外模式)下需要下列引脚:

    IrDA_RDI: 红外模式下的数据输入;

    IrDA_TDO:红外模式下的数据输出;

  调制解调模式下需要:

    nCTS:清除发送;

    nRTS:发送请求;

数据的接收/发送过程示意图:

  

异步串行通信协议需要定义以下5个内容:

  1、起始位  2、数据位(8/9位,9位的话包含奇偶校验位,8位一字节)

  3、奇偶校验位(第9位)

  4、停止位(1、1.5、2位)

  5、波特率设置(速度,波特率决定移位寄存器速度)

异步通信时,双方设置必须一致

     ;

USART用途:

 芯片间的近距离通信:

  

  

 芯片与pc机通信:

模块与模块之间远距离通信:借助RS485芯片-------can总线是在485上面发展起来的;

  RS-485接口的最大传输距离可达3000米;

 

USART内部关于寄存器控制:

USART发送设置:

   1、通过在USART_CR1寄存器上置位UE位来激活USART

   2、设置USART_CR1的M位来定义字长;

   3、设置USART_CR2中停止位的位数;

     如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT),按多缓冲器通信中的描述配置DMA寄存器;

    4、设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送;

    5、利用USART_BRR寄存器选择要求的波特率;

   6、把要发送的数据写进USART_DR寄存器(若数据发送完成由硬件清除);在只有一个缓冲器的情况下,重复步骤6;

  1 #include "stm32f10x_gpio.h"
  2 #include "stm32f10x_rcc.h"
  3
  4 #define GPIOA_ODR_A (GPIOA_BASE+0x0C)
  5 #define GPIOA_IDR_A (GPIOA_BASE+0x08)
  6 #define GPIOA_ODR_B (GPIOB_BASE+0x0C)
  7 #define GPIOA_IDR_B (GPIOB_BASE+0x08)
  8 #define GPIOA_ODR_C (GPIOC_BASE+0x0C)
  9 #define GPIOA_IDR_C (GPIOC_BASE+0x08)
 10 #define GPIOA_ODR_D (GPIOD_BASE+0x0C)
 11 #define GPIOA_IDR_D (GPIOD_BASE+0x08)
 12 #define GPIOA_ODR_E (GPIOE_BASE+0x0C)
 13 #define GPIOA_IDR_E (GPIOE_BASE+0x08)
 14
 15 #define BitBand(Addr, BitNum) *((volatile unsigned long *)((Addr&0xF0000000)+0x2000000 +((Addr&0xfffff)<<5)+(BitNum<<2)))
 16 #define PAout(n) BitBand(GPIOA_ODR_A, n)
 17 #define PAin(n)     BitBand(GPIOA_IDR_A, n)
 18
 19 /*******************************************************************************
 20 * Function Name  : RCC_Configuration
 21 * Description    : Configures the different system clocks.
 22 * Input          : None
 23 * Output         : None
 24 * Return         : None
 25 *******************************************************************************/
 26 void RCC_Configuration(void)
 27 {
 28         /*---------------使用外部RC晶振----------*/
 29         RCC_DeInit();             //设置时钟为缺省值
 30         RCC_HSEConfig(RCC_HSE_ON);    //使能外部高速晶振
 31         while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);//等待HSE准备就绪
 32
 33 //        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);    //使能指令预取
 34 //        FLASH_SetLatency(FLASH_Latency_2);                        //等待2个周期
 35
 36         RCC_HCLKConfig(RCC_SYSCLK_Div1);    //HCLK = SYSCLK
 37         RCC_PCLK2Config(RCC_HCLK_Div1);        //PCLK2 = HCLK
 38         RCC_PCLK1Config(RCC_HCLK_Div2);        //PCLK1 = HCLK/2
 39         RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);    //PLLCLK = 72MHZ
 40         RCC_PLLCmd(ENABLE);                                    //Enable PLLCLK
 41         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);    //Wait PLL is ready
 42
 43        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);          //SYSCLK = PLLCLK
 44        while(RCC_GetSYSCLKSource()!= 0x08);                      //Wait PLLCLK as system clock
 45
 46
 47     //---------打开相应外设时钟--------------------
 48     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);    //使能APB2外设的GPIOA的时钟
 49     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  //使能USART1时钟
 50 }
 51
 52 void GPIO_Configuration(void)
 53 {
 54     GPIO_InitTypeDef    GPIO_InitStructure;        //声明一个结构体变量
 55     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;     //选择PA.3
 56     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
 57     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //输出模式为推挽输出
 58     GPIO_Init(GPIOA,&GPIO_InitStructure);                 //初始化GPIOA寄存器
 59
 60
 61     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;     //选择PA.10
 62     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     //管脚频率为50MHZ
 63     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//输入为浮空输入
 64     GPIO_Init(GPIOA,&GPIO_InitStructure);                 //初始化GPIOA寄存器
 65 }
 66
 67
 68 int main()
 69 {
 70     float div;
 71     u16 M, F, BRR;
 72     u32 Bound;
 73     u8 data = 'A';
 74 //USART1模块的设置:UE使能、M位来定字长    、停止位的位数、
 75 //TE位; BRR寄存器选择要求的波特率,
 76
 77     RCC_Configuration();    //打开系统时钟
 78     GPIO_Configuration();    //引脚设置
 79     USART1->CR1 |= (1<<13);
 80     USART1->CR1 &= ~(1<<12);
 81     USART1->CR2 &= ~(3<<12);
 82     USART1->CR1 |=(1<<3);
 83 //Tx / Rx 波特率 = fck/(16 *USARTDIV )
 84 //波特率=9600; fck=72M
 85     //小数部分=0.75×16=12 = 0x
 86     Bound = 9600;
 87     div = (float)(72*1000*1000)/(Bound*16);
 88     M = div;
 89     F = (div-M)*16;
 90 //拼接数据
 91     BRR = (M<<4)+F;
 92     USART1->BRR = BRR;
 93
 94
 95
 96 //发送字符‘A’到USART1的TXD
 97     for(F=0;F<20;F++)
 98     {
 99         USART1->DR = data;
100         data++;
101         while((USART1->SR &(1<<6)) ==0 )    //等待发送完成才能再次发送
102             ;
103     }
104
105     return 0;
106 }

 USART接收设置:

  1、将USART_CR1寄存器的UE置1来激活USART.

  2、编程USART_CR1的M位定义字长;

  3、在USART_CR2中编写停止位的个数;

    注意:如果需多缓冲通信,选择USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信所要求的配置DMA寄存器;

  4、利用波特率寄存器USART_BRR选择希望的波特率;

  5、设置USART_CR1的RE位,激活接收器,使它开始寻找起始位;

    当一字符被接收到时:

      RXNE位被置位,它表明移位寄存器的内容被转移到RDR.

      如果RXNEIE位被设置,产生中断;

      在接收期间如果检测到帧错误,噪音或者溢出错误,错误标志将被置起;

 

时间: 2024-10-24 18:14:41

stm32之USART通信的相关文章

51的usart可以用查询的方式吧,stm32的有查询的方式吗

问题描述 51的usart可以用查询的方式吧,stm32的有查询的方式吗 51的usart可以用查询的方式吧,stm32的有查询的方式吗 解决方案 都可以用查询方式.stm32的USART接收数据的时候,一般情况下都是用中断方式,因为我们知道什么时候给串口发数据,但是不知道数据到底什么时候接收完,所以接收采用了中断,发送没用中断. 用查询的话,就是去不断查询寄存器状态. while(!(USART1->SR & (1<<5))); //收到数据,可以读出 data=USART1-

《STM32库开发实战指南:基于STM32F4》----导读

目 录 前 言第1章 如何安装KEIL51.1 温馨提示1.2 获取KEIL5安装包1.3 开始安装KEIL51.4 安装STM32芯片包第2章 如何用DAP仿真器下载程序2.1 仿真器简介2.2 硬件连接2.3 仿真器配置2.4 选择目标板2.5 下载程序第3章 初识STM323.1 什么是STM323.2 STM32能做什么3.2.1 智能手环3.2.2 微型四轴飞行器3.2.3 淘宝众筹3.3 STM32选型3.3.1 STM32分类3.3.2 STM32命名方法3.3.3 选择合适的MC

fpga-stm32与FPGA spi通信

问题描述 stm32与FPGA spi通信 求 FPGA的vhdl 程序 和stm32液晶如何显示 fpga的vhdl代码 解决方案 STM32 spi总线通信 最近在研究SPI总线,至于协议和硬件描述就不多说了 四线包括时钟.片选.接收.发送 初始化SP ? SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; ?//全双工 ? SPI_InitStructure.SPI_Mode = S......答案就在这里:

【STM32 .Net MF开发板学习-19】DHT11温湿度传感器通信(上)

前段时间开发远程医疗系统(Dr.Cloud)就曾用到过温湿度传感器,不过当时考虑到集成难度,选了一个RS485接口的传感器,该传感器实现了Modbus Rtu Slave的功能,只要客户程序实现Modbus Rtu Client即可读出温湿度数据.是方便了开发,不过价格不菲,要价要150元左右. 网友fangyuan推荐了一款仅7元的DHT11温湿度传感器,刚开始以为是TTL电平的串口通信,后来一研究,原来通过一根数据线的双向通信,并且对时序要求很严格,这东西也许用单片做更容易,用STM32来做

stm32中写关于usart的程序中,如果要使用printf,现在我看到2种方式,

问题描述 stm32中写关于usart的程序中,如果要使用printf,现在我看到2种方式, 一种是用微库,就是在MDK里面打开microlib,程序中添加一个重定义的程序就可以了,另一种是用半主机,这种方式不用打开microlib,半主机不懂事什么意思,他们的区别是什么,

显示-stm32与上位机通过网口通信,网口读不出数据?

问题描述 stm32与上位机通过网口通信,网口读不出数据? 使用w5500evb与上位机通信,w5500evb是一个网络芯片,它的MCU是stm32f103系列的,要实现将传感器采集到的数据值通过网口显示在上位机的网络调试助手上,现在我可以通过串口将数据显示在串口调试助手上(说明传感器工作正常),但是通过网口传数据时,在上位机的网络调试助手不显示,请教大神,这是什么原因呢?(网络通信是正常的,我用上位机的网络调试助手给下位机发送数据123,下位机收到之后会自动将123发送给上位机,而且在网络调试

wi-fi-android与单片机(STM32)通过wifi如何实现通信?

问题描述 android与单片机(STM32)通过wifi如何实现通信? 新人求解,最近在做一个APP,到时候要与stm32通信,要实现数据,图像同步到APP上 ,想问一下怎么实现,协议用什么?望大牛指导一下. 解决方案 stm32支持网络协议有点困难, 单片机加WIFI透传模块比较好.搞定串口通迅就行了. 解决方案二: 想都不用想,肯定wifi透传,两个主从wifi模块通过串口收发数据,http你就别想了. 解决方案三: 用HTTP协议进行通信 解决方案四: 单片机买了wifi模块,只要搞定串

rfid-STM32F4 USART工业通信

问题描述 STM32F4 USART工业通信 用stm32f4的USART给RF发送指令,报文为数字形式,如0230353003.用串口助手发送的16进制指令没有问题,但是用单片机发送的不成功.用串口助手看过单片机发送的指令,没有错误,但就是不能成功初始化RF,请问是什么原因呢? 解决方案 STM32F4--串口(USART)通信总结 解决方案二: http://www.cnblogs.com/zyqgold/archive/2013/05/20/3088414.html 解决方案三: http

stm32 can通信-我在两个stm32f103 之间can通信还有问题

问题描述 我在两个stm32f103 之间can通信还有问题 我现在会用环回模式进行自检测,但是 我不了解两个103 之间can通信怎么配置? 我把原来自发自收的程序分开配置成发送和接收,但是出新不了我想要的现象,我对硬件的理解 是只需硬件can口连接两根线CANH连接CANH,CANL连接CANL就行了 还有我不知道过滤器的那些0x数字是为什么配置成那样的,不懂,求大师指点 解决方案 好像还需要外置电平转换板才可以