手把手教你从0创建STM32串口空闲+DMA数据接收工程

串口通讯是嵌入式系统中最常用的通讯方式。

STM32的串口接收普通的方式是在串口读数据寄存器非空RXNE中断(Read data register not empty)中1个字节1个字节的接收串口数据,一帧数据的接收完成可以使用结束帧判断,也可以使用定时器计时当定时器溢出时认为一帧数据已经接收完成(一帧数据中各byte的时间间隔很短<1mS,因此可以将定时器设置为3mS溢出,在RXNE中断中清0定时器,若产生定时器溢出中断表明已经3mS没有接收到数据了,判定已结束一帧数据接收)。

如上方式每一个字节的接收都会触发RXNE中断进行接收字节的保存,因此若一直接收数据会占用较多的CPU时间,从而影响其它业务程序的执行。比较好的方式是使用DMA+串口空闲中断实现数据的接收,STM32只需要进一次中断即可。直接存储器存取(DMA)是用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,从而可以节省CPU的资源来做其他操作。

 

工具准备:

STM32CubeMX(Verison5.6.1)

KEIL5(uVision V5.26.2.0)

正点原子潘多拉IOT开发板(芯片型号:STM32L475VET6,也可以使用其它STM32芯片)

 

设计需求:

  1. LED状态指示灯指示系统运行状态(正常为闪烁)
  2. 可实现串口DMA数据接收,并将接收到的数据原封不动的返回

 

硬件配置:

  1. 使用板载的绿色LED灯作为系统运行状态指示灯,硬件引脚为PE8
  2. 使用潘多拉IOT开发板开发板的USART1,硬件引脚为PA9(TX),PA10(RX)

     USART1配置如下:

     波特率:128000bps

     数据位:8

     校验位:无

     停止位:1

 

<Part 1 工程生成>

1、打开STM32CubeMX后选择Start My Project from MCU

2、根据芯片型号创建工程

3、选择系统时钟源为外部晶振(可自由配置)

这里需要解释的是选择外部高速时钟HSE时有2个时钟源选项。其中Crystal/Ceramic Resonator表示使用晶振/陶瓷振荡器Bypass Clock Sourc表示使用旁路时钟源,即不使用晶振,外部直接供给一个可靠的时钟源。

4、配置程序的调试方式,一般选JTAG或SWD(根据自己项目的调试方式选就可以)

5、配置系统时钟频率,最终配置系统时钟频率为80MHz

6、配置USART1基本信息

7、配置USART1 DMA接收

需要配置的模式为USART1接收DMA,方向从外设到内存(即将USART1接收到的数据搬运到用户定义的内存空间中),数据宽度为1Byte,DMA的优先级设置为High,模式为Normal即搬运完用户指定的字节数后停止DMA工作,Circle循环模式则在搬运完成后又从头开始搬运,因此循环接收时会覆盖掉用户定义的内存空间中保存的之前接收到的数据。

8、设置USART1中断优先级

NVIC在此处默认为4bit为抢占优先级,0bit为从优先级,即不支持配置从优先级,抢占优先级的配置范围为0~15(0优先级为最高,此处将串口中断优先级设置为3,也算是优先级比较高了)

9、配置系统运行指示灯PE8的管脚信息

配置系统运行指示灯的意义在于,可以直观的观察到程序是否正常运行。这里需要注意的是,在GPIO端口被配置为输出时,其弱上拉和弱下拉电阻是不可用的。

10、配置工程生成相关配置

<Part 2 工程修改>

需要修改的文件有如下几个:

main.c

usart.c

usart.h

stm32l4xx_it.c

 

main.c中修改部分如下红框所示:

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_Delay(100);		__HAL_UART_CLEAR_IDLEFLAG(&huart1);							/* 使能IDLE中断前先清除其中断标志位,以免使能后就立刻进入中断 */								HAL_Delay(100);		__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);		/* 使能IDLE串口空闲中断 */		/* USART1使能串口DMA接收,最多接收DMA_MAX_RECV_SIZE个字节,接收内容存储于gu8_dma_recv_buff_a缓冲区 */HAL_Delay(100);		HAL_UART_Receive_DMA(&huart1, gu8_dma_recv_buff_a, DMA_MAX_RECV_SIZE); /* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);	/* 翻转状态指示灯引脚电平 */HAL_Delay(300);																	/* 每300mS翻转一次 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 1;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB busses clocks */RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK){Error_Handler();}PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}/** Configure the main internal regulator output voltage */if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state *//* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{ /* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

