板子IAP15f2k60s2
第一次写才发现五个小时根本写不完,写了两三天,太菜了呜呜
main.c
#include "reg52.h"
#include "intrins.h"
#include "IIC.h"
#define u8 unsigned char
#define u16 unsigned int
sfr P4 = 0xC0; //P4
sbit P42 = P4^2;
sbit P44 = P4^4;
sfr AUXR=0x8e;
//deal !!!
u8 duan[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,
0x3e,0x73,0x54,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
u16 temp3=0,temp4=500;
u8 disbuff[8];
// P U n
u8 falg_bit[]={0x73,0x3e,0x54};
u8 falg=1,key_value=0,Vpp=0,value_jishu=0;
u8 adc_value=0;
u16 value=0,s=0,i=0;
void display(u8 *duan_zhu,u8 wei);
void data_dis();
void cls_buzz()
{
P2&=0xa0;
P0=0x00;
P2&=0x1f;
P2&=0x80;
P0=0xff;
P2&=0x1f;
}
void Delay(u8 i)
{
do{_nop_();}
while(i--);
}
//按键检测函数
void Keys_down()
{
unsigned char temp1,temp2;
P3=0xf0;P42=1;P44=1;//列检测
temp1=(P3&0xf0);
Delay(100);
if(temp1!=0xf0||P42==0||P44==0)
{
switch (temp1)
{
case 0xe0: key_value = 16;break;
case 0xd0: key_value = 12;break;
default :key_value = 0;break;
}
P3=0x0f;P42=0;P44=0;
temp1=(P3&0x0f);
Delay(100);
if(temp1!=0x0f)
{
switch(temp1)
{
case 0x07: key_value+=0;break;
case 0x0b: key_value+=1;break;
case 0x0d: key_value+=2;break;
case 0x0e: key_value+=3;break;
}
switch (key_value)
{
case 12: falg++;if(falg==4) falg=1;break;//切换界面
case 13: if(falg==3) value_jishu=0;break; //计数界面 按下清零
case 16: if(falg==2) Vpp++;break;//参考值加一
case 17: if(falg==2) Vpp--;break;//参考值减一
}
data_dis();
if(key_value!=12&&key_value!=13&&key_value!=16&&key_value!=17)//判断无效按键
{
i++;
}
else{i=0;}
while(P3!=0x0f) //根据最近一次赋值判断
{
//value=key_value;
Delay(300);
data_dis();
if(falg==1||falg==2)
display(duan,2);//即使一直按着也会显示
else display(duan,0);
}
}
if(temp2==2&&falg!=2)
EEPROM_Write(0x00,Vpp);
temp2=falg;
}
}
bit reg_0=1;
bit reg_1=0;
bit flage=0;
bit flage1=0;
void data_dis()
{
u16 adc_value;
adc_value = read_adc(0x03);
adc_value *=100*5/255.00f;
P0=0xff;
P2=P2&0x1f|0x80;
P0=0xff;
if(value_jishu%2)//指示灯L2:当前计数值为奇数时,L2点亮,否则熄灭。
{
P0&=0xfd;
}
else{P0|=0x02;}
if(adc_value<Vpp*50)//指示灯L1:当V<V的状态持续时间超过5秒时,L1点亮,否则熄灭。
{
s++;
if(s>=10224)
P0&=0xfe;
else{P0|=0x01;}
}
else{s=0;}
if(i>=3)//指示灯L3:连续3次以上(含3次)的无效按键操作触发L3点亮,直到
{
P0&=0xfb;
}
else{P0|=0x04;}
P2&=0x1f;
//按键 功能要求
if(falg==1) //数据界面
{
value=adc_value;
}
if(falg==2) //参数界面
{
value=Vpp*50;
}
if(falg==3) //计数界面
{
value=value_jishu;
}
//下降沿检测
if(!reg_1) //首先检测这个数大于参考值
{
if(adc_value>Vpp*50)//如果大于就不检测了
reg_1=1;
}
if(reg_1)//如果大于就开始检测小于参考值
{
if(adc_value<Vpp*50)//如果小于就不检测了
reg_0=0;
}
if(reg_1==1&®_0==0)
{
value_jishu++;
reg_0=1;reg_1=0; //恢复reg_1 和reg_0的值,先检测大于,如果大于再小于
}
//参数模式 功能要求
if(Vpp==255) //小于0就变255了
{
Vpp=10;
}
if(Vpp>=11) //大于就归0
{
Vpp=0;
}
}
//数码管显示函数
void display(u8 *duan_zhu,u8 wei)
{
static index=0;
u8 j;
disbuff[0]=10+falg;
disbuff[1]=10;
disbuff[2]=10;
disbuff[3]=10;
disbuff[4]=10;
disbuff[5]=value/100;
disbuff[6]=value/10%10;
disbuff[7]=value%10;
if(wei)
disbuff[7-wei]+=14;
for(j=5;j<7;j++)//从高到低检测是否为0 直到不为0
{
if(disbuff[j]==0)
disbuff[j]=10;
else break;
}
P2=P2&0x1f|0xe0; //消除干扰
P0=0xff; //
P2&=0x1f; //
P2=P2&0x1f|0xc0;
P0=1<<index;
P2&=0x1f;
P2=P2&0x1f|0xe0;
P0=~duan_zhu [disbuff[index]];
P2&=0x1f;
index++;
index&=0x07;
}
void Timer_Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0x1f; //设置定时器模式
TL1 = 0x17; //设置定时初值
TH1 = 0xFC; //设置定时初值
TF1 = 0; //清除TF0标志
TR1 = 1; //定时器0开始计时
PT1=1;
ET1=1;
EA=1;
}
void timer1() interrupt 3 //中断主要用于按键检测和显示 适用于任何程序
{
TF1=0;
TL1 = 0x17; //设置定时初值
TH1 = 0xFC; //设置定时初值
Keys_down();
if(falg==1||falg==2)
display(duan,2);//即使一直按着也会显示
else display(duan,0);
s++;
}
void main()
{
cls_buzz();
Timer_Init();
Vpp=EEPROM_Read(0x00);
while(1)
{
data_dis();
}
}
IIC.C
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0:应答,1:非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
void EEPROM_Write(unsigned char add,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xa0);//芯片地址
IIC_WaitAck();
IIC_SendByte(add);//选择页
IIC_WaitAck();
IIC_SendByte(dat);//数据
IIC_WaitAck();
IIC_Stop();
}
unsigned char EEPROM_Read(unsigned char add)
{
unsigned char temp;
EA=0;
IIC_Start();
IIC_SendByte(0xa0);//芯片地址
IIC_WaitAck();
IIC_SendByte(add);//选择页
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xa1);//芯片地址 读
IIC_WaitAck();
temp=IIC_RecByte();//选择页
IIC_WaitAck();
IIC_Stop();
EA=1;
return temp;
}
void write_adc(unsigned char add) //AIN3 RB2
{
IIC_Start();
IIC_SendByte(0x90);//写
IIC_WaitAck();
IIC_SendByte(add);//模式 channel
IIC_WaitAck();
IIC_Stop();
}
unsigned char read_adc(unsigned char add)
{
unsigned char temp;
EA=0;
IIC_Start();
IIC_SendByte(0x90);//写
IIC_WaitAck();
IIC_SendByte(add);//模式选择channel
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);//读
IIC_WaitAck();
temp=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
EA=1;
return temp;
}