free性丰满hd毛多多,久久综合给合久久狠狠狠97色69 ,欧美成人乱码一区二区三区,国产美女久久久亚洲综合,7777久久亚洲中文字幕

0
問答首頁 最新問題 熱門問題 等待回答標(biāo)簽廣場
我要提問

單片機(jī)

電腦(PC)通過串口向單片機(jī)發(fā)送浮點(diǎn)數(shù)(float、double)的方法

電腦(PC)通過串口向單片機(jī)發(fā)送浮點(diǎn)數(shù)(float、double)的方法version1.0maswellxiao         在實(shí)際應(yīng)用中我們可能會遇到這樣一個(gè)問題,PC機(jī)要向單片機(jī)發(fā)送一個(gè)浮點(diǎn)數(shù),float類型、double類型也好。maswell我曾經(jīng)做過AD轉(zhuǎn)換并發(fā)送數(shù)據(jù)到MATLAB中做FFT、濾波器等數(shù)字信號處理。處理完畢以后maswell我遇到一個(gè)非常棘手的問題……MATLAB數(shù)據(jù)處理完畢以后得到的數(shù)據(jù)類型是小數(shù)類型,就算忽略后幾位精度,最起碼也是一個(gè)float數(shù)據(jù)類型的數(shù),怎么把這個(gè)數(shù)發(fā)送到單片機(jī)呢?         經(jīng)過幾天的折騰。maswell我一不小心就實(shí)現(xiàn)PC通過串口向單片機(jī)發(fā)送浮點(diǎn)小數(shù)。下面把這種方法分享給大家。         首先我們需要一個(gè)預(yù)備知識。也就是float數(shù)據(jù)類型在單片機(jī)中的存儲方式。         float數(shù)據(jù)類型總共占據(jù)32個(gè)位bit,其中第一個(gè)位為數(shù)據(jù)符號(Symbol,在下面簡稱為S)該位表示數(shù)據(jù)的正負(fù)性。接下來8個(gè)位是階碼(Expoent,下面簡稱為E),這8個(gè)位表示浮點(diǎn)數(shù)的小數(shù)點(diǎn)的位置。最后有23位的尾數(shù)(mantissa,M),這23個(gè)位表示數(shù)據(jù)。下面做個(gè)示意圖  1位S  8個(gè)位E23個(gè)位M         例如:十進(jìn)制的數(shù)據(jù)Nfile:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png將之換成二進(jìn)制表示file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.pngfile:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.pngfile:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.pngfile:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image010.png因此file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.png并由公式file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image014.png得file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image016.png組合起來就是  S  EM0file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image018.pngfile:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image020.png4bit一格隔開  0100  001011110110111010010111100142F6E979因此十進(jìn)制浮點(diǎn)小數(shù)N = 123.456在單片機(jī)里存儲的數(shù)據(jù)為0x42F6E979         

提問者:gvjhvbc 地點(diǎn):- 瀏覽次數(shù):2996 提問時(shí)間:10-19 17:43
我有更好的答案
提 交
2條回答
semiaxis 07-29 02:12

至此,我們的思路有了一點(diǎn)了。PC機(jī)向單片機(jī)發(fā)送十六進(jìn)制代碼0x42F6E979就意味著向單片機(jī)發(fā)送浮點(diǎn)小數(shù)123.456了。

下面是MATLAB向單片機(jī)發(fā)送數(shù)據(jù)的一段代碼

function pushbutton7_Callback(hObject, eventdata, handles)

% hObject    handle to pushbutton7 (see GCBO)

% eventdata  reserved - to be defined in a future version of MATLAB

% handles    structure with handles and user data (see GUIDATA)

global s;

global TxDataToMSP430;

TxDataHex = num2hex(single(TxDataToMSP430));

fwrite(s,'dcba','uchar');%協(xié)議密碼

t1 =clock;

while 1

    if fread(s,1) == hex2dec('af');

        break;

    end

    if etime(clock , t1) > 1%1秒鐘內(nèi)未收到數(shù)據(jù)則放棄

        break ;

    end

end

TxDataHexTemp(1) = TxDataHex(1);

TxDataHexTemp(2) = TxDataHex(2);

fwrite(s,base2dec(TxDataHexTemp,16),'uchar');%協(xié)議數(shù)據(jù)

         我當(dāng)初做的是一個(gè)GUI界面,函數(shù)名是MATLAB自動(dòng)生成的,我的下位機(jī)用的是MSP430G2553單片機(jī)。編譯環(huán)境CCS5.2

volatile float DisplayData1,DisplayData2,DisplayData3,DisplayData4;

volatile long DisplayData;//接收到的數(shù)據(jù)轉(zhuǎn)換前數(shù)據(jù)

unsigned char TXVolFlag = 0;

static char FrameHeaderFlag = 1;//識別幀頭標(biāo)志位

