当前位置:   article > 正文

基于STM32的物联网项目经验总结与技术分享(一:串口通信)_stm32物联网

stm32物联网

上一篇博客提到的多串口通信同时收发信息的问题,绝对排的上号,其次是不同的单片机通信的时候一定要注意硬件上电平的问题,比如供电,共地等,最后就是不同的串口通信收发信息方式会大大影响到Wi-Fi连接手机和服务器的速度。

具体怎么解决这些问题会在接下来的几篇博客中挨个分享开源

这篇文章除了介绍下这个项目覆盖到的知识点和难点,先简单的向大家介绍一下项目中最基础的串口通信吧。

首先简单直白的讲一下串口是什么,你可以认为是一根数据线,能在不同设备之间传输信息,是单片机中固有的资源,可以对其进行初始化以后使用,不同单片机的串口资源是不同的。会进行区分讲解

第一个问题,怎么初始化串口

讲怎么初始化串口之前,先说下什么是初始化吧,即对即将使用到的资源的各种属性按照你的需求,在其可供选择的范围之内进行设置,使得每次运行程序使用该资源的时候,他都可以按照你的设置去工作。

现在讲讲怎么初始化,串口,使用它进行信息收发,那势必会使用到两个引脚,Tx和Rx,那么我们得先学会引脚的初始化,即GPIO的初始化。GPIO有什么属性我们一一来看,首先是他的速率,其次是他的8种模式,以及管脚号,这是他的属性,初始化不止这些,在设置属性之前先要给他使能,那么知道它在哪个总线上是必须的(后续有详细介绍),可以通过编辑器查看,也可以记下来,使能完成以后,就用一个结构体完成对他的初始化吧,代码如下:

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能时钟
  
  GPIO_InitTypeDef GPIO_InitStruct;//用结构体初始化其属性
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; //管脚号
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//模式,其余几种稍后详解
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//速率
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//一般用不到
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//一般用不到
  GPIO_Init(GPIOA, &GPIO_InitStruct);//到这里就完成了

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这是刚提到的八种GPIO_MODE,简单介绍一下

STM32的GPIO模式有以下8种:
typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;(这是keil里的结构体,下面是我带有解释性的模式)
1. 输入模式(Input mode)
当GPIO配置为输入模式时,它将读取外部信号,并将其传输到CPU或其他系统级组件。该模式具有低功耗和高稳定性的特点。
2. 输出模式(Output mode)
当GPIO配置为输出模式时,它将向外部设备或其他系统级组件发送信号。这个模式可以用于驱动LED,马达,蜂鸣器等外部设备。该模式具有较高的稳定性,低功耗和高灵活性。
3. 复用模式(Alternate mode)
当GPIO配置为复用模式时,它将多个外设连接到同一个GPIO引脚上。每个外设都对应特定的GPIO模式。例如,UART通信使用不同的GPIO模式进行收发信号的复用。该模式具有较高的可扩展性和灵活性。
4. 模拟模式(Analog mode)
当GPIO配置为模拟模式时,它将成为模拟输入或输出引脚,用于输入或输出模拟电信号。该模式适用于模拟信号需要传输的场合,具有较高的精确度和可靠性。
5. 推挽输出模式(Push-Pull output mode)
当GPIO配置为推挽输出模式时,它将可以提供较高电平或较低电平输出,但不会产生中间状态。该模式适用于双向电路的输出控制,具有较高的灵活性,但功耗相对较高。
6. 开漏输出模式(Open-Drain output mode)
当GPIO配置为开漏输出模式时,它将可以提供较低电平,但不能提供较高电平输出。该模式用于驱动一些带有外部上拉电路的设备,或用于实现多设备输出控制,具有较高的灵活性和节能效果。
7. 浮空输入模式(Floating input mode)
当GPIO配置为浮空输入模式时,它将读取周围环境的电信号,但不会被任何外部电路影响。该模式适用于单次触发事件的输入读取,具有较高的准确度和稳定性。
8. 串行外设模式(Serial peripheral interface mode,SPI)
当GPIO配置为SPI模式时,它将与SPI总线进行通信,用于接口芯片、LCD等外设。该模式具有高速数据传输和低功耗的特点,适合高速外设通信。

