zoukankan      html  css  js  c++  java
  • 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位被设置,产生中断;

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

  • 相关阅读:
    前端vue采用formData数据格式传递文件(Post请求)和非文件参数。后端怎样接收的问题(已解决)
    easyExcel 所需的maven 依赖
    基于客户数据的银行信用卡风险控制模型研究-金融风控模型标准评分卡
    chrome 插件知识点(转载)
    EasyNVR调用指定时间端录像播放接口出现黑屏的问题原因以及解决方法
    EasyNVR智能云终端推送视频流至EasyNVS管理平台失败且报错如何排查?
    EasyNVR分发rtsp不标准导致客户端检查报错是什么原因?
    EasyNVR前端在线修改录像存储路径后hls直播失效问题的处理
    EasyNVR实时阅览四分屏状态下最后一路流无法正常播放问题排查
    通过EasyNVR推流到抖音快手直播间无法正常推流是什么原因?
  • 原文地址:https://www.cnblogs.com/chris-cp/p/3905838.html
Copyright © 2011-2022 走看看