STM32L051测试 (五、串口测试 — 与Enocean模块通讯问题)

2023-10-27

STM32L051测试 第五课,串口的使用      ....  by 矜辰所致
..添加目录栏目 												2021/9/30
..调整文章格式,增加串口接收卡死处理说明							2022/7/18

前言

早些时候写的一些测试记录的文章,并没有完全是以那种教材的方式写的,所以相对于最新的文章,整体格式框架可能没那么好。

❤️ 好消息是,博主是实打实的实际应用记录,每次遇到问题会来重新更新文章,做新的记录!❤️

经过前面一段时间的测试,我们把STM32L051 的需要用到的基本功能都测试过了,这次我们得把产品替换成L051了。

基本的IO使用都没问题,数据存储EEPROM和flash也没有问题,测试过正常用就可以了(实际上后来 EEPROM折腾了好久),在串口的使用上,也需要测试一下。

这里贴的代码是我测试流程使用过的代码,当时的文章以记录各种测试数据为主,仅供参考!

本系列博文目录:

STM32L051测试 (一、使用CubeMX生成工程文件 — ST系列芯片通用)
STM32L051测试 (二、开始添加需要的代码)
STM32L051测试 (三、I2C协议设备的添加测试)
STM32L051测试 (四、Flash和EEPROM的读写)

一、串口接收处理的几种方式

1.1 串口接收发送不定长度的数据(非DMA方式)

以前在在标准库STM32F103标准库的使用上用到的IDLE中断接收一帧数据,测试用起来确实好用

void USART2_IRQHandler(void)                	//串口2中断服务程序
	{
	u8 clear=clear;	   //消除编译器没有用到的提醒

	//USART_ClearFlag(USART2,USART_FLAG_TC);
		if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  
		{
			USART_RX_BUF[RX_Data++] = USART2->DR;
		}
		else if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)		  
		{
		 	clear=USART2->SR; //读SR寄存器	可以清空寄存器
        	clear=USART2->DR; //读DR寄存器(先读SR寄存器,再读DR,为了清除IDLE中断)						
	        ReceiveState=1;	  //标记接收到了一帧数据
		}
 }

不需要自己做延时处理,在某些情况下,比如通讯模块的串口3使用中,还是用到了延时处理,具体就是判断串口是否接收到一个字节的数据?如果接收到一个字节的数据,那么延时一定时间,一般是几毫秒(这个延时时间就是干等,等待这一串数据全部接收完成,所以这个时间需要实际使用中不同的测试优化,干等时间太长了不太合理,太短数据接收不完全处理起来会出错),如下:

RETURN_TYPE blue_getTelegram(TEL_RADIO_TYPE *pu8RxRadioTelegram, TEL_PARAM_TYPE *pu8TelParam)
{
//	uint8 i=0;
	uint8 u8CRC = 0;
	uint8 u8Count = 0; 
	uint8 TmpVal = 0;
	uint8 DATA_LEN = 0;
	uint8 n = 0;
	uint8 HEADER_BYTES[4];
	uint8 DatBuf[30] = {0};
	u8state = GET_SYNC_STATE;
	if (Read_pt != Enocean_Data){
		delay_ms(7);  //这里的等待就是干等!从收到第一个字节开始干等
		while (Read_pt != Enocean_Data)
		{
			TmpVal = USART_Enocean_BUF[Read_pt++];
			if(Read_pt >= 100)                        //定义缓存大小,测试时候用100直接替代
			  Read_pt = 0;
			switch(u8state)
			...

自己也使用过环形缓冲区等一些方式进行优化,可能目前的处理方式能够满足大部分功能需求,所以也没有确实的花心思正真去测试优化一个环形缓冲区的使用。

那么现在再L051下面,我们怎么来使用 IDLE 中断呢? 当然我先去网上查找了大神们的各种帖子,然后还是得自己修改一下程序,来一步一步做测试,先回到串口接收简单的测试:

if(test_data != Enocean_Data){
        HAL_Delay(7);
        // printf("Enocean_Data ID is: 0x %d  test_data is : 0x%d \r\n",Enocean_Data,test_data);
        if(Enocean_Data > 10){
          HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF); //将串口3接收到的数据通过串口1传出 
        }      
        memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 
        Enocean_Data=0;
        // (&hlpuart1)->pRxBuffPtr = &USART_Enocean_BUF[Enocean_Data];//用下面的简洁,数组名就可以当做指针用
        (&hlpuart1)->pRxBuffPtr = USART_Enocean_BUF;//这一句很重要,没有这一句,后面接收会出错
    }
    }

在主函数初始化串口后,有这么一句,打开串口中断(这里的中断可不可以理解为打开IT中断)

 HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);

