单片机子程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一;头文件和位定义
#include
void delay(unsigned int); //函数声明
void led();
sbit Leden=P1^2;//流水灯使能端
sbit wei=P1^1; // 数码管位控制,点阵列控制
sbit duan=P1^0; //段控制端
sbit Line=P1^3; //点阵行控制
sbit lcd_en=P1^7;//1602液晶使能端
lcd_en=0;//关闭1602液晶
P0=0X00; //关闭点阵
Line=0;
P0=0XFF; //关闭数码管
wei=0;
P0=0XFF; //关闭LED灯
Leden=0;
二;延迟函数
void delay(unsigned int sm)
{
for(x=sm;x>0;x--) //改变SM可以改变流水的速度。
for(y=110;y>0;y--);
}
三;流水灯循环
闪烁灯
while (1) //主循环
{
P0=0X00;
delay(150);
P0=0XFF; //具体参考3-8译码器的真值表
delay(150);
}
右移
Leden=1;
i=0x7f;
while(1)
{
P0=i;
delay(100);
i=_cror_(i,1); //流水灯右移位
}
左移
Leden=1; //开灯锁存端
i=0xfe; //送1111 1110给 i
while(1)
{
P0=i; // 把i的值赋给P0口,低电平点亮
delay(100);
i=_crol_(i,1); //移位函数,流水灯左移位
}
循环移动
i=0xfe;
while(1)
{
for(k=0;k<7;k++)//for 循环,执行8次
{
P0=i; //把i的值0XFE赋给P0口
delay(100);
i=_crol_(i,1); //流水灯左移位
}
for(k=0;k<7;k++)
{
P0=i; //把i的值0XFE赋给P0口
delay(100);
i=_cror_(i,1);//流水右移
}
}
四;中断
TMOD=0X01; //选择定时器0工作方式1
TH0=(65536-45872)/256; //装初值
TL0=(65536-45872)%256;
EA=1; //开总中断
ET0=1; //开定时中断
TR0=1; // 打开定时器T0
while(1); //无限循环等待中断
中断0
void T0_time()interrupt 1
{
TH0=(65536-45872)/256; //重新装入初值
TL0=(65536-45872)%256;
i++; //每次中断加1
if(i==20) //检测I是否为20
{
i=0; //当i到20时重新赋值0
LED=~LED; //值取反
}
}
五;蜂鸣器发声
sbit Buzzer=P3^7; //定义P2.4为喇叭驱动端
lcd_en=0;//关闭1602液晶
while(1)
{
while(i<=200)
{
delay_500us(); //延迟500us
Buzzer=~Buzzer; //喇叭驱动位取反
i++; //取反次数加1
}
i=0; //清时间控制变量
while(i<=400)
{
delay_250us(); //延迟250US
Buzzer=~Buzzer; //喇叭驱动位取反
i++; //取反次数加1
}
i=0; //清时间控制变量
}
911报警器
lcd_en=0;//关闭1602液晶
Buzzer=1;
TMOD = 0x01; //定时器0,工作方式1
f = 0x00;
TH0 = 0x00; //装入初值
TL0 = 0xff;
TR0 = 1; //开定时器
IE = 0x82; //开总中断,允许定时0中断
while(1)
{
f++;
delay(1);
}
////////////////中断函数处理///////////////////////
void T0_time()interrupt 1
{
TH0 = 0xfe;
TL0 = f;
Buzzer = ~Buzzer;
}
六;数码管显示
int w[10]={0x3f,0x30,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0--9
unsigned char code DM[]={0x3f,0x30,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x
71};// 显示段码值0~9
unsigned char code WM[]={0x0e,0x0d,0x0b,0x07,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不带小数点数字编码
uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; //带小数点数字编码
单个循环
wei=1;
P0 = 0x7f;
wei=0;
while (1) //主循环
{
for(ti=0;ti<10;ti++) //循环执行10次
{
duan=1;
P0=w[ti]; //循环调用表中的数值
duan=0;
delay(400);
}
}
0-9999动态显示
ti=0; //赋值9999给数码管
ti=9999; //赋值9999给数码管
ti1=ti/1000; //千位
ti2=(ti-ti1*1000)/100;//百位
ti3=(ti-ti1*1000-ti2*100)/10; //十位
ti4=ti-ti1*1000-ti2*100-ti3*10;//个位
/***********第一个数码管显示千位*********/
duan=1; //开段锁存
P0=w[ti1]; //3F/0(不带点) 06\30/1 5B/2 4F/3 66/4 6D/5 FD/6 07/7 7F/8 6F/9 80/.
delay(0);
duan=0; //关段锁存
P0=0Xff; //消影
wei=1; //开位锁存
P0=0Xef; // 0F/全灭 0E/亮第1个 0D/亮第2个 0B/亮第3个 07/亮第4个 EF/第5个 DF/第6个 BF/第7个 FF/第8个
wei=0; //关位锁存
delay(10);
/***********第二个数码管显示百位*********/
duan=1;
P0=w[ti2];
delay(0);
duan=0;
P0=0Xff;
wei=1;
P0=0Xdf;
wei=0;
delay(10);
/***********第三个数码管显示十位*********/
duan=1;
P0=w[ti3];
delay(0);
duan=0;
P0=0Xff;
wei=1;
P0=0Xbf;
wei=0;
delay(10);
/************第四个数码管显示个位*********/
duan=1;
P0=w[ti4];
delay(0);
duan=0;
P0=0Xff;
wei=1;
P0=0X7f;
wei=0;
delay(10); //时间大了会闪烁,小了会重影
n++;
if(n>2){n=0;ti++;} //从0到9999
if(n>2){n=0;ti--;} //从9999减到0
单个右移位
y=0Xfe;
delay(350);
y=_crol_(y,1); //移位函数
wei=1;
P0=y; // 0F/全灭 0E/亮第1个 0D/亮第2个 0B/亮第3 07/亮第4个
wei=0;
P0=0XFF; //消影
duan=1;
P0=0XFF; //3F/0(不带点) 06\30/1 5B/2 4F/3 66/4 6D/5 FD/6 07/7 7F/8 6F/9 80/.
duan=0;
void display(uint temp)
{
uchar qian, bai,shi,ge;
qian=temp/1000;
bai=temp%1000/100;
shi=temp%100/10;
ge=temp%100%10;
duan=1;
P0=table[qian]; //显示千位
_nop_();
_nop_();
_nop_();
duan=0;
P0=0xff;
wei=1;
P0=0xFe;
wei=0;
delay(3);
duan=1;
P0=table1[bai]; //显示百位
_nop_(); //从0到1,有个上升沿,解除锁存,显示相应段
_nop_();
_nop_();
duan=0; //从1到0再次锁存
P0=0xff;
wei=1;
P0=0xFd;
wei=0;
delay(3); //延时约3ms
duan=1;
P0=table[shi]; //显示十位
_nop_();
_nop_();
_nop_();
duan=0;
P0=0xff;
wei=1;
P0=0xFb;
wei=0;
delay(3);
duan=1;
P0=table[ge]; //显示个位
_nop_();
_nop_();
_nop_();
dua
n=0;
P0=0xff;
wei=1;
P0=0xF7;
wei=0;
delay(3);
}
八;AT24C02
sbit sda=P3^2;//定义24C02数据位SDA
sbit scl=P3^3;//定义24C02时钟位SCL
sbit LeDen=P1^2;//LED灯控制端
sbit Line=P1^3;//点阵行控制端
sbit rst=P3^4;//关闭1302时钟复位
sbit lcd_en=P1^7;//1602液晶使能端
void start() //开始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0; //SCL在高电平期间,SDA从高电平变化到低电平,信号开始写入
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay(); //SCL在高电平期间,SDA一个上升沿停止信号 ,SDA从低电平变化到高电平,信号停止写入
}
void respons() //应答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<255))
i++;
scl=0;
delay(); //SCL在高电平时,SDA被拉为低电平表示应答
}
void init() //总线初始化
{
scl=1;
delay();
sda=1;
delay(); //把总线拉高以释放总线
}
void write_byte(uchar date) //写字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1; //将temp左移一位,最高位将移入PSW寄存器的CY位中,然后将CY赋值给SDA进而在SCL的控制下发送出去
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte() //读字节
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda; //k左移一位后与SDA进行“或”运算,依次把8个独立的位放入一个字节中来完成接受
scl=0;
delay();
}
return k;
}
void write_add(uchar address,uchar date) //向24C02写字节
{
start();
write_byte(0xa0); //10100000对芯片地址进行写操作
respons(); //芯片应答
write_byte(address); //写地址
respons();
write_byte(date); //写数据
respons();
stop(); //停止应答
}
uchar read_add(uchar address) //从24C02读字节
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
void xianshi(uchar bai,uchar shi) //数码管显示
{
duan=0;
P0=table[bai];
delay();
duan=1;
duan=0;
wei=0;
P0=0xfe;
wei=1;
wei=0;
delay1ms(2);
duan=0;
P0=table[shi];
delay();
duan=1;
duan=0;
wei=0;
P0=0xfd;
wei=1;
wei=0;
delay1ms(2);
}
void main() //主函数
{
lcd_en=0;//关闭1602液晶
rst=0; //关闭DS1302
P0=0X00; //关闭点阵
Line=0;
P0=0XFF; //关闭LED灯
LeDen=0;
init(); //总线初
始化
time=read_add(2); //读出保存的数据赋值给sec
if(time>100) //防止首次读取出错误数据
time=0; //数据清零,首次读取
TMOD=0X01; //定时器工作在方式1
ET0=1;
EA=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //50ms中断一次
TR0=1;
while(1)
{
xianshi(time/10,time%10);
if(biaozhi==1) //判断计时器是否计时1秒
{
biaozhi=0; //清零
write_add(2,time); //在24C02的地址2中写入数据sec
}
}
}
void t0()interrupt 1 //中断
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
m++;
if(m==20) //中断一次50ms,20次之后就是1s,也就是1s之后就清零,重新计时
{
m=0;
time++; // 中断一次50ms,20次之后就是1s,也就是1s之后就清零,重新计时
biaozhi=1;
if(time==100)
time=0;
}
}
应用试验
温度传感器显示温度在数码管
#include "reg52.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit ds=P1^4; //18B20信号端口
sbit duan=P1^0; //数码管段码控制端
sbit wei=P1^1; //数码管位码控制端
sbit LeDen=P1^2; //led灯控制端
sbit Line=P1^3; //点阵行控制端
sbit lcd_en=P1^7;//1602液晶使能端
uchar flag ;
uint temp; //参数temp一定要声明为 int 型
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //不带小数点数字编码
uchar code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; //带小数点数字编码
/*延时函数*/
void TempDelay (uchar us)
{
while(us--);
}
void delay(uint count) //延时子函数
{ }
/*串口初始化,波特率9600,方式1 */
void init_com()
{
TMOD=0x20; //设置定时器1为模式2
TH1=0xfd; //装初值设定波特率
TL1=0xfd;
TR1=1; //启动定时器
SM0=0; //串口通信模式设置
SM1=1;
PCON=0; //波特率不倍频
}
/*数码管的显示 */
void display(uint temp)
{ }
void ds_reset(void)
{
ds=1;
_nop_(); //1us
ds=0;
TempDelay(68); //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里//延时约530us总线停留在低电平超过480μs,总线上的所有器件都
//将 被复位。
_nop_();
ds=1; //产生复位脉冲后,微处理器释放总线,让总线处于空闲状
TempDelay(10); //释放总线后,以便从机18b20通过拉低总线来指示其是否在线,
//存在检测高电平时间:15~60us, 所以延时44us,
_nop_();
_nop_();
_nop_();
if(ds==0)
flag=1;
else
flag=0;
TempDelay(20); //存在检测低电平时间:60~240us,所以延时约140us
_nop_();
_nop_();
ds=1; //再次拉高总线,让总线处于空闲状态
/**/
}
/*----------------------------------------
读/写时间隙:
-----------
-------------------------------*/
bit ds_read_bit(void) //读一位
{
bit dat;
ds=0; //单片机(微处理器)将总线拉低
_nop_(); //读时隙起始于微处理器将总线拉低至少1us
ds=1; //拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据
_nop_();
_nop_(); //小延时一下,读取18b20上的数据 ,因为从ds18b20上输出的数据
//在读"时间隙"下降沿出现15us内有效
dat=ds; //主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现//15us内有效
TempDelay(20); //所有读"时间隙"必须60~120us,这里77us
return(dat); //返回有效数据
}
uchar ds_read_byte(void ) //读一字节
{
uchar value,i,j;
value=0; //一定别忘了给初值
for(i=0;i<8;i++)
{
j=ds_read_bit();
value=(j<<7)|(value>>1); //这一步的说明在一个word文档里面
}
return(value); //返回一个字节的数据
}
void ds_write_byte(uchar dat) //写一个字节
{
uchar i;
bit onebit; //一定不要忘了,onebit是一位
for(i=1;i<=8;i++)
{
onebit=dat&0x01;
dat=dat>>1;
if(onebit) //写 1
{
ds=0;
_nop_();
_nop_(); //看时序图,至少延时1us,才产生写"时间隙"
ds=1; //写时间隙开始后的15μs内允许数据线拉到高电平
TempDelay(20); //所有写时间隙必须最少持续60us
}
else //写 0
{
ds=0;
TempDelay(20); //主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64us
ds=1;
_nop_();
_nop_();
}
}
}
void tem_change() //温度转换
{
ds_reset();
delay(3); //约2ms
ds_write_byte(0xcc); //写跳过读ROM指令
ds_write_byte(0x44); //写温度转换指令
}
------------------------------------------*/
uint get_temperature() //读取寄存器中存储的温度数据
{
float wendu;
uchar a,b;
ds_reset();
delay(3); //约2ms
ds_write_byte(0xcc);
ds_write_byte(0xbe);
a=ds_read_byte(); //读低八位
b=ds_read_byte(); //读高八位
temp=b;
temp<<=8; //两个字节组合为一个字节
temp=temp|a;
wendu=temp*0.0625; //一次读取十六位,之后将低11位转换为十进制后乘以0.0625便使所测实际温度
temp=wendu*100+0.5; // 乘以100表示读取小数点后面2位,+0.5表示四舍五入
return temp; //temp是整型
}
void main()
{
uint a;
lcd_en=0;//关闭1602液晶
P0=0XFF;
LeDen=0;
P0=0X00;
Line=0;
init_com();
while(1)
{
tem_change(); //12位转换时间最大为750ms
for(a=20;a>0;a--)
{
display( get_temperature()); //获取温度并显示
}
}
}
/*------------------------------------------------------
数码管从0开始自加,到99后
清零,但断电时,AT2402会自动保存断点,下次启动时,数码管显示从上次断点开始
#include
#define uchar unsigned char
#define uint unsigned int
sbit sda=P3^2;//定义24C02数据位SDA
sbit scl=P3^3;//定义24C02时钟位SCL
sbit duan=P1^0;//定义锁存器控制数码管段
sbit wei=P1^1;//定义锁存器控制数码管位
sbit LeDen=P1^2;//LED灯控制端
sbit Line=P1^3;//点阵行控制端
sbit rst=P3^4;//关闭1302时钟复位
sbit lcd_en=P1^7;//1602液晶使能端
uchar time,m;
char biaozhi=0; //写24C02的标志
char code table[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管显示0~9
void delay() //微妙级延时
{;;}
void delay1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void start() //开始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0; //SCL在高电平期间,SDA从高电平变化到低电平,信号开始写入
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay(); //SCL在高电平期间,SDA从低电平变化到高电平,信号停止写入
}
void respons() //应答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<255))
i++;
scl=0;
delay(); //SCL在高电平时,SDA被拉为低电平表示应答
}
void init() //总线初始化
{
scl=1;
delay();
sda=1;
delay(); //把总线拉高以释放总线
}
void write_byte(uchar date) //写字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1; //将temp左移一位,最高位将移入PSW寄存器的CY位中,然后将CY赋值给SDA进而在SCL的控制下发送出去
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte() //读字节
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda; //k左移一位后与SDA进行“或”运算,依次把8个独立的位放入一个字节中来完成接受
scl=0;delay();
}
return k;
}
void write_add(uchar address,uchar date) //向24C02写字节
{
start();
write_byte(0xa0); //10100000对芯片地址进行写操作
respons(); //芯片应答
write_byte(address); //写地址
respons();
write_byte(date); //写数据
respons();
stop(); //停止应答
}
uchar read_add(uchar address) //从24C02读字节
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
void xianshi(uchar bai,uchar shi) //数码管显示
{
duan=0;
P0=table[bai];
delay();
duan=1;
duan=0;
wei=0;
P0=0xfe
;
wei=1;
wei=0;
delay1ms(2);
duan=0;
P0=table[shi];
delay();
duan=1;
duan=0;
wei=0;
P0=0xfd;
wei=1;
wei=0;
delay1ms(2);
}
void main() //主函数
{
lcd_en=0;//关闭1602液晶
rst=0; //关闭DS1302
P0=0X00; //关闭点阵
Line=0;
P0=0XFF; //关闭LED灯
LeDen=0;
init(); //总线初始化
time=read_add(2); //读出保存的数据赋值给sec
if(time>100) //防止首次读取出错误数据
time=0; //数据清零,首次读取
TMOD=0X01; //定时器工作在方式1
ET0=1;
EA=1;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //50ms中断一次
TR0=1;
while(1)
{
xianshi(time/10,time%10);
if(biaozhi==1) //判断计时器是否计时1秒
{
biaozhi=0; //清零
write_add(2,time); //在24C02的地址2中写入数据sec
}
}
}
void t0()interrupt 1 //中断
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
m++;
if(m==20) //中断一次50ms,20次之后就是1s,也就是1s之后就清零,重新计时
{
m=0;
time++; // 中断一次50ms,20次之后就是1s,也就是1s之后就清零,重新计时
biaozhi=1;
if(time==100)
time=0;
}
}
电机
步进电机转动原理
sbit A1=P1^4; //定义步进电机连接端口
sbit B1=P1^3;
sbit C1=P1^2;
sbit D1=P1^1;
sbit lcd_en=P1^7; //1602液晶使能端
void qudong1();
#define Dy_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
#define Dy_AB1 {A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电
#define Dy_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
#define Dy_BC1 {A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电
#define Dy_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
#define Dy_CD1 {A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电
#define Dy_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电//采用4相八拍励磁
#define Dy_DA1 {A1=1;B1=0;C1=0;D1=1;}
#define Dy_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电
unsigned char Speed;
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245); //大致延时1mS
DelayUs2x(245);
}
}
main()
{
lcd_en=0;//关闭1602液晶
Dy_OFF
for(;;)
{ qudong1(); }
}
void qudong1()
{
unsigned int i=510;//旋转一周时间
Speed=5;
while(i--) //正向
{
Dy_A1 //遇到Coil_A1 用{A1=1;B1=0;C1=0;D1=0;}代
DelayMs(Speed); //改变这个参数可以调整电机转速 ,
//数字越小,转速越大,力矩越小
Dy_AB1
DelayMs(Speed);
Dy_B1 //顺序从A1--D1相通电如果为正转,从D1--A1相通电则为反转
DelayMs(Speed);
Dy_BC1
DelayMs(Speed);
Dy_C1
DelayMs(Speed);
Dy_CD1
DelayMs(Speed);
Dy_D1
DelayMs(Speed);
Dy_DA1
DelayMs(Speed);
}
Dy_OFF
i=510;
while(i--
)//反向
{
Dy_DA1
DelayMs(Speed);
Dy_D1 //遇到Coil_A1 用{A1=1;B1=0;C1=0;D1=0;}代替
DelayMs(Speed); //改变这个参数可以调整电机转速 ,
Dy_CD1
DelayMs(Speed); //数字越小,转速越大,力矩越小
Dy_C1
DelayMs(Speed);
Dy_BC1
DelayMs(Speed);
Dy_B1
DelayMs(Speed);
Dy_AB1
DelayMs(Speed);
Dy_A1
DelayMs(Speed);
}
}
单相八拍工作方式:A-AB-B-BC-C-CD-D-DA (即一个脉冲,转 3.75 度)
#include "reg52.h" //Motor
sbit A = P1^4; //定义管脚
sbit b = P1^3;
sbit C = P1^2;
sbit D = P1^1;
sbit lcd_en=P1^7;//1602液晶使能端
unsigned char MotorStep=0; //步进马达步序
unsigned int MotorDelay,Speed=1,TIM,CT;
#define speed 12 // 调整速度 数值不要设的太低 低了会引起震动。
void InitMotor()
{
A = 1;
b = 1;
C = 1;
D = 1;
}
void SetMotor()
{
// if(Speed == 0) return;
MotorDelay=Speed; //调整速度
switch(MotorStep)
{
case 0:
if(TIM) // A
{
A = 0; //0xf1
b = 1;
C = 1;
D = 1;
MotorStep = 1;
TIM=0;
}
break;
case 1: // AB
if(TIM)
{
A = 0; //0xf3
b = 0;
C = 1;
D = 1;
MotorStep = 2;
TIM=0;
}
break;
case 2: //B
if(TIM)
{
A = 1;
b = 0; //0xf2
C = 1;
D = 1;
MotorStep = 3;
TIM=0;
}
break;
case 3: //BC
if(TIM)
{
A = 1;
b = 0; //0xf6
C = 0;
D = 1;
MotorStep = 4;
TIM=0;
}
break;
case 4: //C
if(TIM)
{
A = 1;
b = 1; //0xf4
C = 0;
D = 1;
MotorStep = 5;
TIM=0;
}
break;
case 5: //CD
if(TIM)
{
A = 1;
b = 1; //0xfc
C = 0;
D = 0;
MotorStep = 6;
TIM=0;
}
break;
case 6: //D
if(TIM)
{
A = 1;
b = 1; //0xf8
C = 1;
D = 0;
MotorStep = 7;
TIM=0;
}
break;
case 7: //DA
if(TIM)
{
A = 0;
b = 1; //0xf9
C = 1;
D = 0;
MotorStep = 0;
TIM=0;
}
break;
}
}
void system_Ini()
{
TMOD|= 0x11;
TH0=0xDC; //11.0592M
TL0=0x00;
IE = 0x8A;
TR0 = 1;
}
main()
{
system_Ini();
InitMotor();
lcd_en=0;//关闭1602液晶
while(1)
{
SetMotor();
}
}
定时中断延时
void Tzd(void) interrupt 1
{
TH0 = 0xfe; //11.0592
TL0 = 0x33;
if( CT++==speed)
{
TIM=1;
CT=0;
}
}