有符號與無符號數據傳輸--學習筆記

在調試CAN通信的時候,智能電錶會發送功率數據,功率可以爲正,也可以發送的是負功率。在接收傳輸數據的時候,遇到的一些問題,記錄一下。

首先粘貼幾個錯誤的代碼塊。

if(getCANMessage(CAN_RX_MSG_OBJ) > 0)
{
	PVpower = getCANMessage(CAN_RX_MSG_OBJ);
}
else
{
	PVpower = -getCANMessage(CAN_RX_MSG_OBJ);
}	
if(getCANMessage(CAN_RX_MSG_OBJ) > 0x186A0)
{
	PVpower = number - getCANMessage(CAN_RX_MSG_OBJ);
}
else
{
	PVpower = getCANMessage(CAN_RX_MSG_OBJ);
}

上面一個getCANMessage(CAN_RX_MSG_OBJ)這個函數的返回值爲有符號32位整型,下面一個是無符號的32位整型。首先這兩種寫法都犯了一個一樣的錯誤,getCANMessage(CAN_RX_MSG_OBJ)這個函數被調用了兩次,一來這樣浪費cpu性能,二來最重要的是,當第一次調用getCANMessage(CAN_RX_MSG_OBJ)函數的時候,相關寄存器的數值會被置位清零,因此第二次調用getCANMessage(CAN_RX_MSG_OBJ)的時候,返回值實際上是0,這也就是爲什麼機子上顯示的功率爲0的原因。

總結一下:雖然某個有返回值的函數,雖然是有返回值,但是也不能把它當一個變量來用。一來是計算性能會受到影響,二來是由於某些寄存器讀取數據的機制,讀取完了數據之後,會清零,所以下次再去讀取的時候只會讀到0;因此正確的做法是先用某個變量把函數返回值的數據提取出來,放在某個RAM片段上,然後再對該變量進行操作。

正確做法:

 PVpower = getCANMessage(CAN_RX_MSG_OBJ);
            if(PVpower<0)
            {
                PVpower = abs(PVpower);
 //              flag=0;
            }
PVpower = getCANMessage(CAN_RX_MSG_OBJ);
if(getCANMessage(CAN_RX_MSG_OBJ) > 0x186A0)
{
	PVpower = number - getCANMessage(CAN_RX_MSG_OBJ);
}

第二種寫法前面已經#define number>0xFFFFFFFF;  這裏涉及到一個無符號整型的變量去接收一個負數的規則,當一個無符號整型的變量去接收一個負數的時候,講會以補碼的形式接收出來,因此我們在處理數據的時候返回原來數值就應該是以0xFFFFFFFF減去接收到的這個數據。當然準確值應該是:

PVpower = number - getCANMessage(CAN_RX_MSG_OBJ) + 1;

因爲這個影響不大,因此在工程中就省去了。

下面一種寫法也是利用無符號的變量去接收一個負數的。

PVpower = getCANMessage(CAN_RX_MSG_OBJ);
if((PVpower>>31) == 1)
{
	PVpower = ~PVpower ;
	flag = 1;
}
else
{
	flag = 0;
}

這裏是利用取反這個操作,應該多學習這個操作,而不是我上面用的粗暴的用number去減。當然,準確值是~Pvpower+1    。

爲了補充一下這個地方關於無符號的變量去接收負數,這裏還舉一個例子。

#include<stdio.h>

int main(void)
{
	unsigned int a ;
	int b = -2;
	a = b;
	printf("%8x\n",a);
	printf("%8x\n",~a+1);
	printf("%8x\n",0xFFFFFFFF-a+1);
	
	return 0;
}

最後輸出的如上所示。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章