现在我们要开启IDLE中断

 __HAL_UART_ENABLE_IT(&hlpuart1,UART_IT_IDLE);
  HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[0], 1);

在stm32l0xx_it.c中找到 LPUART1_IRQHandler函数,因为所有中断先是进入 stm32l0xx_it.c 中相应的IRQHandler函数中,调用对应函数,最后才会进入到 自己设置的 Callback函数中,我们这次测试直接在void LPUART1_IRQHandler(void)函数中系统设置的函数前写一个 实现 IDLE中断后操作的函数:

void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
  if((__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE) != RESET))
  {
    		__HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);
        ReceiveState = 1;   
  }
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&hlpuart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */

  /* USER CODE END LPUART1_IRQn 1 */
}

用 ReceiveState 来标志是否接受到了一串数据,然后打印函数变成

 if(ReceiveState == 1){
        ReceiveState = 0;      
        HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF); //将串口3接收到的数据通过串口1传出            
        memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 
        Enocean_Data=0;
        (&hlpuart1)->pRxBuffPtr = USART_Enocean_BUF;//这一句很重要,没有这一句,后面接收会出错
    }

结果, 数据异常,就是收不全,结尾会有问题,明天得继续测试优化了,先上个正常的接收,这是上面用HAL_Delay(7)测试得到的正常结果。
在这里插入图片描述
在这里插入图片描述实际测试,数据会断接收不全,考虑了一下,是否本身我的通讯模组串口给MCU的时候一包数据就是分两次发送(其实就是一包数据中间有个时间会长一点,然后MCU判定为2帧数据,每次能够收到开头的一段),
我测试的打印函数每次收到一包数据,都会把数据全部打印出来,然后清空缓存区,所以下一包数据直接被清掉了,因为在进行输出的过程,可能下一包的数据中断进来了,为了验证一下,还是加上了一个延时,代码改成如下:

if(ReceiveState == 1){
        HAL_Delay(7); //测试,重要
        ReceiveState = 0;      
        HAL_UART_Transmit(&huart1,USART_Enocean_BUF, Enocean_Data,0xFFFF); //将串口3接收到的数据通过串口1传出            
        memset(USART_Enocean_BUF, 0, sizeof(USART_Enocean_BUF));   //清空缓存区 
        Enocean_Data=0;
        (&hlpuart1)->pRxBuffPtr = USART_Enocean_BUF;//这一句很重要,没有这一句,后面接收会出错
    }

发现加上延时后,数据就正常了……,其实中途测试的时候在IDLE中断处理时候,我打印过 测试语句,发现我正常的一包数据,都会打印2次测试语句,也进一步的证实了,测试模块给MCU的正常的一包数据会被MCU认为是 2帧数据。
那么我们怎么来解决这个问题呢,还是直接加一个ms延时吗? 至少IDLE中断在这里用不了,一帧数据会触发2次中断,可能和通讯模块有关,因为以前测试的时候也遇到过类似情况。

但至少IDLE中断我们可以用起来,在这里做一个小结:
1、正常初始化串口以后,打开IDLE中断:

__HAL_UART_ENABLE_IT(&hlpuart1,UART_IT_IDLE);

这个语句可以放在串口初始化函数MX_LPUART1_UART_Init中,也可以放在main函数后面,看个人习惯;

