1. 程式人生 > >C51 for ADXL345 微控制器程式 加速度感測器

C51 for ADXL345 微控制器程式 加速度感測器

/*
 * ADXL345模組
 * 
 * 用途:ADXL345模組IIC測試程式
 * 
 * 作者日期 備註
 * leevy2013 1 8   新增
 
 * 
 */


#include  <REG51.H>
#include  <math.h>    //Keil library  
#include  <stdio.h>   //Keil library
#include  <INTRINS.H>
#define   uchar unsigned char
#define   uint unsigned int
#define   DataPort P0    //LCD1602資料埠
sbit SCL=P1^0;      //IIC時鐘引腳定義
sbit  SDA=P1^1;      //IIC資料引腳定義
sbit      LCM_RS=P2^6;   //LCD1602命令埠
sbit      LCM_RW=P2^5;   //LCD1602命令埠
sbit      LCM_EN=P2^7;   //LCD1602命令埠


#defineSlaveAddress   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;                       //變數


void delay(unsigned int k);
void InitLcd();                      //初始化lcd1602
void Init_ADXL345(void);             //初始化ADXL345


void WriteDataLCM(uchar dataW);
void WriteCommandLCM(uchar CMD,uchar Attribc);
void DisplayOneChar(uchar X,uchar Y,uchar DData);
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;
}


