#include<STC12C5A60S2.h>
#include<lcd1602.h>
#include<MPU9250.H>
unsigned char XS[]="Welcome!";
unsigned char BUF[10]; //接收數據緩存區
signed int T_X,T_Y,T_Z;
unsigned char readkey()
{
unsigned char keytemp,KEY=0;
P0=0x0f;
keytemp=P0;
if(keytemp==0x0f) return 0xff;
else KEY=keytemp;
P0=0xf0;
keytemp=P0;
if(keytemp==0xf0) return 0xff;
else KEY=KEY|keytemp;
switch(KEY)
{
case 0xEE: KEY=1;break;
case 0xDE: KEY=2;break;
case 0xBE: KEY=3;break;
case 0x7E: KEY=4;break;
case 0xED: KEY=5;break;
case 0xDD: KEY=6;break;
case 0xBD: KEY=7;break;
case 0x7D: KEY=8;break;
case 0xEB: KEY=9;break;
case 0xDB: KEY=10;break;
case 0xBB: KEY=11;break;
case 0x7B: KEY=12;break;
case 0xE7: KEY=13;break;
case 0xD7: KEY=14;break;
case 0xB7: KEY=15;break;
case 0x77: KEY=16;break;
default:KEY=0;
}
return(KEY);
}
void main()
{ unsigned char i,key,keytemp;
signed int volt,Angle; //裝AD轉換結果
float VDF;
P0M0=0xff;
P0M1=0x00; //設置P0口為強上拉輸
P1M1=0x20;
P1M0=0x00; //設置P1.5口為高阻輸入 AD轉換的需求
P1ASF=0x20; //只將P1.5 設置為AD轉換的輸入
AUXR1=AUXR1&0xFB;//只將ADRJ置1,其余各位不變
//AD轉換的數據高8位在ADC_RES里,低2位在ADC_RESL里
ADC_CONTR=0xE5; //給ADC電源,清除ADC_FLAG,指定P1.5為轉換輸入
LCD1602_delay_ms(10); //延時
Init_MPU9250(); //初始化MPU9250
Init_LCD1602(); //初始化LCD1602
LCD1602_delay_ms(1000);
LCD1602_POT(5,0); //指針設置到第0行
i=0;
while(XS[i]!='\0')
{
LCD1602_write_data(XS[i++]);
LCD1602_delay_ms(2000); //延時
}
LCD1602_write_com(0x01); //清屏指令
LCD1602_delay_ms(2000); //延時
while(1)
{
key=readkey(); //調用鍵盤判斷,返回值是0xff,表示沒有按鍵按下,否則返回按鍵值:1---16
if(key!=0xff)
{
if(key<10) keytemp=key|0x30;
else keytemp='A'+key-10;
LCD1602_POT(0,0);
LCD1602_write_word("KEY=");
LCD1602_write_data(keytemp);
}
else
{
LCD1602_POT(0,0);
LCD1602_write_word("KEY=?");
}
ADC_CONTR=0xED; //給ADC電源,清除ADC_FLAG,指定P1.5為轉換輸入 并且啟動轉換
i=5;
while(i--); //空等幾個時鐘,等AD啟動命令生效
while(ADC_CONTR&0x10==0); //等待判斷ADC_FLAG是否為1,為0將原地等待
volt=ADC_RES*4+(ADC_RESL&0x03); //拼裝10位轉換得到的數據
VDF=(float)volt*5/1024; //根據分辨率10位,分辨率就是2的10次方=1024,參考電壓是芯片的工作電壓(5V),必須定義為浮點型
VDF=VDF*100; //將x.yy的電壓值擴大100倍,變成xyy
volt=(unsigned int)VDF; //再將其轉換為整形,為分離各位進行顯示做準備
LCD1602_POT(11,0);
LCD1602_write_data((volt/100)|0x30); //將百位數的ASCII碼輸出(|0x30就是得到數字的ADCII碼)
LCD1602_write_data('.'); //顯示小數點
LCD1602_write_data(((volt%100)/10)|0x30); //顯示十分位
LCD1602_write_data((volt%10)|0x30); //顯示百分位
LCD1602_write_data('V');
LCD1602_delay_ms(100);
MPU9250_Read_Average(&T_X,&T_Y,&T_Z,5,ACCEL); //讀5次加速度,求平均值
// LCD1602_MPU9250XYZ(T_X,T_Y,T_Z); //在LCD1602上顯示X,Y,Z方向的加速度值
// LCD1602_delay_ms(100);
Angle=MPU9250_Get_ZAngle(T_X,T_Y,T_Z); //獲得相對于自然Z軸的傾斜角度:4位十進制帶符號整數 -1800---+1800度
//用來顯示,自己在第三位后加. 用來比較計算,記得是比實際值大10倍
LCD1602_POT(0,1);
LCD1602_write_word("Agl_Z:");
if(Angle<0)
{
LCD1602_write_data('-');
Angle=-Angle; //顯示的時候,為了計算方便,負值(補碼)要轉換為正數來計算
}
else
LCD1602_write_data('+');
LCD1602_write_data((Angle/1000)|0x30); //將千位數的ASCII碼輸出(|0x30就是得到數字的ADCII碼) 實際角度的百位
LCD1602_write_data(((Angle%1000)/100)|0x30); //顯示百位 實際角度的十位
LCD1602_write_data((Angle%100)/10|0x30); //顯示十位 實際角度的個位
LCD1602_write_data('.'); //顯示小數點
LCD1602_write_data((Angle%10)|0x30); //顯示個位 實際角度的十分位
LCD1602_write_data('\'');
/*
Angle=MPU9250_Get_Angle(T_X,T_Y,T_Z,0); //計算得到與自然Z軸的角度
LCD1602_POT(0,1);
LCD1602_write_data((Angle/100)|0x30); //將百位數的ASCII碼輸出(|0x30就是得到數字的ADCII碼)
LCD1602_write_data(((Angle%100)/10)|0x30); //顯示十分位
LCD1602_write_data((Angle%10)|0x30); //顯示百分位
Angle=MPU9250_Get_Angle(T_X,T_Y,T_Z,1); //計算得到與自然X軸的角度
LCD1602_POT(4,1);
LCD1602_write_data((Angle/100)|0x30); //將百位數的ASCII碼輸出(|0x30就是得到數字的ADCII碼)
LCD1602_write_data(((Angle%100)/10)|0x30); //顯示十分位
LCD1602_write_data((Angle%10)|0x30); //顯示百分位
Angle=MPU9250_Get_Angle(T_X,T_Y,T_Z,2); //計算得到與自然Y軸的角度
LCD1602_POT(8,1);
LCD1602_write_data((Angle/100)|0x30); //將百位數的ASCII碼輸出(|0x30就是得到數字的ADCII碼)
LCD1602_write_data(((Angle%100)/10)|0x30); //顯示十分位
LCD1602_write_data((Angle%10)|0x30); //顯示百分位
*/
// MPU9250_Read_Average(&T_X,&T_Y,&T_Z,10,GYRO); //讀10次陀螺儀的值,求平均值
// MPU9250_Read_Average(&T_X,&T_Y,&T_Z,10,MAG); //讀10次磁場的值,求平均值
}
}
|