2、在stm32l0xx_it.c 文件中响应的中断相应函数LPUART1_IRQHandler 中加入关于IDLE中断的处理于语句:

void LPUART1_IRQHandler(void)
{
  /* USER CODE BEGIN LPUART1_IRQn 0 */
  
  /* USER CODE END LPUART1_IRQn 0 */
  HAL_UART_IRQHandler(&hlpuart1);
  /* USER CODE BEGIN LPUART1_IRQn 1 */
  if((__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE) != RESET))
  {
    usartreceive_IDLE(&hlpuart1);
  }
  /* USER CODE END LPUART1_IRQn 1 */
}

/* USER CODE BEGIN 1 */
void usartreceive_IDLE(UART_HandleTypeDef *huart)
{
  __HAL_UART_CLEAR_IT(&hlpuart1,UART_CLEAR_IDLEF); //清除中断
  // HAL_UART_AbortReceive_IT(huart); //终止接收
  ReceiveState = 1;
}

用一个标志位表示收到了一帧数据,即便这个一帧不完全,也至少表示收到一段数据了,这里不能加
HAL_UART_AbortReceive_IT(huart); //终止接收 ,因为IT中断可以继续接收,如果终止了,数据处理不够及时,下一帧数据就收不到了。

3、最后通过判断标志位 ReceiveState 来处理数据,一般情况下直接处理,特除情况,在标志位至1 后,刻意的等待几个毫秒,等待数据接收完全再处理。

!!!最后移植又发现一个问题
代码中 #define ID_blueNum 44

	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);
	printf("send command !\r\n");
	COMMAND_GetmoduleID();
	// HAL_Delay(10);	//7ms不够	
	while ((Enocean_Data - Read_pt) < ID_blueNum);//加了这句不需要加上面的延时,这句就是等待,这句很重要,能够过滤掉不相关的报文
	// while ((Enocean_Data - Read_pt) < ID_blueNum){
	// 	HAL_UART_Receive_IT(&hlpuart1, &USART_Enocean_BUF[Enocean_Data], 1);
	// }//2021/8/11  不是很懂为什么这里这个while等待必须得加点东西
	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);

在这里插入图片描述
如果按照上面的代码,会一直卡在这里过不去,其实就是while ((Enocean_Data - Read_pt) < ID_blueNum);过不去,开始怀疑是不是通讯模块本来就是坏的,我们有多种方式测试:

测试代码1(好理解,发送命令了,等待一会,让串口把数据收完):

	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);
	printf("send command !\r\n");
	COMMAND_GetmoduleID();
	HAL_Delay(10);//7ms不够	
	while ((Enocean_Data - Read_pt) < ID_blueNum);//加了这句不需要加上面的延时,这句就是等待,这句很重要,能够过滤掉不相关的报文
	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);

在这里插入图片描述
测试代码2(本来是想看看等待时候打印什么东西,加个条件怕一直循环):

	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);
	printf("send command !\r\n");
	COMMAND_GetmoduleID();
	while ((Enocean_Data - Read_pt) < ID_blueNum){
		if(Enocean_Data < 10)printf("测试过随便打印点东西都可以!\r\n");
	}//2021/8/11  不是很懂为什么这里这个while等待必须得加点东西
	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);

在这里插入图片描述
测试代码3 , 4(不加条件随便在等待中打印 , 延时 ):

printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);
	printf("send command !\r\n");
	COMMAND_GetmoduleID();
	while ((Enocean_Data - Read_pt) < ID_blueNum){
		printf("不要条件乱打都可以测试过随便打印点东西都可以!\r\n");
		//HAL_Delay(1);//延时可以,1ms就可以
	}//2021/8/11  不是很懂为什么这里这个while等待必须得加点东西
	printf("Enocean_Data is :%d Read_pt is :%d\n\r",Enocean_Data,Read_pt);

在这里插入图片描述
经过测试发现,while中虽然是干等,但是没有语句就会有问题,不是很明白,因为以前都可以,虽然知道解决办法,但是不知道问题原因,所以也不知道哪种是更优的解决办法!
= =!