/*******************************/
void delay(unsigned int k)
{
unsigned int i,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++)
{;}}
}
/*******************************/
void WaitForEnable(void)
{
DataPort=0xff;
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);
LCM_EN=0;
}
/*******************************/
void WriteCommandLCM(uchar CMD,uchar Attribc)
{
if(Attribc)WaitForEnable();
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/*******************************/
void WriteDataLCM(uchar dataW)
{
WaitForEnable();
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/***********************************/
void InitLcd()
{
WriteCommandLCM(0x38,1);
WriteCommandLCM(0x08,1);
WriteCommandLCM(0x01,1);
WriteCommandLCM(0x06,1);
WriteCommandLCM(0x0c,1);
}
/***********************************/
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40;
X|=0x80;
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}


/**************************************
延時5微秒(

[email protected])
不同的工作環境,需要調整此函式,注意時鐘過快時需要修改
當改用1T的MCU時,請調整此延時函式
**************************************/
void Delay5us()
{
    _nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}


/**************************************
延時5毫秒([email protected]
)
不同的工作環境,需要調整此函式
當改用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頁
}


//
//
//
//
//
//
//void send_data(uchar da)
//{
//SBUF=da;
//while(!TI);
//TI=0;
//}
////顯示x軸
//void send_x()
//{   
//float temp;
//
//send_data('x');//x  
//    dis_data=(BUF[1]<<8)+BUF[0];  //合成數據 
//if(dis_data<0)
//{
//dis_data=-dis_data;
//   send_data('-');    //顯示正負符號位
//}
//else send_data('+'); //
//
//    temp=(float)dis_data*3.9;  //計算資料和顯示,查考ADXL345快速入門第4頁
//    conversion(temp);          //轉換出顯示需要的資料
////send_data(qian*16+bai);
////send_data(shi*16+ge);
//send_data(qian);
//send_data(bai);
//send_data(shi);
//send_data(ge);
//}
//
////***********************************************************************
////顯示y軸
//void send_y()
//{   
//
//float temp;
//
//send_data('y');  
//    dis_data=(BUF[3]<<8)+BUF[2];  //合成數據   
//if(dis_data<0)
//{
//dis_data=-dis_data;
//   send_data('-');    //顯示正負符號位
//}
//else send_data('+'); //顯示空格
//
//    temp=(float)dis_data*3.9;  //計算資料和顯示,查考ADXL345快速入門第4頁
//    conversion(temp);          //轉換出顯示需要的資料
////send_data(qian*16+bai);
////send_data(shi*16+ge);
//send_data(qian);
//send_data(bai);
//send_data(shi);
//send_data(ge);
//
//}
//
////***********************************************************************
////顯示z軸
//void send_z()
//{      
//
//float temp;
//
//send_data('z'); 
//    dis_data=(BUF[5]<<8)+BUF[4];    //合成數據   
//if(dis_data<0)
//{
//dis_data=-dis_data;
//   send_data('-');    //顯示正負符號位
//}
//else send_data('+'); //顯示空格
//
//    temp=(float)dis_data*3.9;  //計算資料和顯示,查考ADXL345快速入門第4頁
//    conversion(temp);          //轉換出顯示需要的資料
////send_data(qian*16+bai);
////send_data(shi*16+ge);
//send_data(qian);
//send_data(bai);
//send_data(shi);
//send_data(ge);
//
//
//}
//
//
















 
//***********************************************************************
//顯示x軸
void display_x()
{   
float temp;
//send_data('x');//x  
    dis_data=(BUF[1]<<8)+BUF[0];  //合成數據   
if(dis_data<0)
{
dis_data=-dis_data;
   DisplayOneChar(10,0,'-');      //顯示正負符號位
//send_data('-');
}
else 
{
DisplayOneChar(10,0,'+'); //顯示空格
//send_data('+');

}



    temp=(float)dis_data*3.9;  //計算資料和顯示,查考ADXL345快速入門第4頁
    conversion(temp);          //轉換出顯示需要的資料
DisplayOneChar(8,0,'X');
    DisplayOneChar(9,0,':'); 
    DisplayOneChar(11,0,qian); 
DisplayOneChar(12,0,'.'); 
    DisplayOneChar(13,0,bai); 
    DisplayOneChar(14,0,shi); 
DisplayOneChar(15,0,ge); 
//send_data(qian);
//send_data(bai);
//send_data(shi);
//send_data(ge);
}


//***********************************************************************
//顯示y軸
void display_y()
{     
float temp;
//send_data('y');
    dis_data=(BUF[3]<<8)+BUF[2];  //合成數據   
if(dis_data<0)
{
dis_data=-dis_data;
   DisplayOneChar(2,1,'-');      //顯示正負符號位
//send_data('-');
}
else 
{
DisplayOneChar(2,1,'+'); //顯示空格
//send_data('+');
}


    temp=(float)dis_data*3.9;  //計算資料和顯示,查考ADXL345快速入門第4頁
    conversion(temp);          //轉換出顯示需要的資料
DisplayOneChar(0,1,'Y');   //第1行,第0列 顯示y
    DisplayOneChar(1,1,':'); 
    DisplayOneChar(3,1,qian); 
DisplayOneChar(4,1,'.'); 
    DisplayOneChar(5,1,bai); 
    DisplayOneChar(6,1,shi);  
DisplayOneChar(7,1,ge); 
//send_data(qian);
//send_data(bai);
//send_data(shi);
//send_data(ge); 
}


//***********************************************************************
//顯示z軸
void display_z()
{
    float temp;
//send_data('z');
    dis_data=(BUF[5]<<8)+BUF[4];    //合成數據   
if(dis_data<0)
{
dis_data=-dis_data;
   DisplayOneChar(10,1,'-');       //顯示負符號位
//send_data('-');
}
else 
{
DisplayOneChar(10,1,' ');  //顯示空格
//send_data('+');
}


    temp=(float)dis_data*3.9;  //計算資料和顯示,查考ADXL345快速入門第4頁
    conversion(temp);          //轉換出顯示需要的資料
DisplayOneChar(8,1,'Z');  //第0行,第10列 顯示Z
    DisplayOneChar(9,1,':'); 
    DisplayOneChar(11,1,qian); 
DisplayOneChar(12,1,'.'); 
    DisplayOneChar(13,1,bai); 
    DisplayOneChar(14,1,shi); 
DisplayOneChar(15,1,ge);
//send_data(qian);
//send_data(bai);
//send_data(shi);
//send_data(ge);  
}
/*
void ser_int()
{
        SCON = 0x50;       //REN=1允許序列接受狀態,串列埠工作模式2       
   TMOD|= 0x20;      //定時器工作方式2                       
PCON|= 0x80;      //波特率提高一倍                                                    
     // TH1  = 0xFD;     //baud*2  /* reload value 19200、資料位8、停止位1。效驗位無(11.0592)     
   TH1 = 0xF3;// //baud*2  /*  波特率4800、資料位8、停止位1。效驗位無 (12M)
    TL1 = 0xF3; 
TR1  = 1;        //開啟定時器1                                                      
ES   = 1;        //開串列埠中斷                  
EA   = 1;        // 開總中斷 
  // IE = 0x0;

*/


//*********************************************************
//******主程式********
//*********************************************************
void main()

uchar devid;
delay(500);                   //上電延時
InitLcd();                      //液晶初始化ADXL345
//ser_int();
DisplayOneChar(0,0,'A');
DisplayOneChar(1,0,'D'); 
DisplayOneChar(2,0,'X'); 
DisplayOneChar(3,0,'L'); 
DisplayOneChar(4,0,'3'); 
DisplayOneChar(5,0,'4');  
DisplayOneChar(6,0,'5'); 

Init_ADXL345();                 //初始化ADXL345
devid=Single_Read_ADXL345(0X00);//讀出的資料為0XE5,表示正確
while(1)                         //迴圈

Multiple_Read_ADXL345();       //連續讀出資料,儲存在BUF中
display_x();                   //---------顯示X軸
display_y();                   //---------顯示Y軸
display_z();                   //---------顯示Z軸
delay(200);                    //延時    
//send_x();
//send_y();
//send_z();        
}

