演示视频
题目讲解
首先将程序框图的PCF8591(模拟输入和输出),按键,数码管,NE555都先调试好。
基本要求,将P34和NE555的输出用超声波的跳线帽连接起来。
按照数码管对应的显示出来就行了,注意频率测量需要只显示使用的。
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf,0x81,0xc1};//f u
uchar SMG[8]={20,20,20,20,20,20,20,20};//初始显示20,全息数码管
uint high=0,low=0,highdata=0,lowdata=0;//ne555高低时间
uint time;//ne555时间
uchar SMG_mode=0;//控制数码管模式
void main(void)
{
init();
Timer0Init();
EA=1;ET0=1;
while(1)
{
if(SMG_mode==0)
{
led &=0xfd;led |=0x01;//L2点亮,L1熄灭
time=(1000000/((highdata+lowdata)*20));\
SMG[0]=22;SMG[1]=20;
if(time<10){SMG[2]=SMG[3]=SMG[4]=SMG[5]=SMG[6]=20;
SMG[7]=time/10;}
else if(time<100){SMG[2]=SMG[3]=SMG[4]=SMG[5]=20;
SMG[6]=time%100/10;SMG[7]=time%10;}
else if(time<1000){SMG[2]=SMG[3]=SMG[4]=20;
SMG[5]=time%1000/100;
SMG[6]=time%100/10;SMG[7]=time%10;}
else if(time<10000){SMG[2]=SMG[3]=20;
SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
SMG[6]=time%100/10;SMG[7]=time%10;}
else if(time<100000){SMG[2]=20;SMG[3]=time/10000;
SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
SMG[6]=time%100/10;SMG[7]=time%10;}
}
else if(SMG_mode==1)
{
led &=0xfe;led |=0x02;//L1点亮,L2熄灭
SMG[0]=23;SMG[1]=SMG[2]=SMG[3]=SMG[4]=20;
move=1.9607*move;//move *(5 /255 *100) 将0-255转换到0-500,便于显示
if(move<150)led |=0x04;//L3熄灭
else if(move<250) led &=0xfb;//L3点亮
else if(move<350)led |=0x04;//L3熄灭
else led &=0xfb;//L3点亮
SMG[5]=move/100+10;SMG[6]=move%100/10;SMG[7]=move%10;
move=IIC_read(PCF8591_address,Move_address);//读取滑动变阻器
// IIC_write(PCF8591_address,Output_address,move);//输出
}
}
然后看按键控制。
S4:控制电压和频率界面
S5:控制电压输出
S6:LED使能
S7:数码管显示
首先分别建立对应的变量进行控制,然后按照对应的按键补充功能。
void Dkey_scan(void)
{
static uchar keybyte=0;
static uchar key;
if(((P3&0X0F)!=0X0F)&&(keybyte==0))
{
Delay5ms();
if((P3&0X0F)!=0X0F)
{
keybyte=1;key=P3&0x0f;
}
}
if((keybyte==1)&&((P3&0X0F)==0X0F))
{
if((P3&0X0F)==0X0F)
{
switch(key)
{
case 0x0e: //S7
if(SMG_out==0)SMG_out=1;
else SMG_out=0;
break;
case 0x0d: //S6
if(led_mode==0)led_mode=1;
else led_mode=0;
break;
case 0x0b: //S5
if(Output_mode==0)Output_mode=1;
else Output_mode=0;
break;
case 0x07: //S4
if(SMG_mode==0)SMG_mode=1;
else SMG_mode=0;
break;
}
keybyte=0;
}
}
}
if(Output_mode==0){IIC_write(PCF8591_address,Output_address,102);
led |=0x10;}//输出2v 模式0
else {IIC_write(PCF8591_address,Output_address,move);
led &=0xef;}//输出move v 模式1
然后就是LED的模式。
if(SMG_mode==0)
{led &=0xfd;led |=0x01;//L2点亮,L1熄灭}
else if(SMG_mode==1)
{led &=0xfe;led |=0x02;//L1点亮,L2熄灭}
if(move<150)led |=0x04;//L3熄灭
else if(move<250) led &=0xfb;//L3点亮
else if(move<350)led |=0x04;//L3熄灭
else led &=0xfb;//L3点亮
if(Output_mode==0){IIC_write(PCF8591_address,Output_address,102);
led |=0x10;}//输出2v 模式0 L1熄灭
else {IIC_write(PCF8591_address,Output_address,move);
led &=0xef;}//输出move v 模式1 L1亮
if(time<1000)led |=0x08; //L4熄灭
else if(time<5000)led &=0xf7; //L4点亮
else if(time<10000)led |=0x08; //L4熄灭
else led &=0xf7; //L4点亮
if(led_mode==1){P2=0X80;P0=led;}
else {P2=0X80;P0=0xff;}
初始化要求。
完整程序
main.c
#include<stc15f2k60s2.h>
#include"intrins.h"
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int
#define PCF8591_address 0x90
#define Light_address 0x01
#define Move_address 0x03
#define Output_address 0x40
void SMG_output(void);
void init(void);
void Delay1ms(void);
void Timer0Init(void);
void Dkey_scan(void);
void Delay5ms(void);
uchar tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf,0x8e,0xc1};//f u
uchar SMG[8]={20,20,20,20,20,20,20,20};//初始显示20,全息数码管
uint high=0,low=0,highdata=0,lowdata=0;//ne555高低时间
uint time;//ne555时间
uchar SMG_mode=0;//控制数码管模式
bit Output_mode=0;//控制输出电压
bit led_mode=0;//控制led
bit SMG_out=0;//数码管显示
uint move=0;//pcf8591的滑动变阻器读取值
uchar led=0xff;
void main(void)
{
init();
Timer0Init();
EA=1;ET0=1;
while(1)
{
if(SMG_out==1)
{
if(SMG_mode==0)
{
led &=0xfd;led |=0x01;//L2点亮,L1熄灭
time=(1000000/((highdata+lowdata)*20));\
SMG[0]=22;SMG[1]=20;
if(time<10){SMG[2]=SMG[3]=SMG[4]=SMG[5]=SMG[6]=20;
SMG[7]=time/10;}
else if(time<100){SMG[2]=SMG[3]=SMG[4]=SMG[5]=20;
SMG[6]=time%100/10;SMG[7]=time%10;}
else if(time<1000){SMG[2]=SMG[3]=SMG[4]=20;
SMG[5]=time%1000/100;
SMG[6]=time%100/10;SMG[7]=time%10;}
else if(time<10000){SMG[2]=SMG[3]=20;
SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
SMG[6]=time%100/10;SMG[7]=time%10;}
else if(time<100000){SMG[2]=20;SMG[3]=time/10000;
SMG[4]=time%10000/1000;SMG[5]=time%1000/100;
SMG[6]=time%100/10;SMG[7]=time%10;}
}
else if(SMG_mode==1)
{
led &=0xfe;led |=0x02;//L1点亮,L2熄灭
SMG[0]=23;SMG[1]=SMG[2]=SMG[3]=SMG[4]=20;
move=1.9607*move;//move *(5 /255 *100) 将0-255转换到0-500,便于显示
if(move<150)led |=0x04;//L3熄灭
else if(move<250) led &=0xfb;//L3点亮
else if(move<350)led |=0x04;//L3熄灭
else led &=0xfb;//L3点亮
SMG[5]=move/100+10;SMG[6]=move%100/10;SMG[7]=move%10;
move=IIC_read(PCF8591_address,Move_address);//读取滑动变阻器
// IIC_write(PCF8591_address,Output_address,move);//输出
}
}
else if(SMG_out==0)//关闭显示
{
SMG[0]=SMG[1]=SMG[6]=SMG[2]=SMG[3]=SMG[4]=SMG[5]=SMG[7]=20;//全息
}
if(Output_mode==0){IIC_write(PCF8591_address,Output_address,102);
led |=0x10;}//输出2v 模式0 L1熄灭
else {IIC_write(PCF8591_address,Output_address,move);
led &=0xef;}//输出move v 模式1 L1亮
if(time<1000)led |=0x08; //L4熄灭
else if(time<5000)led &=0xf7; //L4点亮
else if(time<10000)led |=0x08; //L4熄灭
else led &=0xf7; //L4点亮
if(led_mode==1){P2=0X80;P0=led;}
else {P2=0X80;P0=0xff;}
SMG_output();
Dkey_scan();
}
}
void Dkey_scan(void)
{
static uchar keybyte=0;
static uchar key;
if(((P3&0X0F)!=0X0F)&&(keybyte==0))
{
Delay5ms();
if((P3&0X0F)!=0X0F)
{
keybyte=1;key=P3&0x0f;
}
}
if((keybyte==1)&&((P3&0X0F)==0X0F))
{
if((P3&0X0F)==0X0F)
{
switch(key)
{
case 0x0e: //S7
if(SMG_out==0)SMG_out=1;
else SMG_out=0;
break;
case 0x0d: //S6
if(led_mode==0)led_mode=1;
else led_mode=0;
break;
case 0x0b: //S5
if(Output_mode==0)Output_mode=1;
else Output_mode=0;
break;
case 0x07: //S4
if(SMG_mode==0)SMG_mode=1;
else SMG_mode=0;
break;
}
keybyte=0;
}
}
}
void time0() interrupt 1
{
if(P34==1)
{
high++;
if(low !=0)
{
lowdata=low;
low=0;
}
}
else if(P34==0)
{
low++;
if(high !=0)
{
highdata=high;
high=0;
}
}
}
void SMG_output(void)
{
uchar i;
for(i=0;i<8;i++)
{
P2=(P2&0X1F)|0Xc0;
P0=(1<<i);
P2=(P2&0X1F)|0Xe0;
P0=tab[SMG[i]];
Delay1ms();
}
P2=(P2&0X1F)|0Xc0;
P0=0Xff;
P2=(P2&0X1F)|0Xe0;
P0=0Xff;
}
void Timer0Init(void) //20微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x23; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void init(void)
{
P2=(P2&0X1F)|0XA0;
P0=0X00;
P2=(P2&0X1F)|0X80;
P0=0Xff;
P2=(P2&0X1F)|0Xc0;
P0=0Xff;
P2=(P2&0X1F)|0Xe0;
P0=0Xff;
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 54;
j = 199;
do
{
while (--j);
} while (--i);
}
void Delay1ms(void) //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
iic.h
#ifndef _IIC_H
#define _IIC_H
#include "stc15f2k60s2.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit SDA = P2^1;
sbit SCL = P2^0;
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 IIC_write(uchar hw_address,uchar reg_address,uchar num);
uchar IIC_read(uchar hw_address,uchar reg_address);
#endif
iic.c
#include "iic.h"
#define DELAY_TIME 40
void IIC_write(uchar hw_address,uchar reg_address,uchar num)
{
IIC_Start();
IIC_SendByte(hw_address&0xfe);
IIC_WaitAck();
IIC_SendByte(reg_address);
IIC_WaitAck();
IIC_SendByte(num);
IIC_WaitAck();
IIC_Stop();
}
uchar IIC_read(uchar hw_address,uchar reg_address)
{
uchar num;
IIC_Start();
IIC_SendByte(hw_address&0xfe);
IIC_WaitAck();
IIC_SendByte(reg_address);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(hw_address|0x01);
IIC_WaitAck();
num=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return num;
}
//
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;
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;
}
//
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;
}
//
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;
}