usart.c中修改部分如下红框所示:

/********************************************************************************* File Name          : USART.c* Description        : This file provides code for the configuration*                      of the USART instances.******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************//* Includes ------------------------------------------------------------------*/
#include "usart.h"/* USER CODE BEGIN 0 */volatile uint8_t gu8_dma_recv_buff_a[DMA_MAX_RECV_SIZE] = {0};							/* DMA接收缓冲区 */
/* USER CODE END 0 */UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;/* USART1 init function */void MX_USART1_UART_Init(void)
{huart1.Instance = USART1;huart1.Init.BaudRate = 128000;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}}void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(uartHandle->Instance==USART1){/* USER CODE BEGIN USART1_MspInit 0 *//* USER CODE END USART1_MspInit 0 *//* USART1 clock enable */__HAL_RCC_USART1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/**USART1 GPIO Configuration    PA9     ------> USART1_TXPA10     ------> USART1_RX */GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF7_USART1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USART1 DMA Init *//* USART1_RX Init */hdma_usart1_rx.Instance = DMA1_Channel5;hdma_usart1_rx.Init.Request = DMA_REQUEST_2;hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;hdma_usart1_rx.Init.Mode = DMA_NORMAL;hdma_usart1_rx.Init.Priority = DMA_PRIORITY_HIGH;if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK){Error_Handler();}__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);/* USART1 interrupt Init */HAL_NVIC_SetPriority(USART1_IRQn, 3, 0);HAL_NVIC_EnableIRQ(USART1_IRQn);/* USER CODE BEGIN USART1_MspInit 1 *//* USER CODE END USART1_MspInit 1 */}
}void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{if(uartHandle->Instance==USART1){/* USER CODE BEGIN USART1_MspDeInit 0 *//* USER CODE END USART1_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_USART1_CLK_DISABLE();/**USART1 GPIO Configuration    PA9     ------> USART1_TXPA10     ------> USART1_RX */HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);/* USART1 DMA DeInit */HAL_DMA_DeInit(uartHandle->hdmarx);/* USART1 interrupt Deinit */HAL_NVIC_DisableIRQ(USART1_IRQn);/* USER CODE BEGIN USART1_MspDeInit 1 *//* USER CODE END USART1_MspDeInit 1 */}
} /* USER CODE BEGIN 1 *//*******************************************
*   Function Name       :   UART_IDLE_Callback
*   Creat Date          :   2020/11/05
*   Author/Corporation  :   Jason
*   Description         :   usart idle callback function
*   Para                :   huart: the usart user use
*   Return Code         :   null
------------------------------
*   Revision History
*   Date        Revised by    Description
*   2020/11/05  Jason         the first verison
*******************************************/
void UART_IDLE_Callback(UART_HandleTypeDef *huart)
{if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)){/* 计算接收到的字节数 */uint8_t u8_recv_num = DMA_MAX_RECV_SIZE -  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);	__HAL_UART_CLEAR_IDLEFLAG(huart);			/* 清除串口空闲中断标志位 */	HAL_UART_DMAStop(huart);							/* 停止串口DMA接收 */			/* 使用阻塞发送的方式将接收到的数据原封不动的返回至上位机 */HAL_UART_Transmit(&huart1, gu8_dma_recv_buff_a, u8_recv_num, 1000);/* 重新使能USART1 DMA接收,最多接收DMA_MAX_RECV_SIZE个字节,接收内容存储于gu8_dma_recv_buff_a缓冲区 */HAL_UART_Receive_DMA(&huart1, gu8_dma_recv_buff_a, DMA_MAX_RECV_SIZE); }
}
/* USER CODE END 1 *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

usart.h中修改部分如下红框所示:

/********************************************************************************* File Name          : USART.h* Description        : This file provides code for the configuration*                      of the USART instances.******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __usart_H
#define __usart_H
#ifdef __cplusplusextern "C" {
#endif/* Includes ------------------------------------------------------------------*/
#include "main.h"/* USER CODE BEGIN Includes *//* USER CODE END Includes */extern UART_HandleTypeDef huart1;/* USER CODE BEGIN Private defines */
#define DMA_MAX_RECV_SIZE          128				/* DMA接收数据最大长度 */
/* USER CODE END Private defines */void MX_USART1_UART_Init(void);/* USER CODE BEGIN Prototypes */
extern volatile uint8_t gu8_dma_recv_buff_a[DMA_MAX_RECV_SIZE];
/* USER CODE END Prototypes */#ifdef __cplusplus
}
#endif
#endif /*__ usart_H *//*** @}*//*** @}*//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

