用LED灯和按键来模拟工业自动化设备的运动控制
/*
开场白:
前面讲了独立按键控制跑马灯的各种状态,这一例讲的是一个机械手控制程序,这个机械手可以左右移动,最左边有
一个开关感应器,最右边也有一个开关感应器。它也可以上下移动,最下边有一个开关感应器。左右移动是通过一个
气缸控制,上下移动也是通过一个气缸控制。而单片机控制气缸,本质上是通过三极管把信号放大,然后控制气缸上
的电磁阀。这个系统机械手驱动部分的输出信号和输入信号如下:
2个输出IO口,分别控制两个气缸。对于左右移动的气缸,IO口为0表示左移,当IO口为1表示右移。对于上下移动的
气缸,当IO口为0往上跑,当IO口为1时往下跑。
3个输入IO口,分别检测3个开关感应器。感应器没有被触发时,IO口检测到高电平1.被触发时,检测到低电平0
实现功能:
开机默认机械手在左上方的原点位置,按下启动按键后,机械手从左边开始往右边移动,当机械手移动到最右边时,
机械手马上开始往下移动,当机械手移动到最右下角的时候,延时1秒,然后原路返回,一直返回到左上角的原点位置。
请注意:按键必须等机械手处于左上角的位置时,启动按键的触发才有效。
前面讲了独立按键控制跑马灯的各种状态,这一例讲的是一个机械手控制程序,这个机械手可以左右移动,最左边有
一个开关感应器,最右边也有一个开关感应器。它也可以上下移动,最下边有一个开关感应器。左右移动是通过一个
气缸控制,上下移动也是通过一个气缸控制。而单片机控制气缸,本质上是通过三极管把信号放大,然后控制气缸上
的电磁阀。这个系统机械手驱动部分的输出信号和输入信号如下:
2个输出IO口,分别控制两个气缸。对于左右移动的气缸,IO口为0表示左移,当IO口为1表示右移。对于上下移动的
气缸,当IO口为0往上跑,当IO口为1时往下跑。
3个输入IO口,分别检测3个开关感应器。感应器没有被触发时,IO口检测到高电平1.被触发时,检测到低电平0
实现功能:
开机默认机械手在左上方的原点位置,按下启动按键后,机械手从左边开始往右边移动,当机械手移动到最右边时,
机械手马上开始往下移动,当机械手移动到最右下角的时候,延时1秒,然后原路返回,一直返回到左上角的原点位置。
请注意:按键必须等机械手处于左上角的位置时,启动按键的触发才有效。
S5和S1同时按下,启动,从左往右移动;S9从上往下移动;S13延时1S后由下往上移动,S9由右往左移动,知道S5触发停止。
*/
*/
#include "REG52.H"
#define const_voice_short 40 //蜂鸣器短叫的持续时间
#define const_key_time1 20 //按键去抖动延时的时间
#define const_sensor 20 //开关感应器去抖动延时的时间
#define const_1s 500 //1秒钟大概的定时中断次数
void initial_myself();
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelayLong);
void left_to_right(); //从左边移到右边
void right_to_left(); //从右边返回左边
void up_to_down(); //从上边移动到下边
void down_to_up(); //从下边返回到上边
void run(); //设备自动控制程序
void hc595_drive(unsigned char ucLedStatusTemp08_01);
void led_update(); //LED更新函数
void T0_time(); //定时中断函数
void key_service(); //按键服务的应用程序
void key_scan(); //按键扫描函数,放在定时中断里
void sensor_scan(); //开关感应器软件抗干扰处理函数,放在定时中断里
#define const_voice_short 40 //蜂鸣器短叫的持续时间
#define const_key_time1 20 //按键去抖动延时的时间
#define const_sensor 20 //开关感应器去抖动延时的时间
#define const_1s 500 //1秒钟大概的定时中断次数
void initial_myself();
void initial_peripheral();
void delay_short(unsigned int uiDelayShort);
void delay_long(unsigned int uiDelayLong);
void left_to_right(); //从左边移到右边
void right_to_left(); //从右边返回左边
void up_to_down(); //从上边移动到下边
void down_to_up(); //从下边返回到上边
void run(); //设备自动控制程序
void hc595_drive(unsigned char ucLedStatusTemp08_01);
void led_update(); //LED更新函数
void T0_time(); //定时中断函数
void key_service(); //按键服务的应用程序
void key_scan(); //按键扫描函数,放在定时中断里
void sensor_scan(); //开关感应器软件抗干扰处理函数,放在定时中断里
sbit hc595_sh_dr=P3^6; //上升沿时,数据寄存器数据移位
sbit hc595_st_dr=P3^5; //上升沿时移位寄存器的数据进入数据寄存器,下降沿时数据不变。当移位结束后,会产生一个正脉冲,用于更新显示数据。
sbit hc595_ds_dr=P3^4; //串行数据输入端,级联的话接上一级的Q7
sbit hc595_st_dr=P3^5; //上升沿时移位寄存器的数据进入数据寄存器,下降沿时数据不变。当移位结束后,会产生一个正脉冲,用于更新显示数据。
sbit hc595_ds_dr=P3^4; //串行数据输入端,级联的话接上一级的Q7
sbit beep_dr=P1^5; //蜂鸣器的IO口
sbit key_sr1=P0^0; //S1键
sbit left_sr=P0^1; //左边的开关传感器 S5键
sbit right_sr=P0^2; //右边的开关传感器 S9键
sbit down_sr=P0^3; //下边的开关传感器 S13键
sbit key_gnd_dr=P0^4;
sbit left_sr=P0^1; //左边的开关传感器 S5键
sbit right_sr=P0^2; //右边的开关传感器 S9键
sbit down_sr=P0^3; //下边的开关传感器 S13键
sbit key_gnd_dr=P0^4;
unsigned char ucKeySec=0; //被触发的按键编号
unsigned int uiKeyTimeCnt1=0; //按键去抖动延时计数器
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
unsigned char ucLeftSr=0; //左边感应器经过软件干扰后处理后的状态标志
unsigned char ucRightSr=0; //右边感应器经过软件干扰后处理后的状态标志
unsigned char ucDownSr=0; //下边感应器经过软件干扰后处理后的状态标志
unsigned char ucRightSr=0; //右边感应器经过软件干扰后处理后的状态标志
unsigned char ucDownSr=0; //下边感应器经过软件干扰后处理后的状态标志
unsigned int uiLeftCnt1=0; //左边感应器软件抗干扰所需的计数器变量
unsigned int uiLeftCnt2=0;
unsigned int uiLeftCnt2=0;
unsigned int uiRightCnt1=0; //右边感应器软件抗干扰所需的计数器变量
unsigned int uiRightCnt2=0;
unsigned int uiRightCnt2=0;
unsigned int uiDownCnt1=0; //下边感应器软件抗干扰所需的计数器变量
unsigned int uiDownCnt2=0;
unsigned int uiDownCnt2=0;
unsigned int uiVoiceCnt=0; //蜂鸣器鸣叫的持续时间计数器
unsigned char ucLed_dr1=0; //代表16个灯的亮灭状态,0灭,1亮
unsigned char ucLed_dr2=0;
unsigned char ucLed_dr3=0;
unsigned char ucLed_dr4=0;
unsigned char ucLed_dr5=0;
unsigned char ucLed_dr6=0;
unsigned char ucLed_dr7=0;
unsigned char ucLed_dr8=0;
unsigned char ucLed_dr2=0;
unsigned char ucLed_dr3=0;
unsigned char ucLed_dr4=0;
unsigned char ucLed_dr5=0;
unsigned char ucLed_dr6=0;
unsigned char ucLed_dr7=0;
unsigned char ucLed_dr8=0;
unsigned char ucLed_update=1; //刷新变量。每次更改LED灯的状态都要更新一次
unsigned char ucLedStatus08_01=0; //代表底层74HC595输出状态的中间变量
unsigned int uiRunTimeCnt=0; //运动中的时间延时计数器变量
unsigned char ucRunStep=0; //运动控制的步骤变量
unsigned char ucLedStatus08_01=0; //代表底层74HC595输出状态的中间变量
unsigned int uiRunTimeCnt=0; //运动中的时间延时计数器变量
unsigned char ucRunStep=0; //运动控制的步骤变量
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
run(); //设备自动控制程序
led_update(); //LED更新函数
key_service(); //按键服务应用程序
}
}
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
run(); //设备自动控制程序
led_update(); //LED更新函数
key_service(); //按键服务应用程序
}
}
/*注释一:
开关传感器的抗干扰处理,本质上类似按键的去抖动处理。唯一的区别是:
按键去抖动关注的是IO口的一种状态,而开关感应器关注的是IO口的两种状态。
当开关感应器从原来的1状态切换到0状态之前,要进行软件滤波处理过程,一旦
成功的切换到0状态了,再想从0状态切换到1状态的时候,又要经过软件滤波处
理过程,符合条件后才能切换到1状态。
通俗的讲,按键去抖动从1变成0难,从0变成1容易。
开关感应器从1编程0难,从0编程1也难。这里的“难”指的是要进行去抖动。
*/
开关传感器的抗干扰处理,本质上类似按键的去抖动处理。唯一的区别是:
按键去抖动关注的是IO口的一种状态,而开关感应器关注的是IO口的两种状态。
当开关感应器从原来的1状态切换到0状态之前,要进行软件滤波处理过程,一旦
成功的切换到0状态了,再想从0状态切换到1状态的时候,又要经过软件滤波处
理过程,符合条件后才能切换到1状态。
通俗的讲,按键去抖动从1变成0难,从0变成1容易。
开关感应器从1编程0难,从0编程1也难。这里的“难”指的是要进行去抖动。
*/
void sensor_scan() //开关感应器软件抗干扰处理函数,放在定时中断里
{
if(left_sr==1) //左边传感器是高电平,说明可能没有被触发,对应着 S5键
{
uiLeftCnt1=0; //在软件滤波中,非常关键的语句!!! 类似按键去抖动程序的及时清零
uiLeftCnt2++; //类似独立按键去抖动的软件抗干扰处理
if(uiLeftCnt2>const_sensor)
{
uiLeftCnt2=0;
ucLeftSr=1; //说明感应器确实没有被触发
}
}
else //左边感应器是低电平,说明有可能被触发到了
{
uiLeftCnt2=0; //在软件滤波中,非常关键的语句!!!类似按键去抖动程序要及时清零
uiLeftCnt1++;
if(uiLeftCnt1>const_sensor)
{
uiLeftCnt1=0;
ucLeftSr=0; //说明传感器被触发了
}
}
if(right_sr==1)
{
uiRightCnt1=0;
uiRightCnt2++;
if(uiRightCnt2>const_sensor)
{
uiRightCnt2=0;
ucRightSr=1; //说明传感器没有被触发
}
}
else
{
uiRightCnt2=0;
uiRightCnt1++;
if(uiRightCnt1>const_sensor)
{
uiRightCnt1=0;
ucRightSr=0; //说明传感器被触发了
}
}
if(down_sr==1)
{
uiDownCnt1=0;
uiDownCnt2++;
if(uiDownCnt2>const_sensor)
{
uiDownCnt2=0;
ucDownSr=1; //说明传感器没有被触发
}
}
else
{
uiDownCnt2=0;
uiDownCnt1++;
if(uiDownCnt1>const_sensor)
{
uiDownCnt1=0;
ucDownSr=0; //说明传感器被触发了
}
}
}
{
if(left_sr==1) //左边传感器是高电平,说明可能没有被触发,对应着 S5键
{
uiLeftCnt1=0; //在软件滤波中,非常关键的语句!!! 类似按键去抖动程序的及时清零
uiLeftCnt2++; //类似独立按键去抖动的软件抗干扰处理
if(uiLeftCnt2>const_sensor)
{
uiLeftCnt2=0;
ucLeftSr=1; //说明感应器确实没有被触发
}
}
else //左边感应器是低电平,说明有可能被触发到了
{
uiLeftCnt2=0; //在软件滤波中,非常关键的语句!!!类似按键去抖动程序要及时清零
uiLeftCnt1++;
if(uiLeftCnt1>const_sensor)
{
uiLeftCnt1=0;
ucLeftSr=0; //说明传感器被触发了
}
}
if(right_sr==1)
{
uiRightCnt1=0;
uiRightCnt2++;
if(uiRightCnt2>const_sensor)
{
uiRightCnt2=0;
ucRightSr=1; //说明传感器没有被触发
}
}
else
{
uiRightCnt2=0;
uiRightCnt1++;
if(uiRightCnt1>const_sensor)
{
uiRightCnt1=0;
ucRightSr=0; //说明传感器被触发了
}
}
if(down_sr==1)
{
uiDownCnt1=0;
uiDownCnt2++;
if(uiDownCnt2>const_sensor)
{
uiDownCnt2=0;
ucDownSr=1; //说明传感器没有被触发
}
}
else
{
uiDownCnt2=0;
uiDownCnt1++;
if(uiDownCnt1>const_sensor)
{
uiDownCnt1=0;
ucDownSr=0; //说明传感器被触发了
}
}
}
void key_scan() //按键扫描函数 放在定时中断里
{
if(key_sr1==1) //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock1=0; //按键自锁标志清零
uiKeyTimeCnt1=0; //按键去抖动延时计数器清零
}
else if(ucKeyLock1==0) //有按键按下,且第一次被按下
{
uiKeyTimeCnt1++;
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //避免一直自锁
ucKeySec=1; //触发1号按键
}
}
}
{
if(key_sr1==1) //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock1=0; //按键自锁标志清零
uiKeyTimeCnt1=0; //按键去抖动延时计数器清零
}
else if(ucKeyLock1==0) //有按键按下,且第一次被按下
{
uiKeyTimeCnt1++;
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //避免一直自锁
ucKeySec=1; //触发1号按键
}
}
}
void key_service()
{
switch(ucKeySec)
{
case 1: //启动按键,对应S1
if(ucLeftSr==0) //处于左上角原点位置,即S5触发
{
ucRunStep=1; //启动
uiVoiceCnt=const_voice_short; //按键触发,嘀一声就停
}
ucKeySec=0;
break;
}
}
{
switch(ucKeySec)
{
case 1: //启动按键,对应S1
if(ucLeftSr==0) //处于左上角原点位置,即S5触发
{
ucRunStep=1; //启动
uiVoiceCnt=const_voice_short; //按键触发,嘀一声就停
}
ucKeySec=0;
break;
}
}
void led_update() //LED更新函数
{
if(ucLed_update==1)
{
ucLed_update=0; //及时清零,避免一直更新
if(ucLed_dr1==1)
ucLedStatus08_01=ucLedStatus08_01&0xfe; //确保第1位为0 亮
else
ucLedStatus08_01=ucLedStatus08_01|0x01; //确保第1位为1 灭
if(ucLed_dr2==1)
ucLedStatus08_01=ucLedStatus08_01&0xfd;
else
ucLedStatus08_01=ucLedStatus08_01|0x02;
if(ucLed_dr3==1)
ucLedStatus08_01=ucLedStatus08_01&0xfb;
else
ucLedStatus08_01=ucLedStatus08_01|0x04;
if(ucLed_dr4==1)
ucLedStatus08_01=ucLedStatus08_01&0xf7;
else
ucLedStatus08_01=ucLedStatus08_01|0x08;
if(ucLed_dr5==1)
ucLedStatus08_01=ucLedStatus08_01&0xef;
else
ucLedStatus08_01=ucLedStatus08_01|0x10;
if(ucLed_dr6==1)
ucLedStatus08_01=ucLedStatus08_01&0xdf;
else
ucLedStatus08_01=ucLedStatus08_01|0x20;
if(ucLed_dr7==1)
ucLedStatus08_01=ucLedStatus08_01&0xbf;
else
ucLedStatus08_01=ucLedStatus08_01|0x40;
if(ucLed_dr8==1)
ucLedStatus08_01=ucLedStatus08_01&0x7f;
else
ucLedStatus08_01=ucLedStatus08_01|0x80;
hc595_drive(ucLedStatus08_01); //74HC595底层驱动程序
}
}
{
if(ucLed_update==1)
{
ucLed_update=0; //及时清零,避免一直更新
if(ucLed_dr1==1)
ucLedStatus08_01=ucLedStatus08_01&0xfe; //确保第1位为0 亮
else
ucLedStatus08_01=ucLedStatus08_01|0x01; //确保第1位为1 灭
if(ucLed_dr2==1)
ucLedStatus08_01=ucLedStatus08_01&0xfd;
else
ucLedStatus08_01=ucLedStatus08_01|0x02;
if(ucLed_dr3==1)
ucLedStatus08_01=ucLedStatus08_01&0xfb;
else
ucLedStatus08_01=ucLedStatus08_01|0x04;
if(ucLed_dr4==1)
ucLedStatus08_01=ucLedStatus08_01&0xf7;
else
ucLedStatus08_01=ucLedStatus08_01|0x08;
if(ucLed_dr5==1)
ucLedStatus08_01=ucLedStatus08_01&0xef;
else
ucLedStatus08_01=ucLedStatus08_01|0x10;
if(ucLed_dr6==1)
ucLedStatus08_01=ucLedStatus08_01&0xdf;
else
ucLedStatus08_01=ucLedStatus08_01|0x20;
if(ucLed_dr7==1)
ucLedStatus08_01=ucLedStatus08_01&0xbf;
else
ucLedStatus08_01=ucLedStatus08_01|0x40;
if(ucLed_dr8==1)
ucLedStatus08_01=ucLedStatus08_01&0x7f;
else
ucLedStatus08_01=ucLedStatus08_01|0x80;
hc595_drive(ucLedStatus08_01); //74HC595底层驱动程序
}
}
void hc595_drive(unsigned char ucLedStatusTemp08_01)
{
unsigned char i;
unsigned char ucTempData;
hc595_sh_dr=0;
hc595_st_dr=0;
ucTempData=ucLedStatusTemp08_01; //先送高8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80) //更新一次数据,移一次位
hc595_ds_dr=1;//串行数据输入,如果是多片联级的话,更新一次,输入一次数据。(我的单片机只用了一个74HC595芯片)
else
hc595_ds_dr=0;
hc595_sh_dr=0;
delay_short(15);
hc595_sh_dr=1;//SH引脚的上升沿把数据送入寄存器
delay_short(15);
ucTempData=ucTempData<<1;//左移一位
}
hc595_st_dr=0;
delay_short(15);
hc595_st_dr=1; //ST引脚负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。上升沿时更新显示数据。
delay_short(15);
hc595_sh_dr=0; //拉低,抗干扰就增强
hc595_st_dr=0;
hc595_ds_dr=0;
}
{
unsigned char i;
unsigned char ucTempData;
hc595_sh_dr=0;
hc595_st_dr=0;
ucTempData=ucLedStatusTemp08_01; //先送高8位
for(i=0;i<8;i++)
{
if(ucTempData>=0x80) //更新一次数据,移一次位
hc595_ds_dr=1;//串行数据输入,如果是多片联级的话,更新一次,输入一次数据。(我的单片机只用了一个74HC595芯片)
else
hc595_ds_dr=0;
hc595_sh_dr=0;
delay_short(15);
hc595_sh_dr=1;//SH引脚的上升沿把数据送入寄存器
delay_short(15);
ucTempData=ucTempData<<1;//左移一位
}
hc595_st_dr=0;
delay_short(15);
hc595_st_dr=1; //ST引脚负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。上升沿时更新显示数据。
delay_short(15);
hc595_sh_dr=0; //拉低,抗干扰就增强
hc595_st_dr=0;
hc595_ds_dr=0;
}
void left_to_right() //从左边移动到右边
{
ucLed_dr1=1; //1代表左右气缸从左边移动到右边
ucLed_update=1; //刷新变量,每次更改LED灯的状态都要更新一次
}
{
ucLed_dr1=1; //1代表左右气缸从左边移动到右边
ucLed_update=1; //刷新变量,每次更改LED灯的状态都要更新一次
}
void right_to_left() //从右边返回到左边
{
ucLed_dr1=0; //0代表左右气缸从右边返回到左边
ucLed_update=1;
}
{
ucLed_dr1=0; //0代表左右气缸从右边返回到左边
ucLed_update=1;
}
void up_to_down() //从上边移动到下边
{
ucLed_dr2=1; //1代表上下气缸从上边移动到下边
ucLed_update=1;
}
{
ucLed_dr2=1; //1代表上下气缸从上边移动到下边
ucLed_update=1;
}
void down_to_up() //从下边返回到上边
{
ucLed_dr2=0; //0代表上下气缸从下边返回到上边
ucLed_update=1;
}
{
ucLed_dr2=0; //0代表上下气缸从下边返回到上边
ucLed_update=1;
}
void run() //设备自动控制程序
{
switch(ucRunStep)
{
case 0: //机械手处于左上角原点位置,待命状态。此时触发启动按键ucRunStep=1,就触发后续一系列连续动作
break;
case 1: //机械手从左边往右边移动
left_to_right();
ucRunStep=2;
break;
case 2: //等待机械手移动到最右边,直到触发了最右边的开关感应器
if(ucRightSr==0) //右边感应器触发
ucRunStep=3;
break;
case 3:
up_to_down();
ucRunStep=4;
break;
case 4:
if(ucDownSr==0) //右下边感应器触发
{
uiRunTimeCnt=0; //时间计数器清零,为接下来1秒做准备
ucRunStep=5;
}
break;
case 5:
if(uiRunTimeCnt>const_1s) //延时1秒
ucRunStep=6;
break;
case 6: //原路返回,机械手从右下边往右上边移动
down_to_up();
ucRunStep=7;
break;
case 7: //原路返回,等待机械手移动到最右边的感应开关
if(ucRightSr==0)
ucRunStep=8;
break;
case 8: //原路返回,等待机械手从右边移动到左边
right_to_left();
ucRunStep=9;
break;
case 9:
if(ucLeftSr==0) //原路返回,等待机械手移动到最左边的感应开关,表示回到了原点
ucRunStep=0;
break;
}
}
{
switch(ucRunStep)
{
case 0: //机械手处于左上角原点位置,待命状态。此时触发启动按键ucRunStep=1,就触发后续一系列连续动作
break;
case 1: //机械手从左边往右边移动
left_to_right();
ucRunStep=2;
break;
case 2: //等待机械手移动到最右边,直到触发了最右边的开关感应器
if(ucRightSr==0) //右边感应器触发
ucRunStep=3;
break;
case 3:
up_to_down();
ucRunStep=4;
break;
case 4:
if(ucDownSr==0) //右下边感应器触发
{
uiRunTimeCnt=0; //时间计数器清零,为接下来1秒做准备
ucRunStep=5;
}
break;
case 5:
if(uiRunTimeCnt>const_1s) //延时1秒
ucRunStep=6;
break;
case 6: //原路返回,机械手从右下边往右上边移动
down_to_up();
ucRunStep=7;
break;
case 7: //原路返回,等待机械手移动到最右边的感应开关
if(ucRightSr==0)
ucRunStep=8;
break;
case 8: //原路返回,等待机械手从右边移动到左边
right_to_left();
ucRunStep=9;
break;
case 9:
if(ucLeftSr==0) //原路返回,等待机械手移动到最左边的感应开关,表示回到了原点
ucRunStep=0;
break;
}
}
void T0_time() interrupt 1
{
TF0=0; //清除中断标志
TR0=0; //关中断
sensor_scan(); //开关传感器软件抗干扰函数
key_scan(); //按键扫描函数
if(uiRunTimeCnt<0xffff) //设定这个条件,防止超范围
{
uiRunTimeCnt++; //延时计数器
}
{
TF0=0; //清除中断标志
TR0=0; //关中断
sensor_scan(); //开关传感器软件抗干扰函数
key_scan(); //按键扫描函数
if(uiRunTimeCnt<0xffff) //设定这个条件,防止超范围
{
uiRunTimeCnt++; //延时计数器
}
if(uiVoiceCnt!=0)
{
uiVoiceCnt--;
beep_dr=0; //PNP三极管控制,低电平开始鸣叫
}
else
{
;
beep_dr=1;
}
TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
TL0=0x2f;
TR0=1; //开中断
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i<uiDelayShort;i++)
;
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
for(j=0;j<500;j++)
;
}
void initial_myself() //第一区 初始化单片机
{
key_gnd_dr=0;
beep_dr=1;
TMOD=0x01; //设置定时器0工作方式为1
TH0=0xf8;
TL0=0x2f;
}
void initial_peripheral()
{
EA=1; //开总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
}
{
uiVoiceCnt--;
beep_dr=0; //PNP三极管控制,低电平开始鸣叫
}
else
{
;
beep_dr=1;
}
TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
TL0=0x2f;
TR0=1; //开中断
}
void delay_short(unsigned int uiDelayShort)
{
unsigned int i;
for(i=0;i<uiDelayShort;i++)
;
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i<uiDelayLong;i++)
for(j=0;j<500;j++)
;
}
void initial_myself() //第一区 初始化单片机
{
key_gnd_dr=0;
beep_dr=1;
TMOD=0x01; //设置定时器0工作方式为1
TH0=0xf8;
TL0=0x2f;
}
void initial_peripheral()
{
EA=1; //开总中断
ET0=1; //允许定时中断
TR0=1; //启动定时中断
}
/*最近忙着写开题报告,之后会晚点更新。之后更新如何与上位机通讯等代码*/