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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9333|回復: 10
打印 上一主題 下一主題
收起左側

HMC5883L電子指南針單片機程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:127035 發表于 2016-12-19 21:19 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
HMC5883L電子指南針
完整的單片機源程序下載:
2014年6月7日 指南針 1602.rar (45.92 KB, 下載次數: 187)

預覽:
  1. #include <reg52.h>                 //調用單片機頭文件
  2. #define uchar unsigned char  //無符號字符型 宏定義        變量范圍0~255
  3. #define uint  unsigned int         //無符號整型 宏定義        變量范圍0~65535
  4. #include  <math.h>    //Keil library  
  5. #include  <stdio.h>   //Keil library        
  6. #include  <INTRINS.H>

  7. sbit rs=P2^3;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  8. sbit rw=P2^4;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  9. sbit e =P2^5;         //片選信號   下降沿觸發

  10. sbit SCL=P1^1;      //IIC時鐘引腳定義
  11. sbit SDA=P1^0;      //IIC數據引腳定義

  12. #define        SlaveAddress   0x3C                 //定義器件在IIC總線中的從地址
  13. uchar BUF[8];                        //接收數據緩存區              
  14. uchar ge,shi,bai,qian,wan;           //顯示變量
  15. int  dis_data;                       //變量

  16. /******************1ms 延時函數*******************/
  17. void delay_1ms(uint q)
  18. {
  19.         uint i,j;
  20.         for(i=0;i<q;i++)
  21.                 for(j=0;j<120;j++);
  22. }


  23. /***********************延時函數************************/
  24. void delay_uint(uint q)
  25. {
  26.         while(q--);
  27. }

  28. /**************************************
  29. 延時5微秒(STC90C52RC@12M)
  30. 不同的工作環境,需要調整此函數,注意時鐘過快時需要修改
  31. 當改用1T的MCU時,請調整此延時函數
  32. **************************************/
  33. void Delay5us()
  34. {
  35.              _nop_();_nop_();_nop_();_nop_();
  36.              _nop_();_nop_();_nop_();_nop_();
  37.         _nop_();_nop_();_nop_();_nop_();
  38.         _nop_();_nop_();_nop_();_nop_();
  39.               _nop_();_nop_();_nop_();_nop_();
  40.         _nop_();_nop_();_nop_();_nop_();
  41.         _nop_();_nop_();_nop_();_nop_();
  42.              _nop_();_nop_();_nop_();_nop_();

  43. }

  44. /***********************lcd1602寫命令函數************************/
  45. void write_com(uchar com)
  46. {
  47.         e=0;
  48.         rs=0;
  49.         rw=0;
  50.         P0=com;
  51.         delay_uint(3);
  52.         e=1;
  53.         delay_uint(25);
  54.         e=0;
  55. }

  56. /***********************lcd1602寫數據函數************************/
  57. void write_data(uchar dat)
  58. {
  59.         e=0;
  60.         rs=1;
  61.         rw=0;
  62.         P0=dat;
  63.         delay_uint(3);
  64.         e=1;
  65.         delay_uint(25);
  66.         e=0;        
  67. }

  68. /***********************lcd1602上顯示特定的字符************************/
  69. void write_zifu(uchar hang,uchar add,uchar date)
  70. {
  71.         if(hang==1)   
  72.                 write_com(0x80+add);
  73.         else
  74.                 write_com(0x80+0x40+add);
  75.         write_data(date);        
  76. }

  77. /***********************lcd1602上顯示這字符函數************************/
  78. void write_string(uchar hang,uchar add,uchar *p)
  79. {
  80.         if(hang==1)   
  81.                 write_com(0x80+add);
  82.         else
  83.                 write_com(0x80+0x40+add);
  84.         while(1)                                                                                                                 
  85.         {
  86.                 if(*p == '\0')  break;
  87.                 write_data(*p);
  88.                 p++;
  89.         }        
  90. }


  91. /***********************lcd1602初始化設置************************/
  92. void init_1602()         //lcd1602初始化設置
  93. {
  94.         write_com(0x38);        //
  95.         write_com(0x0c);
  96.         write_com(0x06);
  97.         delay_uint(1000);
  98.         write_string(1,0,"  zhi nan zhen ");               
  99.         write_string(2,0,"               ");        
  100.         write_zifu(2,11,0xdf);  //顯示度        
  101. }

  102. /***********************lcd1602上顯示兩位十進制數************************/
  103. void write_jiaodu(uchar hang,uchar add,uint date)
  104. {
  105.         if(hang==1)   
  106.                 write_com(0x80+add);
  107.         else
  108.                 write_com(0x80+0x40+add);
  109.         write_data(0x30+date/1000%10);
  110.         write_data(0x30+date/100%10);
  111.         write_data(0x30+date/10%10);
  112.         write_data('.');
  113.         write_data(0x30+date%10);        
  114. }

  115. /**************************************
  116. 起始信號
  117. **************************************/
  118. void HMC5883_Start()
  119. {
  120.     SDA = 1;                    //拉高數據線
  121.     Delay5us();                 //延時
  122.     SDA = 0;                    //產生下降沿
  123.     Delay5us();                 //延時
  124.     SCL = 0;                    //拉低時鐘線
  125. }

  126. /**************************************
  127. 停止信號
  128. **************************************/
  129. void HMC5883_Stop()
  130. {
  131.     SDA = 0;                    //拉低數據線
  132.     SCL = 1;                    //拉高時鐘線
  133.     Delay5us();                 //延時
  134.     SDA = 1;                    //產生上升沿
  135.     Delay5us();                 //延時
  136. }

  137. /**************************************
  138. 發送應答信號
  139. 入口參數:ack (0:ACK 1:NAK)
  140. **************************************/
  141. void HMC5883_SendACK(bit ack)
  142. {
  143.     SDA = ack;                  //寫應答信號
  144.     SCL = 1;                    //拉高時鐘線
  145.     Delay5us();                 //延時
  146.     SCL = 0;                    //拉低時鐘線
  147.     Delay5us();                 //延時
  148. }

  149. /**************************************
  150. 接收應答信號
  151. **************************************/
  152. bit HMC5883_RecvACK()
  153. {
  154.     SCL = 1;                    //拉高時鐘線
  155.     Delay5us();                 //延時
  156.     CY = SDA;                   //讀應答信號
  157.     SCL = 0;                    //拉低時鐘線
  158.     Delay5us();                 //延時

  159.     return CY;
  160. }

  161. /**************************************
  162. 向IIC總線發送一個字節數據
  163. **************************************/
  164. void HMC5883_SendByte(uchar dat)
  165. {
  166.     uchar i;

  167.     for (i=0; i<8; i++)         //8位計數器
  168.     {
  169.         dat <<= 1;              //移出數據的最高位
  170.         SDA = CY;               //送數據口
  171.         SCL = 0;                //拉高時鐘線
  172.         Delay5us();             //延時
  173.         SCL = 1;                //拉低時鐘線
  174.         Delay5us();             //延時
  175.     }
  176.     HMC5883_RecvACK();
  177. }

  178. /**************************************
  179. 從IIC總線接收一個字節數據
  180. **************************************/
  181. uchar HMC5883_RecvByte()
  182. {
  183.     uchar i;
  184.     uchar dat = 0;

  185.     SDA = 1;                    //使能內部上拉,準備讀取數據,
  186.     for (i=0; i<8; i++)         //8位計數器
  187.     {
  188.         dat <<= 1;
  189.         SCL = 1;                //拉高時鐘線
  190.         Delay5us();             //延時
  191.         dat |= SDA;             //讀數據               
  192.         SCL = 0;                //拉低時鐘線
  193.         Delay5us();             //延時
  194.     }
  195.     return dat;
  196. }

  197. //***************************************************

  198. void Single_Write_HMC5883(uchar REG_Address,uchar REG_data)
  199. {
  200.     HMC5883_SendByte(SlaveAddress);   //發送設備地址+寫信號
  201.     HMC5883_SendByte(REG_Address);    //內部寄存器地址,請參考中文pdf
  202.     HMC5883_SendByte(REG_data);       //內部寄存器數據,請參考中文pdf
  203. }

  204. //******************************************************
  205. //
  206. //連續讀出HMC5883內部角度數據,地址范圍0x3~0x8
  207. //
  208. //******************************************************
  209. void Multiple_read_HMC5883(void)
  210. {   uchar i;
  211.     HMC5883_Start();                          //起始信號
  212.     HMC5883_SendByte(SlaveAddress);           //發送設備地址+寫信號
  213.     HMC5883_SendByte(0x03);                   //發送存儲單元地址,從0x3開始        
  214.     HMC5883_Start();                          //起始信號
  215.     HMC5883_SendByte(SlaveAddress+1);         //發送設備地址+讀信號
  216.         for (i=0; i<6; i++)                      //連續讀取6個地址數據,存儲中BUF
  217.     {
  218.         BUF[i] = HMC5883_RecvByte();          //BUF[0]存儲數據
  219.         if (i == 5)
  220.         {
  221.            HMC5883_SendACK(0);                //最后一個數據需要回NOACK
  222.         }
  223.         else
  224.         {
  225.           HMC5883_SendACK(1);                //回應ACK
  226.        }
  227.    }
  228.     delay_1ms(5);
  229. }

  230. //初始化HMC5883,根據需要請參考pdf進行修改****
  231. void Init_HMC5883()
  232. {
  233.      Single_Write_HMC5883(0x02,0x00);  //
  234. }


  235. /*****************主函數********************/
  236. void main()
  237. {        
  238.     int x,y,z,jiadu;
  239.     double angle;
  240.         P0 = P1 = P2 = P3 = 0xff;                //單片機IO口初始化為1
  241.     Init_HMC5883();
  242.         init_1602();                 //lcd1602初始化
  243.         while(1)
  244.         {   
  245.             Multiple_read_HMC5883();      //連續讀出數據,存儲在BUF中
  246.         //---------顯示X軸
  247.             x=BUF[0] << 8 | BUF[2]; //Combine MSB and LSB of X Data output register
  248.             z=BUF[2] << 8 | BUF[4]; //Combine MSB and LSB of Z Data output register
  249.         
  250.             angle= atan2((double)y,(double)x) * (180 / 3.14); // angle in degrees
  251.                 jiadu = angle;
  252.                 write_jiaodu(2,6,angle);        //顯示角度
  253.                 if((angle >= 3380) || (angle <= 220))          //北 N
  254.                         write_string(2,0,"  N  ");        
  255.                 if((angle >= 230) && (angle <= 670))          //東 北
  256.                         write_string(2,0," E N ");        
  257.                 if((angle >= 680) && (angle <= 1120))          //東 E
  258.                         write_string(2,0,"  E  ");        
  259.                 if((angle >= 1130) && (angle <= 1570))          //東 南
  260.                         write_string(2,0," E S ");        
  261.                 if((angle >= 1580) && (angle <= 2010))          //南  S
  262.                         write_string(2,0,"  S  ");        
  263.                 if((angle >= 2020) && (angle <= 2460))          //西 南  
  264.                         write_string(2,0," W S ");        
  265.                 if((angle >= 2470) && (angle <= 2910))          //西  W  
  266.                         write_string(2,0,"  W  ");        
  267.                 if((angle >= 2920) && (angle <= 3360))          //西  北  
  268.                         write_string(2,0," W N  ");        
  269.                 delay_1ms(300);

  270.         }
  271. }
