|
制作光电计数器,仿真和实物都一步步摸索过来... 又有想不明白的地方,请做过或者了解的朋友能指导或者分享一下经验、看法,谢谢大家!!
采用槽型光耦,当计数是十的整数倍时,连接单片机的led报警闪烁2s, 下方还有两个led的模块是光电转换模块,一个led作电源指示(绿色),另一个作开关指示(红色)。仿真图如图1,视频是实物操作。
问题: 1、感觉当物体经过光电开关时,数码管显示的计数值和物体的速度有关,速度快计数跳变少,速度慢计数很多!但仿真时不是这样的啊。光电计数模块的输出作为外部中断的输入。
2、当物体经过速度变慢时,感觉物体进入和出来,数码管会产生两次跳变!不应该啊。。。
已经检查过实际电路,感觉没有问题,应该是代码的问题?但是本人小白一个,而且仿真也没有问题,现在很迷茫。。
代码:
#include<AT89x51.H>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码
uchar wei[2]={0X01,0X02}; //位的控制端
uint c,v,date; //定义数据类型
uint dispcount=0;
sbit led=P1^4; //定义P1.4口是led
/*****延时函数*****/
void delay(uchar t)
{
uchar i,j;
for(i=0;i<t;i++)
for(j=13;j>0;j--);
}
/*****数码管动态扫描*****/
void xianshi()
{
/***数据转换***/
c=date/10; //求十位
v=date%10; //求个位
P2=wei[0];
P0=duan[c];
delay(20);
P2=wei[1];
P0=duan[v];
delay(20);
}
/*****中断函数*****/
void ExtInt0() interrupt 0 //中断服务程序
{
dispcount++; //外部中断一次,计数加一
if(dispcount>99) //计数范围0~50
dispcount=1;
}
/*******************************************************************************
* 函 数 名 : Timer0Init
* 函数功能 : 定时器0初始化
*******************************************************************************/
void Timer0Init()
{
TMOD|=0X01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XFC; //给定时器高八位赋初值,定时1ms
TL0=0X18;
ET0=1; //打开定时器0中断允许
EA=1; //打开中断总开关
TR0=1; //打开定时器0
}
/*****主函数*****/
void main()
{
// static u16 i;
TCON=0x01; //中断设置 TCON寄存器
IE|=0x81; //IE外部中断0请求标志位
Timer0Init(); //定时器0初始化
while(1)
{
date=dispcount;
xianshi(); //调用数码管显示
}
}
/*******************************************************************************
* 函 数 名 : void Timer0() interrupt 1
* 函数功能 : 定时器1中断函数
*******************************************************************************/
void Timer0() interrupt 1
{
static u16 i;
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
if(dispcount%10==0&&dispcount!=0)
{
i++;
if(i%100==0) //100ms
led=~led;
if(i>=2000) //时间大于2s
{
i=2000;
led=1;
}
}
else
{
led=1;
i=0;
}
}
|
|