stm32l4xx_it.c中修改部分如下红框所示:

/* USER CODE BEGIN Header */
/********************************************************************************* @file    stm32l4xx_it.c* @brief   Interrupt Service Routines.******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD *//* USER CODE END TD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_usart1_rx;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
extern void UART_IDLE_Callback(UART_HandleTypeDef *huart);	/* 串口空闲中断回调函数 */
/* USER CODE END EV *//******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */ 
/******************************************************************************/
/*** @brief This function handles Non maskable interrupt.*/
void NMI_Handler(void)
{/* USER CODE BEGIN NonMaskableInt_IRQn 0 *//* USER CODE END NonMaskableInt_IRQn 0 *//* USER CODE BEGIN NonMaskableInt_IRQn 1 *//* USER CODE END NonMaskableInt_IRQn 1 */
}/*** @brief This function handles Hard fault interrupt.*/
void HardFault_Handler(void)
{/* USER CODE BEGIN HardFault_IRQn 0 *//* USER CODE END HardFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_HardFault_IRQn 0 *//* USER CODE END W1_HardFault_IRQn 0 */}
}/*** @brief This function handles Memory management fault.*/
void MemManage_Handler(void)
{/* USER CODE BEGIN MemoryManagement_IRQn 0 *//* USER CODE END MemoryManagement_IRQn 0 */while (1){/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 *//* USER CODE END W1_MemoryManagement_IRQn 0 */}
}/*** @brief This function handles Prefetch fault, memory access fault.*/
void BusFault_Handler(void)
{/* USER CODE BEGIN BusFault_IRQn 0 *//* USER CODE END BusFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_BusFault_IRQn 0 *//* USER CODE END W1_BusFault_IRQn 0 */}
}/*** @brief This function handles Undefined instruction or illegal state.*/
void UsageFault_Handler(void)
{/* USER CODE BEGIN UsageFault_IRQn 0 *//* USER CODE END UsageFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_UsageFault_IRQn 0 *//* USER CODE END W1_UsageFault_IRQn 0 */}
}/*** @brief This function handles System service call via SWI instruction.*/
void SVC_Handler(void)
{/* USER CODE BEGIN SVCall_IRQn 0 *//* USER CODE END SVCall_IRQn 0 *//* USER CODE BEGIN SVCall_IRQn 1 *//* USER CODE END SVCall_IRQn 1 */
}/*** @brief This function handles Debug monitor.*/
void DebugMon_Handler(void)
{/* USER CODE BEGIN DebugMonitor_IRQn 0 *//* USER CODE END DebugMonitor_IRQn 0 *//* USER CODE BEGIN DebugMonitor_IRQn 1 *//* USER CODE END DebugMonitor_IRQn 1 */
}/*** @brief This function handles Pendable request for system service.*/
void PendSV_Handler(void)
{/* USER CODE BEGIN PendSV_IRQn 0 *//* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */
}/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 *//* USER CODE END SysTick_IRQn 1 */
}/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32l4xx.s).                    */
/******************************************************************************//*** @brief This function handles DMA1 channel5 global interrupt.*/
void DMA1_Channel5_IRQHandler(void)
{/* USER CODE BEGIN DMA1_Channel5_IRQn 0 *//* USER CODE END DMA1_Channel5_IRQn 0 */HAL_DMA_IRQHandler(&hdma_usart1_rx);/* USER CODE BEGIN DMA1_Channel5_IRQn 1 *//* USER CODE END DMA1_Channel5_IRQn 1 */
}/*** @brief This function handles USART1 global interrupt.*/
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* HAL_UART_IRQHandler中不包括串口空闲中断回调函数,因此需要自己实现UART_IDLE_Callback */UART_IDLE_Callback(&huart1);	/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}/* USER CODE BEGIN 1 *//* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

修改完成后编译,下载到开发板中。

<Part 3  试验部分>

使用正点原子串口调试助手和开发板进行通讯,发现可以将发送的内容原封不动的返回至上位机,符合程序设计意图,成功实现DMA+串口空闲中断接收!

实验结果如下图所示:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TC214B直流电机控制芯片

潘多拉开发板中通过TC214B电机驱动芯片驱动板载直流电机&#xff0c;因此需要先了解TC214B芯片的主要功能及其使用方法。 通过以上资料可以了解到&#xff0c;MCU控制TC214B从而进行直流电机转动方向&#xff0c;方向控制&#xff08;即前进/后退&#xff09;主要是通过控制MCU…

ST7789V2 LCD驱动芯片

ST7789V2是一个单芯片TFT-LCD驱动器。该芯片可以直接连接到外部MCU&#xff0c;支持并行8080系列的8位/9位/16位/18位接口&#xff0c;也支持SPI串行通讯接口。 显示数据可以存储在240x320x18bits的片上显示数据RAM中。 它可以在没有外部操作时钟的情况下执行显示数据RAM读写操…

STM32 USB虚拟串口原理(上)

USB虚拟串口是使用USB的CDC&#xff08;CDC为communication device class(virtual port com)&#xff09;类实现的一种通讯接口。使用STM32自带的USB slave功能可以在电脑上实现一个USB虚拟串口&#xff0c;在电脑上可以直接使用串口调试助手打开该虚拟串口和STM32进行通讯。ST…

RT-Thread使用ENV生成工程时自己添加的文件被清掉的解决方法

在项目中难得一次就可以将需要的模块或组件包添加完成&#xff0c;因此在实际开发中经常会遇到在未完成的项目中增加软件包或使能硬件功能的情况。一般我们会使用RT-Thread的ENV辅助开发环境的menuconfig图形化系统配置工具对组件包进行配置&#xff0c;配置完后使用pkgs --upd…

怎样使用两行代码实现博客园打赏功能

也许大家看博客园博客的时候&#xff0c;遇到过一些博客右侧&#xff0c;展示了打赏二维码~ 如下图所示 那么&#xff0c;这是怎么实现的呢~~~ 不错&#xff0c;你没猜错&#xff0c;他们使用的是本人写的一个js插件--tctip。 大家搜一下&#xff0c;还能搜到网上有些tctip的教…

STM32 HAL库 .c/.h 文件介绍

HAL库中各个文件的介绍&#xff1a; startup_stm32l475xx.s 启动文件的主要作用是进行RAM中堆、栈内存的分配和初始化&#xff0c;中断向量表及中断函数的定义等&#xff0c;进行完这一系列工作后执行系统复位从而跳转至用户main函数开始执行。 stm32l4xx_hal_ppp.c/.h 基本…

RT-Thread设备框架学习感悟

前面几周跟着野火的教程从0到1实现了RT-Thread的内核&#xff0c;对RT-Thread的调度机制和线程、定时器的底层实现有了总体的了解。后面还需进一步对齐实现细节进行探索&#xff0c;但大致先了解其框架&#xff0c;后面再进行细致的了解。在学习新知识时&#xff0c;最重要的是…

RT-Thread中自定义MSH命令传入的参数是字符串,需用户自行检查和解析

如下是在将安富莱的dac8563模块对接到潘多拉开发板RT-Thread SPI设备框架中时导出到RT-Thread的自定义MSH命令&#xff0c;需要注意的是MSH传入的是字符串&#xff0c;需要自行对字符串进行解析处理。 #include "stdlib.h" /* 使用其中的函数&#xff1a;atoi(); */…