static char StopTxFlag = 0;//上位機(jī)發(fā)送停止發(fā)送標(biāo)志

unsigned char ReadDataClassFlag = 0x00;//讀數(shù)據(jù)包格式

         以上為全局變量。注意DisplayData為long數(shù)據(jù)類型

#pragma vector=USCIAB0RX_VECTOR

__interrupt void USCI0RX_ISR(void)

{

    static char k = 0;

    if(FrameHeaderFlag)

    {

        ReadDataClassFlag = IdentifyHeader();

        if(ReadDataClassFlag != 0x00)//識別幀頭

            FrameHeaderFlag = 0;

    }

    else//上一次讀到的temp不是0,說明握手成功

    {

        switch(ReadDataClassFlag)

        {

        case 0xaf:

        case 0xbe:

        case 0xcc:

        case 0xdb:

            switch(k)

            {

            case 0:

                DisplayData = UCA0RXBUF;

                DisplayData <<= 8;

                k = 1;

                break;

            case 1:

                DisplayData += UCA0RXBUF;

                DisplayData <<= 8;

                k = 2;

                break;

            case 2:

                DisplayData += UCA0RXBUF;

                DisplayData <<= 8;

                k = 3;

                break;

            case 3:

                DisplayData += UCA0RXBUF;

                k = 0;

                switch(ReadDataClassFlag)

                {

                ///////////////////////////////////接收數(shù)據(jù),以下是接收數(shù)據(jù)的控制字

                case 0xaf:DisplayData1 = *((float *)&DisplayData);break;

                case 0xbe:DisplayData2 = *((float *)&DisplayData);break;

                case 0xcc:DisplayData3 = *((float *)&DisplayData);break;

                case 0xdb:DisplayData4 = *((float *)&DisplayData);break;

                default:;

                }

                FrameHeaderFlag = 1;//幀數(shù)據(jù)接收完畢,32個(gè)bit數(shù)據(jù)為一幀

                break;

            default:;

            }

            break;

        case 0xfa://停止發(fā)送的密碼

            IdentifyHeader();

            break;

        default:;

        }

    }

}

我這個(gè)函數(shù)是MSP430G2553單片機(jī)的接受中斷函數(shù),單片機(jī)串口接收到數(shù)據(jù)后進(jìn)入中斷,首先判斷是不是協(xié)議的幀頭(我這里自行定義了一個(gè)協(xié)議)如果不是幀頭,則是數(shù)據(jù),進(jìn)入數(shù)據(jù)的判斷,由于PC機(jī)發(fā)送的是32位的數(shù)據(jù),而UART只支持接收8位的數(shù)據(jù),故此用了四個(gè)case語句判斷。接收完32位的數(shù)據(jù)以后,問題又來了,我們用來存儲接收來的數(shù)據(jù)是long類型(volatile long DisplayData;)的。而我們需要接收的數(shù)據(jù)是float數(shù)據(jù)類型的。故此還需要一個(gè)轉(zhuǎn)換。其實(shí)這個(gè)轉(zhuǎn)換很簡單。一個(gè)語句就可以了。

DisplayData1 = *((float *)&DisplayData);

首先將DisplayData的地址強(qiáng)制轉(zhuǎn)換為float數(shù)據(jù)類型的地址,然后再對地址取值就可以了。至此,就可以完整地將long數(shù)據(jù)類型轉(zhuǎn)換為float數(shù)據(jù)類型。

         那么一整個(gè)過程就可以完整地實(shí)現(xiàn),從PC機(jī)發(fā)送1、0代碼到MSP430單片機(jī)接收為long數(shù)據(jù)類型,再由long數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)換為float數(shù)據(jù)類型。

         那么同樣道理,我們可以用同樣的方法將long long數(shù)據(jù)類型轉(zhuǎn)換為double數(shù)據(jù)類型。

pmet 08-01 09:04

我們每次接受一個(gè)float數(shù)據(jù),只需把這個(gè)數(shù)據(jù)從long轉(zhuǎn)換成float就行了,為什么這里要分四種情況         

                case 0xafisplayData1 = *((float *)&DisplayData);break;

                case 0xbeisplayData2 = *((float *)&DisplayData);break;

                case 0xccisplayData3 = *((float *)&DisplayData);break;

                case 0xdbisplayData4 = *((float *)&DisplayData);break;

            

撰寫答案
提 交
1 / 3
1 / 3
相關(guān)單片機(jī)
具有音調(diào)控制的單片機(jī)立體聲前置放大器
用于單片機(jī)與電子裝置中的開關(guān)電源
單片機(jī)軟硬件復(fù)位的條件都有啥
電動(dòng)機(jī)的單片機(jī)控制
單片機(jī)應(yīng)用系統(tǒng)開發(fā)實(shí)例導(dǎo)航