相關推薦

C51 for ADXL345 微控制器程式 加速度感測器

/*  * ADXL345模組  *   * 用途:ADXL345模組IIC測試程式  *   * 作者日期 備註  * leevy2013 1 8   新增    *   */ #include  <REG51.H> #include  <math.h

Arduino學習筆記二三軸加速度感測器ADXL345

很早就聽說Arduino,早就想玩了。最近搞了快Arduino板子,就是前面介紹的Arduino Leonardo,最近需要用到感測器,從三軸加速度ADXL345開始。 開發環境: 系統:XP 單板:Arduino Leonardo 平臺:Arduino-1.5.2 目標:

手把手教您編寫第一個微控制器程式

51微控制器的開發環境是Keil 軟體。Keil 軟體雖然是一個收費軟體,但從uVision2到目前的uVison4版本都有破解版,在網上都可以找到下載。筆者推薦大家使用uVisong4破解版本,好處不用多說。Keil uVision4軟體的壓縮包裡附有安裝和破解說明,本文不再贅述。 開發一個微控制器程式,

2-物聯網開發標配方案(51微控制器程式介紹+WIFI程式介紹)

  上一節  https://www.cnblogs.com/yangfengwu/p/9944438.html 購買雲伺服器安裝MQTT就不用說了,以前寫過文章介紹   https://www.cnblogs.com/yangfengwu/p/8758733.html&

《The most important non-programming skills for programmers(程式設計師的軟技能)》

