ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

串口通讯时,为什么需要同时打开串口时钟和GPIO时钟

2022-02-24 20:32:59  阅读:278  来源: 互联网

标签:USART void InitStruct 串口 DEBUG GPIO 时钟


1. 项目:野火stm32f10指南者开发板,使用USART实现数据的发送和接收。

2. 代码

  •   主函数main.c
#include "stm32f10x.h"
#include "bsp_usart.h"

int main(void)
{		
	USART_Config();
	//发送一个字符
	Usart_SendByte(DEBUG_USARTx,'A');
	while(1)
	{

	}

}

  

  • bsp_usart.c
#include "bsp_usart.h"

static void NVIC_Config(void)
{
	NVIC_InitTypeDef	NVIC_InitStruct;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);					/*配置NVIC为优先级组2*/
	NVIC_InitStruct.NVIC_IRQChannel= DEBUG_USART_IRQ;				/*配置USART中断源*/
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;							/*使能中断通道*/
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;		/*配置抢占优先级:1*/
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;						/*配置子优先级:1*/
	
	NVIC_Init(&NVIC_InitStruct);	/*初始化配置NVIC*/
}

void USART_Config(void)
{
	GPIO_InitTypeDef		GPIO_InitStruct;
	USART_InitTypeDef		USART_InitStruct;
	
	//打开串口GPIO时钟
	DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
	//打开串口外设时钟
	DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
	
	//将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStruct.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStruct);
	
	//将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStruct.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStruct);
	
	//配置串口的工作参数
	//配置波特率
	USART_InitStruct.USART_BaudRate = DEBUG_USART_BAUNDRATE;
	//配置针数据字长
	USART_InitStruct.USART_WordLength = USART_WordLength_8b;
	//配置停止位
	USART_InitStruct.USART_StopBits = USART_StopBits_1;
	//配置校验位
	USART_InitStruct.USART_Parity = USART_Parity_No;
	//配置硬件流控制
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//配置工作模式,收发一起
	USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	//完成串口的初始化配置
	USART_Init(DEBUG_USARTx, &USART_InitStruct);
	
	//串口中断优先级配置
	NVIC_Config();
	//使能串口接收中断
	USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
	//使能串口
	USART_Cmd(DEBUG_USARTx,ENABLE);
	
}

//发送字节函数
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
	USART_SendData(pUSARTx, data);
	while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
}

 

 

  • bsp_usart.h
#ifndef __bsp_usart_h
#define __bsp_usart_h

#include "stm32f10x.h"
//串口USART宏定义
#define DEBUG_USARTx								USART1
#define DEBUG_USART_CLK							RCC_APB2Periph_USART1
#define DEBUG_USART_APBxClkCmd			RCC_APB2PeriphClockCmd
#define DEBUG_USART_BAUNDRATE				115200

//USART GPIO宏定义
#define DEBUG_USART_GPIO_CLK				(RCC_APB2Periph_GPIOA)
#define DEBUG_USART_GPIO_APBxClkCmd		RCC_APB2PeriphClockCmd
#define DEBUG_USART_TX_GPIO_PORT			GPIOA
#define DEBUG_USART_TX_GPIO_PIN				GPIO_Pin_9
#define DEBUG_USART_RX_GPIO_PORT			GPIOA
#define DEBUG_USART_RX_GPIO_PIN				GPIO_Pin_10

#define DEBUG_USART_IRQ								USART1_IRQn
#define DEBUG_USART_IRQHandler				USART1_IRQHandler


void USART_Config(void);
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data);

