这两天遇到一个问题,大概就是程序跑一半嗝屁了,然后嗝屁在了一个非常奇怪的地方。
首先呢,我是怀疑变量出问题了,因为很显然,我们卡在了赋值这里,难不成是double类型的赋值出现了问题?
首先我尝试将double类型修改为了float类型,这里虽然觉得很大的可能并不是这个的原因,但是没有办法,程序确确实实卡在了这么个奇怪的地方,我当然也怀疑单片机在处理双精度浮点数是不是出问题了。
不过随着我修改完数据类型,问题并没有得到有效的解决,程序依旧是在这里卡住。
不过有一点非常奇怪,程序是在这个地方卡住没有错,但是卡住的位置会在这两个语句之间切换,就是可能是这条语句,也可能下一条语句!这时候我已经有一点懵逼了,不过为了确认程序卡在了哪里(通常这个情况是进异常中断了)我们暂停程序,查看程序指针当前的位置。
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 */ }}
我发现程序指针所在的位置非常的奇怪,程序指针这时候卡在的地方是一个异常中断没错,但是这个中断回调函数的所在.c文件居然是dma的附属文件,没错这份工程是开了ADC的DMA采样的,采样的数据是传输进入DMA的。
这说明问题的主要的原因和DMA有关系,并且查看关于这个中断的说明造成这个中断的主要原因是:
-
**
未完成硬件初始化而使用硬件
** -
**
数据越界
** -
**
野指针
**
其实这三个的问题都可以归类为指针问题,而由于我的程序是初始化部分是正常执行的,那么可以排除硬件初始化未完成导致的异常。
至于野指针也几乎没有出现使用指针而未声明的情况。
因此大概率是数组越界导致的原因,结合出现在DMA文件的报错,猜测可能是由于DMA传输的时候,缓存区和缓存区大小不匹配,导致传入数据的时候,索引超出发生数组越界错误。
HAL_UART_Transmit (&huart1,(uint8_t*)message1,strlen(message1),100);end(); HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); HAL_ADCEx_Calibration_Start(&hadc1); //ad校准 HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Value,1024);
之后去查看DMA的缓存区,发现其数组大小是100(其实这时候我就知道了)因为我之前使用ADC信号的缓存区大小通常是1024的,再不济也是2的倍数,因为这样子好方便计算机处理。
所以这里的主要原因还是在于DMA传输的时候数组越界问题。 而ADC的触发采样则正好是定时器触发,定时器触发越界之后刚好卡在了那段话。
这类也提醒大家,一定要注意编程习惯,如果在编程中我们习惯性的使用宏定义的方式来编程,就能即方便而又能有效的规避掉这类的错误。
同样的关于STM32的中断源除了我们常见的硬件中断例如定时器,外部中断等等。
还不能忽略了其 软件中断 ,包括一些硬件错误,未知命令错误以及我们程序员自己出现的错误,因此关注我们的中断错误类型可以有效 地
避免我们的程序出现很多异常的错误。也可以帮助我们更快地修改我们的异常代码。