资源描述
STC89C51单片机产生正弦波、方波、三角波LED显示频率源程序
#include <stdio.h>
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LATCH1=P2^6;//定义锁存使能端口 段锁存
sbit LATCH2=P2^7;// 位锁存
unsigned char TempData[8]; //存储显示值的全局变量
unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
unsigned char code DuanMa2[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};// 显示段码值0~9
unsigned char code DuanMa1[3]={0x77,0x7c,0x39};
unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
#define DataPort P0
sbit keyA=P3^3;
sbit keyB=P3^4;
sbit keyC=P3^5;
sbit wc=P1^0;
sbit scl=P1^1;
sbit sda=P1^2;
sbit scl1=P1^3;
sbit sda1=P1^4;
sbit p5=P1^5;
sbit p6=P1^6;
sbit p7=P1^7;
uint sign,ad;
uchar temp[10], temp1[3];//定义显示区域临时存储数组
uchar voltage; //定义浮点变量
uchar l=0,m=100,n=0;
uchar code sin[200] = {52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,75,77,78,79,81,82,83,84,85,86,88,
89,90,90,91,92,93,94,95,95,96,96,97,97,98,98,98,99,99,99,99,100,100,100,100,100,99,
99,99,99,98,98,98,97,97,96,96,95,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,79,78,
77,75,74,73,71,70,68,67,65,64,62,61,59,58,56,55,53,52,50,48,47,45,44,42,41,39,38,36,
34,33,32,30,29,27,26,24,23,22,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,5,4,4,3,2,2,
2,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,2,2,2,3,4,4,5,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,22,23,24,26,27,29,30,32,33,35,36,38,39,41,42,44,45,47,48,50};
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
void delay()
{ ;; }
void delay1(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
void Delay2(unsigned int t)
{
while(--t);
}
void Display()
{
uchar i;
for(i=0;i<4;i++)
{
DataPort=WeiMa[i]; //取位码
LATCH2=1; //位锁存
LATCH2=0;
if(i==0) DataPort=DuanMa1[sign-1];
else if(i==1) DataPort=DuanMa2[temp1[i]];
else DataPort=DuanMa[temp1[i]]; //取显示数据,段码
LATCH1=1; //段锁存
LATCH1=0;
Delay2(500); // 扫描间隙延时,时间太长会闪烁,太短会造成重影
}
}
//pcf8591
void init1()
{
sda1=1;
delay();
scl1=1;
delay();
}
void start1() //开始信号
{
sda1=1;
delay();
scl1=1;
delay();
sda1=0;
delay();
}
void stop1() //停止
{
sda1=0;
delay();
scl1=1;
delay();
sda1=1;
delay();
}
void respons1() //应答
{
uchar i;
scl1=1;
delay();
while((sda1==1)&&(i<250))i++;
scl1=0;
delay();
}
void write_byte1(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl1=0;
delay();
sda1=CY;
delay();
scl1=1;
delay();
}
scl1=0;
delay();
sda1=1;
delay();
}
uchar read_byte1()
{
uchar i,k;
scl1=0;
delay();
sda1=1;
delay();
for(i=0;i<8;i++)
{
scl1=1;
delay();
k=(k<<1)|sda1;
scl1=0;
delay();
}
return k;
}
void write_add1(uchar date) //写入DA
{
start1();
write_byte1(0x90);
respons1();
write_byte1(0x40);
respons1();
write_byte1(date);
respons1();
// delay1(100);
stop1();
}
uchar read_add1( uchar address ) //读AD值
{
uchar date;
start1();
write_byte1(0x90);
respons1();
write_byte1(0x40|address);
respons1();
start1();
write_byte1(0x91);
respons1();
date=read_byte1();
stop1();
return date;
}
//键盘
void keyscan()
{
if(keyA==0)
{
delay1(10);
if(keyA==0)
sign=1;
while(!keyA);
}
if(keyB==0)
{
delay1(10);
if(keyB==0)
sign=2;
while(!keyB);
}
if(keyC==0)
{
delay1(10);
if(keyC==0)
sign=3;
while(!keyC);
}
}
//eeprom
void start() //开始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons() //应答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_add(uchar date[],uchar address )
{
uchar i,*pdate;
pdate=date;
for(i=0;i<2;i++)
{
start();
write_byte(0xae);
respons();
write_byte(address+i);
respons();
write_byte(*(pdate+i));
respons();
stop();
}
}
void read_add(uchar date[] ,uchar address )
{
uchar i,*pdate;
pdate=date;
for(i=0;i<2;i++)
{
start();
write_byte(0xae);
respons();
write_byte(address+i);
respons();
start();
write_byte(0xaf);
respons();
*(pdate+i)=read_byte();
stop();
}
}
void sj()
{
if(l<100)
{
write_add1(l);
l++;
}
if(l>=100&m>0)
{
write_add1(m);
m--;
}
if(l>=100&m<=0)
{
l=0;
m=100;
}
p5=0;p6=1;p7=1;
}
void zx()
{
if(l<200)
{
write_add1(sin[l]);
l++;
}
if(l>=200)
l=0;
p6=0;p7=1;p5=1;
}
void fb()
{
if(l<100)
{
write_add1(255);
l++;
}
if(l>=100&n<100)
{
write_add1(0);
n++;
}
if(l>=100&n>=100)
{l=0;n=0;}
p7=0;p5=1;p6=1;
}
void main()
{
uchar i,num,tab[2];//定义显示区域临时存储数组
wc=0;
num=0;
tab[0]=0;
tab[1]=0;
TMOD=0x21;//设置定时器1为工作方式2定时器0为工作方式1
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
init();
init1();
for(i=0;i<5;i++)
num=read_add1(0);
read_add(tab,1);
sign=tab[0];
ad=(uint)num*100;
TH0=(65536-ad)/256;
TL0=(65536-ad)%256;
ET0=1; //定时器中断打开
TR0=1;
while(1)
{
keyscan();
for(i=0;i<5;i++)
num=read_add1(0);
voltage=500/num;
ad=(uint)num*100;
tab[0]=sign;
tab[1]=ad;
write_add(tab,1);
num=read_add1(0);
voltage=500/num;
temp1[0]=voltage/100;
temp1[1]=(voltage%100)/10;
temp1[2]=voltage%1000;
Display();
}
}
void ser() interrupt 4
{
RI=0;
sign=SBUF;
}
void T0_time() interrupt 1
{
ad=(uint)read_add1(0)*100;
TH0=(65536-ad)/256;
TL0=(65536-ad)%256;
if(sign==1) sj();
if(sign==2) zx();
if(sign==3) fb();
}
展开阅读全文