一·前言
其实大部分这种难度的设计常用的延时方式为软件延时,这种软件延时的方式在大部分情况下是很恰当的,但本文也不失为一个理解硬件延时的简单例子。
此外,本程序利用单片机外部中断,实现了在继电器运行时仍可以控制继电器。也是一种简单易理解的写法。
二·源程序
#include "reg52.h"
typedef unsigned int uint;
typedef unsigned char uchar;
sbit pos=P1^0;//步进电机正转
sbit neg=P1^1;//反转
sbit relay=P2^5;//继电器状态控制
#define out P2//步进电机控制输出
//**********************************
/*
头文件以及引脚接口名定义
*/
//**********************************
//**********************************
void delay(uint j)
{
uchar i;
for (i=0;i<j;i++){
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
while(!TF0);
TF0=0;
}
}
//***********************************
/*
通过单片机内部计时器T0进行延时
一个延时时长为5ms
以查询TF寄存器方式实现
*/
//***********************************
uchar code turn[]={0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03};
//***********************************
/*
步进电机采用一相二相励磁交替进行
相序:
0x02 00000010
0x06 00000110
0x04 00000100
0x0c 00001100
0x08 00001000
0x09 00001001
0x01 00000001
0x03 00000011
*/
//************************************
void Int0Init()
{
IT0=1;//下降沿触发
EX0=1;//int0中断允许
EA=1;//打开总中断
}
void Int0() interrupt 0 //????0?????
{
relay=~relay;
}
//************************************
/*设置启动继电器中断函数*/
//************************************
void main()
{
uchar i;
out=0x03;
relay=0;
Int0Init();
while(1)
{
if(!pos)
{
i = i < 8 ? i+1 : 0; //i<8 i+1;i>8 i=0
out=turn[i];
delay(100);
} else if(!neg)
{
i = i > 0 ? i-1 : 7;
out=turn[i];
delay(100);
}
}
}
//*******************************************
/*主函数
包含步进电机继电器正反转控制驱动函数*/
//*******************************************
本程序以单片机P2口作为输出接口,通过ULN2003芯片控制步进电机以及继电器,继电器控制按钮每按下一次就触发一次外部中断,通过外部中断函数取反输出一次继电器状态以实现对继电器的控制。
三·原理图
四·其他
若是通过P2口使用移位的方式控制流水等的话,需要增加一个头文件#include<intrins.h>。
关于中断函数再说一下容易犯的错吧
中断函数不能进行参数传递,同时中断函数也无返回值,这个在第一次编写中断函数的时候特别容易犯,而且要特别注意,如返回值数据类型为整数型的话,一般编译器都不会对此报错,因为整型值是默认值,编译器不能够正常识别。
在任何情况下都不能够直接调用中断函数,因直接调用中断函数而硬件上无对应的中断请求存在,这讲直接导致这个调用中断函数的指令结果不确定并且通常来讲会非常致命。
在定义中断函数时
void 函数名(【形式参数】) interrupt n [using m]
程序使用的寄存器组通常由程序状态字PSW中的两位RS1和RS0中决定。上述代码表示在定义中断函数时可以使用using指令指定该函数具体使用具体哪一组寄存器,m的取值范围为0、1、2、3,对应四组寄存器R0~R7。若在两个可能嵌套的中断函数中使用同一组寄存器则会产生资源冲突,这一点要稍稍注意。关于使用了using指令的中断函数中调用的函数,这个被调用的函数所使用的寄存器必须与中断函数所指定的寄存器相同,并且C编译器不会检查这一点。
五·8051控制器所支持的5个中断源以及对应类型号
外部中断0 | 0 |
定时/计数器0 | 1 |
外部中断1 | 2 |
定时计数器1 | 3 |
串行口中断 | 4 |