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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

ADXL345計步器單片機程序,找不到器件地址

[復制鏈接]
跳轉到指定樓層
樓主
ID:515167 發表于 2019-4-19 15:33 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include  <REG51.H>        
  2. #include  <INTRINS.H>

  3. #define   uchar unsigned char
  4. #define   uint unsigned int        
  5. #define   DataPort P0    //LCD1602數據端口

  6. sbit          SCL=P1^5;      //IIC時鐘引腳定義
  7. sbit           SDA=P1^4;      //IIC數據引腳定義

  8. uchar code table_num[]="0123456789abcdefg";

  9. sbit rs=P1^0;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  10. sbit rw=P1^1;         //寄存器選擇信號 H:數據寄存器          L:指令寄存器
  11. sbit e =P1^2;         //片選信號   下降沿觸發

  12. sbit key1 = P1^6;
  13. sbit key2 = P1^7;


  14. #define        SlaveAddress   0xA6          //定義器件在IIC總線中的從地址,根據ALT  ADDRESS地址引腳不同修改
  15.                               //ALT  ADDRESS引腳接地時地址為0xA6,接電源時地址為0x3A
  16. long bushu,zong;  //步數

  17. uchar BUF[8];                         //接收數據緩存區              
  18. uchar ge,shi,bai,qian,wan;           //顯示變量
  19. int  dis_data;                       //變量

  20. void  Multiple_Read_ADXL345();                                  //連續的讀取內部寄存器數據

  21. #define RdCommand 0x01 //定義ISP的操作命令
  22. #define PrgCommand 0x02
  23. #define EraseCommand 0x03
  24. #define Error 1
  25. #define Ok 0
  26. #define WaitTime 0x01 //定義CPU的等待時間
  27. sfr ISP_DATA=0xe2;  //寄存器申明
  28. sfr ISP_ADDRH=0xe3;
  29. sfr ISP_ADDRL=0xe4;
  30. sfr ISP_CMD=0xe5;
  31. sfr ISP_TRIG=0xe6;
  32. sfr ISP_CONTR=0xe7;
  33. uchar a_a;

  34. /* ================ 打開 ISP,IAP 功能 ================= */
  35. void ISP_IAP_enable(void)
  36. {
  37.          EA = 0;       /* 關中斷   */
  38.          ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */
  39.          ISP_CONTR = ISP_CONTR | WaitTime; /* 寫入硬件延時 */
  40.          ISP_CONTR = ISP_CONTR | 0x80;       /* ISPEN=1  */
  41. }
  42. /* =============== 關閉 ISP,IAP 功能 ================== */
  43. void ISP_IAP_disable(void)
  44. {
  45.          ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
  46.          ISP_TRIG = 0x00;
  47.          EA   =   1;   /* 開中斷 */
  48. }
  49. /* ================ 公用的觸發代碼 ==================== */
  50. void ISPgoon(void)
  51. {
  52.          ISP_IAP_enable();   /* 打開 ISP,IAP 功能 */
  53.          ISP_TRIG = 0x46;  /* 觸發ISP_IAP命令字節1 */
  54.          ISP_TRIG = 0xb9;  /* 觸發ISP_IAP命令字節2 */
  55.          _nop_();
  56. }
  57. /* ==================== 字節讀 ======================== */
  58. unsigned char byte_read(unsigned int byte_addr)
  59. {
  60.         EA = 0;
  61.          ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
  62.          ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  63.          ISP_CMD   = ISP_CMD & 0xf8;   /* 清除低3位  */
  64.          ISP_CMD   = ISP_CMD | RdCommand; /* 寫入讀命令 */
  65.          ISPgoon();       /* 觸發執行  */
  66.          ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
  67.          EA  = 1;
  68.          return (ISP_DATA);    /* 返回讀到的數據 */
  69. }
  70. /* ================== 扇區擦除 ======================== */
  71. void SectorErase(unsigned int sector_addr)
  72. {
  73.          unsigned int iSectorAddr;
  74.          iSectorAddr = (sector_addr & 0xfe00); /* 取扇區地址 */
  75.          ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
  76.          ISP_ADDRL = 0x00;
  77.          ISP_CMD = ISP_CMD & 0xf8;   /* 清空低3位  */
  78.          ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3  */
  79.          ISPgoon();       /* 觸發執行  */
  80.          ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
  81. }
  82. /* ==================== 字節寫 ======================== */
  83. void byte_write(unsigned int byte_addr, unsigned char original_data)
  84. {
  85.          EA  = 0;
  86.          SectorErase(byte_addr);
  87.          ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */
  88.          ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  89.          ISP_CMD  = ISP_CMD & 0xf8;    /* 清低3位 */
  90.          ISP_CMD  = ISP_CMD | PrgCommand;  /* 寫命令2 */
  91.          ISP_DATA = original_data;   /* 寫入數據準備 */
  92.          ISPgoon();       /* 觸發執行  */
  93.          ISP_IAP_disable();     /* 關閉IAP功能 */
  94.          EA =1;
  95. }

  96. /******************把數據保存到單片機內部eeprom中******************/
  97. void write_eeprom()        //保存數據
  98. {
  99.         SectorErase(0x2000);
  100.         byte_write(0x2000, bushu);
  101.         byte_write(0x2001, bushu >> 8);
  102.         byte_write(0x2002, bushu >> 16);

  103.         byte_write(0x2003, zong);
  104.         byte_write(0x2004, zong >> 8);
  105.         byte_write(0x2005, zong >> 16);

  106.         byte_write(0x2055, a_a);        
  107. }

  108. /******************把數據從單片機內部eeprom中讀出來*****************/
  109. void read_eeprom()         //讀出保存數據
  110. {
  111.         bushu = byte_read(0x2002);
  112.         bushu <<= 8;
  113.         bushu |= byte_read(0x2001);  
  114.         bushu <<= 8;
  115.         bushu |= byte_read(0x2000);

  116.         zong = byte_read(0x2005);
  117.         zong <<= 8;
  118.         zong |= byte_read(0x2004);  
  119.         zong <<= 8;
  120.         zong |= byte_read(0x2003);
  121.         a_a    = byte_read(0x2055);
  122. }

  123. ///**************開機自檢eeprom初始化*****************/
  124. void init_eeprom()         ////開始初始化保存的數據
  125. {
  126.         read_eeprom();         //讀出保存數據
  127.         if(a_a != 14)                //新的單片機初始單片機內問eeprom
  128.         {
  129.             zong = 0;
  130.                 bushu = 0;
  131.                 a_a = 14;
  132.                 write_eeprom();        //保存數據
  133.         }        
  134. }

  135. /***************************************************************
  136. * 名稱 : delay_1ms()
  137. * 功能 : 延時1ms函數
  138. * 輸入 : q
  139. * 輸出 : 無
  140. ****************************************************************/
  141. void delay_1ms(uint q)
  142. {
  143.         uint i,j;
  144.         for(i=0;i<q;i++)
  145.                 for(j=0;j<120;j++);
  146. }
  147. /********************************************************************
  148. * 名稱 : delay_uint()
  149. * 功能 : 小延時。
  150. * 輸入 : 無
  151. * 輸出 : 無
  152. ***********************************************************************/
  153. void delay_uint(uint q)
  154. {
  155.         while(q--);
  156. }

  157. /********************************************************************
  158. * 名稱 : write_com(uchar com)
  159. * 功能 : 1602命令函數
  160. * 輸入 : 輸入的命令值
  161. * 輸出 : 無
  162. ***********************************************************************/
  163. void write_com(uchar com)
  164. {
  165.         e=0;
  166.         rs=0;
  167.         rw=0;
  168.         P0=com;
  169.         delay_uint(25);
  170.         e=1;
  171.         delay_uint(100);
  172.         e=0;
  173. }

  174. /********************************************************************
  175. * 名稱 : write_data(uchar dat)
  176. * 功能 : 1602寫數據函數
  177. * 輸入 : 需要寫入1602的數據
  178. * 輸出 : 無
  179. ***********************************************************************/
  180. void write_data(uchar dat)
  181. {
  182.         e=0;
  183.         rs=1;
  184.         rw=0;
  185.         P0=dat;
  186.         delay_uint(25);
  187.         e=1;
  188.         delay_uint(100);
  189.         e=0;        
  190. }


  191. /***********************lcd1602上顯示十進制數************************/
  192. void write_bushu(uchar hang,uchar add,long date)
  193. {
  194.         if(hang==1)   
  195.                 write_com(0x80+add);
  196.         else
  197.                 write_com(0x80+0x40+add);
  198.         if(date >= 1000000)
  199.                 write_data(0x30+date/1000000%10);
  200.         if(date >= 100000)
  201.                 write_data(0x30+date/100000%10);
  202.         if(date >= 10000)
  203.                 write_data(0x30+date/10000%10);
  204.         if(date >= 1000)
  205.                 write_data(0x30+date/1000%10);
  206.         if(date >= 100)
  207.                 write_data(0x30+date/100%10);
  208.         if(date >= 10)
  209.                 write_data(0x30+date/10%10);
  210.         write_data(0x30+date%10);        
  211. }

  212. /***********************lcd1602上顯示這字符函數************************/
  213. void write_string(uchar hang,uchar add,uchar *p)
  214. {
  215.         if(hang==1)   
  216.                 write_com(0x80+add);
  217.         else
  218.                 write_com(0x80+0x40+add);
  219.                 while(1)                                                                                                                 
  220.                 {
  221.                         if(*p == '\0')  break;
  222.                         write_data(*p);
  223.                         p++;
  224.                 }        
  225. }
  226.                
  227. /***********************lcd1602初始化設置************************/
  228. void init_1602()        //lcd1602初始化
  229. {
  230.         write_com(0x38);        
  231.         write_com(0x0c);
  232.         write_com(0x06);
  233.         delay_uint(1000);
  234.         write_string(1,0,"bushu:0            ");        
  235.         write_string(2,0," zong:0            ");        

  236. }
  237.                                 

  238. /**************************************
  239. 延時5微秒(STC90C52RC---12MHz---12T)
  240. 不同的工作環境,需要調整此函數,注意時鐘過快時需要修改
  241. 當改用1T的MCU時,請調整此延時函數
  242. **************************************/
  243. void Delay5us()
  244. {
  245.     _nop_();_nop_();_nop_();_nop_();
  246.     _nop_();_nop_();_nop_();_nop_();
  247.         _nop_();_nop_();_nop_();_nop_();
  248. }

  249. /**************************************
  250. 延時5毫秒(STC90C52RC@12M)
  251. 不同的工作環境,需要調整此函數
  252. 當改用1T的MCU時,請調整此延時函數
  253. **************************************/
  254. void Delay5ms()
  255. {
  256.     uint n = 560;

  257.     while (n--);
  258. }

  259. /**************************************
  260. 起始信號
  261. **************************************/
  262. void ADXL345_Start()
  263. {
  264.     SDA = 1;                    //拉高數據線
  265.     SCL = 1;                    //拉高時鐘線
  266.     Delay5us();                 //延時
  267.     SDA = 0;                    //產生下降沿
  268.     Delay5us();                 //延時
  269.     SCL = 0;                    //拉低時鐘線
  270. }

  271. /**************************************
  272. 停止信號
  273. **************************************/
  274. void ADXL345_Stop()
  275. {
  276.     SDA = 0;                    //拉低數據線
  277.     SCL = 1;                    //拉高時鐘線
  278.     Delay5us();                 //延時
  279.     SDA = 1;                    //產生上升沿
  280.     Delay5us();                 //延時
  281. }

  282. /**************************************
  283. 發送應答信號
  284. 入口參數:ack (0:ACK 1:NAK)
  285. **************************************/
  286. void ADXL345_SendACK(bit ack)
  287. {
  288.     SDA = ack;                  //寫應答信號
  289.     SCL = 1;                    //拉高時鐘線
  290.     Delay5us();                 //延時
  291.     SCL = 0;                    //拉低時鐘線
  292.     Delay5us();                 //延時
  293. }

  294. /**************************************
  295. 接收應答信號
  296. **************************************/
  297. bit ADXL345_RecvACK()
  298. {
  299.     SCL = 1;                    //拉高時鐘線
  300.     Delay5us();                 //延時
  301.     CY = SDA;                   //讀應答信號
  302.     SCL = 0;                    //拉低時鐘線
  303.     Delay5us();                 //延時

  304.     return CY;
  305. }

  306. /**************************************
  307. 向IIC總線發送一個字節數據
  308. **************************************/
  309. void ADXL345_SendByte(uchar dat)
  310. {
  311.     uchar i;

  312.     for (i=0; i<8; i++)         //8位計數器
  313.     {
  314.         dat <<= 1;              //移出數據的最高位
  315.         SDA = CY;               //送數據口
  316.         SCL = 1;                //拉高時鐘線
  317.         Delay5us();             //延時
  318.         SCL = 0;                //拉低時鐘線
  319.         Delay5us();             //延時
  320.     }
  321.     ADXL345_RecvACK();
  322. }

  323. /**************************************
  324. 從IIC總線接收一個字節數據
  325. **************************************/
  326. uchar ADXL345_RecvByte()
  327. {
  328.     uchar i;
  329.     uchar dat = 0;

  330.     SDA = 1;                    //使能內部上拉,準備讀取數據,
  331.     for (i=0; i<8; i++)         //8位計數器
  332.     {
  333.         dat <<= 1;
  334.         SCL = 1;                //拉高時鐘線
  335.         Delay5us();             //延時
  336.         dat |= SDA;             //讀數據               
  337.         SCL = 0;                //拉低時鐘線
  338.         Delay5us();             //延時
  339.     }
  340.     return dat;
  341. }

  342. //******單字節寫入*******************************************

  343. void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
  344. {
  345.     ADXL345_Start();                  //起始信號
  346.     ADXL345_SendByte(SlaveAddress);   //發送設備地址+寫信號
  347.     ADXL345_SendByte(REG_Address);    //內部寄存器地址,請參考中文pdf22頁
  348.     ADXL345_SendByte(REG_data);       //內部寄存器數據,請參考中文pdf22頁
  349.     ADXL345_Stop();                   //發送停止信號
  350. }

  351. //********單字節讀取*****************************************
  352. uchar Single_Read_ADXL345(uchar REG_Address)
  353. {  uchar REG_data;
  354.     ADXL345_Start();                          //起始信號
  355.     ADXL345_SendByte(SlaveAddress);           //發送設備地址+寫信號
  356.     ADXL345_SendByte(REG_Address);            //發送存儲單元地址,從0開始        
  357.     REG_data=ADXL345_RecvByte();              //讀出寄存器數據
  358.         ADXL345_SendACK(1);   
  359.         ADXL345_Stop();                           //停止信號
  360.     return REG_data;
  361. }
  362. //*********************************************************
  363. //
  364. //連續讀出ADXL345內部加速度數據,地址范圍0x32~0x37
  365. //
  366. //*********************************************************
  367. void Multiple_read_ADXL345(void)
  368. {   uchar i;
  369.     ADXL345_Start();                          //起始信號
  370.     ADXL345_SendByte(SlaveAddress);           //發送設備地址+寫信號
  371.     ADXL345_SendByte(0x32);                   //發送存儲單元地址,從0x32開始        
  372.          for (i=0; i<6; i++)                      //連續讀取6個地址數據,存儲中BUF
  373.     {
  374.         BUF[i] = ADXL345_RecvByte();          //BUF[0]存儲0x32地址中的數據
  375.         if (i == 5)
  376.         {
  377.            ADXL345_SendACK(1);                //最后一個數據需要回NOACK
  378.         }
  379.         else
  380.         {
  381.           ADXL345_SendACK(0);                //回應ACK
  382.        }
  383.    }
  384.     ADXL345_Stop();                          //停止信號
  385.     Delay5ms();
  386. }


  387. //*****************************************************************

  388. //初始化ADXL345,根據需要請參考pdf進行修改************************
  389. void Init_ADXL345()
  390. {
  391.    Single_Write_ADXL345(0x31,0x2B);   //測量范圍,正負16g,13位模式
  392.    Single_Write_ADXL345(0x2C,0x08);   //速率設定為12.5 參考pdf13頁
  393.    Single_Write_ADXL345(0x2D,0x08);
  394.    Single_Write_ADXL345(0x2E,0x80);   //使能 DATA_READY 中斷
  395.    Single_Write_ADXL345(0x1F,0x00);   // 偏移量 根據測試傳感器的狀態寫入pdf29頁
  396.    Single_Write_ADXL345(0x20,0x05);   // 偏移量 根據測試傳感器的狀態寫入pdf29頁
  397. }

  398. //***********************************************************************
  399. //顯示y軸
  400. void display_y()
  401. {     
  402.         static uchar flag_en,flag_fu;
  403.         float temp;
  404.     dis_data=(BUF[3]<<8)+BUF[2];  //合成數據   
  405.         if(dis_data<0)
  406.         {
  407.                 dis_data=-dis_data;
  408.                 flag_fu = 1;
  409.         }
  410.         else
  411.         {
  412.                 flag_en = 1;
  413.                 flag_fu = 0;
  414.         }
  415.          temp = dis_data;
  416.          if(temp > 100)   //步數加1
  417.         {
  418.                 if((flag_en == 1) && (flag_fu == 1))
  419.                 {
  420.                         flag_en = 0;
  421.                         bushu ++;
  422.                         zong ++;        
  423.                         write_eeprom();        //保存數據
  424.                         write_bushu(1,6,bushu);                //顯示步數
  425.                         write_bushu(2,6,zong);                //顯示總步數
  426.                 }
  427.         }
  428.         if(temp < 70)  
  429.         {
  430.                 flag_en = 1;        
  431.         }
  432. }

  433. //   按鍵控制程序
  434. void key()
  435. {
  436.         if(key1 == 0)
  437.         {
  438.                 delay_1ms(1);
  439.                 if(key1 == 0)
  440.                 {
  441.                         zong = 0;
  442.                         write_string(2,6,"        ");
  443.                         write_bushu(1,6,bushu);                //顯示步數
  444.                         write_bushu(2,6,zong);                //顯示總步數
  445.                         write_eeprom();        //保存數據               
  446.                 }
  447.                 while(key1 == 0);  //松手檢測
  448.         }
  449.         if(key2 == 0)
  450.         {
  451.                 delay_1ms(1);
  452.                 if(key2 == 0)
  453.                 {
  454.                         bushu = 0;
  455.                         write_string(1,6,"        ");
  456.                         write_bushu(1,6,bushu);                //顯示步數
  457.                         write_bushu(2,6,zong);                //顯示總步數
  458.                         write_eeprom();        //保存數據               
  459.                 }
  460.                 while(key2 == 0);  //松手檢測
  461.         }
  462. }


  463. //*********************************************************
  464. //******主程序********
  465. //*********************************************************
  466. void main()
  467. {
  468.         static uint flag_value;
  469.         uchar devid;
  470.         init_1602();        //lcd1602初始化
  471.         Init_ADXL345();                         //初始化ADXL345
  472.         devid=Single_Read_ADXL345(0X00);        //讀出的數據為0XE5,表示正確
  473.         delay_1ms(20);
  474.         init_eeprom();         ////開始初始化保存的數據
  475.         write_bushu(1,6,bushu);                //顯示步數
  476.         write_bushu(2,6,zong);                //顯示總步數
  477.         while(1)                                 //循環
  478.         {                 
  479.                 key();          //按鍵程序
  480.                 flag_value ++;
  481.                 if(flag_value >= 100)           //100ms
  482.                 {
  483.                         flag_value = 0;
  484.                         Init_ADXL345();                         //初始化ADXL345
  485.                         devid=Single_Read_ADXL345(0X00);        //讀出的數據為0XE5,表示正確
  486.                         if(devid!=0XE5)
  487.                         {                        
  488.                                 write_string(2,11,"error");                        
  489.                         }
  490.                         else
  491.                         {                        
  492.                                 Multiple_Read_ADXL345();               //連續讀出數據,存儲在BUF中

  493.                                 display_y();                           //---------顯示Y軸
  494.                         }     
  495.                 }
  496.                 delay_1ms(1);                            //延時  
  497.         }
  498. }
復制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:515167 發表于 2019-4-19 15:56 | 只看該作者
一直顯示error
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产 日韩 欧美 在线 | 一区二区三区视频在线免费观看 | 亚洲区一区二 | 日韩在线视频免费观看 | 免费成人在线网站 | 国产高清在线精品 | 夜夜骑首页 | 日本三级视频 | 日韩一二区| 日日爽| 久久99国产精品久久99果冻传媒 | 蜜桃视频在线观看免费视频网站www | 久久香焦 | 日本一区精品 | 免费观看av网站 | 婷婷色网| 伊人超碰| 国产精品99视频 | 精品久久久久久久久久久久 | 中文在线一区 | 国产在线区 | 少妇诱惑av| 犬夜叉在线观看 | 亚洲精品自拍视频 | 午夜精品久久久久久久久久久久久 | 日本久草视频 | 日本一区二区三区四区 | 干干干日日日 | 欧美理论 | 91精品久久久久 | 青青草免费在线视频 | 亚洲成人中文字幕 | 亚洲福利片 | 中文字幕一区二区三区不卡 | 久久黄色精品视频 | 国内精品免费久久久久软件老师 | 久草在线在线精品观看 | 亚州国产 | 午夜免费福利电影 | 国产特级毛片aaaaaa喷潮 | 美女福利网站 |