个人编写,代码仅供参考
如有不足,多多指教
1.题目2.代码
main.c程序
#include "reg52.h"
#include "iic.h"
#include "intrins.h"
uchar code smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xFF,0xc1,0x8e,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x8c,0xc8};
// 0 1 2 3 4 5 6 7 8 9 - mie U F 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. p n
//===========================延时函数
void delay_smg(uint time)
{
while(time--);
}
//===========================参数定义
sfr P4 = 0xC0;
sfr AUXR = 0x8E;
sbit c3 = P3^5;
sbit c4 = P3^4;
//================================
uchar xianshi_flag = 1;// 1 : 数据显示界面 2 : 参数显示界面 3 :计数显示界面
uchar wuxiaocishu = 0;//无效次数
uint count_flag = 0;//定时器计数标志,达到5s,led1亮起
uchar comp_flag = 0;//比较标志位
uchar count = 0;//计数值
float vp;//Vp的值 上电之后的值来自eeprom
uchar vain3_temp;//0~255
#define vain3 5*((float)vain3_temp/255)
//电位器的实际电压
uchar led1_flag = 0;//1 亮 0 暗
//===========================函数定义
void init();
void select(uchar channel);
void read_vp_eeprom();
void key_scan();
void smg_show();
void Timer1Init(void); //1毫秒@12.000MHz
void led_show();
//====================================
void main()
{
init();
Timer1Init();
//write_24c02(0x00 ,40); 初始化写入4.00伏的vp
while(1)
{
read_vp_eeprom();
vain3_temp = read_pcf_ain3();
if(vp < vain3)
{
comp_flag = 1;
}
if(vp >= vain3 && comp_flag == 1)
{
if(count + 1 >=100)
{
comp_flag = 0;
count = 0;
}
else
{
comp_flag = 0;
count++;
}
}
key_scan();
led_show();
smg_show();
}
}
//==========================初始化函数
void select(uchar channel)
{
switch(channel)
{
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 init()
{
select(5);
P0 &= 0xAF;
select(4);
P0 = 0xFF;
select(6);
P0 = 0xFF;
select(7);
P0 = smg[11];
select(0);
P0 = 0xFF;
}
//=============================按键扫描函数
void key_scan()
{
P3 = (P3 & 0xF0) | 0x07;
c3 = c4 = 1;
if(c3 == 0)//S12按下
{
smg_show();
if(c3 == 0)
{
while(c3 == 0)
{
smg_show();
}
switch(xianshi_flag)
{
case 1 : xianshi_flag = 2;wuxiaocishu = 0;break;
case 2 : xianshi_flag = 3;wuxiaocishu = 0;break;
case 3 : xianshi_flag = 1;wuxiaocishu = 0;break;
}
}
}
else if(c4 == 0)//S16按下
{
smg_show();
if(c4 == 0)
{
while(c4 == 0)
{
smg_show();
}
if(xianshi_flag == 2)
{
wuxiaocishu = 0;
if(vp + 0.50 <= 5.00)
{vp += 0.50; write_24c02(0x00 ,vp*10);}
else
{vp = 0.00; write_24c02(0x00 ,vp*10);}
}
else
{
wuxiaocishu++;
}
}
}
P3 = (P3 & 0xF0) | 0x0B;
c3 = c4 = 1;
if(c3 == 0)//S13按下
{
smg_show();
if(c3 == 0)
{
while(c3 == 0)
{
smg_show();
}
if(xianshi_flag == 3)
{
wuxiaocishu = 0;
count = 0;
}
else
{
wuxiaocishu++;
}
}
}
else if(c4 == 0)//S17按下
{
smg_show();
if(c4 == 0)
{
while(c4 == 0)
{
smg_show();
}
if(xianshi_flag == 2)
{
wuxiaocishu = 0;
if(vp - 0.50 >= 0.00)
{vp -= 0.50; write_24c02(0x00 ,vp*10);}
else
{vp = 5.00; write_24c02(0x00 ,vp*10);}
}
else
{
wuxiaocishu++;
}
}
}
}
//============================读出eeprom中的vp*10值
void read_vp_eeprom()
{
vp = ((float)read_24c02(0x00))/10;
}
//============================数码管函数
void smg_dis(uchar pos,uchar val)
{
select(6);
P0 = 0x01 << pos;
select(7);
P0 = smg[val];
select(0);
P0 = 0xFF;
delay_smg(800);
}
void smg_show()
{
if(xianshi_flag == 1)
{
smg_dis(0,12);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,((int)((vain3*100))/100)+14);
smg_dis(6,(((int)((vain3*100))/10))%10);
smg_dis(7,((int)((vain3*100)))%10);
}
else if(xianshi_flag == 2)
{
smg_dis(0,24);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,((int)((vp*100))/100)+14);
smg_dis(6,(((int)((vp*100))/10))%10);
smg_dis(7,((int)((vp*100)))%10);
}
else if(xianshi_flag == 3)
{
smg_dis(0,25);
smg_dis(1,11);
smg_dis(2,11);
smg_dis(3,11);
smg_dis(4,11);
smg_dis(5,11);
smg_dis(6,count/10);
smg_dis(7,count%10);
}
}
//=============================定时器1用来计算vp>vain3的时间
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
ET1 = EA = 1;
TR1 = 1; //定时器1开始计时
}
void ser_timer1() interrupt 3
{
if(vp > vain3)
{
count_flag++;
if(count_flag == 5000)
{
led1_flag = 1;
}
}
else if(vp <= vain3)
{
led1_flag = 0;
count_flag = 0;
}
}
//================================led函数
void led_show()
{
if(led1_flag == 1)
{
select(4);
P0 &= 0xFE;//xxxx xxx0
select(0);
}
else if(led1_flag ==0)
{
select(4);
P0 |= 0x01;//xxxx xxx1
select(0);
}
if(count %2 == 1)
{
select(4);
P0 &= 0xFd;//xxxx xx0x
select(0);
}
else if(count %2 == 0)
{
select(4);
P0 |= 0x02;//xxxx xx1x
select(0);
}
if(wuxiaocishu >= 3)
{
select(4);
P0 &= 0xfb;//xxxx x0xx
select(0);
}
else if(wuxiaocishu < 3)
{
select(4);
P0 |= 0x04;//xxxx x1xx
select(0);
}
}
iic.c程序
#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;
}
//==============================
uchar read_pcf_ain3()
{
uchar ain3;
//伪写操作
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(0x03);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
ain3 = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return ain3;
}
uchar read_24c02(uchar addr)
{
uchar temp;
//伪写操作
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
void write_24c02(uchar addr ,uchar dat)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
iic.h程序
#ifndef _IIC_H #define _IIC_H void IIC_Start(void); void IIC_Stop(void); bit IIC_WaitAck(void); void IIC_SendAck(bit ackbit); void IIC_SendByte(unsigned char byt); unsigned char IIC_RecByte(void); void write_24c02(uchar addr ,uchar dat); uchar read_24c02(uchar addr); uchar read_pcf_ain3(); #endif