安富莱DAC8653模块

产品规格&#xff1a;1、供电电压 &#xff1a; 2.7 - 5.5V 【3.3V供电时&#xff0c;输出电压也可以到正负10V】2、通道数&#xff1a; 2路 &#xff08;通过1片DAC8563实现&#xff09;3、输出电压范围 &#xff1a; -10V ~ 10V 【客户可以自己更改为 0-10V输出范围。使…

flex布局应用与踩坑

一、预告本文不是一篇入门的文章所有请符合以下条件的战斗人员绕道&#xff1a; 1、初学前端&#xff0c;对前端的传统布局还不是很熟悉的人 2、后端人员对前端不打算深入学习的同学 二、开篇flex布局原本是好几个月前就一直想学习的东西&#xff0c;当时flex布局还算是比较新鲜…

RT-Thread I/O设备模型

I/O设备指的是嵌入式系统中的一些Input输入/Output输出设备&#xff0c;输入输出设备是嵌入式系统重要的组成部分。输入和输出设备可以看做是计算机系统和外界进行沟通的桥梁&#xff0c;因此在计算机组成原理中输入输出设备是重要的组成部分。 计算机组成原理中的5大组成部分…

如何使用易我数据恢复向导恢复数码相机删除的图片

1 使用"易我数据恢复向导"的高级恢复(务必将数码相机的存储卡取出单独插入SD卡槽,而不是直接用数据线连接到电脑上,这样存储卡才能以磁盘方式显示) 2 选中对应磁盘,点击下一步 3 如果出现"分区参数不正确"提示&#xff0c;直接取消即可开始搜索 4 搜索完…

