目录
一、IIC初始化代码
二、开发板电路图
三、PCF8591读/写字节操作流程及相关函数
(1)PCF8591(AD)读操作流程及代码
(2)PCF8591(AD)写操作流程及代码
四、应用示例-显示电压值
一、IIC初始化代码
- 加载“iic.c文件”,主函数中添加iic.h头文件
- 调节软件延迟时长(全部扩大十倍即可)
- 编写PCF8591读写函数,并且在头文件中定义
- 编写用户用能函数
二、开发板电路图
(图源第十五届蓝桥杯电子赛资源包)
- 根据图以及前面所学的EEPROM存储器的位置,可知IIC总线上有两个设备,一个是PCF85191另一个是AT24C02 EEPROM存储器。
- AIN1(光敏电阻线路)、AIN3(活动变阻器、电压采集)
三、PCF8591读/写字节操作流程及相关函数
(1)PCF8591(AD)读操作流程及代码
- 主控器发出起始信号
- 主控器发出寻址字节(写:0X90)
- 被控器做出应答后
- 主控器发出控制字节(写:)
- 被控器做出应答后
- 主控器发出停止信号
- 主控器发出起始信号
- 主控器发出寻址字节(读:0x91)
- 被控器做出应答后
- 主控器从被控器读出数据字节,主控器发出应答
- 主控器发出停止信号
unsigned char AD_read(unsigned char add)
{unsigned char dat;I2CStart();I2CSendByte(0X90);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0X91);I2CWaitAck();dat=I2CReceiveByte();I2CSendAck(1);I2CStop();return dat;
}
(2)PCF8591(AD)写操作流程及代码
- 主控器发出起始信号
- 主控器发出寻址字节(写:0X90)
- 被控器做出应答后
- 主控器发出控制字节(写)
- 被控器做出应答后
- 主控器发出DA输出数据字节(写)
- 被控器做出应答后
- 主控器发出停止信号
void AD_write(unsigned char dat)
{I2CStart();I2CSendByte(0X90);I2CWaitAck();I2CSendByte(0X40);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();}
四、应用示例-显示电压值
//iic.c
#include <STC15F2K60S2.H>
#include<intrins.h>
#define DELAY_TIME 50//总线引脚定义
sbit sda = P2^1;
sbit scl = P2^0; //
static void I2C_Delay(unsigned char n)
{do{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); }while(n--);
}//
void I2CStart(void)
{sda = 1;scl = 1;I2C_Delay(DELAY_TIME);sda = 0;I2C_Delay(DELAY_TIME);scl = 0;
}//
void I2CStop(void)
{sda = 0;scl = 1;I2C_Delay(DELAY_TIME);sda = 1;I2C_Delay(DELAY_TIME);
}//
void I2CSendByte(unsigned char byt)
{unsigned char i;for(i=0; i<8; i++){scl = 0;I2C_Delay(DELAY_TIME);if(byt & 0x80){sda = 1;}else{sda = 0;}I2C_Delay(DELAY_TIME);scl = 1;byt <<= 1;I2C_Delay(DELAY_TIME);}scl = 0;
}//
unsigned char I2CReceiveByte(void)
{unsigned char da;unsigned char i;for(i=0;i<8;i++){ scl = 1;I2C_Delay(DELAY_TIME);da <<= 1;if(sda) da |= 0x01;scl = 0;I2C_Delay(DELAY_TIME);}return da;
}//
unsigned char I2CWaitAck(void)
{unsigned char ackbit;scl = 1;I2C_Delay(DELAY_TIME);ackbit = sda; scl = 0;I2C_Delay(DELAY_TIME);return ackbit;
}//
void I2CSendAck(unsigned char ackbit)
{scl = 0;sda = ackbit; I2C_Delay(DELAY_TIME);scl = 1;I2C_Delay(DELAY_TIME);scl = 0; sda = 1;I2C_Delay(DELAY_TIME);
}unsigned char AD_read(unsigned char add)
{unsigned char dat;I2CStart();I2CSendByte(0X90);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0X91);I2CWaitAck();dat=I2CReceiveByte();I2CSendAck(1);I2CStop();return dat;}
void AD_write(unsigned char dat)
{I2CStart();I2CSendByte(0X90);I2CWaitAck();I2CSendByte(0X40);I2CWaitAck();I2CSendByte(dat);I2CWaitAck();I2CStop();}
//IIC.h
#ifndef _IIC_H
#define _IIC_H
//
static void I2C_Delay(unsigned char n);//
void I2CStart(void);//
void I2CStop(void);//
void I2CSendByte(unsigned char byt);//
unsigned char I2CReceiveByte(void);//
unsigned char I2CWaitAck(void);//
void I2CSendAck(unsigned char ackbit);
//
unsigned char AD_read(unsigned char add);
void AD_write(unsigned char dat);#endif
//main.c
#include <STC15F2K60S2.H>
#include<intrins.h>
#include<IIC.h>#define uchar unsigned char
#define uint unsigned intunsigned char LED_Bit=0XFF;
unsigned char Actuator_Bit=0X00;#define LEDx_ON(n) { LED_Bit&=_crol_(0XFE,n-1); P0=LED_Bit; P2|=0X80; P2&=0X9F; P2&=0X1F;}
#define LEDx_OFF(n) { LED_Bit|=_crol_(0X01,n-1); P0=LED_Bit; P2|=0X80; P2&=0X9F; P2&=0X1F;}#define Buzzer_ON Actuator_Bit|=0x40; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
#define Buzzer_OFF Actuator_Bit&=0XBF; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
#define Relay_ON Actuator_Bit|=0x10; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;
#define Relay_OFF Actuator_Bit&=0XEF; P0=Actuator_Bit; P2|=0XA0; P2&=0XBF; P2&=0X1F;unsigned char code tab[]= {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\0XBF,0XFF};
unsigned char KEY_Value = 0 ;
unsigned char DigCom=0;
unsigned char DigBuf[8] = {10,10,10,10,10,10,10,10};unsigned char LED = 1 ;
unsigned int LED_tt =0;
bit LED_Ref = 0 ;unsigned int SEG_tt =0; //定义一个数码管计数时间标识位
bit SEG_Ref = 0 ; //定义一个数码管刷新标识位
bit SEG_Run = 0 ; //定义一个控制数码管运行标识位
unsigned int Num = 999 ;unsigned char Open;unsigned char EEPROM_Write[8] = {2,3,4,5,6,7,8,9};
unsigned char EEPROM_Read[8] = {0,0,0,0,0,0,0,0};unsigned int AD_VALUE=0;
unsigned int AD_tt =0;
bit AD_Ref =0;void ALL_Init(void);
void Delay_MS(unsigned int MS);
void KeyScan(void);
void ArrKeyScan(void);
void Timer0Init(void); //1毫秒@11.0592MHzvoid main(void)
{ALL_Init();Timer0Init();EA=1;ET0=1;while(1){if(AD_Ref == 1){AD_Ref = 0 ;AD_VALUE = AD_read(0X03);AD_write(AD_VALUE);AD_VALUE = AD_VALUE * 1.96;DigBuf[2]=21;DigBuf[3]=21;DigBuf[4]=21;DigBuf[5]=AD_VALUE/100 + 10; DigBuf[6]=AD_VALUE%100/10;DigBuf[7]=AD_VALUE%10; }KeyScan();if(KEY_Value==7){KEY_Value=0;SEG_Run = 1 ;}if(KEY_Value==6){KEY_Value=0;SEG_Run = 0 ;}if(KEY_Value==5){KEY_Value=0;LEDx_ON(1);Buzzer_ON;}if(KEY_Value==4){KEY_Value=0;LEDx_OFF(1);Buzzer_OFF;} }
}void KeyScan(void)
{if(P30==0){Delay_MS(10);if(P30==0)KEY_Value = 7 ; while(!P30);}else if(P31==0){Delay_MS(10);if(P31==0)KEY_Value = 6 ; while(!P31);} else if(P32==0){Delay_MS(10);if(P32==0)KEY_Value = 5 ; while(!P32);} else if(P33==0){Delay_MS(10);if(P33==0)KEY_Value = 4 ; while(!P33);}
}void Timer0(void) interrupt 1
{P0=0X00;P2|=0XC0; // P2=P2|0XC0; XXXX XXXX | 1100 0000 = 11XX XXXXP2&=0XDF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX P2&=0X1F; //关闭所有的74HC573锁存器 P0=tab[DigBuf[DigCom]]; P2|=0XE0; // P2=P2|0XE0; XXXX XXXX | 1110 0000 = 111X XXXXP2&=0XFF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX P2&=0X1F; //关闭所有的74HC573锁存器P0=(0X01<<DigCom); //然后选中第一个数码管P2|=0XC0; // P2=P2|0XC0; XXXX XXXX | 1100 0000 = 11XX XXXXP2&=0XDF; // P2=P2&0XDF; 11XX XXXX & 1101 1111 = 110X XXXX P2&=0X1F; //关闭所有的74HC573锁存器if(++DigCom == 8)DigCom = 0 ;LED_tt++;if(LED_tt == 999) {LED_tt = 0 ; LED_Ref = 1 ;}if(++SEG_tt==1000){SEG_tt=0;SEG_Ref=1;}if(++AD_tt==500){AD_tt=0;AD_Ref=1;}
// XXX_tt++;
// if(++XXX_tt==NNN){XXX_tt=0;XXX_Ref=1;}
}void Timer0Init(void) //1毫秒@11.0592MHz
{AUXR |= 0x80; //定时器时钟1T模式TMOD &= 0xF0; //设置定时器模式TL0 = 0xCD; //设置定时初始值TH0 = 0xD4; //设置定时初始值TF0 = 0; //清除TF0标志TR0 = 1; //定时器0开始计时
}void Delay_MS(unsigned int MS)
{unsigned i,j;for(i=0;i<MS;i++)for(j=853;j>0;j--); //STC15单片机设置为853; STC8H单片机修改为1109;STC32G单片机修改为427;
}void ALL_Init(void)
{P0 =0X00; //先设置关闭蜂鸣器继电器的P0输出值(全关)P2|=0XA0; // 将P27 P25 设置为1 其他位保持不变P2&=0XBF; // 将P26设置为0 其他位保持不变P2&=0X1F; //关闭所有的74HC573锁存器P0 =0XFF; //先设置关闭所有的LED的P0输出值(全关)P2|=0X80; // 将P27设置为1 其他位保持不变P2&=0X9F; // 将P26 P25设置为0 其他位保持不变P2&=0X1F; //关闭所有的74HC573锁存器P0 =0X00; //先设置选择数码管位选的P0输出值(全不选)P2|=0XC0; // 将P27 P26 设置为1 其他位保持不变P2&=0XDF; // 将P26设置为0 其他位保持不变P2&=0X1F; //关闭所有的74HC573锁存器
}