51单片机课程设计:基于ADXL345的三轴偏移值显示(可用于加速度测量)
51单片机课程设计:基于ADXL345的三轴偏移值显示(可用于加速度测量)
本程序通过IIC的通讯方式读取三轴加速度模块ADXL345的数值,并且利用数码管显示出来,通过三个按键可以实现不同轴偏移值的显示,数码管显示电路和需要用到的相关器件,还有工程文件以及相关资料,可以在附件下载,程序适用于吉林农业大学单片机开发板,其他型号开发板修改部分代码既可以完成移植。
关于粘贴复制乱码的问题:如果程序复制到Keil编译器上出现注释乱码,可以先建一个.c文件,也就是说不在keil里面编辑,然后用记事本打开.c文件,将源码复制进去,再在keil中添加文件即可。
/***********************************************************************************ADXL345加速度传感器实验本程序是基于三轴加速度模块ADXL345的,能够读取到ADXL345三轴偏移数值,没有实现加速度显示,如需达到此要求,可以自己找资料然后编写对应的函数。程序利用三个按键实现不同轴的偏移数值显示,P3.0:显示x轴偏移值P3.1:显示y轴偏移值P3.2:显示z轴偏移值模块的通讯方式为IICSCL接P1.0SDA接P1.1CS接P1.2(适用于吉农51开发板,如需移植,只需要更改显示电路即可)2016-12-30---------------------------------SWorld***********************************************************************************/#include<REG51.H>#include<math.h>//库函数#include<stdio.h>//库函数#include<INTRINS.H>#defineucharunsignedchar#defineuintunsignedint/*********************************八段数码管引脚定义*********************************/#defineGPIO_DIGP0//位选以及段选数据输出端口定义sbitWEC=P2^3;sbitDUC=P2^2;unsignedcharcodeDIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码unsignedcharDisplayData[8];//用来存放要显示的8位数的值sbitSCL=P1^0;//IIC时钟引脚定义sbitSDA=P1^1;//IIC数据引脚定义sbitCS=P1^2;sbitisx=P3^0;//显示xsbitisy=P3^1;//显示ysbitisz=P3^2;//显示Zunsignedintshow;//定义器件在IIC总线的从地址根据ADDRESS引脚不同修改接地时则地址为0xA6接电源时0x3A#defineSlaveAddress0xA6typedefunsignedcharBYTE;typedefunsignedshortWORD;BYTEBUF[8];//接收数据缓冲区ucharge,shi,bai,qian,wan;//显示变量个十百千万intdis_data;//变量voiddelay(unsignedintk);//延时voidInit_ADXL345(void);//初始化ADXLvoidconversion(uinttemp_data);//用来分离各位voidSingle_Write_ADXL345(ucharREG_Address,ucharREG_data);//单个写入数据ucharSingle_Read_ADXL345(ucharREG_Address);//单个读取内部寄存器数据voidMultiple_Read_ADXL345();//连续读取内部寄存器数据//------------------------------------voidDelay5us();//延时5usvoidDelay5ms();//延时5msvoidADXL345_Start();//其实信号voidADXL345_Stop();//停止信号voidADXL345_SendACK(bitack);//发送一位数据bitADXL345_RecvACK();//接收一位数据voidADXL345_SendByte(BYTEdat);//发送一字节数据BYTEADXL345_RecvByte();//接收一字节数据//-----------------------------------/********************************************************************************函数名:DigDisplay*函数功能:使用数码管显示*输入:无*输出:无*******************************************************************************/voidDigDisplay(){unsignedchari;unsignedintj;for(i=0;i<8;i++){WEC=1;DUC=0;switch(i)//位选,选择点亮的数码管,{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];//发送段码j=15;//扫描间隔时间设定while(j--);GPIO_DIG=0x00;//消隐}}//延时10msvoidDelay10ms(unsignedintc)//误差0us{unsignedchara,b;//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//for(;c>0;c--){for(b=38;b>0;b--){for(a=130;a>0;a--);}}}/*--------------------------------------三个按键检测-----------------------------------------------*/unsignedcharKey_Scan(){unsignedcharkeyValue=0,i;//保存键值//--检测按键1--//if(isx!=1)//检测按键K1是否按下{Delay10ms(1);//消除抖动if(isx!=1)//再次检测按键是否按下{keyValue=1;i=0;while((i<50)&&(isx!=1))//检测按键是否松开{Delay10ms(1);i++;}}}//--检测按键1--//if(isy!=1)//检测按键K1是否按下{Delay10ms(1);//消除抖动if(isy!=1)//再次检测按键是否按下{keyValue=2;i=0;while((i<50)&&(isy!=1))//检测按键是否松开{Delay10ms(1);i++;}}}//--检测按键1--//if(isz!=1)//检测按键K1是否按下{Delay10ms(1);//消除抖动if(isz!=1)//再次检测按键是否按下{keyValue=3;i=0;while((i<50)&&(isz!=1))//检测按键是否松开{Delay10ms(1);i++;}}}returnkeyValue;//将读取到键值的值返回}//*************存入各位数据********************************************voidconversion(uinttemp_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;}/*******************************/voiddelay(unsignedintk){unsignedinti,j;for(i=0;i<k;i++){for(j=0;j<121;j++){;}}}/**************************************延时5us**************************************/voidDelay5us(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/**************************************延时5ms**************************************/voidDelay5ms(){WORDn=560;while(n--);}/**************************************起始信号**************************************/voidADXL345_Start(){SDA=1;//拉高数据线SCL=1;//拉高时钟线Delay5us();//延时SDA=0;//拉低数据线Delay5us();//延时SCL=0;//拉低时钟线}/**************************************结束信号**************************************/voidADXL345_Stop(){SDA=0;//拉低数据线SCL=1;//拉高时钟线Delay5us();//延时SDA=1;//产生上升沿Delay5us();//延时}/**************************************发送应答信号**************************************/voidADXL345_SendACK(bitack){SDA=ack;//写应答信号SCL=1;//拉高时钟线Delay5us();//延时SCL=0;//拉低时钟线Delay5us();//延时}/**************************************接收应答信号**************************************/bitADXL345_RecvACK(){SCL=1;//拉高时钟线Delay5us();//延时CY=SDA;//读取应答信号SCL=0;//拉低时钟线Delay5us();//延时returnCY;//返回应答数据}/**************************************向IIC总线发送一字节数据**************************************/voidADXL345_SendByte(BYTEdat){BYTEi;for(i=0;i<8;i++)//8位计数器{dat<<=1;//移除数据最高位SDA=CY;//送数据口SCL=1;//拉高时钟线Delay5us();//延时SCL=0;//拉低时钟线Delay5us();//延时}ADXL345_RecvACK();}/**************************************向IIC总线取一字节数据**************************************/BYTEADXL345_RecvByte(){BYTEi;BYTEdat=0;SDA=1;//拉高数据线for(i=0;i<8;i++)//8为计数器{dat<<=1;SCL=1;//左移一位Delay5us();//延时dat|=SDA;//读数据SCL=0;//拉低时钟线Delay5us();//延时}returndat;//返回一字节数据}//******单字节写入*******************************************voidSingle_Write_ADXL345(ucharREG_Address,ucharREG_data){ADXL345_Start();//起始信号ADXL345_SendByte(SlaveAddress);//发送设备地址ADXL345_SendByte(REG_Address);//内部寄存器地址ADXL345_SendByte(REG_data);//内部数据地址ADXL345_Stop();//结束信号}//********单字节读取*****************************************ucharSingle_Read_ADXL345(ucharREG_Address){ucharREG_data;ADXL345_Start();//起始信号ADXL345_SendByte(SlaveAddress);//发送设备地址ADXL345_SendByte(REG_Address);//发送寄存器地址ADXL345_Start();//起始信号ADXL345_SendByte(SlaveAddress+1);//发送设备地址REG_data=ADXL345_RecvByte();//接收一字节数据ADXL345_SendACK(1);ADXL345_Stop();//结束信号returnREG_data;}//*********************************************************////连续读取器内部加速度数据范围0x32-0x37////*********************************************************voidMultiple_read_ADXL345(void){uchari;ADXL345_Start();//起始ADXL345_SendByte(SlaveAddress);//设备地址ADXL345_SendByte(0x32);//存储单元地址ADXL345_Start();//起始信号ADXL345_SendByte(SlaveAddress+1);//设备地址加读信号for(i=0;i<6;i++)//连续接收六个地址数据存入BUF{BUF[i]=ADXL345_RecvByte();//if(i==5){ADXL345_SendACK(1);//最后一个数据}else{ADXL345_SendACK(0);//回应ACK}}ADXL345_Stop();//结束Delay5ms();}//*****************************************************************//初始化ADXL345***********************voidInit_ADXL345(){Single_Write_ADXL345(0x31,0x0B);//测量范围正负16g13位模式Single_Write_ADXL345(0x2C,0x08);//速率12.5Single_Write_ADXL345(0x2D,0x08);//电源模式Single_Write_ADXL345(0x2E,0x80);//使能DATA_READY中断Single_Write_ADXL345(0x1E,0x00);//X偏移量Single_Write_ADXL345(0x1F,0x00);//YSingle_Write_ADXL345(0x20,0x05);//Z}//***********************************************************************//显示xvoiddisplay_x(){floattemp;dis_data=(BUF[1]<<8)+BUF[0];//合成数据if(dis_data<0){dis_data=-dis_data;DisplayData[6]=0x40;}else{DisplayData[6]=0x00;}temp=(float)dis_data*3.9;//计算数据conversion(temp);//分解数据}//***********************************************************************//yvoiddisplay_y(){floattemp;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);}//***********************************************************************//zvoiddisplay_z(){floattemp;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);}//*********************************************************//************************主函数***************************//*********************************************************voidmain(){uchardevid;delay(500);//延时Init_ADXL345();//初始化ADXL345CS=1;devid=Single_Read_ADXL345(0X00);//读取数据为0xE5表示正确show=1;DisplayData[7]=DIG_CODE[1];while(1)//循环{switch(Key_Scan()){case1:show=1;DisplayData[7]=DIG_CODE[1];break;case2:show=2;DisplayData[7]=DIG_CODE[2];break;case3:show=3;DisplayData[7]=DIG_CODE[3];break;}switch(show){case1:Multiple_Read_ADXL345();//读取数据存入BUFdisplay_x();//显示xbreak;case2:Multiple_Read_ADXL345();//读取数据存入BUFdisplay_y();//显示xbreak;case3:Multiple_Read_ADXL345();//读取数据存入BUFdisplay_z();//显示xbreak;}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();}}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。