在用28335取樣的時候,難免會碰到因為資料型別的問題導致無法順利從結果暫存器adcresult中提取到我們想要的值,
尋其原因是因為在結果暫存器中的資料型別,和我們需要精確讀出的資料型別不同,
尤其是adc是存在比例關係的,在進行除法運算的時候經常會出現錯誤,
所以在此分享一下我提取的方法,主要運用volatile限定符來改變資料型別。
1 volatile限定符
當乙個物件的值可能會在編譯器的控制或檢測之外被改變時,例如乙個被系統時鐘更新的變數,那麼物件應該宣告成volatile。
一般說來,volatile用在如下的幾個地方:
1、中斷服務程式中修改的供其它程式檢測的變數需要加volatile;
2、多工環境下各任務間共享的標誌應該加volatile;
3、儲存器對映的硬體暫存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;
另外,以上這幾種情況經常還要同時考慮資料的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1中可以通過關中斷來實現,2中可以禁止任務排程,3中則只能依靠硬體的良好設計了。
簡單點:
就是該變數會以編譯器無法預知的方式發生變化,請編譯器不要做優化(所有的編譯器的優化均假設編譯器知道變數的變化規律)
2 adc結果暫存器介紹
首先我們看結果暫存器,f28335內部a/d只有12位,用16位的結果暫存器來儲存,所以必然有四位是空著的,如下表所示是從15-4位的有效位。
然後再看結果暫存器內的資料型別
從下圖標頭檔案的定義我們可以看出,在結果暫存器內uint16型,而uint16代表unsigned int即無符號整型。而我們需要讀取的一般是小數,即浮點型。f28335的浮點型是有7位小數的,
所以我們就需要用volatile限定符來定義我們的讀取值
volatile uint16 sampletable[1];
volatile float adc0=0;
讀取部分
sampletable[0]= ( (adcregs.adcresult0)>>4);
adc0=(float)sampletable[0] * 3.0 /4096.0;
首先定義其為volatile變數,然後從暫存器adcregs.adcresult0內讀取出其10進製的值,並通過(float)操作強制轉換資料型別為浮點型,使其計算值能夠賦給同為volatile float 型的 adc0,並且在後面的乘法和除法運算中也要使用3.0和4096.0
這是因為
1.計算算術表示式結果時,相同資料型別的資料/變數進行運算,結果保持原有資料型別。
2.當不同資料型別的資料/變數進行運算時,結果為精度高的資料型別。
小結:
整體而言,從暫存器adcregs.adcresult0到 我們需要的1.34423這種數,需要從
16進製制(uint16)———> 十進位制(uint16)——> float
通過使得中間這個十進位制數變成 volatile 能夠有效的防止因為資料型別的轉換和除法導致的錯誤。
F28335 ADC學習過程
1 adc轉換步驟 a d轉換器 adc 將模擬量轉換為數字量通常要經過四個步驟 取樣 保持 量化和編碼 2 adc的關鍵指標 舉個例子講解以上四個指標 例如f28335的ad轉換模組是12位的,ad的最大時鐘頻率為25mhz,取樣速率12.5msps,如果要對乙個1v電壓進行取樣,解析度 1 2的...
資料型別 型別轉換
這樣的語句將報錯,因為char型別精度低於int型別,編譯器無法將其自動轉換,只能進行強制轉換 int x 65 char ch char x 舉例1 int age 19 char 女 char result age int 不可以自動轉換成char 精度損失 舉例2 int a 10 int b...
Objective C資料型別 資料型別轉換
資料型別 1.objective c資料型別可以分為 基本資料型別 物件資料型別和id型別。2.基本資料型別有 int float double和char型別。3.物件型別就是類或協議所宣告的指標型別,例如 nsautoreleasepool pool 其中,nsautoreleasepool是乙個...