復制代碼


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

使用道具 舉報

沙發
ID:1 發表于 2017-1-3 00:01 | 只看該作者
51黑有你更精彩!!!
回復

使用道具 舉報

板凳
ID:198094 發表于 2017-5-8 14:58 | 只看該作者
大神您好,能幫忙解釋一下如下程序中,角度值為什么這樣設置嗎?

angle= atan2((double)y,(double)x) * (180 / 3.14); // angle in degrees
                jiadu = angle;
                write_jiaodu(2,6,angle);        //顯示角度
                if((angle >= 3380) || (angle <= 220))          //北 N
                        write_string(2,0,"  N  ");        
                if((angle >= 230) && (angle <= 670))          //東 北
                        write_string(2,0," E N ");        
                if((angle >= 680) && (angle <= 1120))          //東 E
                        write_string(2,0,"  E  ");        
                if((angle >= 1130) && (angle <= 1570))          //東 南
                        write_string(2,0," E S ");        
                if((angle >= 1580) && (angle <= 2010))          //南  S
                        write_string(2,0,"  S  ");        
                if((angle >= 2020) && (angle <= 2460))          //西 南  
                        write_string(2,0," W S ");        
                if((angle >= 2470) && (angle <= 2910))          //西  W  
                        write_string(2,0,"  W  ");        
                if((angle >= 2920) && (angle <= 3360))          //西  北  
                        write_string(2,0," W N  ");        
                delay_1ms(300);
