stm32_H750VB_cubemx_HAL----三----UART_DMA学习记录(2)

一次hard_fault

不知道为什么它让我进入hard_fault
在这里插入图片描述
,换成remote_deal(buf,0)就好?(收到的数据依然不完整,是放错数组了?)

为什么没有进来??
在这里插入图片描述

看起来好像没进来,但是赋值成功了,成功了为什么还会进hard_fault??
在这里插入图片描述

,懂了:
经过step one line后发现其实第一次触发中断时还未执行board_init();
这时这个函数指针确实是NULL!!!进去后程序跑到0x000000了还跑个der~,所以就成了hard_fault
难怪教科书上经常见到这类判断语句:if(xxx!=NULL){ }
(并且不单步运行时等了半分钟都半天不给我进去赋值,不知道为什么)

在这里插入图片描述
改进:先完成函数指针赋值,再开启中断,例如:
先调用regeister();在调用init(); 瞬间就赋值完成了:
在这里插入图片描述
,一会就把这个阴间初始化函数改得阳间一些。

强烈推荐亲身体验一下函数指针指向NULL引发的hard_fault,不体会一次真的理解不了为什么教科书写那么多if(xxx!=NULL),血的教训。QvQ

但其实不是很懂hardfault到底是什么
在这里插入图片描述

到底什么是定长数组接收,什么是不定长数组接收啊?

0
在这里插入图片描述
1
在这里插入图片描述
2
在这里插入图片描述
3
在这里插入图片描述
4
在这里插入图片描述
5
在这里插入图片描述
在这里插入图片描述

我自己的理解:

定长数据接收/发送:
仅仅只开启 “DMA的接收和发送完成中断” ----(准确定义应该是,啊我猜是,buffer中的每一字节都填入/发出后,某个Counter寄存器从预设的rec_len/ tra_len递减到0时,出发完成中断)

然后假设buffer_size定的和一帧数据长度相等,且发送端(上位机)在接收端初始化完成前一直在发送的话,刚开启接受的那一瞬间可能接收到任意位置的数据,产生错位。
不定长数据接收发送:

在这里插入图片描述

自己尝试体验一下定长接收中断是什么样的(单步执行),设一个100字节数组,每次进中断时都查看一下re_length,并查看数据是否会错位什么的。

定长数组代码编写参考:

(三)stm32之串口通信DMA传输完成中断
在这里插入图片描述

代码编写经历:

没嫖到HAL库的代码,不信邪自己分析着写了一下,DMA函数寻找是照着UART中断处理的名字找的:
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位
if((tmp_flag != RESET))//idle标志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除标志位
//temp = huart1.Instance->SR; //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
//temp = huart1.Instance->DR; //读取数据寄存器中的数据
//这两句和上面那句等效
HAL_UART_DMAStop(&huart2); //
temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 获取DMA中未传输的数据个数
//temp = hdma_usart1_rx.Instance->NDTR;//读取NDTR寄存器 获取DMA中未传输的数据个数,
//这句和上面那句等效
rx_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
recv_end_flag = 1; // 接受完成标志位置1
}

/* USER CODE END USART2_IRQn 0 /
HAL_UART_IRQHandler(&huart2);
/
USER CODE BEGIN USART2_IRQn 1 */

/* USER CODE END USART2_IRQn 1 */
}
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
依据上几个图片分析写得代码且经实验正确(我设置了100字节的缓冲数组,每次只发送50字节,经断点观察,确实是发送两次,发送100个字节过去后才触发接收完成中断):

代码:

cubemx自动开启DMA中断,不用改什么;
it.c:

void DMA1_Stream4_IRQHandler(void)//usart3_rec
{
  /* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
 if(__HAL_DMA_GET_FLAG(&hdma_usart3_rx,DMA_FLAG_TCIF0_4))
    {
			  HAL_UART_Transmit_DMA(&huart3, (uint8_t *)test_3,sizeof(test_3));	

        __HAL_DMA_CLEAR_FLAG(&hdma_usart3_rx,DMA_FLAG_TCIF0_4); //清除全部中断标志
    }
  /* USER CODE END DMA1_Stream4_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_usart3_rx);
  /* USER CODE BEGIN DMA1_Stream4_IRQn 1 */

  /* USER CODE END DMA1_Stream4_IRQn 1 */
}

实验截图

疑惑:

每次数据错位都是错到9012345…太巧合了?还是别的原因?【】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

什么叫“定长数组的数据错位问题”?

见上一条的实验截图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
H7系列是ST最新的高性能ARM微处理器产品线,而STM32H750VBT6是H7产品线中性价比最高的产品。它具有H7系列的所有功能,例如Cortex-M7内核,400Mhz主频率,1MB分配SRAM,16K指令和数据缓存。128KB零等待Flash等,而且价格合适,非常适合高性能嵌入式应用程序开发。 该开发板基于STM32H750VBT6内核,可用于评估,学习和开发H7系列微处理器 板载ST-Link V2.1,调试,串口,U盘下载合一。 板载资源详细信息 STM32H750VBT6高性能ARM微处理器 STM32F103CBT6微处理器用作ST-Link功能 1个RGB LED 16Mbit QSPI-Flash可以实现xIP功能(QSPI-BANK2),并且可以更改为兼容的更大容量的NOR-Flash(例如W25Q128)。 Micro-SD卡接口 LCD接口可用于驱动Arduino Mega2560专用的3.2英寸LCD(由于此屏幕非常便宜且显示效果非常好,因此选择该屏幕是其他屏幕),LCD驱动器型号:ILT9481 LM358运算放大器用于提高DAC输出能力,可以在5V电源下正常使用。或将其替换为LMV358以在3.3V电源下使用 超级电容器用作RTC备用电源。 带有自恢复保险丝的Micro-USB接口。 您可以设置LPUART1是否通过跳线帽连接到板载ST-LINK(左侧丝印SERIAL接头,可以通过短接跳线帽访问1〜2,3〜4)。 注意:由于端口多路复用,因此原理图中的一根线可能属于多个网络。但是,切换到PCB时,将随机保留一个网络。这将导致不同数量的原理图和PCB网络。这种情况不会影响正常的编辑和使用。在使用之前,请通过另一个ST-Link刷新板载STM32F103CB的ST-LinkV2.1引导程序。闪烁后,通过USB连接开发板。使用ST-Link实用程序更新固件后,您可以正常使用板载ST-Link。所有功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值