大家好,又见面了,我是你们的朋友全栈君。
步进电机正反转设计
设计要求:
设置开始、停止以及正反转键。转速以及转向由数码管显示。
#include <reg52.h>
/* 步进电机正反转设计 设计要求: 设置开始、停止以及正反转键。转速以及转向由数码管显示。 步距角=5.625°/64,其意思就是每64个脉冲步进电机就会转5.625度。 转一圈的脉冲数为 (360 / 5.625) * 64 = 4096 个脉冲 计算发送 4096/4 个脉冲需要的时间t 转速 = 1/t*4 rad/s 注意:这里由于实际开发板驱动能力不足及电机性能不够,在此显示转速的导数 即转一圈需要多少时间 单位s/rad */
/* 参考资料:https://www.bilibili.com/read/cv11379422/ https://blog.csdn.net/wuhenyouyuyouyu/article/details/51612073 https://blog.csdn.net/sdkdlwk/article/details/106573784 https://blog.csdn.net/weixin_54092701/article/details/113484193 */
#define uc unsigned
unsigned char code F_Rotation[8]={
0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08};//正转表格
unsigned char code B_Rotation[8]={
0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09};//反转表格 1000 1100 1011
uc code x[13]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
0x6f,0x80,0x00,0x40}; // 小数点 全隐 负号
int shumaguan[8]={
0}; // 第一位定义为mod 模式选择
//mod x x z . z z z
// mod 0 (停止)
// mod 1 (开始) k2 正转 k3 反转 k4 停止
// mod 2 (开始) k2 加速 k3 减速 k4 停止
// C51 没有bool
bit is_action = 0; //是否开始旋转
bit correct = 1; //1 正转 0 反转
int hz = 150;
sbit k1 = P3^1; //模式选择 按下时 mod+1
sbit k2 = P3^0;
sbit k3 = P3^2;
sbit k4 = P3^3;
sbit lsa = P2^2;
sbit lsb = P2^3;
sbit lsc = P2^4;
int num = 0; //计算发送的脉冲数
int time = 0;
int mod = 0;
float zhuansu = 0;
void delayms(int xms)//延时
{
unsigned int x,y;
for(x=xms;x>0;x--)
for(y=110;y>0;y--);
}
void delay10um(int h) //延时10*h us
{
while(h--);
}
// 数码管动态显示
void display()
{
uc i;
if(correct == 0) //反转
{
shumaguan[2] = 12; //显示负号
}
else
{
shumaguan[2] = 11;
}
if(mod == 0) //停转
{
shumaguan[3] = 0;
shumaguan[5] = 0;
shumaguan[6] = 0;
shumaguan[7] = 0;
}
for(i=0;i<8;i++)
{
switch(7-i)
{
case (0): lsa=0,lsb=0;lsc=0;break;
case (4): lsa=0,lsb=0;lsc=1;break;
case (2): lsa=0,lsb=1;lsc=0;break;
case (6): lsa=0,lsb=1;lsc=1;break;
case (1): lsa=1,lsb=0;lsc=0;break;
case (5): lsa=1,lsb=0;lsc=1;break;
case (3): lsa=1,lsb=1;lsc=0;break;
case (7): lsa=1,lsb=1;lsc=1;break;
}
P0=x[shumaguan[i]];
delay10um(80);
P0=0x00;
}
}
//按键扫描函数
void scan()
{
if(!(k1 & k2 & k3 & k4 ) )
{
delayms(10);
if(!k1)
{
//mod +1
mod = mod + 1 ;
is_action = 1;
if(mod == 3)
{
mod = 0;
}
}
if(!k2)
{
is_action = 1;
if(mod == 1)
{
//正转
correct = 1;
}
if(mod == 2)
{
//加速
hz = hz - 10 ;
}
}
if(!k3)
{
if(mod == 1)
{
//反转
correct = 0;
}
if(mod == 2)
{
//减速
hz = hz + 10 ;
}
}
if(!k4)
{
//stop!
is_action = 0 ;
mod = 0;
}
}
while(!(k1 & k2 & k3 & k4 )) ;
shumaguan[0] = mod ;
}
void motor_zheng(void)
{
char i =0;
for(i=0;i<8;i++)
{
P1=F_Rotation[i]; //输出对应的相 可以自行换成反转表格
num++;
delay10um(hz); //改变这个参数可以调整电机转速
}
}
void motor_fan(void)
{
char i =0;
for(i=0;i<8;i++)
{
P1=B_Rotation[i]; //输出对应的相 可以自行换成反转表格
num++;
delay10um(hz); //改变这个参数可以调整电机转速
}
}
void xuanzhuan()
{
if(correct == 1) //正转
{
motor_zheng();
}
if(correct == 0) //反转
{
motor_fan();
}
}
//定时器0 初始化 用于精确计时
void tim0_init()
{
TMOD=0x01;//1.模式设置,00000001,采用的是定时器0,工作与式1(M1=0,M0=1)。
TH0=(65536-1000)/256; //2.定时器设置,每隔1毫秒发起一次中断。
TL0=(65536-1000)%256;
ET0=1; //3.开定时器0中断
EA = 1; //4.开总中断
TR0=1; //5.打开定时器
}
void jiexi(float t)
{
char ge=0,gef=0,shif=0,baif=0,qianf=0;
ge = t ;
gef = (t-ge)*10;
shif = (t*1000 - ge*1000- gef*100)/10;
baif = t*1000 - ge*1000- gef*100-shif*10;
shumaguan[3] = ge;
shumaguan[5] = gef;
shumaguan[6] = shif;
shumaguan[7] = baif;
}
void main()
{
tim0_init();
shumaguan[4] = 10;
shumaguan[1] = 11;
while(1)
{
scan();
display();
if(is_action != 0)
{
xuanzhuan();
}
}
}
void timer_0() interrupt 1 //?
{
TH0=(65536-1000)/256; //进入中断要重新设置定时器处置,要注意。
TL0=(65536-1000)%256;
time++ ; //1ms 进入一次中断
if(num == 1024)
{
num = 0;
zhuansu = 4*time/1000.0;
time = 0;
jiexi(zhuansu);
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138419.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...