记录一些关于本人实验课的总结,由于本人是新手小白,许多程序和电路图较为粗略。
这次实验是关于转辙机的,同样使用keil和protues进行仿真与编程。
实验要求
按键控制转辙机的定操、反操动作,同时获取道岔的实际位置通过发光二极管显示出来,还是用最基础的51单片机控制。
前期资料搜索
本次实验关于转辙机,由于专业课刚刚开始,本人对转辙机原理与工作方式并不熟悉。
开始搜索一些资料查看转辙机的工作原理:
转辙机是指用以可靠地转换道岔位置,改变道岔开通方向,锁闭道岔尖轨,反映道岔位置的重要的信号基础设备,它可以很好地保证行车安全,提高运输效率,改善行车人员的劳动强度。
大概就是一种调整轨道的机器,坐等老师上课介绍了
转辙机的种类超多三相异步电机、zd6电动转辙机电机等等
网上有许多图片这里就不一一说明了
电机的原理:
前面的博客推荐过一个bilbil的up主讲解的51protues仿真
再次放上连接 Proteus电路仿真及应用(51单片机系列).
个人觉得讲的真的通俗易懂,很适合自己
本次实验使用的是步进电机,驱动芯片是L298
关于L298的原理与内部电路图再次参考大佬的讲解
链接 l298n.
步进电机通过给一个脉冲转动一个角度的方式工作,顾名思义步进。
当步进电机收到一定顺序的脉冲后,就会根据脉冲的时序进行正反转动,脉冲的个数决定了电机转的角度与圈数,脉冲的频率决定电机转的速度,当不再给电机脉冲后电机将保持现有的状态,还有刹车功能,很容易控制正反转。
选用四项步进电机八步法转动,每次转动45度,ABCD信号分别输入1001、1000、1100、0100、0110、0010、0011、0001
实现
还是偷懒没画上时钟电路与复位电路,采用P1口作为输入,P2口输出,为了方便直接把l298的几个使能口拉高了,只留四个输入口与51单片机相连。同时P1选出了两个口作为输出,本来这里是为了连接实验箱,实验箱中有转辙机的模型引出两个口作为正反操标志输入。由于没有实验箱只能自己搞一个电机作为代替品了。
放上代码
// An highlighted block
#include "reg52.h"
//初始化管脚
sbit LED0=P1^2;
sbit LED1=P1^3;
sbit KEY0=P1^4;
sbit KEY1=P1^5;
//控制信号1001,1000,1100,0100,0110,0010,0011,0001 八步法
//变量定义
unsigned char st[]={0x09,0x08,0x0C,0x04,0x06,0x02,0x03,0x01};
unsigned int flag0=0,flag1=0;//按键按下标志位
unsigned int IN1=1,OUT1=0;//先定义一下让电机处于反操结束状态
unsigned int num0=0,num1=0;
//函数声明
void stepper0();
void stepper1();
void key_detection0();
void key_detection1();
void delay(unsigned int n);
//延时函数定义
void delay(unsigned int n)
{
unsigned i=0,j=0;
for(i=0;i<n;i++)
{
for(j=0;j<120;j++);
}
}
//主函数
int main()
{
while(1)
{
if(IN1==1&&OUT1==0)
{
key_detection0();
stepper0();
}
if(IN1==0&&OUT1==1)
{
key_detection1();
stepper1();
}
}
}
void key_detection0()
{
if(KEY0==0&&flag0==0)//判断按键是否反操
{
flag0=1;
num0++;
}
if(KEY0==1&&flag0==1)
{
IN1=1;
OUT1=0;
flag0=0;
}
if(KEY1==0||KEY0==1)//如果按下正操按键则保持原状态
{
P2=0x00;
IN1=0;
OUT1=1;
}
}
void key_detection1()
{
if(KEY1==0&&flag1==0)//判断按键是否正操
{
flag1=1;
num1++;
}
if(KEY1==1&&flag1==1)
{
IN1=0;
OUT1=1;
flag1=0;
}
if(KEY0==0||KEY1==1)//如果按下反操按键则保持原状态
{
P2=0x00;
IN1=1;
OUT1=0;
}
}
//反操
void stepper0()
{
int a0=0,x0=0;
if(IN1==1&&OUT1==0&&num0%2==1)
{
while(x0<3)
{
for(a0=0;a0<8;a0++)
{
P2=st[a0];
delay(100);
if(a0==8)
{
a0=0;
}
if(a0==0)
{
x0++;
}
}
}
//反操结束标志
P2=0x00;
LED0=1;
LED1=0;
OUT1=1;
IN1=0;
}
}
//正操
void stepper1()
{
int a1=7,x1=0;
if(IN1==0&&OUT1==1&&num1%2==1)
{
while(x1<3)
{
for(a1=7;a1>0;a1--)
{
P2=st[a1];
delay(100);
if(a1==0)
{
a1=7;
}
if(a1==7)
{
x1++;
}
}
}
//正操结束标志
P2=0x00;
LED0=0;
LED1=1;
OUT1=0;
IN1=1;
}
}
这次的代码还是很冗余,重复的功能很多直接复制粘贴,相比之前的代码这次的逻辑上加深了一点点,还是有没解决的问题比如按下反操按键后第二次必须按下正操才能运转。先写一个简单的程序吧慢慢完善起来
结语
学习到了步进电机的相关知识,尽管了解较浅仅仅知道步进电机的使用方法。程序还需要完善一下,逻辑和长度方面要改善。后期老师上到这里再来修改博客了