免費下哦 (PS:有部分資料是從51黑論壇里找的哦)
0.png (62.32 KB, 下載次數: 135)
下載附件
2017-3-1 04:11 上傳
全部資料下載(帶ADXL345中文PDF):
基于ADXL345的計步器.zip
(961.37 KB, 下載次數: 472)
2017-2-28 14:06 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
主程序預覽:
- #include <reg52.h>
- #include <math.h> //Keil library
- #include <stdio.h> //Keil library
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit SCL=P3^1; //IIC時鐘引腳定義
- sbit SDA=P3^2; //IIC數據引腳定義
- sbit key=P3^7; //按鍵引腳定義
- #define SlaveAddress 0xA6 //定義器件在IIC總線中的從地址,根據ALT ADDRESS地址引腳不同修改
- //ALT ADDRESS引腳接地時地址為0xA6,接電源時地址為0x3A
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- BYTE BUF[8]; //接收數據緩存區
- uchar ge,shi,bai,qian,wan; //顯示變量
- int dis_data; //變量
- bit flag1s = 0; //1s定時標志
- uint num1=0,num2=0; //1總步數,2步數
- int aaa=0; //不重復變量
- void Init_ADXL345(void); //初始化ADXL345
- void ConfigTimer0(unsigned int ms);
- unsigned char IntToString(unsigned char *str, int dat);
- extern bit Start18B20();
- extern bit Get18B20Temp(int *temp);
- extern void delay(unsigned int k);
- extern void Lcd_init();
- extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);//定義指針變量,把字符串數組的地址送到該指針變量上(便于指向X并顯示X)
- extern void DisplayOneChar(uchar x, uchar y, uchar str);
- void conversion(uint temp_data);
- void Single_Write_ADXL345(uchar REG_Address,uchar REG_data); //單個寫入數據
- uchar Single_Read_ADXL345(uchar REG_Address); //單個讀取內部寄存器數據
- void Multiple_Read_ADXL345(); //連續的讀取內部寄存器數據
- //------------------------------------
- void Delay5us();
- void Delay5ms();
- void ADXL345_Start();
- void ADXL345_Stop();
- void ADXL345_SendACK(bit ack);
- bit ADXL345_RecvACK();
- void ADXL345_SendByte(BYTE dat);
- BYTE ADXL345_RecvByte();
- void ADXL345_ReadPage();
- void ADXL345_WritePage();
- //-----------------------------------
- //*********************************************************
- void conversion(uint temp_data)
- {
- wan=temp_data/10000+0x30 ;
- temp_data=temp_data%10000; //取余運算
- qian=temp_data/1000+0x30 ;
- temp_data=temp_data%1000; //取余運算
- bai=temp_data/100+0x30 ;
- temp_data=temp_data%100; //取余運算
- shi=temp_data/10+0x30 ;
- temp_data=temp_data%10; //取余運算
- ge=temp_data+0x30;
- }
-
- /**************************************
- 延時5微秒(STC90C52RC---12MHz---12T)
- 不同的工作環境,需要調整此函數,注意時鐘過快時需要修改
- 當改用1T的MCU時,請調整此延時函數
- **************************************/
- void Delay5us()
- {
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- }
- /**************************************
- 延時5毫秒(STC90C52RC@12M)
- 不同的工作環境,需要調整此函數
- 當改用1T的MCU時,請調整此延時函數
- **************************************/
- void Delay5ms()
- {
- WORD n = 560;
- while (n--);
- }
- /**************************************
- 起始信號
- **************************************/
- void ADXL345_Start()
- {
- SDA = 1; //拉高數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 0; //產生下降沿
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- }
- /**************************************
- 停止信號
- **************************************/
- void ADXL345_Stop()
- {
- SDA = 0; //拉低數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 1; //產生上升沿
- Delay5us(); //延時
- }
- /**************************************
- 發送應答信號
- 入口參數:ack (0:ACK 1:NAK)
- **************************************/
- void ADXL345_SendACK(bit ack)
- {
- SDA = ack; //寫應答信號
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- /**************************************
- 接收應答信號
- **************************************/
- bit ADXL345_RecvACK()
- {
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- CY = SDA; //讀應答信號
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- return CY;
- }
- /**************************************
- 向IIC總線發送一個字節數據
- **************************************/
- void ADXL345_SendByte(BYTE dat)
- {
- BYTE i;
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1; //移出數據的最高位
- SDA = CY; //送數據口
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- ADXL345_RecvACK();
- }
- /**************************************
- 從IIC總線接收一個字節數據
- **************************************/
- BYTE ADXL345_RecvByte()
- {
- BYTE i;
- BYTE dat = 0;
- SDA = 1; //使能內部上拉,準備讀取數據,
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1;
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- dat |= SDA; //讀數據
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- return dat;
- }
- //******單字節寫入*******************************************
- void Single_Write_ADXL345(uchar REG_Address,uchar REG_data)
- {
- ADXL345_Start(); //起始信號
- ADXL345_SendByte(SlaveAddress); //發送設備地址+寫信號
- ADXL345_SendByte(REG_Address); //內部寄存器地址,請參考中文pdf22頁
- ADXL345_SendByte(REG_data); //內部寄存器數據,請參考中文pdf22頁
- ADXL345_Stop(); //發送停止信號
- }
- //********單字節讀取*****************************************
- /*uchar Single_Read_ADXL345(uchar REG_Address)
- { uchar REG_data;
- ADXL345_Start(); //起始信號
- ADXL345_SendByte(SlaveAddress); //發送設備地址+寫信號
- ADXL345_SendByte(REG_Address); //發送存儲單元地址,從0開始
- ADXL345_Start(); //起始信號
- ADXL345_SendByte(SlaveAddress+1); //發送設備地址+讀信號
- REG_data=ADXL345_RecvByte(); //讀出寄存器數據
- ADXL345_SendACK(1);
- ADXL345_Stop(); //停止信號
- return REG_data;
- } */
- //*********************************************************
- //
- //連續讀出ADXL345內部加速度數據,地址范圍0x32~0x37
- //
- //*********************************************************
- void Multiple_read_ADXL345(void)
- { uchar i;
- ADXL345_Start(); //起始信號
- ADXL345_SendByte(SlaveAddress); //發送設備地址+寫信號
- ADXL345_SendByte(0x32); //發送存儲單元地址,從0x32開始
- ADXL345_Start(); //起始信號
- ADXL345_SendByte(SlaveAddress+1); //發送設備地址+讀信號
- for (i=0; i<6; i++) //連續讀取6個地址數據,存儲中BUF
- {
- BUF[i] = ADXL345_RecvByte(); //BUF[0]存儲0x32地址中的數據
- if (i == 5)
- {
- ADXL345_SendACK(1); //最后一個數據需要回NOACK
- }
- else
- {
- ADXL345_SendACK(0); //回應ACK
- }
- }
- ADXL345_Stop(); //停止信號
- Delay5ms();
- }
- //*****************************************************************
- //初始化ADXL345,根據需要請參考pdf進行修改************************
- void Init_ADXL345()
- {
- Single_Write_ADXL345(0x31,0x0B); //測量范圍,正負16g,13位模式
- Single_Write_ADXL345(0x2C,0x08); //速率設定為12.5 參考pdf13頁
- Single_Write_ADXL345(0x2D,0x08); //選擇電源模式 參考pdf24頁
- Single_Write_ADXL345(0x2E,0x80); //使能 DATA_READY 中斷
- Single_Write_ADXL345(0x1E,0x00); //X 偏移量 根據測試傳感器的狀態寫入pdf29頁
- Single_Write_ADXL345(0x1F,0x00); //Y 偏移量 根據測試傳感器的狀態寫入pdf29頁
- Single_Write_ADXL345(0x20,0x05); //Z 偏移量 根據測試傳感器的狀態寫入pdf29頁
- }
- //***********************************************************************
- //顯示x軸
- void display_x()
- {
- dis_data=(BUF[1]<<8)+BUF[0]; //合成數據
-
- if(dis_data<30) //靈敏度設置, 0 靈敏度最高
- {
- aaa=1;
- }
- else
- {
- if(aaa==1)
- {
- aaa=0;
- num1++; //總步數 累加
- num2++; //步數 累加
- }
- }
-
- conversion(num2); //步數數據
- DisplayOneChar(0,0,'B'); //第0行,第0列 顯示X
- DisplayOneChar(1,0,':');
- DisplayOneChar(2,0,wan);
- DisplayOneChar(3,0,qian);
- DisplayOneChar(4,0,bai);
- DisplayOneChar(5,0,shi);
- DisplayOneChar(6,0,ge);
- conversion(num1); //總步數數據
- DisplayOneChar(0,1,'Z'); //第1行,第0列 顯示X
- DisplayOneChar(1,1,'B');
- DisplayOneChar(2,1,':');
- DisplayOneChar(3,1,wan);
- DisplayOneChar(4,1,qian);
- DisplayOneChar(5,1,bai);
- DisplayOneChar(6,1,shi);
- DisplayOneChar(7,1,ge);
- }
- //*********************************************************
- //******主程序********
- //*********************************************************
- void main()
- {
- bit res;
- int temp; //讀取到的當前溫度值
- int intT, decT; //溫度值的整數和小數部分
- unsigned char len;
- unsigned char str[12];
- EA = 1; //開總中斷
- ConfigTimer0(10); //T0定時10ms
- Start18B20(); //啟動DS18B20
- //uchar devid;
- delay(500); //上電延時
- Lcd_init(); //液晶初始化ADXL345
- Init_ADXL345(); //初始化ADXL345
- //devid=Single_Read_ADXL345(0X00);//讀出的數據為0XE5,表示正確
- while(1) //循環
- {
- Multiple_Read_ADXL345(); //連續讀出數據,存儲在BUF中
- display_x(); //---------顯示X軸
- delay(200); //延時
-
- if( key == 0 ) //按鍵
- {
- num2 = 0; //歸零
- }
- DisplayOneChar(8,0,'T');
- DisplayOneChar(9,0,'e');
- DisplayOneChar(10,0,'m');
- DisplayOneChar(11,0,':');
- if (flag1s) //每秒更新一次溫度
- {
- flag1s = 0;
- res = Get18B20Temp(&temp); //讀取當前溫度
- if (res) //讀取成功時,刷新當前溫度顯示
- {
- intT = temp >> 4; //分離出溫度值整數部分
- decT = temp & 0xF; //分離出溫度值小數部分
- len = IntToString(str, intT); //整數部分轉換為字符串
- str[len++] = '.'; //添加小數點
- decT = (decT*10) / 16; //二進制的小數部分轉換為1位十進制位
- str[len++] = decT + '0'; //十進制小數位再轉換為ASCII字符
- while (len < 6) //用空格補齊到6個字符長度
- {
- str[len++] = ' ';
- }
- str[len] = '\0'; //添加字符串結束符
- LcdShowStr(12, 0, str); //“數字”顯示到液晶屏上
- }
- else //讀取失敗時,提示錯誤信息
- {
- LcdShowStr(10, 1, "error!");
- }
- Start18B20(); //重新啟動下一次轉換
- }
-
- }
- }
- /* 整型數轉換為字符串,str-字符串指針,dat-待轉換數,返回值-字符串長度 */
- unsigned char IntToString(unsigned char *str, int dat)
- {
- signed char i = 0;
- unsigned char len = 0;
- unsigned char buf[6];
-
- if (dat < 0) //如果為負數,首先取絕對值,并在指針上添加負號
- {
- dat = -dat;
- *str++ = '-';
- len++;
- }
- do { //先轉換為低位在前的十進制數組
- buf[i++] = dat % 10;
- dat /= 10;
- } while (dat > 0);
- len += i; //i最后的值就是有效字符的個數
- while (i-- > 0) //將數組值轉換為ASCII碼反向拷貝到接收指針上
- {
- *str++ = buf[i] + '0';
- }
- *str = '\0'; //添加字符串結束符
-
- return len; //返回字符串長度
- }
- /* 配置并啟動T0,ms-T0定時時間 */
- void ConfigTimer0(unsigned int ms)
- {
- unsigned long tmp; //臨時變量
-
- tmp = 11059200 / 12; //定時器計數頻率
- tmp = (tmp * ms) / 1000; //計算所需的計數值
- tmp = 65536 - tmp; //計算定時器重載值
- tmp = tmp + 12; //補償中斷響應延時造成的誤差
- TMOD &= 0xF0; //清零T0的控制位
- TMOD |= 0x01; //配置T0為模式1
- TH0=(65536-50000)%256;
- TL0=(65536-50000)%256;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- }
- /* T0中斷服務函數,完成1秒定時 */
- void InterruptTimer0() interrupt 1
- {
- static unsigned char tmr1s = 0;
-
- TH0=(65536-50000)%256;
- TL0=(65536-50000)%256;
- tmr1s++;
- if (tmr1s >= 18) //定時1s
- {
- tmr1s = 0;
- flag1s = 1;
- }
- }
復制代碼
|