久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 24724|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

如何將下位機(jī)采集的浮點(diǎn)型數(shù)據(jù)發(fā)送給上位機(jī)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:69862 發(fā)表于 2015-1-29 22:15 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本帖最后由 xiao_yp2014 于 2016-1-21 14:21 編輯

大家好!我叫肖亞平,從小熱愛(ài)上了電子技術(shù),讀書時(shí)陰差陽(yáng)錯(cuò)的選擇了電子這方面的專業(yè),學(xué)習(xí)電子技術(shù)、一直到今年畢業(yè)。對(duì)于我的理解來(lái)說(shuō),學(xué)校里面學(xué)到的技術(shù)不是全部實(shí)用,但是必須有用,所以一直奮斗在前線。我對(duì)學(xué)習(xí)總結(jié)出一句話“壓力不是有人努力,而是比你牛X N倍的人依然在努力

在有些項(xiàng)目中,需要單片機(jī)把數(shù)據(jù)處理完后,返回給上位機(jī),數(shù)據(jù)處理離不成計(jì)算,有計(jì)算就會(huì)涉及到小數(shù),那么,如何將小數(shù)轉(zhuǎn)換成十六進(jìn)制數(shù)據(jù)呢,下面請(qǐng)看簡(jiǎn)便算法。

上位機(jī)發(fā)送命令:01 02 EB 00 55   
下位機(jī)返回-5.625 的十六進(jìn)制數(shù)據(jù) C0 B4 00 00


  1. #include "REG52.H"

  2. #define const_voice_short  40 //蜂鳴器短叫的持續(xù)時(shí)間
  3. #define const_rc_size  10     //接收串口中斷數(shù)據(jù)的緩沖區(qū)數(shù)組大小

  4. #define const_receive_time  5 //如果超過(guò)這個(gè)時(shí)間沒(méi)有串口數(shù)據(jù)過(guò)來(lái),就認(rèn)為一串?dāng)?shù)據(jù)已經(jīng)全部接收完,這個(gè)時(shí)間根據(jù)實(shí)際情況來(lái)調(diào)整大小

  5. unsigned char xdata array[10];//緩存數(shù)組

  6. float value = -5.625;                  //模擬下位機(jī)采集經(jīng)過(guò)計(jì)算后的數(shù)據(jù)
  7. /*
  8. -5.625 = C 0 B 4 0 0 0 0

  9. C    0     B   4     0   0    0    0
  10. 1100 0000 1011 0100 0000 0000 0000 0000
  11. 按照浮點(diǎn)數(shù)格式切割成相應(yīng)的域 1 1000 0001 01101 000000000000000000
  12. 經(jīng)分析:符號(hào)域1 意味著負(fù)數(shù);指數(shù)域?yàn)?29 意味著實(shí)際的指數(shù)為2 (減去偏差值127);
  13. 尾數(shù)域?yàn)?1101 意味著實(shí)際的二進(jìn)制尾數(shù)為1.01101 (加上隱含的小數(shù)點(diǎn)前面的1)。
  14. 所以,實(shí)際的實(shí)數(shù)為:
  15. = -1.01101 × 2^2 =- ( 1*2^0 + 1*2^(-2) + 1*2^(-3) + 1*2^(-5) ) × 2^2
  16. = -(1+0.25+0.125+0.03125)*4
  17. = -1.40625*4
  18. = -5.625
  19. */

  20. void initial_myself(void);   
  21. void initial_peripheral(void);
  22. void delay_long(unsigned int uiDelaylong);



  23. void T0_time(void);       //定時(shí)中斷函數(shù)
  24. void usart_receive(void); //串口接收中斷函數(shù)
  25. void usart_service(void); //串口服務(wù)程序,在main函數(shù)里

  26. sbit beep_dr=P3^6; //蜂鳴器的驅(qū)動(dòng)IO口

  27. unsigned int  uiSendCnt=0;     //用來(lái)識(shí)別串口是否接收完一串?dāng)?shù)據(jù)的計(jì)時(shí)器
  28. unsigned char ucSendLock=1;    //串口服務(wù)程序的自鎖變量,每次接收完一串?dāng)?shù)據(jù)只處理一次
  29. unsigned int  uiRcregTotal=0;  //代表當(dāng)前緩沖區(qū)已經(jīng)接收了多少個(gè)數(shù)據(jù)
  30. unsigned char ucRcregBuf[const_rc_size]; //接收串口中斷數(shù)據(jù)的緩沖區(qū)數(shù)組
  31. unsigned int  uiRcMoveIndex=0;  //用來(lái)解析數(shù)據(jù)協(xié)議的中間變量


  32. unsigned int  uiVoiceCnt=0;  //蜂鳴器鳴叫的持續(xù)時(shí)間計(jì)數(shù)器

  33. void usart_send();                //串口發(fā)送程序
  34. void  Change();                        //將浮點(diǎn)弄轉(zhuǎn)換成字符弄

  35. void main()
  36. {
  37.         initial_myself();  
  38.         delay_long(100);   
  39.         initial_peripheral();

  40.         while(1)  
  41.         {
  42.            usart_service();  //串口服務(wù)程序
  43.         }
  44. }

  45. union                            //聯(lián)合體定義
  46. {
  47.     char a[4];
  48.         float b;
  49. }temp;

  50. void usart_service(void)  //串口服務(wù)程序,在main函數(shù)里
  51. {
  52. /* 注釋一:
  53. * 識(shí)別一串?dāng)?shù)據(jù)是否已經(jīng)全部接收完了的原理:
  54. * 在規(guī)定的時(shí)間里,如果沒(méi)有接收到任何一個(gè)字節(jié)數(shù)據(jù),那么就認(rèn)為一串?dāng)?shù)據(jù)被接收完了,然后就進(jìn)入數(shù)據(jù)協(xié)議
  55. * 解析和處理的階段。這個(gè)功能的實(shí)現(xiàn)要配合定時(shí)中斷,串口中斷的程序一起閱讀,要理解他們之間的關(guān)系。
  56. */
  57.      if(uiSendCnt>=const_receive_time&&ucSendLock==1) //說(shuō)明超過(guò)了一定的時(shí)間內(nèi),再也沒(méi)有新數(shù)據(jù)從串口來(lái)
  58.      {

  59.             ucSendLock=0;    //處理一次就鎖起來(lái),不用每次都進(jìn)來(lái),除非有新接收的數(shù)據(jù)

  60.                     //下面的代碼進(jìn)入數(shù)據(jù)協(xié)議解析和數(shù)據(jù)處理的階段
  61.                uiRcMoveIndex=uiRcregTotal; //由于是判斷數(shù)據(jù)尾,所以下標(biāo)移動(dòng)變量從數(shù)組的最尾端開(kāi)始向0移動(dòng)

  62.             while(uiRcMoveIndex>=5)   //如果處理的數(shù)據(jù)量大于等于5(2個(gè)有效數(shù)據(jù),3個(gè)數(shù)據(jù)頭)說(shuō)明還沒(méi)有把緩沖區(qū)的數(shù)據(jù)處理完
  63.             {
  64.                if(ucRcregBuf[uiRcMoveIndex-3]==0xeb&&ucRcregBuf[uiRcMoveIndex-2]==0x00&&ucRcregBuf[uiRcMoveIndex-1]==0x55)  //數(shù)據(jù)尾eb 00 55的判斷
  65.                {
  66.                                         if(ucRcregBuf[uiRcMoveIndex-5]==0x01&&ucRcregBuf[uiRcMoveIndex-4]==0x02)  //有效數(shù)據(jù)01 02的判斷
  67.                                         {
  68.                                                 usart_send();        //收到正確的數(shù)據(jù)后,開(kāi)發(fā)發(fā)送采集到的數(shù)據(jù)
  69.                                                 uiVoiceCnt=const_voice_short; //蜂鳴器發(fā)出聲音,說(shuō)明數(shù)據(jù)發(fā)送完畢
  70.                                                 
  71.                                         }
  72.                   break;   //退出循環(huán)
  73.                }
  74.                uiRcMoveIndex--; //因?yàn)槭桥袛鄶?shù)據(jù)尾,下標(biāo)向著0的方向移動(dòng)
  75.            }

  76.            uiRcregTotal=0;  //清空緩沖的下標(biāo),方便下次重新從0下標(biāo)開(kāi)始接受新數(shù)據(jù)
  77.      }

  78. }

  79. void usart_send()           //串口發(fā)送
  80. {
  81.     static unsigned int ucSendCnt = 0;

  82.         ES = 0; //關(guān)串口中斷
  83.         TI = 0; //清零串口發(fā)送完成中斷請(qǐng)求標(biāo)志
  84.         Change();
  85.         
  86.         for(ucSendCnt = 0;ucSendCnt<4;ucSendCnt++)//發(fā)送四個(gè)字節(jié),表示一個(gè)浮點(diǎn)數(shù)
  87.         {
  88.              SBUF = array[ucSendCnt];                        //將數(shù)據(jù)裝入緩沖區(qū)
  89.              delay_long(50);                                        //延時(shí)一會(huì)兒
  90.         }
  91.         
  92.         TI = 0; //清零串口發(fā)送完成中斷請(qǐng)求標(biāo)志
  93.         ES = 1; //允許串口中斷
  94. }

  95. /*
  96. 聯(lián)合休:
  97. 當(dāng)多個(gè)數(shù)據(jù)需要共享內(nèi)存或者多個(gè)數(shù)據(jù)每次只取其一時(shí),可以利用聯(lián)合體(union)。
  98.      在C Programming Language 一書中對(duì)于聯(lián)合體是這么描述的:
  99.      1)聯(lián)合體是一個(gè)結(jié)構(gòu);
  100.      2)它的所有成員相對(duì)于基地址的偏移量都為0;
  101.      3)此結(jié)構(gòu)空間要大到足夠容納最"寬"的成員;
  102.      4)其對(duì)齊方式要適合其中所有的成員;

  103. 下面解釋這四條描述:
  104.      由于聯(lián)合體中的所有成員是共享一段內(nèi)存的,因此每個(gè)成員的存放首地址相對(duì)于于聯(lián)合體變量
  105.          的基地址的偏移量為0,即所有成員的首地址都是一樣的。為了使得所有成員能夠共享一段內(nèi)存,
  106.          因此該空間必須足夠容納這些成員中最寬的成員。對(duì)于這句“對(duì)齊方式要適合其中所有的成員”是
  107.          指其必須符合所有成員的自身對(duì)齊方式。
  108. */
  109. void  Change()
  110. {
  111.      temp.b   = value;                //將數(shù)據(jù)存入聯(lián)合休中
  112.      array[0] = temp.a[0];        //一個(gè)字節(jié)一個(gè)字節(jié)的取出來(lái)
  113.      array[1] = temp.a[1];
  114.      array[2] = temp.a[2];
  115.      array[3] = temp.a[3];
  116. }

  117. void T0_time(void) interrupt 1    //定時(shí)中斷
  118. {
  119.         TF0=0;  //清除中斷標(biāo)志
  120.         TR0=0; //關(guān)中斷
  121.         
  122.          uiSendCnt++;    //表面上這個(gè)數(shù)據(jù)不斷累加,但是在串口中斷里,每接收一個(gè)字節(jié)它都會(huì)被清零,除非這個(gè)中間沒(méi)有串口數(shù)據(jù)過(guò)來(lái)

  123.         if(uiSendCnt>=const_receive_time)   //如果超過(guò)這個(gè)時(shí)間沒(méi)有串口數(shù)據(jù)過(guò)來(lái),就認(rèn)為一串?dāng)?shù)據(jù)已經(jīng)全部接收完
  124.         {
  125.             ucSendLock=1;     //開(kāi)自鎖標(biāo)志
  126.         }
  127.         
  128.         if(uiVoiceCnt!=0)
  129.         {
  130.             uiVoiceCnt--; //每次進(jìn)入定時(shí)中斷都自減1,直到等于零為止。才停止鳴叫
  131.             beep_dr=0;  //蜂鳴器是PNP三極管控制,低電平就開(kāi)始鳴叫。
  132.         }
  133.         else
  134.         {
  135.             ; //此處多加一個(gè)空指令,想維持跟if括號(hào)語(yǔ)句的數(shù)量對(duì)稱,都是兩條指令。不加也可以。
  136.             beep_dr=1;  //蜂鳴器是PNP三極管控制,高電平就停止鳴叫。
  137.         }
  138.         
  139.         
  140.         TH0=0xfe;   //重裝初始值(65535-500)=65035=0xfe0b
  141.         TL0=0x0b;
  142.         TR0=1;  //開(kāi)中斷
  143. }


  144. void usart_receive(void) interrupt 4                 //串口接收數(shù)據(jù)中斷        
  145. {        

  146.         if(RI==1)  
  147.         {
  148.                 RI = 0;
  149.                 ++uiRcregTotal;

  150.                 if(uiRcregTotal>=const_rc_size)  //超過(guò)緩沖區(qū)
  151.                 {
  152.                     uiRcregTotal=const_rc_size;
  153.                 }
  154.                 ucRcregBuf[uiRcregTotal-1]=SBUF;   //將串口接收到的數(shù)據(jù)緩存到接收緩沖區(qū)里
  155.                 uiSendCnt=0;  //及時(shí)喂狗,雖然main函數(shù)那邊不斷在累加,但是只要串口的數(shù)據(jù)還沒(méi)發(fā)送完畢,那么它永遠(yuǎn)也長(zhǎng)不大,因?yàn)槊總(gè)中斷都被清零。
  156.         }
  157.         else  //我在其它單片機(jī)上都不用else這段代碼的,可能在51單片機(jī)上多增加" TI = 0;"穩(wěn)定性會(huì)更好吧。
  158.         {
  159.                 TI = 0;
  160.         }

  161. }                                


  162. void delay_long(unsigned int uiDelayLong)
  163. {
  164.    unsigned int i;
  165.    unsigned int j;
  166.    for(i=0;i<uiDelayLong;i++)
  167.    {
  168.       for(j=0;j<50;j++)  //內(nèi)嵌循環(huán)的空指令數(shù)量
  169.           {
  170.              ; //一個(gè)分號(hào)相當(dāng)于執(zhí)行一條空語(yǔ)句
  171.           }
  172.    }
  173. }


  174. void initial_myself(void)  //第一區(qū) 初始化單片機(jī)
  175. {

  176.           beep_dr=1; //用PNP三極管控制蜂鳴器,輸出高電平時(shí)不叫。
  177.         
  178.           //配置定時(shí)器
  179.           TMOD=0x01;  //設(shè)置定時(shí)器0為工作方式1
  180.           TH0=0xfe;   //重裝初始值(65535-500)=65035=0xfe0b
  181.           TL0=0x0b;
  182.         
  183.         
  184.           //配置串口
  185.           SCON=0x50;
  186.           TMOD=0X21;
  187.           TH1=TL1=-(11059200L/12/32/9600);  //這段配置代碼具體是什么意思,我也不太清楚,反正是跟串口波特率有關(guān)。
  188.           TR1=1;        
  189. }

  190. void initial_peripheral(void) //第二區(qū) 初始化外圍
  191. {

  192.            EA=1;     //開(kāi)總中斷
  193.            ES=1;     //允許串口中斷
  194.            ET0=1;    //允許定時(shí)中斷
  195.            TR0=1;    //啟動(dòng)定時(shí)中斷
  196. }
