基于STC12C5A60S2的ADXL345程序

上传人:仙*** 文档编号:31437044 上传时间:2021-10-12 格式:DOC 页数:17 大小:128.50KB
返回 下载 相关 举报
基于STC12C5A60S2的ADXL345程序_第1页
第1页 / 共17页
基于STC12C5A60S2的ADXL345程序_第2页
第2页 / 共17页
基于STC12C5A60S2的ADXL345程序_第3页
第3页 / 共17页
点击查看更多>>
资源描述
基于STC12C5A60S2的ADXL345Z程序(12T单片机未测试)头文件I2C.h#ifndef _I2C_H_#define _I2C_H_#include /-重定义关键词-/#ifndef uchar#define uchar unsigned char#endif#ifndef uint #define uint unsigned int#endif/-定义使用的IO口-/sbit I2C_SCL = P02;sbit I2C_SDA = P01;/-声明全局变量-/void I2C_Delay10us();void I2C_Start();void I2C_Stop();uchar I2C_SendByte(uchar dat, uchar ack);/ uchar I2C_ReadByte();uchar I2C_ReadByte(uchar ack);void I2C_Ack(void);void I2C_NAck(void);#endif源文件I2C.c#include i2c.hvoid I2C_Delay10us()/12.000MHzunsigned char i;i = 12;while (-i);void I2C_Start()I2C_SDA = 1;I2C_Delay10us();I2C_SCL = 1;I2C_Delay10us();/建立时间是I2C_SDA保持时间4.7usI2C_SDA = 0;I2C_Delay10us();/保持时间是4usI2C_SCL = 0;I2C_Delay10us();void I2C_Stop()I2C_SDA = 0;I2C_Delay10us();I2C_SCL = 1;I2C_Delay10us();/建立时间大于4.7usI2C_SDA = 1;I2C_Delay10us();uchar I2C_SendByte(uchar dat, uchar ack)uchar a = 0,b = 0;/最大255,一个机器周期为1us,最大延时255us。for(a=0; a 7; /起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号dat = dat 4.7usI2C_SCL = 0;I2C_Delay10us();/时间大于4usI2C_SDA = 1;I2C_Delay10us();I2C_SCL = 1;while(I2C_SDA & (ack = 1)/等待应答,也就是等待从设备把I2C_SDA拉低b+;if(b 200) /如果超过200us没有应答发送失败,或者为非应答,表示接收结束I2C_SCL = 0;I2C_Delay10us();return 0;I2C_SCL = 0;I2C_Delay10us(); return 1;uchar I2C_ReadByte(unsigned char ack)uchar a = 0,dat = 0;I2C_SDA = 1;/起始和发送一个字节之后I2C_SCL都是0I2C_Delay10us();for(a=0; a8; a+)/接收8个字节I2C_SCL = 1;I2C_Delay10us();dat = 1;dat |= I2C_SDA;I2C_Delay10us();I2C_SCL = 0;I2C_Delay10us();if(!ack)I2C_NAck();elseI2C_Ack();return dat;void I2C_Ack(void)I2C_SCL=0;I2C_SDA=0;I2C_Delay10us();I2C_SCL=1;I2C_Delay10us();I2C_SCL=0;/不产生ACK应答 void I2C_NAck(void)I2C_SCL=0;I2C_SDA=1;I2C_Delay10us();I2C_SCL=1;I2C_Delay10us();I2C_SCL=0;头文件ADXL345Z.h#ifndef _ADXL345Z_H#define _ADXL345Z_H#include #include i2c.h#ifndef u8#define u8 unsigned char#endif#ifndef u16 #define u16 unsigned int#endif#define DEVICE_ID0X00 /器件ID,0XE5#define THRESH_TAP0X1D /敲击阀值#define OFSX0X1E#define OFSY0X1F#define OFSZ0X20#define DUR0X21#define Latent0X22#define Window 0X23 #define THRESH_ACK0X24#define THRESH_INACT0X25 #define TIME_INACT0X26#define ACT_INACT_CTL0X27 #define THRESH_FF0X28#define TIME_FF0X29 #define TAP_AXES0X2A #define ACT_TAP_STATUS 0X2B #define BW_RATE0X2C #define POWER_CTL0X2D #define INT_ENABLE0X2E#define INT_MAP0X2F#define INT_SOURCE 0X30#define DATA_FORMAT 0X31#define DATA_X00X32#define DATA_X10X33#define DATA_Y00X34#define DATA_Y10X35#define DATA_Z00X36#define DATA_Z10X37#define FIFO_CTL0X38#define FIFO_STATUS0X39/用户配置,跟硬件电路有关,VDD-IO接高电平则为此地址,接地请查看数据手册#define ADXL_READ 0X3B#define ADXL_WRITE 0X3Au8 ADXL345_Init(void); /初始化ADXL345void ADXL345_WR_Reg(u8 addr,u8 val);/写ADXL345寄存器u8 ADXL345_RD_Reg(u8 addr);/读ADXL345寄存器void ADXL345_RD_XYZ(short *x,short *y,short *z);/读取一次值void ADXL345_RD_Avval(short *x,short *y,short *z);/读取平均值void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval);/自动校准void ADXL345_Read_Average(short *x,short *y,short *z,u8 times);/连续读取times次,取平均short ADXL345_Get_Angle(float x,float y,float z,u8 dir);void Adxl_Show_Num(u16 x,u16 y,short num,u8 mode);#endif源文件ADXL345Z.c#include ADXL345Z.h#include OLED.h#include u8 ADXL345_Init(void) u8 temp=ADXL345_RD_Reg(DEVICE_ID);if(temp=0xe5)/读取器件ID ADXL345_WR_Reg(DATA_FORMAT,0X2B);/低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(BW_RATE,0x0A);/数据输出速度为100HzADXL345_WR_Reg(POWER_CTL,0x28); /链接使能,测量模式ADXL345_WR_Reg(INT_ENABLE,0x00);/不使用中断 ADXL345_WR_Reg(OFSX,0x00);ADXL345_WR_Reg(OFSY,0x00);ADXL345_WR_Reg(OFSZ,0x00);return 0;else return 1;void ADXL345_WR_Reg(u8 addr,u8 val)I2C_Start();I2C_SendByte(ADXL_WRITE,1);/发送写器件指令,等待应答I2C_SendByte(addr,1);/发送寄存器地址I2C_SendByte(val,1);/发送要写入的值I2C_Stop();u8 ADXL345_RD_Reg(u8 addr)u8 temp;I2C_Start(); I2C_SendByte(ADXL_WRITE,1);/发送写器件指令,等待应答I2C_SendByte(addr,1);/发送寄存器地址I2C_Start();/重新开始起始信号,无需发送结束信号I2C_SendByte(ADXL_READ,1);/发送写器件指令,等待应答temp=I2C_ReadByte(0);/读取寄存器内容I2C_Stop();return temp;/读取3个轴的数据/x,y,z:读取到的数据void ADXL345_RD_XYZ(short *x,short *y,short *z)u8 buf6;u8 i;I2C_Start(); I2C_SendByte(ADXL_WRITE,1);/发送写器件指令I2C_SendByte(DATA_X0,1); I2C_Start(); /重新启动I2C_SendByte(ADXL_READ,1);/发送读器件指令for(i=0;i6;i+) if(i=5) bufi=I2C_ReadByte(0);/读取一个字节,不继续再读,发送NACK else bufi=I2C_ReadByte(1); I2C_Stop();/产生一个停止条件*x=(short)(u16)buf18)+buf0); *y=(short)(u16)buf38)+buf2); *z=(short)(u16)buf58)+buf4); void ADXL345_Read_Average(short *x,short *y,short *z,u8 times)u8 i;short tx,ty,tz;*x=0;*y=0;*z=0;if(times)/读取次数不为0for(i=0;itimes;i+)/连续读取times次ADXL345_RD_XYZ(&tx,&ty,&tz);*x+=tx;*y+=ty;*z+=tz;delay_ms(1);*x/=times;*y/=times;*z/=times;/得到角度/x,y,z:x,y,z方向的重力加速度分量(不需要单位,直接数值即可)/dir:要获得的角度.0,与Z轴的角度;1,与X轴的角度;2,与Y轴的角度./返回值:角度值.单位0.1.short ADXL345_Get_Angle(float x,float y,float z,u8 dir)float temp; float res=0;switch(dir)case 0:/与自然Z轴的角度 temp=sqrt(x*x+y*y)/z; res=atan(temp); break;case 1:/与自然X轴的角度 temp=x/sqrt(y*y+z*z); res=atan(temp); break; case 2:/与自然Y轴的角度 temp=y/sqrt(x*x+z*z); res=atan(temp); break; return res*1800/3.14;/读取ADXL的平均值/x,y,z:读取10次后取平均值void ADXL345_RD_Avval(short *x,short *y,short *z)short tx=0,ty=0,tz=0; u8 i; for(i=0;i10;i+)ADXL345_RD_XYZ(x,y,z);delay_ms(10);tx+=(short)*x;ty+=(short)*y;tz+=(short)*z; *x=tx/10;*y=ty/10;*z=tz/10; /自动校准/xval,yval,zval:x,y,z轴的校准值void ADXL345_AUTO_Adjust(char *xval,char *yval,char *zval)short tx,ty,tz;u8 i;short offx=0,offy=0,offz=0;ADXL345_WR_Reg(POWER_CTL,0x00); /先进入休眠模式.delay_ms(100);ADXL345_WR_Reg(DATA_FORMAT,0X2B);/低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 ADXL345_WR_Reg(BW_RATE,0x0A);/数据输出速度为100HzADXL345_WR_Reg(POWER_CTL,0x28); /链接使能,测量模式ADXL345_WR_Reg(INT_ENABLE,0x00);/不使用中断 ADXL345_WR_Reg(OFSX,0x00);ADXL345_WR_Reg(OFSY,0x00);ADXL345_WR_Reg(OFSZ,0x00);delay_ms(12);for(i=0;i10;i+)ADXL345_RD_Avval(&tx,&ty,&tz);offx+=tx;offy+=ty;offz+=tz; offx/=10;offy/=10;offz/=10;*xval=-offx/4;*yval=-offy/4;*zval=-(offz-256)/4; ADXL345_WR_Reg(OFSX,*xval);ADXL345_WR_Reg(OFSY,*yval);ADXL345_WR_Reg(OFSZ,*zval); /mode:0,显示加速度;1,显示角度void Adxl_Show_Num(u16 x,u16 y,short num,u8 mode)if(mode=0)/显示加速度值if(num0)OLED_ShowChar(x,y,-);/显示负号num=-num;/转为正数else OLED_ShowChar(x,y, );/去掉负号OLED_ShowNum(x+8,y,num,4,16);/显示值 else /显示角度值if(num0)OLED_ShowChar(x,y,-);/显示负号num=-num;/转为正数else OLED_ShowChar(x,y, );/去掉负号 OLED_ShowNum(x+8,y,num/10,2,16);/显示整数部分 OLED_ShowChar(x+24,y,.);/显示小数点OLED_ShowNum(x+32,y,num%10,1,16); /显示小数部分 头文件OLED.h#ifndef _OLED_H#define _OLED_H#include #define u8 unsigned char #define u32 unsigned int #define OLED_CMD 0/写命令#define OLED_DATA 1/写数据#define OLED_MODE 0 /0:4线串行模式 1:并行8080模式/-OLED端口定义- sbit OLED_CS=P00; /片选sbit OLED_RST =P15;/复位sbit OLED_DC =P22;/数据/命令控制sbit OLED_SCL=P20;/时钟 D0(SCLK)sbit OLED_SDIN=P21;/D1(MOSI) 数据/信号控制函数#define OLED_CS_Clr() OLED_CS=0#define OLED_CS_Set() OLED_CS=1#define OLED_RST_Clr() OLED_RST=0#define OLED_RST_Set() OLED_RST=1#define OLED_DC_Clr() OLED_DC=0#define OLED_DC_Set() OLED_DC=1#define OLED_SCLK_Clr() OLED_SCL=0#define OLED_SCLK_Set() OLED_SCL=1#define OLED_SDIN_Clr() OLED_SDIN=0#define OLED_SDIN_Set() OLED_SDIN=1;/#define SIZE 16#define XLevelL0x02#define XLevelH0x10#define Max_Column128#define Max_Row64#defineBrightness0xFF #define X_WIDTH 128#define Y_WIDTH 64 void delay_ms(unsigned int ms); /OLED控制用函数void OLED_WR_Byte(u8 dat,u8 cmd); void OLED_Display_On(void);void OLED_Display_Off(void); void OLED_Init(void);void OLED_Clear(void);void OLED_DrawPoint(u8 x,u8 y,u8 t);void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);void OLED_ShowChar(u8 x,u8 y,u8 chr);void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2);void OLED_ShowString(u8 x,u8 y, u8 *p); void OLED_Set_Pos(unsigned char x, unsigned char y);void OLED_ShowCHinese(u8 x,u8 y,u8 no);void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP);#endif 源文件OLED.c#include oled.h#include oledfont.h void delay_ms(unsigned int ms) unsigned int a;while(ms)a=1800;while(a-);ms-;return;#if OLED_MODE=1/向SSD1106写入一个字节。/dat:要写入的数据/命令/cmd:数据/命令标志 0,表示命令;1,表示数据;void OLED_WR_Byte(u8 dat,u8 cmd)DATAOUT(dat); if(cmd) OLED_DC_Set();else OLED_DC_Clr(); OLED_CS_Clr();OLED_WR_Clr(); OLED_WR_Set();OLED_CS_Set(); OLED_DC_Set(); #else/向SSD1306写入一个字节。/dat:要写入的数据/命令/cmd:数据/命令标志 0,表示命令;1,表示数据;void OLED_WR_Byte(u8 dat,u8 cmd)u8 i; if(cmd) OLED_DC_Set();else OLED_DC_Clr(); OLED_CS_Clr();for(i=0;i8;i+) OLED_SCLK_Clr();if(dat&0x80) OLED_SDIN_Set();else OLED_SDIN_Clr();OLED_SCLK_Set();dat4)|0x10,OLED_CMD);OLED_WR_Byte(x&0x0f)|0x01,OLED_CMD); /开启OLED显示 void OLED_Display_On(void)OLED_WR_Byte(0X8D,OLED_CMD); /SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD); /DCDC ONOLED_WR_Byte(0XAF,OLED_CMD); /DISPLAY ON/关闭OLED显示 void OLED_Display_Off(void)OLED_WR_Byte(0X8D,OLED_CMD); /SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD); /DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD); /DISPLAY OFF /清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样! void OLED_Clear(void) u8 i,n; for(i=0;i8;i+) OLED_WR_Byte (0xb0+i,OLED_CMD); /设置页地址(07)OLED_WR_Byte (0x00,OLED_CMD); /设置显示位置列低地址OLED_WR_Byte (0x10,OLED_CMD); /设置显示位置列高地址 for(n=0;nMax_Column-1)x=0;y=y+2;if(SIZE =16)OLED_Set_Pos(x,y);for(i=0;i8;i+)OLED_WR_Byte(F8X16c*16+i,OLED_DATA);OLED_Set_Pos(x,y+1);for(i=0;i8;i+)OLED_WR_Byte(F8X16c*16+i+8,OLED_DATA);else OLED_Set_Pos(x,y+1);for(i=0;i6;i+)OLED_WR_Byte(F6x8ci,OLED_DATA);/mn函数u32 oled_pow(u8 m,u8 n)u32 result=1; while(n-)result*=m; return result; /显示2个数字/x,y :起点坐标 /len :数字的位数/size:字体大小/mode:模式0,填充模式;1,叠加模式/num:数值(04294967295); void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2) u8 t,temp;u8 enshow=0; for(t=0;tlen;t+)temp=(num/oled_pow(10,len-t-1)%10;if(enshow=0&t120)x=0;y+=2;j+;/显示汉字void OLED_ShowCHinese(u8 x,u8 y,u8 no) u8 t,adder=0;OLED_Set_Pos(x,y); for(t=0;t16;t+)OLED_WR_Byte(Hzk2*not,OLED_DATA);adder+=1; OLED_Set_Pos(x,y+1); for(t=0;t16;t+)OLED_WR_Byte(Hzk2*no+1t,OLED_DATA);adder+=1; /*功能描述:显示显示BMP图片12864起始点坐标(x,y),x的范围0127,y为页的范围07*/void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP) unsigned int j=0; unsigned char x,y; if(y1%8=0) y=y1/8; else y=y1/8+1;for(y=y0;yy1;y+)OLED_Set_Pos(x0,y); for(x=x0;xx1;x+) OLED_WR_Byte(BMPj+,OLED_DATA); /初始化SSD1306 void OLED_Init(void) OLED_RST_Set();delay_ms(100);OLED_RST_Clr();delay_ms(100);OLED_RST_Set(); OLED_WR_Byte(0xAE,OLED_CMD);/-turn off oled panelOLED_WR_Byte(0x00,OLED_CMD);/-set low column addressOLED_WR_Byte(0x10,OLED_CMD);/-set high column addressOLED_WR_Byte(0x40,OLED_CMD);/-set start line address Set Mapping RAM Display Start Line (0x000x3F)OLED_WR_Byte(0x81,OLED_CMD);/-set contrast control registerOLED_WR_Byte(0xCF,OLED_CMD); / Set SEG Output Current BrightnessOLED_WR_Byte(0xA1,OLED_CMD);/-Set SEG/Column Mapping 0xa0左右反置 0xa1正常OLED_WR_Byte(0xC8,OLED_CMD);/Set COM/Row Scan Direction 0xc0上下反置 0xc8正常OLED_WR_Byte(0xA6,OLED_CMD);/-set normal displayOLED_WR_Byte(0xA8,OLED_CMD);/-set multiplex ratio(1 to 64)OLED_WR_Byte(0x3f,OLED_CMD);/-1/64 dutyOLED_WR_Byte(0xD3,OLED_CMD);/-set display offsetShift Mapping RAM Counter (0x000x3F)OLED_WR_Byte(0x00,OLED_CMD);/-not offsetOLED_WR_Byte(0xd5,OLED_CMD);/-set display clock divide ratio/oscillator frequencyOLED_WR_Byte(0x80,OLED_CMD);/-set divide ratio, Set Clock as 100 Frames/SecOLED_WR_Byte(0xD9,OLED_CMD);/-set pre-charge periodOLED_WR_Byte(0xF1,OLED_CMD);/Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WR_Byte(0xDA,OLED_CMD);/-set com pins hardware configurationOLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD);/-set vcomhOLED_WR_Byte(0x40,OLED_CMD);/Set VCOM Deselect LevelOLED_WR_Byte(0x20,OLED_CMD);/-Set Page Addressing Mode (0x00/0x01/0x02)OLED_WR_Byte(0x02,OLED_CMD);/OLED_WR_Byte(0x8D,OLED_CMD);/-set Charge Pump enable/disableOLED_WR_Byte(0x14,OLED_CMD);/-set(0x10) disableOLED_WR_Byte(0xA4,OLED_CMD);/ Disable Entire Display On (0xa4/0xa5)OLED_WR_Byte(0xA6,OLED_CMD);/ Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD);/-turn on oled panelOLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ OLED_Clear();OLED_Set_Pos(0,0); 源文件main.c#include #include OLED.h#include ADXL345Z.h/宏定义#define u8 unsigned char#define u16 unsigned intvoid main()u8 buf4;u8 t=0;short x,y,z;/加速度short angx,angy,angz;/角度 OLED_Init(); while(ADXL345_Init()/3D加速度传感器初始化OLED_ShowString(0,0,ADXL345 Error);OLED_ShowString(0,2,buf);delay_ms(200);OLED_Clear();ADXL345_AUTO_Adjust(char*)&x,(char*)&y,(char*)&z);/自动校准while(1)if(t%10=0)ADXL345_Read_Average(&x,&y,&z,10);/读取X,Y,Z三个方向的加速度值 Adxl_Show_Num(0,1,x,0);Adxl_Show_Num(0,3,y,0);Adxl_Show_Num(0,5,z,0);/显示加速度angx=ADXL345_Get_Angle(x,y,z,1); angy=ADXL345_Get_Angle(x,y,z,2); angz=ADXL345_Get_Angle(x,y,z,0);/显示角度Adxl_Show_Num(64,1,angx,1);Adxl_Show_Num(64,3,angy,1);Adxl_Show_Num(64,5,angz,1); t+;delay_ms(10);
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!