讲完初始化引脚以后,我们可以系统的认识一下串口通信了:

STM32的串口通信主要涉及到以下知识点:

  1. 串口通信协议:串口通信是一种异步通信方式,数据按照固定的帧格式传输。常见的帧格式包括帧起始位、数据位、停止位和校验位。(这些都可以通过配置串口初始化结构体来设置,后续会在程序中讲解)

  2. STM32有哪些串口通信模块:STM32的串口通信模块包括USART、UART、LIN等。其中,USART具有较强的功能和扩展性,支持同步和异步通信。本篇文章主要想讲的也是USART串口通信

  3. STM32的串口通信硬件连接:串口通信需要将Tx和Rx引脚连接到对应设备的Tx和Rx引脚上,同时需要连接共地(这是很重要的事,否则可能会出现收发的信息乱码,导致无法通信)。

接下来,以USART1为例,介绍STM32的串口通信代码实现方式。

  1. 首先,需要打开USART1的时钟。这可以通过设置相应的时钟寄存器来实现。例如,要使用USART1,需要打开USART1的时钟,可以使用以下代码:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  • 1

怎么判断串口位于哪个总线上,很简单,在你的keil5中点击这个函数,跳转函数定义,就可以看到具体哪个设备在哪个总线上了,我简单总结一下:

总线一(编辑器就是这么写的,我原封不动的放这里,给大家熟悉熟悉)

* @brief  Enables or disables the Low Speed APB (APB1) peripheral clock.
  * @param  RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
  *   This parameter can be any combination of the following values:
  *  @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4,
  *          RCC_APB1Periph_TIM5, RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7,
  *          RCC_APB1Periph_WWDG, RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3,
  *          RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, 
  *          RCC_APB1Periph_USART5, RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2,
  *          RCC_APB1Periph_USB, RCC_APB1Periph_CAN1, RCC_APB1Periph_BKP,
  *          RCC_APB1Periph_PWR, RCC_APB1Periph_DAC, RCC_APB1Periph_CEC,
  *          RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14
  * @param  NewState: new state of the specified peripheral clock.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None

总线二
  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.
  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
  *   This parameter can be any combination of the following values:
  *  @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,
  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,
  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,
  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,
  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11     
  * @param  NewState: new state of the specified peripheral clock.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None

特殊的总线,基本用不到

* @brief  Forces or releases AHB peripheral reset.
  * @note   This function applies only to STM32 Connectivity line devices.
  * @param  RCC_AHBPeriph: specifies the AHB peripheral to reset.
  *   This parameter can be any combination of the following values:
  *     @arg RCC_AHBPeriph_OTG_FS 
  *     @arg RCC_AHBPeriph_ETH_MAC
  * @param  NewState: new state of the specified peripheral reset.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None

  1. 设置USART1的参数。参数设置可以使用USART_InitTypeDef结构体进行设置。例如,可以设置波特率为9600,数据位为8位,停止位为1位,校验位为无校验(基本上是大家默认的配置,其实还有别的配置属性,在这里就一笔带过吧,有8位和9位数据长度,奇偶校验无校验,0.5/1/1.5/2长度的停止位),可以使用以下代码:
USART_InitStructure.USART_BaudRate = bound;                           //波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;       //8个数据位
USART_InitStructure.USART_StopBits = USART_StopBits_1;            //1个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;              //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;  //收发模式
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在实际应用中,如果需要中断做一些事情的话,可以使用USART_ITConfig函数打开USART1的中断,在需要用到中断的时候,还需要配置一些别的参数。

说一下抢占优先级和响应优先级,具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套在低抢占式优先级的中断中。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。总结下便是:抢占式优先级>响应优先级>中断表中的排位顺序

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //设置中断向量分组:第2组 抢先优先级:0 1 2 3 子优先级:0 1 2 3	
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);          //开启接收中断    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;       //设置串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		//响应优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//中断通道使能
NVIC_Init(&NVIC_InitStructure);	                        //设置串口1中断
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

img

img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

img

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

!! (备注:嵌入式)**

img

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

更多资料点击此处获qu!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/719639
推荐阅读
相关标签
  

闽ICP备14008679号