復(fù)制代碼




分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:67796 發(fā)表于 2015-1-29 22:35 | 只看該作者
標(biāo)題是不是寫錯(cuò)了?
帖子內(nèi)容講的是聯(lián)合體字節(jié)流。
這個(gè)方法比效率比sprintf高,但是代碼較多,適合于大量源數(shù)據(jù)采集/傳輸。
回復(fù)

使用道具 舉報(bào)

板凳
ID:69862 發(fā)表于 2015-1-29 23:01 | 只看該作者
exv 發(fā)表于 2015-1-29 22:35
標(biāo)題是不是寫錯(cuò)了?
帖子內(nèi)容講的是聯(lián)合體字節(jié)流。
這個(gè)方法比效率比sprintf高,但是代碼較多,適合于大 ...

標(biāo)題沒(méi)有錯(cuò),我的主導(dǎo)思想是聯(lián)合體共用內(nèi)存首地址一個(gè)優(yōu)點(diǎn),也可以叫做是缺點(diǎn)來(lái)為我辦事,你也可以曬曬你的方法。
回復(fù)

使用道具 舉報(bào)

地板
ID:67796 發(fā)表于 2015-1-29 23:24 | 只看該作者
本帖最后由 exv 于 2015-1-29 23:27 編輯
xiao_yp2014 發(fā)表于 2015-1-29 23:01
標(biāo)題沒(méi)有錯(cuò),我的主導(dǎo)思想是聯(lián)合體共用內(nèi)存首地址一個(gè)優(yōu)點(diǎn),也可以叫做是缺點(diǎn)來(lái)為我辦事,你也可以曬曬你 ...