RT-Thread对GPIO操作两种方式的区别:1)通过设备操作接口2)直接通过通用GPIO设备驱动

在学习RT-Thread设备驱动框架时&#xff0c;看到潘多拉开发板的RT-Thread例程资料中的文档《AN0002-RT-Thread-通用 GPIO 设备应用笔记》有如下描述&#xff0c;因此产生使用文档中未使用的方式1&#xff09;通过设备操作接口 方法实现GPIO操作的想法&#xff01; 使用潘多拉开…

清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(一)

I2C是一种双向2线制同步串行通讯接口&#xff0c;是一类非常经典的串行总线通讯&#xff0c;理解好I2C通讯会帮助理解USB通讯、以太网通讯中的握手、数据帧等环节。 I2C的发展历史&#xff1a; SPI串行通讯主要是由MOTOROLA公司提出的&#xff0c;MOTOROLA公司的半导体部门独立…

清华大学-曾鸣-《ARM微控制器与嵌入式系统》I2C总线(二)

I2C&#xff08;Inter IC Bus&#xff09;的通讯数据帧&#xff1a; SCL线无方向区分&#xff0c;SDA线上有数据的流动方向。上图中灰色的代表的是主机向从机发送数据&#xff0c;此时SDA线的电平控制权由主机掌控&#xff0c;从机只能监听该线上的电平状态。白色代表的是从机向…

RT-Thread I2C设备驱动框架的对接使用

I2C和SPI是MCU和板载芯片之间最常用的通讯方式&#xff0c;现在先介绍下I2C总线。I2C的基本原理也很简单&#xff0c;只需要两根线&#xff08;时钟线SCL和信号线SDA&#xff09;即可实现挂载在I2C总线上设备之间的相互通讯。I2C协议并未规定I2C总线上哪个是主机&#xff1f;哪…

RT-Thread 简介及架构

RT-Thread&#xff0c;全称是 Real Time-Thread&#xff0c;顾名思义&#xff0c;它是一个嵌入式实时多线程操作系统&#xff0c;基本属性之一是支持多任务&#xff0c;允许多个任务同时运行并不意味着处理器在同一时刻真地执行了多个任务。事实上&#xff0c;一个处理器核心在…

iOS HTML标签字符实体,转译字符串归类大全 【转载】

为什么要用转义字符串&#xff1f; HTML中<&#xff0c;>&#xff0c;&等有特殊含义&#xff08;<&#xff0c;>&#xff0c;用于链接签&#xff0c;&用于转义&#xff09;&#xff0c;不能直接使用。这些符号是不显示在我们最终看到的网页里的&#xff0c…

RT-Thread在github上的教程中图片显示不出来问题的解决方法

在github上查看RT-Thread STM32系列BSP制作教程时发现教程中所有的图片都加载不出来&#xff0c;非常影响教程的阅读使用。 使用记事本打开文件&#xff1a; C:\Windows\System32\drivers\etc\hosts 将如下内容复制粘贴到hosts文件末尾&#xff1a; # GitHub Start 140.82.11…

在STM32CubeMX生成的MDK5工程上添加RT-Thread Nano后双击工程名无法打开.map文件的解决方法

当我们基于STM32CubeMx完成芯片的基础配置&#xff0c;再将RT-Thread Nano添加到工程编译完成之后。双击工程名称发现无法打开工程的.map文件&#xff0c;.map文件是STM32开发中非常重要的一个文件&#xff0c;map文件中详细描述了各个函数在ROM中的存储地址和大小&#xff0c;…