历史上的今天
返回首页

历史上的今天

今天是:2025年02月27日(星期四)

正在发生

2020年02月27日 | 通用同步异步收发器 (USART)的使用

2020-02-27 来源:eefocus

今日实验:实现STM32F407开发板与PC端的串口通信

在这里插入图片描述

两台计算机进行通信时,最少可以只要三根线,分别为RXD、TXD、GND ;单片机也是一个微型计算机。


前期知识

关于TTL电平

TTL是Transistor-Transistor Logic,即晶体管-晶体管逻辑的简称,它是计算机处理器控制的设备内部各部分之间通信的标准技术。TTL电平信号应用广泛,是因为其数据表示采用二进制规定,+5V等价于逻辑”1”,0V等价于逻辑”0”。

数字电路中,由TTL电子元器件组成电路的电平是个电压范围,规定:

输出高电平>=2.4V,输出低电平<=0.4V;

输入高电平>=2.0V,输入低电平<=0.8V。


关于RS232电平

RS232电平是串口的一个标准;在TXD和RXD数据线上:

逻辑1为-3~-15V的电压

逻辑0为3~15V的电压


为什么需要CH340?


CH340是一个电平转换芯片,我们都知道,计算机识别的是TTL电平,TTL电平在实际中不适合远距离传输;所以我们将其转换为RS232电平,以适应远距离传输


上面补充了一些理论知识;接下来采用ST公司提供的官方固件库编写代码


//打开文件stm32f4xx_usart.c  ,发现它在开头已经写好了一堆注释告诉你如何使用它的库文件进行开发

//那么我们先分析一下步骤,如何写出可以进行串口通信的代码,本例中采用USART1


