appwyp 2023-03-23 06:13 采纳率: 43.8%
浏览 69
已结题

位操作 寄存器 数据正负表示

下图是Sensor 的datasheet. 按我的理解这是 24位ADC (bit0 - bit23) 其中 bit21,22,23 是符号位,bit0 到 bit20是数据位。
stm32F4 板子
官网给的sample code 里面,在表示负数的adc值 没看明白,


bit21-23 符号位有4种情况 ,
(000) 正数 并没有超出正的最大值
(111) 负数 并没有超出负数的最小值
(001)正数但超出了正的最大值
(110)负数但超出了负数的最小值
故用一个int32的变量 adc_data 来表示 adc 的值
int32_t  adc_data = 0;

adc_data = (int32_t)(((SensorData[0] << 16) | (SensorData[1] << 8) | (SensorData[2] << 0))&0xFFFFFF);
 uint8_t sign = 0;
 sign =(uin8_t) ((adc_data & 0xE00000) >> 21);   //1110 0000, 0000 0000, 0000 0000

                                adc_data = (adc_data & 0x1FFFFF); //0001 1111, 1111 1111, 1111 1111

                                switch (sign)
                                {

                                    case 0: // Positive and lower than positive full-scale (within full-scale range)
                                        {
                                            adc_data = (adc_data & 0x1FFFFF);   //0001 1111, 1111 1111, 1111 1111
                                            break;
                                        }
                                    case 7: // Negative and higher than negative full-scale (within full-scale range)
                                        {
                                            adc_data = (adc_data & 0x1FFFFF) * (-1);// 我认为应该这样
                                            adc_data = (adc_data | 0xFFE00000); //官网给的代码 不理解
                                            break;
                                        }

                                    case 1:  //Out of Positive Full scale
                                        {
                                            adc_data = 0x1FFFFF; //0001 1111, 1111 1111, 1111 1111
                                            break;
                                        }

                                    case 6: // Out of Negative Full scale 
                                        {
                                             adc_data = 0x1FFFFF * (-1); // 我认为应该这样
                                             adc_data = 0xFFE00000; //  官网给的代码 不理解而且0xFFE00000 = 4,292,870,144 已经超出  int32 表示范围
                                            break;
                                        }

                                    default:
                                        {
                                            break;
                                        }
                                }// END switch


img

  • 写回答

6条回答 默认 最新

  • LegendOfBear 2023-03-23 08:35
    关注
    1. 按照他文档的说法,如果是正数就直接输出,如果是负数,是按照补码输出的。文档中最小负分度值的表示就是111111...1111(一共24个1),这就是正数1的补码(补码就是将一个数字逐位取反然后再加1)。
    2. 在确认了补码的情况下,一般地,stm32编译器会把int32_t认为是占32个bit位的变量,而现在直接读取ADC结果的时候只会返回24位数值(其中高3位表示符号和是否超出表示范围),如果ADC的读出结果是一个正数,那么只需要将符号位截去,保留低21位就可以了,代码里的表现就是
    
    adc_data = (adc_data & 0x1fffff)
    
    1. 而对于负数而言,还是拿最小负分度值举例子,你读到的是24个1,这个数字如果赋值给一个int32类型的变量,原来的高3位符号位就会变成有效数值,这不是我们想要的,而原来24个1对应到32位里,应该是32个1才对。所以实现上应该用读出的数据或上0xffe00000
    2. int32_t这个变量能表示的范围是“-2147483648”到“2147483647”,只看正数那边的话,16进制是0x00000000i到0x7fffffff
      纯手打,望采纳,可以迭代提问 :)
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 3月31日
  • 已采纳回答 3月23日
  • 赞助了问题酬金15元 3月23日
  • 赞助了问题酬金15元 3月23日
  • 展开全部

悬赏问题

  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?