1.2 串口接收发送不定长度的数据(DMA方式)

在实际使用中,我没有在L051下面测试使用DMA利用 IDLE 中断进行DMA接收发送,实际上,通过我们上面做的实验和测试,对于目前使用的通讯模块,一包数据会触发2次IDLE 中断的情况,也不太适合。
本例程是以前STM32L1系列中使用的例程,以前也是在网上参考过其他人的设计然后自己用起来的,正好也在这里做个笔记

#define USART3_DMA_REC_SIE 256   //DMAbuf空间大小
#define USART3_REC_SIE 512  	   //接收区空间大小两倍,以保持两条历史数据
typedef struct
{   
    uint8_t UsartRecFlag;   //接收数据Flag
    uint16_t UsartDMARecLen; //DMA接收到数据的长度
    uint16_t UsartRecLen;    //RecBuffer中已经存储数据的长度
    uint8_t  Usart3DMARecBuffer[USART3_DMA_REC_SIE];  //dma
    uint8_t  Usart3RecBuffer[USART3_REC_SIE];         //RecBuffer
} Usart3DMAbufstr;
extern Usart3DMAbufstr Usart3type;  
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */

  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
  if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE) == SET)  //判断空闲中断
    {		
      u16 res = 0;                        
      __HAL_UART_CLEAR_IDLEFLAG(&huart3);       //清楚空闲中断标志
      HAL_UART_DMAStop(&huart3);                //暂时关闭DMA中断
	    res = huart3.Instance->ISR;          
   	  res = huart3.Instance->RDR;              
      res = hdma_usart3_rx.Instance->NDTR;                     //读取DMA接收的那个buf还剩多少空间
	  Usart3type.UsartDMARecLen = USART3_DMA_REC_SIE - temp;   //总空间减去还剩下的空间等于存入数据的空间大小  
      HAL_UART_RxCpltCallback(&huart3);		                   //手动调用中断回调,因为空闲中断不会主动调用
   }
  /* USER CODE END USART3_IRQn 1 */
}

数据最初都存储在DMARecBuffer中,然后转存到RecBuffer中。DMARecBuffer中的数据每接收到新的数据都会清空。

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{	
    //可行选着是否开启多条数据缓存,默认不开启,开启删除下划线
    if(huart->Instance == USART3)
    {
      //  if(Usart3type.UsartRecLen>0)//判断RecLen是否清0,如果没有清零代表上一个数据没有读取 
      //  {
        //    memcpy(&Usart3type.Usart3RecBuffer[Usart3type.UsartRecLen],Usart3type.Usart3DMARecBuffer,Usart3type.UsartDMARecLen); //把数据顺延
       //     Usart3type.UsartRecLen +=  Usart3type.UsartDMARecLen;//数据长度增加相应的位数	
      //  }
      //  else
     //   {
            memcpy(Usart3type.Usart3RecBuffer,Usart3type.Usart3DMARecBuffer,Usart3type.UsartDMARecLen);                          //把输入放入buf开头
            Usart3type.UsartRecLen =  Usart3type.UsartDMARecLen;								//记录数据长度																		
       // }
				
        memset(Usart3type.Usart3DMARecBuffer, 0x00, sizeof(Usart3type.Usart3DMARecBuffer));                                     //把DMA缓存中的数据清空,方便下一次接收
        Usart3type.UsartRecFlag = 1;                                                                                            //RecFlag置1,代表RecBuffer中有数据
	    HAL_UART_Receive_DMA(&huart3,Usart3type.Usart3DMARecBuffer,USART3_DMA_REC_SIE);                                         //重新开启DMA中断,方便再一次接收
    }
}

在相应的程序中把上面的代码添加好,然后在主函数循环中使用,RecBuffer中的数据会一直增加,直到用户读取以后才会清空:

