#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次磁场的值,求平均值
}
}
|