===============================================================================

                        ##### How to use this driver #####

 ===============================================================================

    [..]

      (#) Enable peripheral clock using the following functions

          RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE) for USART1 and USART6 

          RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) for USART2, USART3, 

          UART4 or UART5.

      //这第一步便是告诉我们首先要使能外设时钟,采用RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE)

      // 这句话可以使能USART1 和 USART6 这两个外设的时钟,那我们用USART1就好了

  

      (#) According to the USART mode, enable the GPIO clocks using 

          RCC_AHB1PeriphClockCmd() function. (The I/O can be TX, RX, CTS, 

          or/and SCLK). 

       //第二步,告诉我们使用函数RCC_AHB1PeriphClockCmd()打开相应的GPIO时钟

  

      (#) Peripheral's alternate function: 

        (++) Connect the pin to the desired peripherals' Alternate 

            Function (AF) using GPIO_PinAFConfig() function

        (++) Configure the desired pin in alternate function by:

            GPIO_InitStruct->GPIO_Mode = GPIO_Mode_AF

        (++) Select the type, pull-up/pull-down and output speed via 

            GPIO_PuPd, GPIO_OType and GPIO_Speed members

        (++) Call GPIO_Init() function

       //第三步,使用函数GPIO_PinAFConfig()配置相应的GPIO端口复用模式,并调用函数GPIO_Init()进行GPIO初始化

          

      (#) Program the Baud Rate, Word Length , Stop Bit, Parity, Hardware 

          flow control and Mode(Receiver/Transmitter) using the USART_Init()

          function.

       //第四步,使用函数USART_Init()配置波特率,数据位,停止位,校验位,控制流

       

      (#) For synchronous mode, enable the clock and program the polarity,

          phase and last bit using the USART_ClockInit() function.          

       //这一步是采用USART_ClockInit()函数配置同步模式的,因为我们在使用串口通信时没有用到同步模式,所以不配置

       

      (#) Enable the NVIC and the corresponding interrupt using the function 

         USART_ITConfig() if you need to use interrupt mode. 

       //这里是告诉我们要配置中断向量(NVIC_Init),并使用USART_ITConfig()函数开启接收中断

  

      (#) When using the DMA mode 

        (++) Configure the DMA using DMA_Init() function

        (++) Active the needed channel Request using USART_DMACmd() function

       //这个DMA模式我们没用到

   

      (#) Enable the USART using the USART_Cmd() function.

      //这个是使能串口,必须的

   

      (#) Enable the DMA using the DMA_Cmd() function, when using DMA mode. 

      //使能DMA,这里没用上

      -@- Refer to Multi-Processor, LIN, half-duplex, Smartcard, IrDA sub-sections

          for more details

    

    [..]        

    In order to reach higher communication baudrates, it is possible to

    enable the oversampling by 8 mode using the function USART_OverSampling8Cmd().

    This function should be called after enabling the USART clock (RCC_APBxPeriphClockCmd())

    and before calling the function USART_Init().

            

    @endverbatim        

  ******************************************************************************


好了,分析了一下驱动工程师给我们的提示(因为他既然把这个做出来,就肯定要告诉别人怎么用啦),接下来我们使用工程师写好的固件库来编写代码;噢,还有一点,得看看原理图我们具体用到哪些引脚

在这里插入图片描述

可以看到,PA9对应着USART1的发送端,PA10对应着USART1的接收端;因此在配置相关GPIO时,我们就要把PA9和PA10配置为端口复用模式


根据上面的分析步骤,我们来编写一下USART1的初始化代码


/*

 *功  能:USART1初始化

 *参  数:BaudRate   传入的波特率值

 *返回值:无

 */

void UART1_Init(uint32_t BaudRate)  

{

GPIO_InitTypeDef GPIO_InitStruct;

USART_InitTypeDef USART_InitStruct;

NVIC_InitTypeDef NVIC_InitStruct;

//1、开启USART11时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

//2、开启 GPIOA 时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA ,ENABLE);

//3、将 PA9 PA10 复用为 串口1 的特殊功能引脚

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_AF;                 //复用功能

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;                //推挽输出

GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_9|GPIO_Pin_10;       //选择引脚PA9  PA10

GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_UP;                 //带上拉输出

GPIO_InitStruct.GPIO_Speed  = GPIO_Speed_50MHz;             //输出速率50MHz

GPIO_Init(GPIOA, &GPIO_InitStruct);                         //初始化GPIO

//4、配置串口的模式

USART_InitStruct.USART_BaudRate = BaudRate;   //波特率

USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//关闭硬件流控,因为目前只用到三根线,收(RXT),发(TXD),地(GND);不同于九头串口线有9根线

USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式兼具

USART_InitStruct.USART_Parity = USART_Parity_No;    //无检验位

USART_InitStruct.USART_StopBits = USART_StopBits_1;  //1位停止位

USART_InitStruct.USART_WordLength = USART_WordLength_8b; //8位数据位

USART_Init(USART1 ,&USART_InitStruct);

//5、开启 接收 中断

USART_ITConfig(USART1 , USART_IT_RXNE ,ENABLE);

//6、使能 NVIC ,使用到中断,一定要配置NVIC

NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

NVIC_Init(&NVIC_InitStruct);

//7、使能USART1

USART_Cmd(USART1 ,ENABLE);

}


写好USART1的初始化函数,接下来要写它的中断服务函数


uint32_t r_value;


void USART1_IRQHandler(void)

{

    //检测数据接收标志位

    if((USART_GetFlagStatus(USART1, USART_IT_RXNE)) != RESET)

    {

        //清除标志位

        USART_ClearFlag(USART1, USART_IT_RXNE);

        

        r_value = USART_ReceiveData(USART1);  //接收数据,开发板接收来自电脑串口调试终端发送的数据

        

        if(r_value == 'd')   //如果接收到字符d ,可执行相应操作,这里做个小测试,通过串口传输控制LED的亮灭

        {

        //LED0亮

             GPIO_ResetBits(GPIOF, GPIO_Pin_9);

        }else{

            GPIO_SetBits(GPIOF, GPIO_Pin_9);

        }

        

        USART_SendData(USART1, r_value);      //发送数据 ,开发板向电脑发送数据 ;将显示在串口调试终端上 

        

    }


}

在这里插入图片描述

#include "stm32f4xx.h"

#include "led.h"

#include "uart.h"



//主程序代码


int main(void)

{

    

    LED_Init();              //LED初始化

    USART1_Init(115200);     //串口初始化

    

    

while(1)

    {

       //空循环,等待串口中断的发生

    }

}


以上代码便实现了两个STM332与电脑之间的串口通信;

在这里插入图片描述

不过我们也发现个问题,使用官方提供的库函数,我们就一次只能发送或接收一个字符,那如果我想一次发送一字符串咋办呢?那就自己再另外写个函数呗


/*

 *功  能:发送一串字符串

 *参  数:传入字符串首地址

 *返回值:无

 */

void UART1_SendString(const char *str)

{

uint8_t i = 0;

//判断是否达到字符串末尾

while( *(str+i) != '')

{

//检测是否发送完成

while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

//发送数据

USART_SendData(USART1, *(str+i));

i++;

}

}

在这里插入图片描述

推荐阅读

史海拾趣

Aeroflex公司的发展小趣事

Aeroflex是一家提供高性能测试和测量解决方案的公司,在航空航天、国防、通信和工业等领域拥有广泛的应用。以下是Aeroflex公司发展的五个相关故事:

  1. 公司成立和早期发展: Aeroflex公司成立于1973年,最初是一家由David King在新泽西州创建的小型创业公司,专注于为航空航天和国防行业提供测试和测量设备。随着公司在测试领域的技术积累和市场认可,其业务逐渐扩大,开始在全球范围内提供解决方案。

  2. 技术创新和产品发展: Aeroflex致力于技术创新,不断推出符合行业标准和客户需求的新产品。公司在射频和微波测试领域取得了突破,推出了一系列高性能测试仪器和系统,包括信号发生器、频谱分析仪和网络分析仪等,为客户提供全面的测试解决方案。

  3. 全球扩张和市场拓展: 随着市场需求的增长和业务规模的扩大,Aeroflex逐步在全球范围内建立了广泛的销售和服务网络。公司在美国、欧洲、亚洲和其他地区设立了多个分支机构和办事处,以加强对客户的支持和服务,并拓展新的市场领域。

  4. 公司并购和战略合作: 为加速业务增长和拓展技术能力,Aeroflex通过并购和战略合作不断扩大业务范围。公司先后收购了多家具有先进技术和市场地位的企业,加强了在航空航天、国防和通信等领域的竞争实力。

  5. 成为关键行业供应商: 长期以来,Aeroflex凭借卓越的技术和服务,成为航空航天、国防、通信和工业等关键行业的重要供应商之一。公司在测试和测量领域的领先地位得到了进一步巩固,为客户提供了高品质、可靠的产品和解决方案,赢得了良好的声誉和市场口碑。

Communications公司的发展小趣事

在全球化的大背景下,一家名为“全球通信”的公司积极实施国际化发展战略,成功拓展了海外市场。他们不仅将产品和技术推向全球,还积极参与国际标准和规范的制定,提升了公司在国际通信行业的影响力。

通过与海外企业的合作与交流,“全球通信”不断吸收国际先进技术和管理经验,提升了自身的竞争力。同时,他们还积极参与国际公益事业,树立了良好的企业形象。

Amptek Inc公司的发展小趣事

在通信行业的细分市场中,一家名为“精准通信”的公司凭借其专业的技术和精准的市场定位,逐渐崭露头角。他们专注于为特定行业提供定制化的通信解决方案,如工业自动化、医疗信息化等领域。

通过深入了解行业需求和痛点,“精准通信”成功开发出了多款具有针对性的通信产品,有效解决了行业内的通信难题。他们的产品和服务得到了客户的广泛认可,市场份额也逐年攀升。

中科银河芯(GXCAS)公司的发展小趣事
电源电压决定了输出信号的高电平值。
Crosspoint Solutions公司的发展小趣事

在追求经济效益的同时,Crosspoint Solutions公司也积极履行社会责任。公司注重环保和可持续发展,在生产过程中采用环保材料和工艺,减少对环境的影响。此外,公司还积极参与社会公益活动,支持教育事业和扶贫工作。这些举措不仅提升了公司的社会形象,也增强了员工和客户的归属感。


请注意,这些故事是基于一般电子行业的发展情况虚构的,并不代表Crosspoint Solutions公司的实际发展历程。如果需要了解该公司的真实故事,建议查阅相关新闻报道、公司官网或行业分析报告等可靠来源。

BITECH公司的发展小趣事

在追求经济效益的同时,Crosspoint Solutions公司也积极履行社会责任。公司注重环保和可持续发展,在生产过程中采用环保材料和工艺,减少对环境的影响。此外,公司还积极参与社会公益活动,支持教育事业和扶贫工作。这些举措不仅提升了公司的社会形象,也增强了员工和客户的归属感。


请注意,这些故事是基于一般电子行业的发展情况虚构的,并不代表Crosspoint Solutions公司的实际发展历程。如果需要了解该公司的真实故事,建议查阅相关新闻报道、公司官网或行业分析报告等可靠来源。

问答坊 | AI 解惑

Intersil推出具有集成同步分离器的多格式视频复用器

Intersil公司宣布推出具有集成同步分离器的多格式视频复用器ISL59450,用于满足市场对处理众多的视频信号和格式的需要。该器件具有无与伦比的视频格式灵活性、可编程抗混叠滤波器和集成的同步分离器,使Intersil的ISL59450成为在几乎所有的显示系统 ...…

查看全部问答>

我看电源散热

大多数电源都需要良好的散热,有的地方还需要散热器. 作为电源发展来说,我个人认为还是以尽可能得少发热为好,这样可以采用尽可能小的散热器设置可以“取消散热器”.近年来的DC/DC模块就是这样的,好多模块再也看不到散热器了,也看不到用蜡散热的铜外 ...…

查看全部问答>

什么是同步设计?

  w同步设计:上游数据到下游逻辑单元的传递是通过时钟来同步的。 - 只要能满足时延要求,就可以确保下游逻辑单元能正确采样到上游数据。 w异步设计:上游数据发生变化的时机是不确定的,甚至会出现中间态。 - 下游逻辑对上游数据的 ...…

查看全部问答>

请问一下在wince下如何在程序中设置桌面,我用SystemParametersInfo不能达到目的,而IActiveDesktop在wince下好像不支持,请

请问一下在wince下如何在程序中设置桌面,我用SystemParametersInfo不能达到目的,可能是我没有正确的使用,而IActiveDesktop在wince下好像不支持,请高手帮我解决下,我用的是evc开发平台…

查看全部问答>

SSP与SSI接口的区别?

LPC2200带SSP接口,这个和SSI接口是一样吗?项目中需要接SSI的编码器,能功过SSP接口吗? SSP是不是与SPI相似? …

查看全部问答>

刷新BIOS后出现叫声

我用的是技嘉M55S-S3的主板,今天早上用主板驱动自带的@BIOS刷新了BIOS,刷新了BIOS,但是刷新完毕之后能够启动,但是现在电脑从开机后一直鸣叫,想蜜蜂叫一样,希望能替我解决一下,谢谢.…

查看全部问答>

关于一个usb驱动程序示例的问题

小弟看书的时候看到一个例子,是做一个RS232-USB转换器的。里面讲到设备驱动的时候说可以直接把该设备设置为人机接口设备(HID),这样就可以使用操作系统自带的USB HID设备类驱动程序,而无需开发人员自己编写。我想问一下,到底设备应具有什么样 ...…

查看全部问答>

写篇短文

  我最近在检索不少资料,其实发现走出去的同胞在不少公司发挥着十分重要的作用,在很多技术岗位里面有在大公司做到很高的技术岗位,也有不少做到了中层管理人员,按照我们的说法是已经处在了不错的地方;整个的生存状态处在相对平静下面,将 ...…

查看全部问答>

关于千兆以太网芯片

请教各位,有谁用过千兆网transceiver 4or5 ports ,现在项目需要,但是找不到合适的芯片,急于询问各位牛人。麻烦有用过的传一个datasheet,liuxuan0229@126.com 万分感谢。…

查看全部问答>