#include <reg52.h> #include <intrins.h> //要用到_nop_();函數 #define uchar unsigned char #define uint unsigned int /***************************************************************************/ /*********** 單片機引腳定義 ************/ /***************************************************************************/ sbit sda=P1^0; //I2C 數據傳送位 sbit scl=P1^1; //I2C 時鐘傳送位 char x,y,z,num[9]={0,0,0}; /******************************************************************************/ /********** 數據部分 ***********/ /******************************************************************************/ #define IIC_READ 0x1D //定義讀指令 #define IIC_WRITE 0x1D //定義寫指令 #define LCD_data P0 //數據口 sbit inter_0=P3^2; sbit LCD_RS = P2^7; //寄存器選擇輸入 sbit LCD_RW = P2^6; //液晶讀/寫控制 sbit LCD_EN = P2^5; //液晶使能控制 sbit LCD_PSB = P2^4; //串/并方式控制 void delay_1ms(uint x) { uint i,j; for(j=0;j<x;j++) for(i=0;i<110;i++); } /*******************************************************************/ /* */ /*寫指令數據到LCD */ /*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。 */ /* */ /*******************************************************************/ void write_cmd(uchar cmd) { LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; P0 = cmd; delay_1ms(5); LCD_EN = 1; delay_1ms(5); LCD_EN = 0; } /*******************************************************************/ /* */ /*寫顯示數據到LCD */ /*RS=H,RW=L,E=高脈沖,D0-D7=數據。 */ /* */ /*******************************************************************/ void write_dat(uchar dat) { LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; delay_1ms(5); LCD_EN = 1; delay_1ms(5); LCD_EN = 0; } /*********************************************************/ /* */ /* 設定顯示位置 */ /* */ /*********************************************************/ void lcd_pos(uchar X,uchar Y) { uchar pos; if (X==0) {X=0x80;} else if (X==1) {X=0x90;} else if (X==2) {X=0x88;} else if (X==3) {X=0x98;} pos = X+Y ; write_cmd(pos); //顯示地址 } /*******************************************************************/ /* */ /* LCD初始化設定 */ /* */ /*******************************************************************/ void lcd_init() { LCD_PSB = 1; //并口方式 write_cmd(0x30); //基本指令操作 delay_1ms(5); write_cmd(0x0C); //顯示開,關光標 delay_1ms(5); write_cmd(0x01); //清除LCD的顯示內容 delay_1ms(5); } uchar set_key_sign; //是否在設置狀態標志 uchar delaysign; //視覺停留標志 uchar xposivalue; //x正方向滿格顯示g值 uchar xnegavalue; //x反方向滿格顯示g值 uchar yposivalue; //y正方向滿格顯示g值 uchar ynegavalue; //y反方向滿格顯示g值 //11111111 11111110 11111100 --- 10000000 00000000 led_ma[i]:i為亮燈數量 uchar led_ma[9]={0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; uchar xposiupstate; //x正方向上8個LED顯示狀態 uchar xposidownstate; //x正方向下8個LED顯示狀態 uchar xnegaupstate; //x反方向上8個LED顯示狀態 uchar xnegadownstate; //x反方向下8個LED顯示狀態 uchar yupstate; //y方向上8個LED顯示狀態 uchar ydownstate; //y方向下8個LED顯示狀態 uchar xposilightnum; //x正方向亮燈數量(1——16) uchar xnegalightnum; //x反方向亮燈數量(1——16) uchar yposilightnum; //y正方向亮燈數量(1——8) uchar ynegalightnum; //x正方向亮燈數量(1——8) uchar ack_sign; //I2C 應答標志 /**************************************************************************/ /************ 各延時程序 **************/ /**************************************************************************/ void iic_delay() //5us延時 { _nop_(); _nop_(); _nop_(); _nop_(); } void delay_50us(uint t) { uchar j; for(;t>0;t--) for(j=19;j>0;j--); } void delay_50ms(uchar t) { uint j; for(;t>0;t--) for(j=6245;j>0;j--); } /*********************************************************************/ /************** I2C通信部分 ***************/ /*********************************************************************/ void iic_start() //函數功能:I2C通信開始 { sda=1; iic_delay(); scl=1; iic_delay(); sda=0; iic_delay(); } void iic_stop() //函數功能:I2C通信停止 { sda=0; iic_delay(); scl=1; iic_delay(); sda=1; iic_delay(); } void iic_ack() //函數功能:I2C通信查應答位 { sda=1; scl=1; iic_delay(); ack_sign=sda; scl=0; } void iic_write_byte(uchar wdata)//函數功能:向I2C從機寫入一個字節 { uchar i,temp,temp1; temp1=wdata; for(i=0;i<8;i++) { scl = 0; iic_delay(); temp=temp1; temp=temp&0x80; if(temp==0x80) sda=1; else sda=0; iic_delay(); scl=1; iic_delay(); scl=0; iic_delay(); temp1=temp1<<1; } } char iic_read_byte(void) //函數功能:從I2C從機中讀出一個字節 { uchar x; char data_data; for (x=0;x<8;x++) { data_data=data_data<<1; sda=1; iic_delay(); scl=0; iic_delay(); scl=1; iic_delay(); if(sda==1) data_data|=0x01; //else // data_data&=0xfe; } return data_data; } void iic_write(uchar byte_add,uchar wdata)//函數功能:按地址寫入一字節數據 { uchar t; t=(IIC_WRITE<<1); iic_start(); iic_write_byte(t); iic_ack(); iic_write_byte(byte_add); iic_ack(); iic_write_byte(wdata); iic_ack(); iic_stop(); } char iic_read(uchar byte_add) //函數功能:按地址讀出一字節數據 { uchar t; char x; t=(IIC_WRITE<<1); iic_start(); iic_write_byte(t); iic_ack(); iic_write_byte(byte_add); iic_ack(); t=((IIC_READ<<1)|0x01); iic_start(); iic_write_byte(t); iic_ack(); x=iic_read_byte(); iic_ack(); iic_stop(); return x; } void main() {delay_1ms(10); //延時 lcd_init(); delay_1ms(5); iic_write(0x16,0x5); iic_write(0x10,0x32);//校正X值 iic_write(0x12,0x62);//校正Y值 delay_50ms(20); while(1) { x=iic_read(0x06); y=iic_read(0x07); z=iic_read(0x08); num[0]=x/100; num[1]=x/10%10; num[2]=x%10; num[3]=y/100; num[4]=y/10%10; num[5]=y%10; num[6]=z/100; num[7]=z/10%10; num[8]=z%10; lcd_pos(0,0); write_dat(num[0]+48); delay_1ms(5); write_dat(num[1]+48); delay_1ms(5); write_dat(num[2]+48); delay_1ms(5); lcd_pos(1,0); write_dat(num[3]+48); delay_1ms(5); write_dat(num[4]+48); delay_1ms(5); write_dat(num[5]+48); delay_1ms(5); lcd_pos(2,0); write_dat(num[6]+48); delay_1ms(5); write_dat(num[7]+48); delay_1ms(5); write_dat(num[8]+48); delay_1ms(5); }}