📄 yijia.c
字号:
#include <reg51.h>
#define USE_KEY
#define CH451_RESET 0x0201 /*复位 */
#define CH451_LEFTMOV 0x0300 /*设置移动方式-左移 */
#define CH451_LEFTCYC 0x0301 /*设置移动方式-左循 */
#define CH451_RIGHTMOV 0x0302 /*设置移动方式-右移 */
#define CH451_RIGHTCYC 0x0303 /*设置移动方式-右循 */
#define CH451_SYSOFF 0x0400 /*关显示、键盘、看门狗 */
#define CH451_SYSON1 0x0401 /*开显示 */
#define CH451_SYSON2 0x0403 /*开显示、键盘、关看门狗 */
#define CH451_SYSON3 0x0407 /*开显示、键盘、看门狗功能 */
#define CH451_DSP 0x0500 /*设置默认显示方式 */
#define CH451_BCD 0x0580 /*设置BCD译码方式 */
#define CH451_USER 0x05c0 /*设置BCD译码方式、4位数码管、最亮*/
#define CH451_TWINKLE 0x0600 /*设置闪烁控制的命令码,无闪烁 */
#define CH451_TWINKLE1 0x0601 /*设置闪烁控制--从右向左计数,1闪烁(DIG0驱动) */
#define CH451_TWINKLE2 0x0602 /*设置闪烁控制--从右向左计数,2闪烁(DIG1驱动) */
#define CH451_TWINKLE3 0x0604 /*设置闪烁控制--从右向左计数,3闪烁(DIG2驱动) */
#define CH451_TWINKLE4 0x0608 /*设置闪烁控制--从右向左计数,4闪烁(DIG3驱动) */
#define CH451_TWINKLE5 0x0610 /*设置闪烁控制--从右向左计数,5闪烁(DIG4驱动) */
#define CH451_TWINKLE6 0x0620 /*设置闪烁控制--从右向左计数,6闪烁(DIG5驱动) */
#define CH451_TWINKLE7 0x0640 /*设置闪烁控制--从右向左计数,7闪烁(DIG6驱动) */
#define CH451_TWINKLE8 0x0680 /*设置闪烁控制--从右向左计数,8闪烁(DIG7驱动) */
#define CH451_DIG0 0x0800 /*送数码管位0显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG1 0x0900 /*送数码管位1显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG2 0x0a00 /*送数码管位2显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG3 0x0b00 /*送数码管位3显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG4 0x0c00 /*送数码管位4显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG5 0x0d00 /*送数码管位5显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG6 0x0e00 /*送数码管位6显示的数据,本值或上一个要显示的值即可 */
#define CH451_DIG7 0x0f00 /*送数码管位7显示的数据,本值或上一个要显示的值即可 */
#define CH451_KEY 0x07 /*读取键值的命令码 */
#define maxp 3000
#define minp 30
typedef unsigned char U8 ;
typedef unsigned int U16;
bit pf; /* 有脉冲信号标志*/
bit t10msf; /* 10ms 间隔到标志 */
bit udf; /*需要显示更新标志 */
bit kf; /*有按键按下标志*/
bit k1f; /*按键k1按下标志--左键--启动、确认*/
// bit k2f; /*按键k2按下标志--中左键--移位*/
// bit k3f; /*按键k3按下标志--中右键--增1*/
// bit k4f; /*按键k3按下标志--右键--减1*/
sbit HC14=P3^2; /* INT0, 光电信号输入口*/
sbit jout=P2^0; /* 喷码信号输出口*/
/* CH451接口*/
sbit ch451_dout=P3^3; /* INT1,键盘中断和键值数据输入,接CH451的数据输出*/
sbit ch451_load=P1^0; /*串行命令加载,上升延激活 */
sbit ch451_din=P1^1; /*串行数据输出,接CH451的数据输入 */
sbit ch451_dclk=P1^7; /*串行数据时钟上升延激活 */
U8 ch451_key; /* 存放键盘中断中读取的键值 */
sbit s=P1^2; /* 93c46的片选 */
sbit c=P1^3; /* 93c46的串行时钟 */
sbit d=P1^4; /* 93c46的数据输入 */
sbit q=P1^6; /* 93c46的数据输出 */
U8 skv[4]; /*显示缓存,4字节,分别存放要显示的个、十、百、千*/
U16 setv; /*设置的脉冲数值*/
U16 cv; /*当前接受的脉冲数值*/
void int0() interrupt 0 using 1 /*光电输入中断*/
{
/*设置光电输入标志 */
pf=1;
}
/*void int1() interrupt 2 using 1 /* 键盘输入中断*/
/*{
/*设置按键按下标志 */
/* kf=1;
} */
void time0() interrupt 1 using 1 /* 设置T0为10ms中断*/
{
TH0=0xdc; /* 重装时间常数*/
TL0=0x0;
t10msf=1;
}
void updatedisp(unsigned char* disp,bit twif,unsigned char twip); /* 更新显示*/
U16 read93(U8 ax);
void write93(U8 ax, U16 dx);
void erwren93(void);
void erwrdisen93(void);
void erase93(U8 ax);
void eraseall93(void);
void writeall93(U16 dx);
U8 ch451_read();
void ch451_init();
void ch451_write(U16 command);
void delay();
void main()
{
U16 temp1,temp2,temp3;
U8 ck,shift;
/* 初始化*/
P1=0x00; /* 初始化输出端口*/
P2=0x00;
SP=0x5f; /* 初始化堆栈指针*/
/* 初始化变量*/
pf=0;
k1f=0;
kf=0;
temp1=read93(2);
temp2=read93(4);
temp3=read93(6);
if(temp1==temp2)
setv=temp1;
else if(temp2==temp3)
setv=temp2;
else
setv=temp1;
if(setv<minp)
{
setv=3000;
erwren93();
write93(2,0xaaaa);
write93(4,0xaaaa);
write93(6,0xaaaa);
erwrdisen93();
}
cv=0;
skv[0]=setv%10;
skv[1]=(setv%100)/10;
skv[2]=(setv%1000)/100;
skv[3]=(setv/1000);
udf=1;
/* 初始化芯片ch451*/
ch451_init(); /*调用初始化 */
/* 初始化CPU*/
IP=0x05; /* 两个外中断为高优先级*/
TCON=0x05; /*设置外中断为下降沿触发 */
/* 允许两个外中断*/
EX0=1;
EX1=1;
// TMOD=0x21; /* 设置T0/T1工作方式:T0为方式1, 16位定时器,T1为波特率发生器,8位自装入方式*/
// TH0=0x0dc; /* 设置T0为10ms中断--12Mp:d8f0*///10*1000/(12/12M)=10000(T), (65536-10000)=0xd8f0
// TL0=0x0; //11.0592Mp:10ms=10*1000us, 10*1000/(12/11.0592M)=9216(T), (65536-9216)=0xdc00
// TR0=1; /* 启动T0*/
// ET0=1; /* 允许T0中断*/
// ES=1; /* 允许串口中断*/
EA=1; /* 开中断*/
/* 开始运行*/
while(1)
{
if(pf) /* 有光电信号*/
{
pf=0;
cv++; /*当前脉冲数值增1 */
if(cv>=setv) /*如果当前脉冲数与设置值相等,则重新开始计数,并发出一个脉冲--用于喷码机动作 */
{
cv=0;
jout=1;
jout=0;
}
/*更新显示*/
skv[0]=cv%10;
skv[1]=(cv%100)/10;
skv[2]=(cv%1000)/100;
skv[3]=(cv/1000);
udf=1; /*脉冲数改变,需要更新显示 */
}
if(kf) /*有按键--按键处理 */
{
kf=0;
if(k1f) /*已经按过启动键的按键操作处理 */
{
if(ch451_key==0x40) /*减1键操作,当前设置位之值发生改变*/
{
if(ck==0)
ck=9;
else
ck--;
}
else if(ch451_key==0x41) /*增1键操作,当前设置位之值发生改变*/
{
if(ck==9)
ck=0;
else
ck++;
}
else if(ch451_key==0x42) /*移位键操作*/
{
skv[shift]=ck; /*获取修改过的当前设置位之值,暂存起来 */
if(shift==3) /*改变设置位*/
shift=0;
else
shift++;
ck=skv[shift]; /*取得新设置位之值,用于修改 */
}
else if(ch451_key==0x43) /*确认键--与启动按键操作是同一键,第1次按是启动,第2次按是确认 */
{
k1f=0;
/*计算新的设置值,并保存新的设置值*/
setv=skv[3]*1000+skv[2]*100+skv[1]*10+skv[0];
erwren93();
write93(2,setv);
write93(4,setv);
write93(6,setv);
erwrdisen93();
/*设置完毕,重新显示为当前脉冲数 */
skv[0]=cv%10;
skv[1]=(cv%100)/10;
skv[2]=(cv%1000)/100;
skv[3]=(cv/1000);
}
}
else if(ch451_key==0x43) /*启动键--与确认按键操作是同一键,第1次按是启动,第2次按是确认*/
{
k1f=1; /*k1f=1表明当前在操作按键设置,显示设置值,并闪烁*/
skv[0]=setv%10;
skv[1]=(setv%100)/10;
skv[2]=(setv%1000)/100;
skv[3]=(setv/1000);
/*首先设置个位,个位闪烁 */
shift=0; /*表明当前设置位--也是闪烁位 */
ck=skv[shift]; /*取当前要设置的值 */
}
else
{
/*没有按启动键,先按了其它键,则其它的功能处理*/
}
udf=1; /*设置更新显示标志 */
}
if(udf) /*更新显示的操作 */
{
updatedisp(skv,k1f,shift);
udf=0;
}
} /*end of while loop */
}
/*更新显示,*disp--显示内容,twif--是否闪烁标志,twip--闪烁位 */
void updatedisp(unsigned char* disp,bit twif,unsigned char twip)
{
if(twif) /*闪烁 */
{
if(twip==0)
ch451_write(CH451_TWINKLE1);
else if(twip==1)
ch451_write(CH451_TWINKLE2);
else if(twip==2)
ch451_write(CH451_TWINKLE3);
else if(twip==3)
ch451_write(CH451_TWINKLE4);
}
else
ch451_write(CH451_TWINKLE); /*不闪烁 */
/*显示各个位数据 */
ch451_write(CH451_DIG0 | disp[0]);
ch451_write(CH451_DIG1 | disp[1]);
ch451_write(CH451_DIG2 | disp[2]);
ch451_write(CH451_DIG3 | disp[3]);
}
/*读操作,ax:地址,以字为单位*/
U16 read93(U8 ax)
{
char i;
U8 db,ay;
U16 dx;
/* 前导条件 */
c=0;
d=0;
s=0;
s=1;
d=1;
c=1;
c=0;
/* 发送读操作码 */
d=1;
c=1;
c=0;
d=0;
c=1;
c=0;
/* 发送地址 */
for(i=5;i>=0;i--)
{
ay=(ax>>i) & 1;
if(ay==1)
d=1;
else
d=0;
c=1;
c=0;
}
/*输出前导0
c=0;
c=1; */
/*读数据*/
dx=0;
for(i=15;i>=0;i--)
{
c=1;
if(q==1)
db=1;
else
db=0;
dx=dx | (db<<i);
c=0;
}
s=0;
return dx;
}
/*写操作,ax:地址,dx:数据,以字为单位*/
/*总的写操作之前,要调用擦写使能函数*/
/*总的写操作之后,要调用擦写禁止函数*/
void write93(U8 ax, U16 dx)
{
char i;
U8 ay;
/* 前导条件 */
c=0;
d=0;
s=0;
s=1;
d=1;
c=1;
c=0;
/* 发送写操作码 */
d=0;
c=1;
c=0;
d=1;
c=1;
c=0;
/* 发送地址 */
for(i=5;i>=0;i--)
{
ay=(dx>>i) & 1;
if(ay==1)
d=1;
else
d=0;
c=1;
c=0;
}
/* 发送数据 */
for(i=15;i>=0;i--)
{
ay=(dx>>i) & 1;
if(ay==1)
d=1;
else
d=0;
c=1;
c=0;
}
/*启动写操作*/
s=0;
q=1;
s=1;
/*等待写操作结束*/
while(q==0)
{
c=1;
c=0;
}
/* delay();
delay(); */
s=0;
}
/*擦写使能*/
void erwren93(void)
{
char i;
/* 前导条件 */
c=0;
d=0;
s=0;
s=1;
d=1;
c=1;
c=0;
/* 发送操作码 */
d=0;
c=1;
c=0;
c=1;
c=0;
/* 发送"地址" */
for(i=0;i<6;i++)
{
d=1;
c=1;
c=0;
}
s=0;
}
/*擦写禁止*/
void erwrdisen93(void)
{
char i;
/* 前导条件 */
c=0;
d=0;
s=0;
s=1;
d=1;
c=1;
c=0;
/* 发送操作码 */
d=0;
c=1;
c=0;
c=1;
c=0;
/* 发送"地址" */
for(i=0;i<6;i++)
{
d=0;
c=1;
c=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -