您好,登錄后才能下訂單哦!
51單片機(jī)課程設(shè)計(jì):基于ADXL345的三軸偏移值顯示(可用于加速度測(cè)量)
本程序通過(guò)IIC的通訊方式讀取三軸加速度模塊ADXL345的數(shù)值,并且利用數(shù)碼管顯示出來(lái),通過(guò)三個(gè)按鍵可以實(shí)現(xiàn)不同軸偏移值的顯示,數(shù)碼管顯示電路和需要用到的相關(guān)器件,還有工程文件以及相關(guān)資料,可以在附件下載,程序適用于吉林農(nóng)業(yè)大學(xué)單片機(jī)開(kāi)發(fā)板,其他型號(hào)開(kāi)發(fā)板修改部分代碼既可以完成移植。
關(guān)于粘貼復(fù)制亂碼的問(wèn)題:如果程序復(fù)制到Keil編譯器上出現(xiàn)注釋亂碼,可以先建一個(gè).c文件,也就是說(shuō)不在keil里面編輯,然后用記事本打開(kāi).c文件,將源碼復(fù)制進(jìn)去,再在keil中添加文件即可。
/*********************************************************************************** ADXL345加速度傳感器實(shí)驗(yàn) 本程序是基于三軸加速度模塊ADXL345的,能夠讀取到ADXL345三軸偏移數(shù)值,沒(méi)有實(shí)現(xiàn)加速度 顯示,如需達(dá)到此要求,可以自己找資料然后編寫(xiě)對(duì)應(yīng)的函數(shù)。 程序利用三個(gè)按鍵實(shí)現(xiàn)不同軸的偏移數(shù)值顯示, P3.0:顯示x軸偏移值 P3.1:顯示y軸偏移值 P3.2:顯示z軸偏移值 模塊的通訊方式為IIC SCL接P1.0 SDA接P1.1 CS接P1.2 (適用于吉農(nóng)51開(kāi)發(fā)板,如需移植,只需要更改顯示電路即可) 2016-12-30---------------------------------SWorld ***********************************************************************************/ #include <REG51.H> #include <math.h> //庫(kù)函數(shù) #include <stdio.h> //庫(kù)函數(shù) #include <INTRINS.H> #define uchar unsigned char #define uint unsigned int /*********************************八段數(shù)碼管引腳定義*********************************/ #define GPIO_DIG P0//位選以及段選數(shù)據(jù)輸出端口定義 sbit WEC=P2^3; sbit DUC=P2^2; unsigned char code DIG_CODE[10]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f}; //顯示段碼 unsigned char DisplayData[8]; //用來(lái)存放要顯示的8位數(shù)的值 sbit SCL=P1^0; //IIC時(shí)鐘引腳定義 sbit SDA=P1^1; //IIC數(shù)據(jù)引腳定義 sbit CS=P1^2; sbit isx=P3^0; //顯示x sbit isy=P3^1;//顯示y sbit isz=P3^2;//顯示Z unsigned int show; //定義器件在IIC總線的從地址 根據(jù)ADDRESS引腳不同修改 接地時(shí)則地址為0xA6 接電源時(shí)0x3A #defineSlaveAddress 0xA6 typedef unsigned char BYTE; typedef unsigned short WORD; BYTE BUF[8]; //接收數(shù)據(jù)緩沖區(qū) uchar ge,shi,bai,qian,wan; //顯示變量 個(gè)十百千萬(wàn) int dis_data; //變量 void delay(unsigned int k);//延時(shí) void Init_ADXL345(void); //初始化ADXL void conversion(uint temp_data);//用來(lái)分離各位 void Single_Write_ADXL345(uchar REG_Address,uchar REG_data); //單個(gè)寫(xiě)入數(shù)據(jù) uchar Single_Read_ADXL345(uchar REG_Address); //單個(gè)讀取內(nèi)部寄存器數(shù)據(jù) void Multiple_Read_ADXL345(); //連續(xù)讀取內(nèi)部寄存器數(shù)據(jù) //------------------------------------ void Delay5us(); //延時(shí)5us void Delay5ms();//延時(shí)5ms void ADXL345_Start();//其實(shí)信號(hào) void ADXL345_Stop();//停止信號(hào) void ADXL345_SendACK(bit ack); //發(fā)送一位數(shù)據(jù) bit ADXL345_RecvACK();//接收一位數(shù)據(jù) void ADXL345_SendByte(BYTE dat);//發(fā)送一字節(jié)數(shù)據(jù) BYTE ADXL345_RecvByte();//接收一字節(jié)數(shù)據(jù) //----------------------------------- /******************************************************************************* * 函 數(shù) 名 : DigDisplay * 函數(shù)功能 : 使用數(shù)碼管顯示 * 輸 入 : 無(wú) * 輸 出 : 無(wú) *******************************************************************************/ void DigDisplay() { unsigned char i; unsigned int j; for(i=0;i<8;i++) { WEC=1;DUC=0; switch(i) //位選,選擇點(diǎn)亮的數(shù)碼管, { case(0): GPIO_DIG=0x7F; break;//顯示第0位 case(1): GPIO_DIG=0xBF; break;//顯示第1位 case(2): GPIO_DIG=0xDF; break;//顯示第2位 case(3): GPIO_DIG=0xEF; break;//顯示第3位 case(4): GPIO_DIG=0xF7; break;//顯示第4位 case(5): GPIO_DIG=0xFB; break;//顯示第5位 case(6): GPIO_DIG=0xFD; break;//顯示第6位 case(7): GPIO_DIG=0xFE; break;//顯示第7位 } WEC=0;DUC=1; GPIO_DIG=DisplayData[i];//發(fā)送段碼 j=15; //掃描間隔時(shí)間設(shè)定 while(j--); GPIO_DIG=0x00;//消隱 } } //延時(shí)10ms void Delay10ms(unsigned int c) //誤差 0us { unsigned char a, b; //--c已經(jīng)在傳遞過(guò)來(lái)的時(shí)候已經(jīng)賦值了,所以在for語(yǔ)句第一句就不用賦值了--// for (;c>0;c--) { for (b=38;b>0;b--) { for (a=130;a>0;a--); } } } /*--------------------------------------三個(gè)按鍵檢測(cè) -----------------------------------------------*/ unsigned char Key_Scan() { unsigned char keyValue = 0 , i; //保存鍵值 //--檢測(cè)按鍵1--// if (isx != 1)//檢測(cè)按鍵K1是否按下 { Delay10ms(1);//消除抖動(dòng) if (isx != 1)//再次檢測(cè)按鍵是否按下 { keyValue = 1; i = 0; while ((i<50) && (isx != 1)) //檢測(cè)按鍵是否松開(kāi) { Delay10ms(1); i++; } } } //--檢測(cè)按鍵1--// if (isy != 1)//檢測(cè)按鍵K1是否按下 { Delay10ms(1);//消除抖動(dòng) if (isy!= 1)//再次檢測(cè)按鍵是否按下 { keyValue = 2; i = 0; while ((i<50) && (isy != 1)) //檢測(cè)按鍵是否松開(kāi) { Delay10ms(1); i++; } } } //--檢測(cè)按鍵1--// if (isz!= 1)//檢測(cè)按鍵K1是否按下 { Delay10ms(1);//消除抖動(dòng) if (isz!= 1)//再次檢測(cè)按鍵是否按下 { keyValue = 3; i = 0; while ((i<50) && (isz != 1)) //檢測(cè)按鍵是否松開(kāi) { Delay10ms(1); i++; } } } return keyValue; //將讀取到鍵值的值返回 } //*************存入各位數(shù)據(jù)******************************************** void conversion(uint temp_data) { wan=temp_data/10000 ; temp_data=temp_data%10000; qian=temp_data/1000 ; temp_data=temp_data%1000; bai=temp_data/100 ; temp_data=temp_data%100; shi=temp_data/10 ; temp_data=temp_data%10; ge=temp_data; } /*******************************/ void delay(unsigned int k) { unsigned int i,j; for(i=0;i<k;i++) { for(j=0;j<121;j++) {;} } } /************************************** 延時(shí)5us **************************************/ void Delay5us() { _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_(); } /************************************** 延時(shí)5ms **************************************/ void Delay5ms() { WORD n = 560; while (n--); } /************************************** 起始信號(hào) **************************************/ void ADXL345_Start() { SDA = 1; //拉高數(shù)據(jù)線 SCL = 1; //拉高時(shí)鐘線 Delay5us(); //延時(shí) SDA = 0; //拉低數(shù)據(jù)線 Delay5us(); //延時(shí) SCL = 0; //拉低時(shí)鐘線 } /************************************** 結(jié)束信號(hào) **************************************/ void ADXL345_Stop() { SDA = 0; //拉低數(shù)據(jù)線 SCL = 1; //拉高時(shí)鐘線 Delay5us(); //延時(shí) SDA = 1; //產(chǎn)生上升沿 Delay5us(); //延時(shí) } /************************************** 發(fā)送應(yīng)答信號(hào) **************************************/ void ADXL345_SendACK(bit ack) { SDA = ack; //寫(xiě)應(yīng)答信號(hào) SCL = 1; //拉高時(shí)鐘線 Delay5us(); //延時(shí) SCL = 0; //拉低時(shí)鐘線 Delay5us(); //延時(shí) } /************************************** 接收應(yīng)答信號(hào) **************************************/ bit ADXL345_RecvACK() { SCL = 1; //拉高時(shí)鐘線 Delay5us(); //延時(shí) CY = SDA; //讀取應(yīng)答信號(hào) SCL = 0; //拉低時(shí)鐘線 Delay5us(); //延時(shí) return CY; //返回應(yīng)答數(shù)據(jù) } /************************************** 向IIC總線發(fā)送一字節(jié)數(shù)據(jù) **************************************/ void ADXL345_SendByte(BYTE dat) { BYTE i; for (i=0; i<8; i++) //8位計(jì)數(shù)器 { dat <<= 1; //移除數(shù)據(jù)最高位 SDA = CY; //送數(shù)據(jù)口 SCL = 1; //拉高時(shí)鐘線 Delay5us(); //延時(shí) SCL = 0; //拉低時(shí)鐘線 Delay5us(); //延時(shí) } ADXL345_RecvACK(); } /************************************** 向IIC總線取一字節(jié)數(shù)據(jù) **************************************/ BYTE ADXL345_RecvByte() { BYTE i; BYTE dat = 0; SDA = 1; //拉高數(shù)據(jù)線 for (i=0; i<8; i++) //8為計(jì)數(shù)器 { dat <<= 1; SCL = 1; //左移一位 Delay5us(); //延時(shí) dat |= SDA; //讀數(shù)據(jù) SCL = 0; //拉低時(shí)鐘線 Delay5us(); //延時(shí) } return dat; //返回一字節(jié)數(shù)據(jù) } //******單字節(jié)寫(xiě)入******************************************* void Single_Write_ADXL345(uchar REG_Address,uchar REG_data) { ADXL345_Start(); //起始信號(hào) ADXL345_SendByte(SlaveAddress); //發(fā)送設(shè)備地址 ADXL345_SendByte(REG_Address); //內(nèi)部寄存器地址 ADXL345_SendByte(REG_data); //內(nèi)部數(shù)據(jù)地址 ADXL345_Stop(); //結(jié)束信號(hào) } //********單字節(jié)讀取***************************************** uchar Single_Read_ADXL345(uchar REG_Address) { uchar REG_data; ADXL345_Start(); //起始信號(hào) ADXL345_SendByte(SlaveAddress); //發(fā)送設(shè)備地址 ADXL345_SendByte(REG_Address); //發(fā)送寄存器地址 ADXL345_Start(); //起始信號(hào) ADXL345_SendByte(SlaveAddress+1); //發(fā)送設(shè)備地址 REG_data=ADXL345_RecvByte(); //接收一字節(jié)數(shù)據(jù) ADXL345_SendACK(1); ADXL345_Stop(); //結(jié)束信號(hào) return REG_data; } //********************************************************* // //連續(xù)讀取器內(nèi)部加速度數(shù)據(jù) 范圍0x32-0x37 // //********************************************************* void Multiple_read_ADXL345(void) { uchar i; ADXL345_Start(); //起始 ADXL345_SendByte(SlaveAddress); //設(shè)備地址 ADXL345_SendByte(0x32); //存儲(chǔ)單元地址 ADXL345_Start(); //起始信號(hào) ADXL345_SendByte(SlaveAddress+1); //設(shè)備地址加讀信號(hào) for (i=0; i<6; i++) //連續(xù)接收六個(gè)地址數(shù)據(jù) 存入BUF { BUF[i] = ADXL345_RecvByte(); // if (i == 5) { ADXL345_SendACK(1); //最后一個(gè)數(shù)據(jù) } else { ADXL345_SendACK(0); //回應(yīng)ACK } } ADXL345_Stop(); //結(jié)束 Delay5ms(); } //***************************************************************** //初始化ADXL345*********************** void Init_ADXL345() { Single_Write_ADXL345(0x31,0x0B); //測(cè)量范圍 正負(fù)16g 13位模式 Single_Write_ADXL345(0x2C,0x08); //速率12.5 Single_Write_ADXL345(0x2D,0x08); //電源模式 Single_Write_ADXL345(0x2E,0x80); //使能DATA_READY中斷 Single_Write_ADXL345(0x1E,0x00); //X 偏移量 Single_Write_ADXL345(0x1F,0x00); //Y Single_Write_ADXL345(0x20,0x05); //Z } //*********************************************************************** //顯示x void display_x() { float temp; dis_data=(BUF[1]<<8)+BUF[0]; //合成數(shù)據(jù) if(dis_data<0){ dis_data=-dis_data; DisplayData[6]=0x40; } else { DisplayData[6]=0x00; } temp=(float)dis_data*3.9; //計(jì)算數(shù)據(jù) conversion(temp); //分解數(shù)據(jù) } //*********************************************************************** //y void display_y() { float temp; dis_data=(BUF[3]<<8)+BUF[2]; if(dis_data<0){ dis_data=-dis_data; DisplayData[6]=0x40; } else { DisplayData[6]=0x00; } temp=(float)dis_data*3.9; conversion(temp); } //*********************************************************************** //z void display_z() { float temp; dis_data=(BUF[5]<<8)+BUF[4]; if(dis_data<0){ dis_data=-dis_data; DisplayData[6]=0x40; } else { DisplayData[6]=0x00; } temp=(float)dis_data*3.9; conversion(temp); } //********************************************************* //************************主函數(shù)*************************** //********************************************************* void main() { uchar devid; delay(500); //延時(shí) Init_ADXL345(); //初始化ADXL345 CS=1; devid=Single_Read_ADXL345(0X00);//讀取數(shù)據(jù)為0xE5表示正確 show=1; DisplayData[7]=DIG_CODE[1]; while(1) //循環(huán) { switch(Key_Scan()) { case 1: show=1; DisplayData[7]=DIG_CODE[1]; break; case 2: show=2; DisplayData[7]=DIG_CODE[2]; break; case 3: show=3; DisplayData[7]=DIG_CODE[3]; break; } switch(show) { case 1: Multiple_Read_ADXL345(); //讀取數(shù)據(jù)存入BUF display_x(); //顯示x break; case 2: Multiple_Read_ADXL345(); //讀取數(shù)據(jù)存入BUF display_y(); //顯示x break; case 3: Multiple_Read_ADXL345(); //讀取數(shù)據(jù)存入BUF display_z(); //顯示x break; } DisplayData[5]=DIG_CODE[wan]; DisplayData[4]=DIG_CODE[qian]; DisplayData[3]=DIG_CODE[bai]; DisplayData[2]=DIG_CODE[shi]; DisplayData[1]=DIG_CODE[ge]; DigDisplay(); } }
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。