#endif /*bsp_usart_h*/

 

 

  • stm32f10x_it.c函数添加中断函数
    /* Includes ------------------------------------------------------------------*/
    #include "stm32f10x_it.h"
    #include "bsp_usart.h"
    
    /** @addtogroup STM32F10x_StdPeriph_Template
      * @{
      */
    
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    /* Private function prototypes -----------------------------------------------*/
    /* Private functions ---------------------------------------------------------*/
    
    /******************************************************************************/
    /*            Cortex-M3 Processor Exceptions Handlers                         */
    /******************************************************************************/
    
    /**
      * @brief  This function handles NMI exception.
      * @param  None
      * @retval None
      */
    void NMI_Handler(void)
    {
    }
    
    /**
      * @brief  This function handles Hard Fault exception.
      * @param  None
      * @retval None
      */
    void HardFault_Handler(void)
    {
      /* Go to infinite loop when Hard Fault exception occurs */
      while (1)
      {
      }
    }
    
    /**
      * @brief  This function handles Memory Manage exception.
      * @param  None
      * @retval None
      */
    void MemManage_Handler(void)
    {
      /* Go to infinite loop when Memory Manage exception occurs */
      while (1)
      {
      }
    }
    
    /**
      * @brief  This function handles Bus Fault exception.
      * @param  None
      * @retval None
      */
    void BusFault_Handler(void)
    {
      /* Go to infinite loop when Bus Fault exception occurs */
      while (1)
      {
      }
    }
    
    /**
      * @brief  This function handles Usage Fault exception.
      * @param  None
      * @retval None
      */
    void UsageFault_Handler(void)
    {
      /* Go to infinite loop when Usage Fault exception occurs */
      while (1)
      {
      }
    }
    
    /**
      * @brief  This function handles SVCall exception.
      * @param  None
      * @retval None
      */
    void SVC_Handler(void)
    {
    }
    
    /**
      * @brief  This function handles Debug Monitor exception.
      * @param  None
      * @retval None
      */
    void DebugMon_Handler(void)
    {
    }
    
    /**
      * @brief  This function handles PendSVC exception.
      * @param  None
      * @retval None
      */
    void PendSV_Handler(void)
    {
    }
    
    /**
      * @brief  This function handles SysTick Handler.
      * @param  None
      * @retval None
      */
    void SysTick_Handler(void)
    {
    }
    
    void DEBUG_USART_IRQHandler(void)
    {
    	uint8_t ucTemp;
    	if (USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET)
    	{
    		ucTemp = USART_ReceiveData(DEBUG_USARTx);
    		USART_SendData(DEBUG_USARTx,ucTemp);
    	}
    	
    }
    

 Keil5编程总览:

 

 

3. 执行结果:

    打开串口调试助手,配置好串口、波特率等参数。按下开发板上的复位键,接收区域显示A 

             

 

 

4. 参考资料

  •   原理图
  •  

     

     

     

  •   编程要点
    • 使能RX和TX引脚GPIO时钟和USART时钟;
    • 初始化GPIO,并将GPIO复用到USART上;
    • 配置USART参数;
    • 配置中断控制器并使能USART接收中断;
    • 使能USART;
    • 在USART接收中断服务函数实现数据接收和发送。
  •   

5. 总结

  • 串口时钟使能与控制器使能的关系:为何USART时钟使能了,还需要在配置USART控制器的时候再使能一次?(为什么需要同时打开串口时钟和GPIO时钟)
    • 转自:STM32之串口通信 (bbsmax.com)
    • //打开串口GPIO时钟
      DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
      //打开串口外设时钟
      DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

  • (1)USART的时钟使能
    • Note: 当外部时钟没有被激活时,外设寄存器值可能不可读,并且返回值为0x0.

 

  • (2)USART控制器使能
  • 寄存器内部控制关系图
    • RCC_APB2ENR:  控制APB2时钟是否供应给USART控制器

      USART_CR1:   控制USART控制器的分频器和输出是否工作

    • USART1要用到GPIOA的复用管脚输入输出功能,不使能的话只能内部串口外设工作,但是没办法与外界(即串口线)通信。也就是说只使
    • 能USART1的话就只是让USART1这个外设工作,GPIOA作为一个USART1与外界通信的桥梁没有打通,所以不行。

6. 常见的几种通讯协议的参数

转自:

(71条消息) 通信方式梳理:GPIO,I2C,SPI,UART,USART,USB的区别_步印的博客-CSDN博客_gpio i2c spi uart

 

 

 

 

标签:USART,void,InitStruct,串口,DEBUG,GPIO,时钟
来源: https://www.cnblogs.com/kevin-hou1991/p/15924437.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有