聯(lián)合休==>聯(lián)合體

這個(gè)別字太顯眼了,看標(biāo)題感覺(jué)很奇怪,點(diǎn)進(jìn)來(lái)才知講的聯(lián)合體。

聯(lián)合體的這個(gè)特點(diǎn)也不好說(shuō)是缺點(diǎn),就像一個(gè)可自由存取可分隔的盒子,在執(zhí)行效率上有優(yōu)勢(shì)。

回復(fù)

使用道具 舉報(bào)

5#
ID:69862 發(fā)表于 2015-1-30 00:57 | 只看該作者
exv 發(fā)表于 2015-1-29 23:24
聯(lián)合休==>聯(lián)合體

這個(gè)別字太顯眼了,看標(biāo)題感覺(jué)很奇怪,點(diǎn)進(jìn)來(lái)才知講的聯(lián)合體。

回復(fù)

使用道具 舉報(bào)

6#
ID:57234 發(fā)表于 2015-1-30 02:10 來(lái)自手機(jī) | 只看該作者
現(xiàn)在正在回家的火車上面閱讀樓主的帖子。剛剛從一個(gè)隧道里面出來(lái)。一看就知道樓主一定是一個(gè)代碼高手,這個(gè)程序非常精辟,果斷收藏了。我以前也是實(shí)現(xiàn)過(guò)類似的功能,也是需要把浮點(diǎn)數(shù)上傳到上為機(jī)上位機(jī)里面。為了這個(gè)功能我頭疼了很多天。后面還是在51hei論壇里面找到了一個(gè)函數(shù)先把浮點(diǎn)數(shù)轉(zhuǎn)化為字符串,然后再把字符串到上位機(jī)。然后上位機(jī)程序再把字符串轉(zhuǎn)化為浮點(diǎn)數(shù)據(jù)。勉為其難地解決了這個(gè)問(wèn)題。樓主這個(gè)程序改天回去試一下。
回復(fù)

