主函数代码
#include<iic.h>
#include<intrins.h>
sfr P4=0xc0;
sbit R3=P3^2;
sbit R4=P3^3;
sbit C4=P3^4;
sbit C3=P3^5;
unsigned char code led_nodot[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code led_dot[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char code upn[]={0xc1,0x8c,0xc8};
unsigned int count_er=0;//统计错误按键数
unsigned int Vp=0; //参考电压
unsigned int Vn=0; //PCF8591测出来的电压
unsigned int state=0; //窗口切换变量
unsigned int t=0; //时间变量
unsigned int t_v=0; //统计Vn>Vp的时间
unsigned int count=0; //统计下降时Vn>Vp的次数
unsigned char led=0xff; //保存流水灯的状态,防止数码管程序干扰
unsigned char Vn_value; //保存PCF8591测出来的值
bit state_v=0; //用来界定Vn>Vp时是上升还是下降
void serve_timer_INT0(){
TMOD=0x01;
TH0=(65535-50000)/256;//50ms
TL0=(65535-50000)%256;
TR0=1;
EA=1;
ET0=1;
}
void timer_INT0() interrupt 1 using 1{
TH0=(65535-50000)/256;//50ms
TL0=(65535-50000)%256;
t++;
if(Vp>Vn){
t_v++;
}
else
t_v=0;
}
void choose(unsigned int n){
switch(n){
case 4:
P2=(P2 &0x1f)|0x80;
break;
case 5:
P2=(P2 &0x1f)|0xa0;
break;
case 6:
P2=(P2 &0x1f)|0xc0;
break;
case 7:
P2=(P2 &0x1f)|0xe0;
break;
case 0:
P2=(P2 &0x1f)|0x00;
break;
}
}
void delay(unsigned int k) //@11.0592MHz
{
unsigned char data i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
while(k--){
do
{
while (--j);
} while (--i);}
}
void smg_display(unsigned int n,unsigned char dat){
choose(6);
P0=0x01<<n;
choose(7);
P0=dat;
delay(1);
choose(0); //防止最后一位数码管显示过亮
}
void smg_show(){
smg_display(0,upn[state]);
switch(state){
case 0:
smg_display(5,led_dot[Vn/100%10]);
smg_display(6,led_nodot[Vn/10%10]);
smg_display(7,led_nodot[Vn%10]);
break;
case 1:
smg_display(5,led_dot[Vp/100%10]);
smg_display(6,led_nodot[Vp/10%10]);
smg_display(7,led_nodot[Vp%10]);
break;
case 2:
if(count>99)
smg_display(5,led_nodot[count/100%10]);
if(count>9)
smg_display(6,led_nodot[count/10%10]);
smg_display(7,led_nodot[count%10]);
break;
}
}
//unsigned char EEPROM_read(unsigned char addr);
//void EEPROM_write(unsigned char dat);
//unsigned char PCF8591_read(unsigned char addr);
void check_keyboard(){
R4=0;
R3=1;
C3=C4=1;
if(C3==0){
delay(1);
if(C3==0){
count_er=0;
if(state==1)
EEPROM_write(Vp/10); //退出1状态时保存Vp //除以10是因为前面乘了100
state++;
if(state>=3)
state=0;
while(!C3){
smg_show();
}
}
}
R3=0;
R4=1;
C3=C4=1;
if(C3==0){
delay(1);
if(C3==0){
if(state==2){
count_er=0;
count=0;
}
else
count_er++;
while(!C3){
smg_show();
}
}
}
R4=0;
R3=1;
C3=C4=1;
if(C4==0){
delay(1);
if(C4==0){
if(state==1){
Vp+=50;
count_er=0;
if(Vp>500)
Vp=0;
}
else
count_er++;
while(!C4){
smg_show();
}
}
}
R3=0;
R4=1;
C3=C4=1;
if(C4==0){
delay(1);
if(C4==0){
if(state==1){
if(Vp==0)
Vp=500;
else
Vp-=50;
count_er=0;
}
else
count_er++;
while(!C4){
smg_show();
}
}
}
}
void check_led(){
if(t_v>=100){
led=led & 0xfe;
choose(4);
P0=led;
choose(0);
}
else{
led=led | 0x01;
choose(4);
P0=led;
choose(0);
}
if(count%2!=0){
led=led & 0xfd;
choose(4);
P0=led;
choose(0);
}
else{
led=led | 0x02;
choose(4);
P0=led;
choose(0);
}
if(count_er>=3){
led=led & 0xfb;
choose(4);
P0=led;
choose(0);
}
else{
led=led | 0x04;
choose(4);
P0=led;
choose(0);
}
}
void get_Vn(){
Vn_value=PCF8591_read(0x03);
Vn=Vn_value*(5.0/255)*100;
if(Vn<Vp && state_v==0){
count++;
state_v=1;
}
else if(Vn>Vp && state_v==1){
state_v=0;
}
}
void main(){
choose(4);
P0=led;
choose(5);
P0=0x00;
serve_timer_INT0();
Vp=EEPROM_read(0x00)*10;
while(1){
smg_show();
check_keyboard();
check_led();
if(t%10==0){ //每隔0.5秒刷新一次电压Vn
get_Vn();
}
}
}
iic.c文件
#include "iic.h"
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
void IIC_Ack(unsigned char ackbit)
{
if(ackbit)
{
SDA = 0;
}
else
{
SDA = 1;
}
somenop;
SCL = 1;
somenop;
SCL = 0;
SDA = 1;
somenop;
}
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
//void IIC_Start(void);
//void IIC_Stop(void);
//void IIC_Ack(unsigned char ackbit);
//void IIC_SendByte(unsigned char byt);
//bit IIC_WaitAck(void);
//unsigned char IIC_RecByte(void);
unsigned char EEPROM_read(unsigned char addr){
unsigned char ret;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
ret=IIC_RecByte();
IIC_Ack(1);
IIC_Stop();
return ret;
}
void EEPROM_write(unsigned char dat){
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(0x00);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_Ack(1);
IIC_Stop();
}
unsigned char PCF8591_read(unsigned char addr){
unsigned char ret;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ret=IIC_RecByte();
IIC_Ack(1);
IIC_Stop();
return ret;
}
//void PCF8591_out(unsigned char dat){
//IIC_Start();
//IIC_SendByte(0x90);
//IIC_WaitAck();
//IIC_SendByte(0x40);
//IIC_WaitAck();
//IIC_SendByte(dat);
//IIC_Ack(1);
//IIC_Stop();
//}
iic.h文件
#ifndef _IIC_H
#define _IIC_H
#include "regx52.h"
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
sbit SDA = P2^1; /* ˽ߝП */
sbit SCL = P2^0; /* ʱדП */
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Ack(unsigned char ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
unsigned char EEPROM_read(unsigned char addr);
void EEPROM_write(unsigned char dat);
unsigned char PCF8591_read(unsigned char addr);
//void PCF8591_out(unsigned char dat);
#endif