文章標題: The most important non-programming skills for programmers(對程式設計師很重要的軟技能) 作者主要從11個方面進行了闡述,總結了一些對程式設計師來說比較常用的“編外”技巧,接下來我會大致介紹一下,並且附上自己的心得 1.Empathy(移

基於Unique ID的微控制器程式加密系統 微控制器唯一ID程式加密

文章原始地址:http://feotech.com/?p=25 基於Unique ID的微控制器程式加密系統 微控制器唯一ID程式加密 微控制器一般作為一個產品的邏輯中心,工作時一直在進行著邏輯判斷與執行操作,相當於人類的大腦。微控制器可以通過修改程式來控制外圍電路的工作狀態,從

加速度感測器

一、修改MainActivity檔案 package com.example.yxp.jxol; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; impor

Qt for ios 設定程式顯示名稱

前言 Qt 開發 IOS 程式,編譯出來軟體的預設名稱就是 Qt 的工程名,包括 Qt 開發 Android 也是一樣,修改 android 的程式顯示名稱需要在 AndroidManifest檔案中進行修改,而 IOS 的程式顯示名稱就需要在 info.plist檔案中修改。在之前

MMS-F-A01無線加速度感測器

MMS-F-A01無線加速度感測器請新增連結描述說明書 1、產品介紹: MMS-F-A01無線加速度感測器請新增連結描述採用最先進的無線物聯網技術——LORA技術,同時具有低功耗和長距離通訊的特性,通訊距離可達5km,感測器引進歐洲專利技術的三軸加速度感測單元,具有結構固定、功耗低、穩定性好等特點,無線加

MMS-A01型三軸有線加速度感測器

MMS-A01型三軸有線加速度感測器請新增連結描述使用說明書 1、產品介紹:MMS-A01是一款引進歐洲專利技術的三軸加速度感測器請新增連結描述,產品具有結構固定,功耗低,偏差穩定性優異等特點,保證了傑出的輸出可靠性。 可適用於震動測試,撞擊測試等多個領域,可適應在工業惡劣環境中長期工作。 2、產品特點:

51微控制器程式下載、ISP及串列埠基礎知識

本文詳細介紹了串列埠、51微控制器的ISP下載等基礎知識,已經學過微控制器的也可以看看,加強一下對這方面的瞭解。   串列埠   序列介面簡稱串列埠,也稱序列通訊介面,是採用序列通訊方式的擴充套件介面。   我們比較熟悉的USB介面,全名通用序列

html5+ accelerometer-加速度感測器

accelerometer 加速度感測器 Accelerometer模組管理裝置加速度感測器,用於獲取裝置加速度資訊,包括x(螢幕水平方向)、y(垂直螢幕水平方向)、z(垂直螢幕平面方向)三個方向的加速度資訊。通過plus.accelerometer獲取裝置加速

加速度感測器的原理和應用-手機翻轉、失重檢測、運動檢測、位置識別

本文介紹可穿戴裝置加速度感測器-Lis3dh的特性原理和應用場景。意法半導體研發的Lis3dh廣泛應用在智慧手環、智慧計步鞋等智慧穿戴產品中。Lis3dh有兩種工作方式,一種是其內建了多種演算法來處理常

用ILMerge合併Silverlight, WindowsPhone或Mono for Android的程式

為大家所知,ILMerge可用於合併.NET的程式集,但如何合併Silverlight,WindowsPhone或者Mono for Android的程式集呢?其實ILMerge命令引數targetplatform已經提供了對此項功能的支援。 ILMerge下載地址: 使用ILMerge合併Sil

學習筆記之《吳堅鴻-手把手教你微控制器程式框架》

一,在工控專案中,由於受到電源的波動或者是外來的毛刺訊號干擾,開關的輸入訊號(連線MCU的輸入引腳)或讀取到瞬間的電平   注:MCU的輸入引腳預設為上拉電阻   二,微控制器C語言的多檔案程式設計技巧 1,每個檔案保持成雙成對出現。每個.c 原始檔必須有一個.h 標頭檔案跟它對應,每個.h

加速度感測器,磁場感測器和陀螺儀感測器案例

Sensor.TYPE_GYROSCOPE  陀螺儀就是內部有一個陀螺,它的軸由於陀螺效應始終與初始方向平行,這樣就可以通過與初始方向的偏差計算出實際方向。手機裡陀螺儀實際上是一個結構非常精密的晶片,內部包含超微小的陀螺。 陀螺儀測量是參考標準是內部中間在與地面垂直的方

自動跟隨機器人教程(七)軟體部分 樹莓派程式感測器綜合

現在樹莓派的各個感測器就都用上了,超聲波模組、影象識別、聲源定位各司其職,都能對周邊環境做出反應,以便對電機做操作。這樣就不需要電腦的遠端控制了,能真正做到自主執行。 問題是這些感測器都是獨立的,控制電機時以誰為主呢? 經過多次除錯,本人摸索出如下原則: 超聲波模組由於

h5學習之呼叫手機底層硬體----加速度感測器和震動

最近在開發微信公眾平臺時,有一個需求是通過搖一搖進行互動活動,剛開始以為要用微信內的搖一搖功能,但是微信根本沒有提供介面(搖一搖是呼叫手機硬體,根本不能呼叫),所以只能換一種思路,微信可以跟我們的伺服器端對接,所以只能通過一些前端的指令碼語言去解決。幸運的是:H5 + 提供

Android加速度感測器 -- 擡手亮屏

android系統提供以下感測器供應用層使用,具體如下:// android.hardware.Sensor TYPE_ACCELEROMETER 1 // 加速度感測器 TYPE_MAGNETIC_FIELD 2 // 磁力感測器 TYPE_ORI

ArcGIS API for Flex製作程式釋出後出現錯誤:"訪問 URL 時遇到安全性錯誤" 解決辦法嘗試(學習筆記)

問題: 前不久利用ArcGIS API for Flex做了一個程式,在Flash Builder中執行時能夠正常顯示地圖,並不報出錯誤,然後利用IIS釋出後進行瀏覽就出現錯誤[RPC Fault faultString="訪問 URL 時遇到安全性錯誤" faultCo