使用道具 舉報(bào)

7#
ID:69862 發(fā)表于 2015-1-30 18:44 | 只看該作者
xiaoou 發(fā)表于 2015-1-30 02:10
現(xiàn)在正在回家的火車上面閱讀樓主的帖子。剛剛從一個(gè)隧道里面出來(lái)。一看就知道樓主一定是一個(gè)代碼高手,這個(gè) ...

希望對(duì)你有所幫助,帶著回家喜悅的心情,閱讀如此精彩的程序,相信你會(huì)滿載而歸的。
回復(fù)

使用道具 舉報(bào)

8#
ID:249808 發(fā)表于 2023-8-24 19:13 | 只看該作者
xiaoou 發(fā)表于 2015-1-30 02:10
現(xiàn)在正在回家的火車上面閱讀樓主的帖子。剛剛從一個(gè)隧道里面出來(lái)。一看就知道樓主一定是一個(gè)代碼高手,這個(gè) ...

我也是這么操作的……
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美国产日韩在线 | 欧美一区二区 | 亚洲国产精品视频 | 久久三级av| www.激情.com | 男女视频在线观看网站 | 亚洲免费在线视频 | 日韩欧美高清 | 毛片一级电影 | 中文字幕日韩欧美一区二区三区 | 成人在线精品 | 黑人中文字幕一区二区三区 | 伊人网国产 | 中国一级特黄视频 | 久久久99精品免费观看 | 久久久久久久av | 精品久久久久久红码专区 | 天堂av免费观看 | 超碰在线播 | av大片在线| 蜜臀久久99精品久久久久久宅男 | 午夜精品视频在线观看 | 国产一区二区影院 | 久久久新视频 | 中文字幕在线观看精品 | 91精品国产色综合久久不卡98 | 成年人精品视频在线观看 | 日韩精品免费一区二区在线观看 | 成人激情视频在线观看 | 亚洲一一在线 | 国产ts人妖系列高潮 | 99pao成人国产永久免费视频 | 色综久久| 91久久国产综合久久 | 亚洲国产高清免费 | 女人毛片a毛片久久人人 | 最近免费日本视频在线 | 羞羞色网站 | 超碰地址| 日韩中文av在线 | 国产精品99久久久久久久久久久久 |