回復

使用道具 舉報

地板
ID:198094 發表于 2017-5-8 15:02 | 只看該作者
大神麻煩解釋一下如下程序中,東西南北角度值為何這樣設呢?

angle= atan2((double)y,(double)x) * (180 / 3.14); // angle in degrees
                jiadu = angle;
                write_jiaodu(2,6,angle);        //顯示角度
                if((angle >= 3380) || (angle <= 220))          //北 N
                        write_string(2,0,"  N  ");        
                if((angle >= 230) && (angle <= 670))          //東 北
                        write_string(2,0," E N ");        
                if((angle >= 680) && (angle <= 1120))          //東 E
                        write_string(2,0,"  E  ");        
                if((angle >= 1130) && (angle <= 1570))          //東 南
                        write_string(2,0," E S ");        
                if((angle >= 1580) && (angle <= 2010))          //南  S
                        write_string(2,0,"  S  ");        
                if((angle >= 2020) && (angle <= 2460))          //西 南  
                        write_string(2,0," W S ");        
                if((angle >= 2470) && (angle <= 2910))          //西  W  
                        write_string(2,0,"  W  ");        
                if((angle >= 2920) && (angle <= 3360))          //西  北  
                        write_string(2,0," W N  ");        
                delay_1ms(300);
回復

