#include <STC15F2K60S2.H>
#include <IIC.H>
/*变量很可怕,请蒙住眼睛....观看顺序
数码管显示-----外设参数获取 (频率、电压等)-----外设参数的处理------按键----LED*/
sbit S4=P3^3;
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
unsigned int SMG_cylc;
unsigned int SMG_freq;
unsigned int SMG_vlot;
float adc_vlot;
unsigned int count_f;
unsigned int dat_f;
unsigned char count_t;
unsigned char key_t;
unsigned char key_SMG=0;
unsigned char F_SMG=1;
unsigned int old_freq;
unsigned int old_vlot;
bit key_vlot=0;
bit key_freq=0;
bit key_adc=1;
bit led_flag=1;
bit S7_flag;
unsigned char code Nodat[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code Isdat[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
void SelectHC573(unsigned char n)
{
switch(n)
{
case 0 : P2=(P2 &0x1f) |0x00; break;
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;
}
}
// ==================定什么时,计什么数==============//
void Timber0init() //定时器0计数,每中断一次记一次数
{
TMOD=0x06;
TH0=0xff;
TH0=0xff;
EA=1;ET0=1; TR0=1;
}
void Timber1init() //定时器1定时,每中断一次50ms 中断20次就是1秒,1秒计多少次数,就是频率
{
AUXR &= 0xBF;
TMOD &= 0x0F;
TL1 = 0xB0;
TH1 = 0x3C;
TF1 = 0;
TR1 = 1;
EA=1;ET1=1;
}
// ==================怎么选择的==============//
void Delay2ms() //@12.000MH数码管专用延时
{
unsigned char i, j;
i = 24;
j = 85;
do
{
while (--j);
} while (--i);
}
void Output_P0(unsigned char channel,unsigned char value)
{
SelectHC573(channel);
P0=value;
SelectHC573(0);
}
void SMG_Bit(unsigned char pos,unsigned char value)
{
Output_P0(6,0x01<<pos);
Output_P0(7,value);
Delay2ms();
Output_P0(6,0x01<<pos);
Output_P0(7,0xff);
}
void SMG_ALL(unsigned char value)
{
Output_P0(6,0xff);
Output_P0(7,value);
}
//========================显示数码管=================
/* 数码模块 F_SMG即数码管界面标志位,1=频率界面,2=周期界面,3=电压界面*/
/* SMG_Bit(0,0x8e); 选择数码管第0位,然后给P0赋值 怎么选择的往上翻翻*/
void DispalySMG()
{
switch(F_SMG)
{
case 1:
SMG_Bit(0,0x8e);
SMG_Bit(1,0xff);
SMG_Bit(2,0xff);
if(SMG_freq>9999)
SMG_Bit(3,Nodat[ SMG_freq/10000]);
if(SMG_freq>999)
SMG_Bit(4,Nodat[(SMG_freq/1000)%10]);
if(SMG_freq>99)
SMG_Bit(5,Nodat[(SMG_freq/100)%10]);
if(SMG_freq>9)
SMG_Bit(6,Nodat[(SMG_freq/10)%10]);
SMG_Bit(7,Nodat[SMG_freq%10]);
SMG_ALL(0xff); //关闭所有数码管的显示
break;
//SMG_freaq 频率 SMG_syclc 周期 SMG_vlot电压 参数值都按整数处理,参数管理会提及
case 2:
SMG_Bit(0,0xc8);
SMG_Bit(1,0xff);
SMG_Bit(2,0xff);
if(SMG_cylc>9999)
SMG_Bit(3,Nodat[ SMG_cylc/10000]);
if(SMG_cylc>999)
SMG_Bit(4,Nodat[(SMG_cylc/1000)%10]);
if(SMG_cylc>99)
SMG_Bit(5,Nodat[(SMG_cylc/100)%10]);
if(SMG_cylc>9)
SMG_Bit(6,Nodat[(SMG_cylc/10)%10]);
SMG_Bit(7,Nodat[SMG_cylc%10]);
SMG_ALL(0xff);
break;
case 3:
SMG_Bit(0,0xc1);
SMG_Bit(1,0xbf);
if(key_adc)
SMG_Bit(2,Nodat[1]);
else
SMG_Bit(2,Nodat[3]);
SMG_Bit(3,0xff);
SMG_Bit(4,0xff);
SMG_Bit(5,Isdat[SMG_vlot/100]);
SMG_Bit(6,Nodat[(SMG_vlot/10)%10]);
SMG_Bit(7,Nodat[SMG_vlot%10]);
SMG_ALL(0xff);
break;
}
}
//========================参数获取=================
unsigned char Read_adc(unsigned char addr) // pcf8591 addr=0x01 是光敏电压数据 addr=0x03 是电阻电压数据
{
unsigned char medium;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Stop();
DispalySMG();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
medium=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return medium; //返回的最大值255
}
//=====555定时器 定时器0计数,定时器1定时 定什么时,计什么数 ????往上翻翻
void Timber0Service() interrupt 1
{
count_f++;
}
void Timber1Service() interrupt 3
{
count_t++;
if(count_t==20)
{
count_t=0;
dat_f=count_f;
count_f=0;
}
if(S7_flag)
{
key_t+=1;
}
}
//========================参数处理=================
void Date_mange()
{
SMG_freq=dat_f; //频率参数不处理
SMG_cylc=1000000/dat_f; //周期参数 微妙等于多少秒 10的6次方 T=(1/f)*1000000 HZ/us
if(key_adc)
adc_vlot=(Read_adc(0x03)*5.0)/255; //S7按下改变addr
else
adc_vlot=(Read_adc(0x01)*5.0)/255;
SMG_vlot=adc_vlot*100; //电压参数最大5.00 扩大100倍变成整数
}
//========================按键=================
void ScanKey()
{
if(S4==0) //界面切换
{ DispalySMG();
if(S4==0)
{
switch(key_SMG)
{
case 0 :F_SMG=1;key_SMG=1; break;
case 1 :F_SMG=2;key_SMG=2; break;
case 2 :F_SMG=3;key_SMG=0; break;
}
}
while(S4==0)
DispalySMG();
}
if(S5==0) //输出光敏还是电阻电压
{ DispalySMG();
if(S5==0)
{
key_adc= !key_adc;
}
while(S5==0)
DispalySMG();
}
if(S6==0) //保存当前电压
{ DispalySMG();
if(S6==0)
{
old_vlot=SMG_vlot;
}
while(S6==0)
DispalySMG();
}
if(S7==0)
{
DispalySMG();
if(S7==0)
{
S7_flag = 1; //S7 按下了
while(!S7) //S7一直没松手
DispalySMG();
S7_flag=0; //欧耶终于松手
if(key_t>20) //你松手超过一秒了???
led_flag= !led_flag;//长按 LED_flag 标志位改变 0 or 1
else
old_freq=SMG_freq;;//短按 保存当前频率
key_t=0; //退出 按键定时清0
}
}
}
void led()
{
if (led_flag)//led_flag为1 此时正常点亮
{
if (SMG_vlot>old_vlot)//现在的电压和保存的电压比较大小
{
P2 = (P2 & 0x1f) | 0x80;
L1 = 0;
}
if (SMG_freq>old_freq) //现在的频率和保存的频率比较大小
{
P2 = (P2 & 0x1f) | 0x80;
L2 = 0;
}
if (F_SMG==1) //频率界面
{
P2 = (P2 & 0x1f) | 0x80;
L3 = 0;
}
else if (F_SMG==2) //周期界面
{
P2 = (P2 & 0x1f) | 0x80;
L4 = 0;
}
else if (F_SMG==3) //电压界面
{
P2 = (P2 & 0x1f) | 0x80;
L5 = 0;
}
}
else //应该 关闭所有数码管了
{
P2 = (P2 & 0x1f) | 0x80;
P0 = 0xff;
P2 = (P2 & 0x1f);
}
P2 = (P2 & 0x1f); P0=0X00; //推出取消选择
}
//========================LED=================
void InitSystem()
{
Output_P0(5,0x00);
Output_P0(4,0xFF);
}
void main()
{
InitSystem();
Timber0init();
Timber1init();
while(1)
{
Date_mange();
DispalySMG();
ScanKey();
led();
}
}
驱动程序
/*
程序说明: 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;
}
#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);
#endif