曾经写的c51单片机测转速源程序,比较久了,其时电路板有数码显现,代码不是最优化的,不过朋友能够看看其间的测速代码,其时费了点心思写的,24c02的读写代码,贴出来给朋友看看,写的很差劲,高手就不要见笑了。
#include
#include
#include
#define ucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
sbitkey0=P3^0;//按键0
sbitkey1=P3^1;//按键1
sbitkey2=P3^3;//按键2
sbitkey3=P3^4;//按键3
sbitled0=P1^0;//数码管0
sbitled1=P1^1;//数码管1
sbitled2=P1^2;//数码管2
sbitled3=P1^3;//数码管3
sbitscl=P1^6;//24c02scl端
sbitsda=P1^5;//24c02scd端
sbitout=P1^7;//输出端
sbitin=P3^2;//输入
codeucharascled[12]={
0x3f,0x06,0x5b,0x4f,0x66,//0,1,2,3,4
0x6d,0x7d,0x07,0x7f,0x6f,//5,6,7,8,9
0x71,0x00};//F,''
/*****************函数列表**********************/
ucharx24c02_read(ucharaddr);//从24c02的地址addr中读取一个字节数据
voidx24c02_write(ucharaddr,ucharinfo);//向24c02的addr地址中写入一字节数据info
voidx24c02_init();//24c02初始化子程序
voiddelay(ucharx);//延时子程序ms
voidflash();//24c02延时子程序nop
voidstart();//24c02ic开端
voidstop();//24c02ic中止
voidack();//24c02ic应对
voidnack();//24c02ic不应对
voidwritex(ucharj);//24c02ic写1byte数据
voiddsp();//显现子程序
voiddelay(uchari);//us延时
voiddelay1(uchari);//us延时
ucharreadx();//24c02ic读1byte数据
/****************全局变量界说*******************/
ucharktemp;
uchardisp[4];
uintcount;//预设报警值
uintzs;//转速值
uinttime0;//
uinttime1;//记时器
bitbegin1;//T1开端发动标志
ucharltj=1;//凹凸速
uintjs;//脉冲计数器
ulongt0;
ulongt1;
bitkey_set;//设置标志
uchardisp_i[4];//显现闪耀标志
uintdisp_c;//闪耀显现计数器//借用time0
uintdisp_j;//闪耀显现守时//借用time1
bitss=0;//闪耀标志
uintbj;//报警输出信号守时
biten_bj=0;//答应报警标志
bitbjing=0;//报警中
//m:菜单级数mi:参数标号bh:检测维护时刻1-10
ucharbh=0;
ucharm=0,mi=0;//借用zs,js
ucharbhtm=0;//维护检测
//bitcmi=0;//参数设置改动标志//借用bjing
/**********************************************/
voidint_ex0()interrupt0using0
{
/*外部中止0*/
delay1(20);
if(key_set==0){///0非设置状况
if(in==0){
if(ltj==1)
{
js++;
EA=0;
TR0=0;
TL0=0xaf;//50ms
TH0=0x3c;/*计数初值重装*/
if(begin1==0)
{//开端记数
begin1=1;
js=0;
TR1=0;
TL1=0xaf;//50ms
TH1=0x3c;/*计数初值重装*/
TR1=1;/*发动T1*/
}
/*发动T0*/
TR0=1;
time0=0;
EA=1;
}
else
{
if(begin1==0)
{
begin1=1;
EA=0;
TR0=0;
zs=0;
/*发动T0*/
TL0=0xaf;//50ms
TH0=0x3c;/*计数初值重装*/
TR0=1;
time0=0;
EA=1;
}
else
{
EA=0;
TR0=0;
begin1=0;
if(time0==0)
{
zs=0;
}
else
{//核算转速
t0=(time0*50000+(TH0*256+TL0)-0x3caf);
if(t0>0){zs=60000000/t0;}
}
if(zs
if(en_bj==1)
{
out=1;
bjing=1;//报警
}
}
disp[3]=(zs%10000)/1000;//显现转速
disp[2]=(zs%1000)/100;
disp[1]=(zs%100)/10;
disp[0]=zs%10;
TL0=0xaf;//50ms
TH0=0x3c;/*计数初值重装*/
TR0=1;
time0=0;
EA=1;
}
}
}
//
}///0
}
voidtimer0(void)interrupt1using0//记时守时中止
{uchart;
//////
if(key_set==0){///0非设置状况
time0++;
TL0=0xaf;//50ms
TH0=0x3c;/*计数初值重装*/
TR0=1;
/*发动T1*/
t=time0%20;
if(t==0){en_bj=0;}
if(time0>1200)//超时
{
time0=0;
disp[3]=0;
disp[2]=0;
disp[1]=0;
disp[0]=0;
zs=0;
if(en_bj==1)
{
out=1;
bjing=1;//报警
}
}
}///0
}
voidtimer1(void)interrupt3using0//1s记时守时中止
{
/*T1中止服务程序进口*/
//////
if(key_set==0){///0非设置状况
time1++;
if(time1==20)//1s
{EA=0;
TR1=0;
//核算转速
///////////////////
t0=time0*50000+(TH0*256+TL0)-0x3caf;
t1=1000000-t0;
t0=60*js*t0;
zs=60*js+t0/t1;
if(zs>6000){zs=0;}
if(zs
if(en_bj==1)
{
if(bhtm>=bh)
{
out=1;
bjing=1;//报警
}
bhtm++;
}
}
else
{
bhtm=0;
}
if(zs==0)
{///////
///////
disp[3]=0;
disp[2]=0;
disp[1]=0;
disp[0]=0;
}
else
{
disp[3]=zs/1000;//显现转速
disp[2]=(zs%1000)/100;
disp[1]=(zs%100)/10;
disp[0]=zs%10;
}
begin1=0;
js=0;
time0=0;
time1=0;
en_bj=0;//非维护状况
}
//////
TL1=0xaf;//50ms
TH1=0x3c;/*计数初值重装*/
TR1=1;/*发动T1*/
EA=1;
}///0
}
voiddelay(uchari)
{ucharj;
for(j=0;j<=i;j++);
}
voiddelay1(uchari)
{ucharj;
for(j=0;j<=i;j++);
}
voidflash()
{
_nop_();
_nop_();
_nop_();
//_nop_();
//_nop_();
}
voidx24c02_init()
{
scl=1;
flash();
sda=1;
flash();
}
voidstart()
{
sda=1;
flash();
scl=1;
flash();
sda=0;
flash();
scl=0;
flash();
}
voidstop()
{
sda=0;
flash();
scl=1;
flash();
sda=1;
flash();
}
voidack()
{
sda=0;
flash();
scl=1;
flash();
scl=0;
flash();
}
voidnack()
{
sda=1;
flash();
scl=1;
flash();
scl=0;
flash();
}
voidwritex(ucharj)
{
uchari,temp;
temp=j;
for(i=0;i<8;i++){
temp=temp<<1;
scl=0;
flash();
sda=CY;
flash();
scl=1;
flash();
}
scl=0;
flash();
sda=1;
flash();
}
ucharreadx()
{
uchari,j,k=0;
scl=0;
flash();
sda=1;
for(i=0;i<8;i++){
flash();
scl=1;
flash();
if(sda==1)j=1;
elsej=0;
k=(k<<1)│j;
scl=0;
flash();
}
return(k);
}
ucharx24c02_read(ucharaddr)
{
uchari;
start();
writex(0xa0);
ack();
writex(addr);
ack();
start();
writex(0xa1);
ack();
i=readx();
nack();
stop();
delay(10);
return(i);
}
voidx24c02_write(ucharaddr,ucharinfo)
{
//EA=0;//中止总制止
start();
writex(0xa0);
ack();
writex(addr);
ack();
writex(info);
ack();
stop();
//EA=1;//中止开//设置状况制止一切外部中止
}
voidgetdate(void)
{ucharda5,da4,da3,da2,da1,da0;
x24c02_init();
da0=(x24c02_read(0x00)%10);
da1=(x24c02_read(0x01)%10);
da2=(x24c02_read(0x02)%10);
da3=(x24c02_read(0x03)%10);
da4=(x24c02_read(0x04)%10);
da5=(x24c02_read(0x05)%10);
ltj=(x24c02_read(0x06)%10);
count=da3*1000+da2*100+da1*10+da0;
bh=da5*10+da4;
if(bh>99){bh=0;}
if(count>6000){count=6000;}
if(ltj>1){ltj=1;}
}
voidsavedate(void)
{ucharda5,da4,da3,da2,da1,da0;
da5=bh/10;
da4=bh%10;
da3=count/1000;
da2=(count%1000)/100;
da1=(count%100)/10;
da0=count%10;
dsp();
x24c02_init();
x24c02_write(0x00,da0);
x24c02_write(0x00,da0);
dsp();
x24c02_write(0x01,da1);
x24c02_write(0x01,da1);
dsp();
x24c02_write(0x02,da2);
x24c02_write(0x02,da2);
dsp();
x24c02_write(0x03,da3);
x24c02_write(0x03,da3);
dsp();
x24c02_write(0x04,da4);
x24c02_write(0x04,da4);
dsp();
x24c02_write(0x05,da5);
x24c02_write(0x05,da5);
dsp();
x24c02_write(0x06,ltj);
x24c02_write(0x06,ltj);
dsp();
}
//动态显现
voiddsp(void)
{
P2=ascled[disp[0]];led0=0;delay(50);led0=1;//led0=0显现,=1不显现
P2=ascled[disp[1]];led1=0;delay(50);led1=1;
P2=ascled[disp[2]];led2=0;delay(50);led2=1;
P2=ascled[disp[3]];led3=0;delay(50);led3=1;
}
//闪耀动态显现有用
voiden_dsp(void)
{disp_j=0;
disp_i[0]=0x0;//显现闪耀标志0显现
disp_i[1]=0x0;
disp_i[2]=0x0;
disp_i[3]=0x0;
}
//闪耀动态显现
voiddsp_flash(void)
{
disp_j++;
if(disp_j>240)
{disp_j=0;
disp_i[disp_c]=!(disp_i[disp_c]&0x01);
}
P2=ascled[disp[0]];led0=disp_i[0];delay(50);led0=1;//led0=0显现,=1不显现
P2=ascled[disp[1]];led1=disp_i[1];delay(50);led1=1;
P2=ascled[disp[2]];led2=disp_i[2];delay(50);led2=1;
P2=ascled[disp[3]];led3=disp_i[3];delay(50);led3=1;
}
voiddisplay(void)
{
//设定状况时假如有键按下就不闪耀
if((ss==0)││(ktemp!=0x1b))
{
dsp();
}
else
{
dsp_flash();
}
}
voidkbscan(void)//键盘扫描
{uchartemp,i;//0
temp=P3;
ktemp=temp&0x1b;//查看key0,key1,key2,key300011011
if(ktemp!=0x1b)
{//1
for(i=0;i<250;i++){display();}
temp=P3;
if(ktemp==(temp&ktemp))
{//2
//keyval=ktemp;//记载键值
if(key_set==1)
{//3
switch(ktemp){
case0x1a://key0
{
/////////////////
m++;
if(m>2){m=1;}
switch(m){
case1:////显现参数称号
ss=0;disp_c=0;en_dsp();
switch(mi){
case0:
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻
disp[2]=11;
disp[1]=10;
disp[0]=1;
dsp();
break;
case1:
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻
disp[2]=11;
disp[1]=10;
disp[0]=2;
dsp();
break;
case2:
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻,2显现凹凸转速丈量
disp[2]=11;
disp[1]=10;
disp[0]=3;
dsp();
break;
}
break;
case2:////显现参数
ss=1;en_dsp();
switch(mi){//显现设定参数mi=0显现预设报警值,1显现维护检测时刻
case0:
disp[3]=count/1000;
disp[2]=(count%1000)/100;
disp[1]=(count%100)/10;
disp[0]=count%10;
for(i=0;i<150;i++){dsp();}
break;
case1:
disp[3]=11;
disp[2]=11;
disp[1]=bh/10;
disp[0]=bh%10;
for(i=0;i<150;i++){dsp();}
break;
case2:
disp[3]=11;
disp[2]=11;
disp[1]=11;
disp[0]=ltj;
for(i=0;i<150;i++){dsp();}
break;
}
break;
}
/////////////////
}
case0x19://key1
{
break;
}
case0x13://key2
{
//闪耀位移
if(ss==1)
{
switch(mi){
case0:
en_dsp();////预设转速4位显现
disp_c++;
if(disp_c>3){disp_c=0;}
break;
case1:
en_dsp();////输出维护时刻2位显现
disp_c++;
if(disp_c>1){disp_c=0;}
break;
case2:
break;
}
}
if(m==1)
{//保存数据退出设置状况
savedate();
//借用后康复
//bjing=0;
m=0;
mi=0;
key_set=0;
ss=0;
en_dsp();
disp[0]=0;
disp[1]=0;
disp[2]=0;
disp[3]=0;
for(i=0;i<150;i++){dsp();}
if(ltj==1)
{
TMOD=0x11;TL0=0xaf;TH0=0x3c;TL1=0xaf;TH1=0x3c;ET0=1;ET1=1;TR0=1;TR1=1;
}
EA=1;//数据保存答应中止
}
break;
}
case0x0b://key3
{
/////////////////
if(m==1)
{disp_c=0;
mi++;if(mi>2){mi=0;}
switch(mi){
case0:
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻
disp[2]=11;
disp[1]=10;
disp[0]=1;
dsp();
break;
case1:
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻
disp[2]=11;
disp[1]=10;
disp[0]=2;
dsp();
break;
case2:
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻
disp[2]=11;
disp[1]=10;
disp[0]=3;
dsp();
break;
}
}
else
{
m=0;
switch(mi){
case0:
disp[disp_c]++;
if(disp[disp_c]>9){disp[disp_c]=0;}
if((disp[3]*1000+disp[2]*100+disp[1]*10+disp[0])>6000)
{//假如超出设定规模
disp[3]=0;disp[2]=0;disp[1]=0;disp[0]=0;
}
count=disp[3]*1000+disp[2]*100+disp[1]*10+disp[0];
dsp_flash();
break;
case1:
disp[disp_c]++;
if(disp[disp_c]>9){disp[disp_c]=0;}
bh=disp[1]*10+disp[0];
dsp_flash();
break;
case2:
disp[disp_c]++;
if(disp[disp_c]>1){disp[disp_c]=0;}
ltj=disp[0];
dsp_flash();
break;
}
}
break;
}
}
}//3
else
{//4
switch(ktemp){
case0x1a://key0
{
////////////////
//制止测转速
EA=0;
key_set=1;
en_bj=0;//假如设定状况答应报警标志0
out=0;//
/////
//bjing=0;
///disp_c=0;//time0
/////
m=1;
disp[3]=11;////显现设定参数mi=0显现预设报警值,1显现维护检测时刻
disp[2]=11;
disp[1]=10;
disp[0]=1;
for(i=0;i<150;i++){dsp();}
break;
}
case0x19://key1
{
//答应报警
en_bj=1;
break;
}
}
}//4
}//2
}//1
}//0
main()
{uchari;
out=0;
key_set=0;
disp[0]=0;
disp[1]=0;
disp[2]=0;
disp[3]=0;
for(i=0;i<250;i++)display();
getdate();
en_dsp();
//////
time0=0;time1=0;zs=0;bj=0;js=0;begin1=0;bjing=0;
EA=0;EX0=1;IT0=1;PT1=1;//CPU关中止,INT0恳求中止,设定INT0触发方法
if(ltj==1)
{
TMOD=0x11;TL0=0xaf;TH0=0x3c;TL1=0xaf;TH1=0x3c;ET0=1;ET1=1;TR0=1;TR1=1;/*50ms,T1T0作业在守时器方法1,T1开中止,发动T1*/
}
else
{
TMOD=0x11;TL0=0xaf;TH0=0x3c;ET0=1;TR0=1;
}
EA=1;
//////
begin:
if(bjing==1)
{
bj++;
if(bj>500)
{
bjing=0;out=0;//铲除报警
bj=0;bhtm=0;
}
}
else
{
bj=0;
}
display();
kbscan();
gotobegin;
}