• 一个低级错误导致的诡异现象——走近科学能拍三集,(C语言)最简单的数组元素读取,不正确!?


    二维数组,存放ADC采集到的8个通道值,每个通道连续采集20次,用来滤波。数据由DMA直接写入数组ADC_RESULT[20][8]中。

    在使用数组元素时,发现无法正确读取元素值。

    通过内存监控watch数组,所有值都是正常的。

    但是每次使用赋值语句,读取相邻4个数值,诡异事情就发生了

    实际数组值是:

    ADC1_RESULT[0][0]==0;

    ADC1_RESULT[1][0]==0;

    ADC1_RESULT[2][0]==0;

    ADC1_RESULT[3][0]==0;

     

     

    但是经过赋值语句之后

     

    发现TEMP1=0;TEMP2=0x07EA;TEMP3=0;TEMP4=0x07EA;

     

     

    经过比对,0x07EA的值是ADC1_RESULT[0][4]的值;

     

    1、我第一反应是类型不对,ADC采集到的数据是16位的。但是马上就否决了,数组也是16位的,而且即使类型不对,也不会出现这种现象。

    2、查看定义的数组下标[20][8],没有问题。

    3、查看DMA设置,尤其是数据类型,也没有问题。

    4、编译器设置,没有问题。

    反复的测试,修改,就是无法正确赋值。

    明明watch中可以看到正确的值,经过赋值语句就变了

    我又试着在main程序中调用数组赋值,结果又可以正确赋值了。

    突然脑中灵光一闪,再次检查了定义的数组。终于发现了问题所在。这就是为什么上面的字加粗加色的原因。

    ADC_RESULT数组定义在MAIN.H中

    而计算是在DMA中断时处理,不在MAIN.C文件中,所以中断文件stm32f10x_it.c中引用的数组是使用了语句

    extern uint16_t ADC1_RESULT[20][4];

    没错,这里的下标写错了

    MAIN.H中的定义是ADC1_RESULT[20][8];

    之前只检查了MAIN.H中定义的脚标,忽略了引用时定义的脚标。

    低级错误,其实早该想到的。只是现象太诡异,想多了。而且这种错误,编译器不会报错。所以就理所当然的忽略了。

    反过来看,当脚标由8变成了4,数组数据便重新进行了划分,本来8个元素1组,现在4个元素变成了1组。本来是赋值的是第0/8/16/24元素,现在变成了第0/4/8/12元素。这也就是为什么TEMP2会得到[0][4]的值。一切解释得通了。TEMP4得到的其实是[1][4]的值,因为是连续采集,所以二者值几乎不变。

    至此,破案,真相果真只有一个。代价是半天时间浪费掉了。

  • 相关阅读:
    leetcode算法题--机器人的运动范围
    【Java】文件操作篇(二)字节输入流、字节输出流及常用子类
    SQL Server Management Studio (SSMS) 20.1 - 微软数据库管理工具
    js网络编程
    【数据结构】绪论
    二维码智慧门牌管理系统:智能化地址管理,提升社会治理效率
    用冒泡排序完成库函数qsort的作用
    【操作系统】页表映射
    Factory工厂合约的实现-solidity实现智能合约教程(6)
    基于Java发起HTTP请求实现文件的上传
  • 原文地址:https://blog.csdn.net/weixin_43128823/article/details/126028994