if(Usart3type.UsartRecFlag == 1)//如果Recbuffer中有数据
{
	HAL_UART_Transmit(&huart1,Usart3type.Usart3RecBuffer,256,0xffff);//把RecBuffer中的数据发送到串口1
	memset(Usart3type.Usart3RecBuffer, 0x00, sizeof(Usart3type.Usart3RecBuffer));//读取完数据后记得一定要把RecBuffer中的数据清除
	Usart3type.UsartRecFlag = 0;//标志位清0
	Usart3type.UsartRecLen = 0;//已有数据长度清0
}

1.3 环形缓冲区

因为单单靠数组方式,接收处理,总感觉不是那么聪明,有时候需要干等,所以还是得花时间研究下环形缓冲区。。。

二、串口接收卡死处理

在使用了了段时间后,测试部反馈偶尔会有串口卡死说明,最终就是接收不到串口数据,但是轮询发送是正常,后来查阅了一些资料,找到了需要处理的地方,这里特此来记录一下。

2.1 清除错误标志位

在使用 HAL 库的时候,有4个错误 flag,如下图:
在这里插入图片描述

出错的时候,HAL库会把以上flag置位如果不清除就再也接收不到数据了。

所以我们可以在需要的时候使用,下面的语句清除错误标志:

	__HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_PE);//清标志
	__HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_FE);
	__HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_NE);
	__HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_ORE);

比如,在我清除串口接收缓存的函数中,我加上了这几句代码:

在这里插入图片描述

这是实际使用的情况,我并没有详细的测试到底是哪一个错误置位了,在自己了解的简单产品上,直接一步到位也是一种方式。

2.2 HAL 库函数问题

产品使用了上面的串口清除错误标志,在压力测试下下面还是有问题:

现象就是串口发送正常,但是永远接收不到数据了。

实在是没办法,后来继续找答案。

最后确实发现网上也有小伙伴遇到过相同的问题,我使用的是 HAL_UART_Receive_IT 开启中断:

在这里插入图片描述

在这个函数中有这么一段:

在这里插入图片描述

里面有个加锁操作,正式因为这个加锁操作,如果收发同时进行,会有概率卡死。

这个时候的处理方式就是手动解锁,每次接收到一个字节后需要再次开启中断接收,判断一下是否有错误:
在这里插入图片描述
判断的语句如下:

