完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一般情况下,ADC与单片机的通讯方式都是串行的,可能是IIC、SPI等。假设现在有一个24位的ADC,那么在正常工作时,单片机将依次接收到24bit的数据。ADC的数据是24位的,但是没有24位的数据类型。在单片机中,int类型的数据一般是32位的。所以需要一个函数来完成两者的转换。
首先我们要搞清楚计算机中数字的二进制存储形式。对于一个24位数,其计算关系可用下面的公式表达: 对于一个32位数,其计算关系可用下面的公式表达: 显而易见,对于一个正数来说,要拓宽它的位数,只需要在其多出来的位上补0即可。因为只是多项式中多加了几个0而已,并不会改变数据的大小。 而如果我们转换的数据是一个负数,问题就不那么简单了。 首先我们要搞清楚负数是怎么存储的。计算机中的负数是以补码形式存储的,即补码=原码取反+1。就是对正数先取反码,然后再加1。前面我们已经搞清楚了对一个正数该怎么拓宽,即补0。如果对拓宽后的这个正数再进行取反然后加1,那么我们是不是得到了一个位数改变的负数呢?答案肯定是对的。 假设我们现在有一个负数,我们可以先倒推回去,将其变成正数,然后用我们确定正确的方式对这个正数进行转换,然后把正数再变成负数。此时得到的负数位数已经是改变了的。可能有点绕,但确实是可行的。我们会发现,其实最终的效果是在多出来的位上补了1。这是因为我们对正数补0之后取了反,那就相当于直接补1了。 下面开始编写我们的代码。这里定义一个数组adc[3],用来存储ADC的数据。将接收到的三字节数据由低到高依次放置到数组中。即adc[0]放置低字节,adc[1]放置中间的字节,adc[2]放置高字节。 int adc24to32(unsigned char *padc); 此函数的输入参数为数组的地址。函数内部完成数据的转换,返回值为转换之后的32位数据。 在函数内定义一个int型的数据value,然后再定义一个指向value的指针。然后将数组中的数据搬到value所在的地址中。 *p = *padc; *(p+1) = *(padc+1); *(p+2) = *(padc+2); 此处我们默认按照正数处理,然后判断其符号。判断是不是负数只需要判断*(padc+2)的最高位是不是1即可,将其与0x80相与,如果结果为1则表示其为负数,反之则不是。即: if(*(padc+2) & 0x80) { *(p+3) = 0xff; return value; } else { return value; } 假设我们现在有如下数据,下面对其一一进行检验。
这里定义三个数组来存储我们的原始数据,LL为数据的低字节,MM是数据的中间字节,HH为数据的高字节。在测试的时候,给adc[ ]赋值,然后调用刚才编写的函数。最后将结果打印出来,跟预期的结果进行对比,就可以知道我们的函数有没有错误。 unsigned char LL[7] = {0xff,0x00,0x01,0x00,0xff,0x00,0x00}; unsigned char MM[7] = {0xff,0x00,0x00,0x00,0xff,0x00,0x00}; unsigned char HH[7] = {0x7f,0x40,0x00,0x00,0xff,0xc0,0x80}; 然后我们定义一个for循环,依次取出其中的数据进行检验 int main( ) { int i; for(i = 0; i < 7; i++) { adc[0] = LL; adc[1] = MM; adc[2] = HH; value = adc24to32(adc); printf("nThis 24bit value %02x%02x%02x change to int32 is %dn",adc[2],adc[1],adc[0],value); } return 0; } 程序运行的结果如下: 跟表格里的结果进行对比,可知程序没有错误。 |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 08:01 , Processed in 3.254591 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号