使用道具 舉報

5#
ID:204529 發表于 2017-5-24 22:37 | 只看該作者
貌似這個程序不好用!
回復

使用道具 舉報

6#
ID:229064 發表于 2017-9-12 19:55 | 只看該作者
感謝 您對資源的分享!!!!!
回復

使用道具 舉報

7#
ID:225984 發表于 2018-3-31 11:27 | 只看該作者
非常66666,正好用得到
回復

使用道具 舉報

8#
ID:316962 發表于 2018-5-6 17:34 | 只看該作者
為什么那個顯示的角度不會變呢
回復

使用道具 舉報

9#
ID:326147 發表于 2018-5-9 18:12 | 只看該作者
有用!
回復

使用道具 舉報

10#
ID:63090 發表于 2020-4-12 13:58 | 只看該作者
角度竟然是固定的18度,怎么轉動傳感器都不會變啊,這程序有問題啊
回復

使用道具 舉報

11#
ID:348295 發表于 2020-5-11 16:50 | 只看該作者
請問我按上面程序載入,只顯示 18度,值不會變
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久91| 成人激情视频在线观看 | 综合五月婷 | 欧美一区二区三区久久精品 | 国产无套一区二区三区久久 | 久久69精品久久久久久久电影好 | 久久久久中文字幕 | 97精品超碰一区二区三区 | 美女视频一区 | 成人小视频在线观看 | 欧美在线一二三 | 大象一区| 国产一区二区久久 | 国产1区| 久久精品国产亚洲a | 欧美bondage紧缚视频 | 免费视频一区二区 | 国产成人av免费看 | 亚洲精品一区在线观看 | 97国产精品视频人人做人人爱 | 久久不射电影网 | 欧美精品综合在线 | 色婷婷一区二区三区四区 | 懂色av一区二区三区在线播放 | 视频一区二区中文字幕 | 久久毛片 | 91欧美激情一区二区三区成人 | 91超碰在线 | 中文字幕精品一区二区三区在线 | 久久久久久国产精品三区 | 国产精品欧美一区二区 | 久草精品视频 | 羞羞在线观看视频 | 亚洲第一免费播放区 | 国产精品美女久久久久久久网站 | 男人天堂午夜 | 精品在线一区二区三区 | 中文字幕视频在线观看 | 欧美国产日韩在线观看 | 成人国产精品一级毛片视频毛片 | 中文在线a在线 |