if(huart->Instance == LPUART1){
    Enocean_Data++;
    if(Enocean_Data > 98)Enocean_Data = 0;
    while(HAL_UART_Receive_IT(&hlpuart1, (uint8_t *)&USART_Enocean_BUF[Enocean_Data], 1) != HAL_OK){
      hlpuart1.RxState = HAL_UART_STATE_READY;
      __HAL_UNLOCK(&hlpuart1);
    }
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32L051测试 (五、串口测试 — 与Enocean模块通讯问题) 的相关文章

  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • STM32F4 通过软复位跳转到引导加载程序,无需 BOOT0 和 BOOT1 引脚

    我问这个问题是因为可以在这里找到类似问题的答案 通过应用程序跳转到 STM32 中的引导加载程序 即从用户闪存在引导模式下使用引导 0 和引导 1 引脚 用户 JF002 JF002回答 当我想跳转到引导加载程序时 我在其中一个备份寄存器中
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • STM32超声波——HC_SR04

    文章目录 一 超声波图片 二 时序图 三 超声波流程 四 单位换算 五 取余计算 六 换算距离 七 超声波代码 一 超声波图片 测量距离 2cm 400cm 二 时序图 1 以下时序图要先提供一个至少10us的脉冲触发信号 告诉单片机我准备
  • STM32 GPIO工作原理详解

    STM32 GPIO介绍 1 STM32引脚说明 GPIO是通用输入 输出端口的简称 是STM32可控制的引脚 GPIO的引脚与外部硬件设备连接 可实现与外部通讯 控制外部硬件或者采集外部硬件数据的功能 以STM32F103ZET6芯片为例
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • VS Code 有没有办法导入 Makefile 项目?

    正如标题所说 我可以从现有的 Makefile 自动填充 c cpp properties json 吗 Edit 对于其他尝试导入 makefile 的人 我找到了一组脚本 它们完全可以实现我想要实现的目标 即通过 VS Code 管理
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • STM32F207 I2C 测试失败

    我正在使用 STM32F207 微控制器在 STM3220G EVAL 板上学习嵌入式开发 我尝试通过连接同一芯片上的两个 I2C2 和 I2C3 模块并发送 接收字符来测试 I2C 接口 这是我当前编写的代码 使用 mdk arm 5 i
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • Arm:objcopy 如何知道 elf 中的哪些部分要包含在二进制或 ihex 中?

    我正在开发一个项目 其中涉及解析arm elf 文件并从中提取部分 显然 elf 文件中有很多部分没有加载到闪存中 但我想知道 objcopy 到底如何知道要在二进制文件中包含哪些部分以直接闪存到闪存中 以arm elf文件的以下reade
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • 分配大的 DMA 缓冲区

    我想分配一个大的 DMA 缓冲区 大小约为 40 MB 当我使用dma alloc coherent 它失败了 我看到的是 cut here WARNING at mm page alloc c 2106 alloc pages nodem
  • Linux内核设备驱动程序以DMA方式进入内核空间

    LDD3 p 453 演示dma map single使用作为参数传入的缓冲区 bus addr dma map single dev gt pci dev gt dev buffer count dev gt dma dir Q1 这个缓
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • Unity3D笔记第五天——Animation动画

    Animation 动画 动画是游戏开发中必不可少的环节 游戏场景中角色的行走 跑步 弹跳 机关的打开 等等 这些都离不开动画技术的应用 帧 动画中最小单位的单幅影像画面 相当于电影胶片上的每一格镜头 Unity中指实时渲染的一张图像 关键
  • 反射使用---java根据对象集合生成excel

    写作业的时候碰到一个需求 不使用框架写一个将数据库表读取出来然后生成excel表格然后返回给用户下载 一开始写的时候觉得很简单 无非就是连接数据库查数据然后用一个pojo类存储单个数据 把pojo集合写入excel就好 但就是在写入exce
  • 将txt文本内数据转化为数组

    txt文件地址 我之前尝试过放进Maven项目中 在编译器没问题 但打包成jar包 地址找不到 有高人能实现的话 求指教 文本数据 1 2 3 4 5 6 7 8 public Double getlkmList String materi
  • html静态网站基于游戏网站设计与实现共计10个页面 (仿地下城与勇士游戏网页)

    精彩专栏推荐 作者简介 一个热爱把逻辑思维转变为代码的技术博主 作者主页 主页 获取更多优质源码 web前端期末大作业 毕设项目精品实战案例 1000套 程序员有趣的告白方式 HTML七夕情人节表白网页制作 110套 超炫酷的Echarts
  • C 传递数组给函数的三种方式和从函数返回数组

    传递数组给函数 如果想要在函数中传递一个一维数组作为参数 有三种方式来声明函数形式参数 这三种声明方式的结果是一样的 因为每种方式都会告诉编译器将要接收一个整型指针 方式 1 形式参数是一个指针 void myFunction int pa
  • classLoader 介绍

    先声明本文摘自 https www cnblogs com tuning p 6943427 html 以下内容紧凑 但相信看下去会对于我们平时对于java的一些疑问和模糊的地方有一定解释 先解决几个问题 InputStream is ge
  • 当使用mybatis中update方法时数据库中的某些字段自动更新

    我们在使用mybatis时 一般都会手写一个实体类和数据库中的数据对应 public class Article public static final int Article TOP 1 public static final int A
  • 生活杂谈:从Z149到Z78随笔

    听着Z149 北京 贵阳 列车上调皮的钢琴伴奏 看着窗外流逝的繁华 拨通了回家前给母亲的一个电话 翻开那陈旧又熟悉的日记本 一切的一切都和往常回家一样 一次次独处 一次次感悟 也不知道自己什么时候喜欢上了这种独处 回忆 落笔的感觉 并不是我
  • 手机app服务器ip查询网站吗,13813.app服务器iP

    2021 02 04 2021 08 11 45 200 73 197 2021 08 04 2021 08 10 119 8 50 208 2021 08 04 2021 08 10 94 74 101 230 2021 04 14 20
  • 服务端请求伪造(SSRF)及漏洞复现

    文章目录 渗透测试漏洞原理 服务端请求伪造 1 SSRF 概述 1 1 SSRF 场景 1 1 1 PHP 实现 1 2 SSRF 原理 1 3 SSRF 危害 2 SSRF 攻防 2 1 SSRF 利用 2 1 1 文件访问 2 1 2
  • 信号槽传递非Qt库类型参数时,出现QObject::connect: Cannot queue arguments of type 'QUuid'(Make sure 'string' is regi

    例如以C 标准库中string做参数 则会出现 QObject connect Cannot queue arguments of type string Make sure string is registed using qRegist
  • ldconfig提示is not a symbolic link警告的去除方法

    错误提示 ldconfig ldconfig usr local lib gliethttp libxerces c 3 0 so is not a symbolic link 问题分析 因为libxerces c 3 0 so正常情况下应
  • ISIS课堂笔记12.3

    7805与78l05区别 1 管脚不同 管脚相反 2 78L05是一种固定电压 5V 三端集成稳压器 可适用于很多应用场合 其卓越的内部电流限制和热关断特性使之特别适用于过载的情况 当用于替代传统的齐纳二极管 电阻组的时候 其输出阻抗得到有
  • 进行数据离散化的原因_离散制造业MES相比流程制造业MES的区别在何处

    MES可以使得不同企业的工艺流程和管理需求通过现场定义来达到目的 MES可以提供诸多模块并为企业打造一个扎实 可靠 全面 可行的制造协同管理平台 MES系统作为制造企业信息化进程中不可替代的重要技术和手段 其应用和普及自然成为企业最理想的选
  • TypeScript 基础类型 —— Object

    声明为 Object 类型表示非原始类型 也就是除 number string boolean symbol null 或 undefined 之外的类型 const obj object function const res name s
  • 防止撤回插件 Android,微信防撤回插件

    微信防撤回插件是一款微信防撤回插件 可以把好友撤销的消息留在自己的手机聊天界面上 微信防撤回插件再也不怕消息被撤回了 即使有人不小心发了小秘密及时撤回 你也可以看到哟 并且还有强大的自动抢红包等功能 需要的朋友赶紧下载吧 微信防撤回插件官方
  • 志愿者招募计划--2019CTA 核心技术及应用峰会(杭州)

    5月25 27日 CSDN 与数字经济人才发展中心联合主办的第一届 CTA 核心技术及应用峰会将在杭州开启 首届 CTA 核心技术及应用峰会将围绕人工智能 邀请技术领航者 与开发者共同探讨机器学习和知识图谱的前沿研究及应用 不久之前我们公布
  • 数据库连接池自动重新连接问题

    http sailorls blogchina com 2606862 html tomcat连接池自动重新连接问题 Tag Tag tomcat 连接池 重新连接 在以往的开发中 常常遇到tomcat连接池断掉后 比如网络断线 无法自动重
  • 知识图谱02:知识图谱的应用

    公众号 数据挖掘与机器学习笔记 知识图谱提供了一种更好的组织 管理和理解互联网信息的能力 可用于语义搜索 智能问答 个性化推荐等 在社交和电子商务等领域中实现价值 基于知识图谱的应用是信息领域当前的研究热点 也是促进人工智能发展的基础技术之
  • STM32L051测试 (五、串口测试 — 与Enocean模块通讯问题)

    STM32L051测试 第五课 串口的使用 by 矜辰所致 添加目录栏目 2021 9 30 调整文章格式 增加串口接收卡死处理说明 2022 7 18 目录 前言 一 串口接收处理的几种方式 1 1 串口接收发送不定长度的数据 非DMA方