完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
#include #include #include #define MAIN_Fosc 11059200UL //宏定义主时钟HZ #define PCF8591_ADDR 0x90 //PCF8591地址 /*==================================== 自定义类型名 ====================================*/ typedef unsigned char INT8U; typedef unsigned char uchar; typedef unsigned int INT16U; typedef unsigned int uint; /*==================================== 硬件接口位声明 ====================================*/ ***it SDA = P2^0; //I2C串行数据 ***it SCL = P2^1; //I2C串行时钟 ***it DU = P2^6; //数码管段选 ***it WE = P2^7; //数码管位选 ***it EN = P3^4; // 液晶使能控制 ***it RS = P3^5; //数据命令选择端 ***it RW = P3^6; //读写选择端 ***it LCD_PSB = P3^7;//串行选择端 uint AD_Value; //存储AD转换回的数字量 uchar i,temp,com; uchar code dis1[]={"压力值:"}; uchar code dis2[]={"角度值:"}; /*==================================== 函数:void Delay_Ms(INT16U ms) 参数:ms,毫秒延时形参 描述:12T 51单片机自适应主时钟毫秒级延时函数 ====================================*/ void Delay_Ms(INT16U ms) { INT16U i; do{ i = MAIN_Fosc / 96000; while(--i); //96T per loop }while(--ms); } /*==================================== 函数:void Delay5us() 描述:12T 51单片机5微秒延时函数自适应时钟(11.0592M,12M,22.1184M) ====================================*/ void Delay5us() { #if MAIN_Fosc == 11059200 _nop_(); #elif MAIN_Fosc == 12000000 _nop_() #elif MAIN_Fosc == 22118400 _nop_(); _nop_(); _nop_(); #endif } /*==================================== 函数:I2C_init() 描述:I2C总线初始化 ====================================*/ void I2C_init() { SDA = 1; //数据总线高 _nop_(); SCL = 1; //时钟总线高 _nop_(); } /*==================================== 函数:I2C_Start() 描述:I2C起始信号 ====================================*/ void I2C_Start() { SCL = 1; _nop_(); SDA = 1; Delay5us(); SDA = 0; Delay5us(); } /*==================================== 函数:I2C_Stop() 描述:I2C停止信号 ====================================*/ void I2C_Stop() { SDA = 0; _nop_(); SCL = 1; Delay5us(); SDA = 1; Delay5us(); } /*==================================== 函数:Master_ACK(bit i) 参数:i 为0时发送非应答 为1时发送应答 描述:I2C主机发送应答 ====================================*/ void Master_ACK(bit i) { SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化 _nop_(); // 让总线稳定 if (i) //如果i = 1 那么拉低数据总线 表示主机应答 { SDA = 0; } else { SDA = 1; //发送非应答 } _nop_();//让总线稳定 SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号 _nop_(); SCL = 0;//拉低时钟总线, 占用总线继续通信 _nop_(); SDA = 1;//释放SDA数据总线。 _nop_(); } /*==================================== 函数:Test_ACK() 返回:0为非应答 1为应答 描述:I2C检测从机应答 ====================================*/ bit Test_ACK() // 检测从机应答 { SCL = 1;//时钟总线为高电平期间可以读取从机应答信号 Delay5us(); if (SDA) { SCL = 0; I2C_Stop(); return(0); } else { SCL = 0; return(1); } } /*==================================== 函数:I2C_send_byte(uchar byte) 参数:byte 要发送的字节 描述:I2C发送一个字节 ====================================*/ void I2C_send_byte(uchar byte) { uchar i; for(i = 0 ; i < 8 ; i++) { SCL = 0; _nop_(); if (byte & 0x80) // { SDA = 1; _nop_(); } else { SDA = 0; _nop_(); } SCL = 1; _nop_(); byte <<= 1; } SCL = 0; _nop_(); SDA = 1; _nop_(); } /*==================================== 函数:I2C_read_byte() 返回:读取的字节 描述:I2C读一个字节 ====================================*/ uchar I2C_read_byte() { uchar i, dat; SCL = 0 ; _nop_(); SDA = 1; _nop_(); for(i = 0 ; i < 8 ; i++) { SCL = 1; _nop_(); dat <<= 1; if (SDA) { dat |= 0x01; } _nop_(); SCL = 0; _nop_(); } return(dat); } /*读AD数据*/ bit ADC_Read(uchar CON) { I2C_Start(); I2C_send_byte(PCF8591_ADDR+0); if (!Test_ACK()) { return(0); } I2C_send_byte(CON); Master_ACK(0); I2C_Start(); I2C_send_byte(PCF8591_ADDR+1); if (!Test_ACK()) { return(0); } AD_Value = I2C_read_byte(); Master_ACK(0); I2C_Stop(); return(1); } /*void delay(uint z) { uint x,y; for(x = z; x > 0; x--) for(y = 114; y > 0 ; y--); } */ /*==================================== 函数:LCD_status() 描述:判断忙 ====================================*/ bit lcd_status() { bit status; RS = 0; RW = 1; Delay_Ms(5); EN = 1; status = P0&0x80; EN = 0; return(status); } /*==================================== 函数:write_cmd() 描述:写指令到LCD ====================================*/ void write_cmd( uchar cmd) { while(lcd_status()); RS = 0; RW = 0; EN = 0; P0 = cmd; Delay_Ms(5); EN= 1; Delay_Ms(5); EN = 0; } /*==================================== 函数:write_dat() 描述:写数据到LCD ====================================*/ void write_dat( uchar dat) { while(lcd_status()); RS = 1; RW = 0; EN = 0; P0 = dat; Delay_Ms(5); EN= 1; Delay_Ms(5); EN = 0; } /*==================================== 函数:write_dat() 描述:设定显示位置 ====================================*/ void lcd_pos(uchar X,uchar Y) { uchar pos; switch(X) { case 0: X = 0x80;break; case 1: X = 0x90;break; case 2: X = 0x88;break; case 3: X = 0x98;break; } pos = X+Y; write_cmd(pos); } /* /*==================================== 函数:lcd_init() 描述:lcd初始化 ====================================*/ void lcd_init() { LCD_PSB = 1; write_cmd(0x30); Delay_Ms(5); write_cmd(0x0c); Delay_Ms(5); write_cmd(0x01); Delay_Ms(5); } /* void ad_display(uint i) { uint t1,t2,t3,t4,t5; if( 10000 < i <100000) { t1 = i/10000 +0x30; t2 = i/10000%1000+0x30 ; t3 = i%1000/100 +0x30; t4 = i%100/10 +0x30; t5 = i%10+0x30; write_dat(t1); write_dat(t2); write_dat(t3); write_dat('.'); write_dat(t4); write_dat(t5); } else if(1000 { t1 = i/1000+0x30; t2 = i/1000%100+0x30; t3 = i%100/10 +0x30; t4 = i%10 +0x30; write_dat(t1); write_dat(t2); write_dat('.'); write_dat(t3); write_dat(t4); } else if(10 { t1 = i/100+0x30; t2 = i/100%10+0x30; t3 = i%10+0x30; write_dat(t1); write_dat('.'); write_dat(t2); write_dat(t3); } } */ void display(uint i) { uchar count,tmp; uchar datas[] = {0, 0, 0, 0, 0,0}; datas[0] = tmp / 10000; datas[1] = tmp % 10000 / 1000; datas[2] = tmp % 1000 / 100; datas[3] = tmp % 100 / 10; datas[4] = tmp % 10; lcd_pos(0,4); for(count = 1; count != 6; count++) { write_dat('0'+datas[count]); if(count == 3) { write_dat('.'); } } } void main() { uchar a,b; WE= 0; DU = 0; I2C_init(); lcd_init(); while(1) { lcd_pos(0,0); a = 0; while(dis1[a]!=' |