6个回答
展开全部
这是我自己做过的。源码都给你了
#include<reg52.h>
#include<intrins.h>
#include<absacc.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
uint count; //当前计数值
uint distance;
bit intt=1;
unsigned char cont=0;
unsigned char co=0;
uchar buf;
//uchar m,lm,cm;
/**************针脚定义************/
sbit rect_wave=P2^0; //晶振控制信号
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^2;
sbit CLR=P1^3;
sbit DATA=P1^4;
sbit CLK=P1^5;
sbit d=P2^1;
sbit cp=P2^2;
sbit dir=P2^3;
/***********************************/
/**************函数声明************/
void time0over(void); //定时器计时程序
void clrlcd(void); //clr LCD
void c_send(unsigned char y); //发命令
void reset(void); // reset LCD
void d_send(unsigned char x); //发数据
void pos(unsigned char pos); //设定显示位置
void l_delay(unsigned int t); //长延时
void trans(j);
void ret(void); //初始化系统
void retcont(void); //定时器复位
void math(void); //计算测量距离
/***************************/
void init(void)
{ TH1=0xf3;
TL1=0xf3;
PCON=0x80;
TR1=1;
SCON=0x50; /*串口初始化设置,波特率4800BPS*/
}
//*******************************//
void send(uchar dat) /*发送子程序*/
{ //uchar i;
/*发送一个数据*/
SBUF=dat;
while(TI==0);
TI=0;
}
/***********************************/
void turn (void) //电机转动控制
{
unsigned char x;
cont++;
cp=~cp;
l_delay(50);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
if (cont == 200) //判断是否进行反转复位
{dir=~dir;
cont=0;
for(x=0;x < 200;x++)
{cp=~cp;
l_delay(5);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
}
dir=~dir;
cont=0;
}
}
/**************子程序**********************/
void int0 () interrupt 0 //中断0服务程序
{
EX0=0; //关闭中断
TR0=0; //关闭定时器
TF0=0; //标志位清零
rect_wave=0; //停止发送超声波
intt=0;
}
void work(void)
{
if(!intt)
{
intt=1;
if (distance < 400)
{
buf=distance;
send(buf);
turn();
math();} //计算所测得的距离
l_delay(5); //延时
retcont(); //定时器复位
rect_wave=1;
count=0;
}
}
void math(void) //计算所测得的距离
{ uchar m,lm,cm;
cm=distance%10; //取距离的最低位
distance=distance/10; //取距离的次高位
lm=distance%10;
distance=distance/10; //取距离的最高位
m=distance%10;
clrlcd(); //输出计算结果
pos(0);
d_send('d');
d_send('i');
d_send('s');
d_send('=');
//pos(4);
d_send(m+0x30);
d_send(lm+0x30);
d_send(cm+0x30);
d_send('c');
d_send('m');
l_delay(500);
}
void time0over(void) //定时器计时程序
{ TF0=0;
count++;
distance=count;
}
/*
void trans(j)
{
switch(j)
{
case 0: d_send('0');break;
case 1: d_send('1');break;
case 2: d_send('2');break;
case 3: d_send('3');break;
case 4: d_send('4');break;
case 5: d_send('5');break;
case 6: d_send('6');break;
case 7: d_send('7');break;
case 8: d_send('8');break;
case 9: d_send('9');break;
}
}
*/
delay() //延时
{
int i;
for(i=0;i<1000;i++);
}
void l_delay(unsigned int t) //延时
{
unsigned int p;
unsigned int j;
for(j=0;j<t;j++)
{
for(p=0;p<1000;p++);
}
}
void reset(void) // reset LCD
{
delay();
c_send(0x38);
c_send(0x01);
c_send(0x06);
c_send(0x0c);
c_send(0x80);
}
void clrlcd(void) // clr LCD
{
delay();
c_send(0x01);
}
void pos(unsigned char pos) //设定显示位置
{
c_send(pos | 0x80);
}
void c_send(unsigned char y) //发命令
{
unsigned char i;
EN=1;
RS=0;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(y,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void d_send(unsigned char x) //发数据
{
unsigned char i;
EN=1;
RS=1;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(x,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void ret(void) //初始化计数器
{ TMOD=0x22; //设置定时器计数器1为工作方式2
TH0=0xc6; //设置计数初值高字节
TL0=0xc6; //设置计数初值低字节
count=0;
IE=0x00; //禁止中断
TF0=0; //溢出标志位清零
TR0=1; //打开定时器1
rect_wave=1;
EA=1; //打开中断
IP=0x01; //外部中断0为高中断优先级
IT0=0; //外部中断低电平触发シ?
EX0=1;
}
void retcont(void)
{ TF0=0; //溢出标志位清零
TR0=1; //打开定时器1
EA=1; //打开中断
IP=0x01; //外部中断0为高中断优先级
IT0=0; //外部中断下降沿触发
EX0=1;
rect_wave=1;
}
/**************主程序************/
void main(void)
{ rect_wave=0;
reset();
l_delay(10);
ret();
init();
math();
for(;;)
{
if(TF0)
{
time0over();
}
work();
}
}
#include<reg52.h>
#include<intrins.h>
#include<absacc.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
uint count; //当前计数值
uint distance;
bit intt=1;
unsigned char cont=0;
unsigned char co=0;
uchar buf;
//uchar m,lm,cm;
/**************针脚定义************/
sbit rect_wave=P2^0; //晶振控制信号
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^2;
sbit CLR=P1^3;
sbit DATA=P1^4;
sbit CLK=P1^5;
sbit d=P2^1;
sbit cp=P2^2;
sbit dir=P2^3;
/***********************************/
/**************函数声明************/
void time0over(void); //定时器计时程序
void clrlcd(void); //clr LCD
void c_send(unsigned char y); //发命令
void reset(void); // reset LCD
void d_send(unsigned char x); //发数据
void pos(unsigned char pos); //设定显示位置
void l_delay(unsigned int t); //长延时
void trans(j);
void ret(void); //初始化系统
void retcont(void); //定时器复位
void math(void); //计算测量距离
/***************************/
void init(void)
{ TH1=0xf3;
TL1=0xf3;
PCON=0x80;
TR1=1;
SCON=0x50; /*串口初始化设置,波特率4800BPS*/
}
//*******************************//
void send(uchar dat) /*发送子程序*/
{ //uchar i;
/*发送一个数据*/
SBUF=dat;
while(TI==0);
TI=0;
}
/***********************************/
void turn (void) //电机转动控制
{
unsigned char x;
cont++;
cp=~cp;
l_delay(50);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
if (cont == 200) //判断是否进行反转复位
{dir=~dir;
cont=0;
for(x=0;x < 200;x++)
{cp=~cp;
l_delay(5);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
}
dir=~dir;
cont=0;
}
}
/**************子程序**********************/
void int0 () interrupt 0 //中断0服务程序
{
EX0=0; //关闭中断
TR0=0; //关闭定时器
TF0=0; //标志位清零
rect_wave=0; //停止发送超声波
intt=0;
}
void work(void)
{
if(!intt)
{
intt=1;
if (distance < 400)
{
buf=distance;
send(buf);
turn();
math();} //计算所测得的距离
l_delay(5); //延时
retcont(); //定时器复位
rect_wave=1;
count=0;
}
}
void math(void) //计算所测得的距离
{ uchar m,lm,cm;
cm=distance%10; //取距离的最低位
distance=distance/10; //取距离的次高位
lm=distance%10;
distance=distance/10; //取距离的最高位
m=distance%10;
clrlcd(); //输出计算结果
pos(0);
d_send('d');
d_send('i');
d_send('s');
d_send('=');
//pos(4);
d_send(m+0x30);
d_send(lm+0x30);
d_send(cm+0x30);
d_send('c');
d_send('m');
l_delay(500);
}
void time0over(void) //定时器计时程序
{ TF0=0;
count++;
distance=count;
}
/*
void trans(j)
{
switch(j)
{
case 0: d_send('0');break;
case 1: d_send('1');break;
case 2: d_send('2');break;
case 3: d_send('3');break;
case 4: d_send('4');break;
case 5: d_send('5');break;
case 6: d_send('6');break;
case 7: d_send('7');break;
case 8: d_send('8');break;
case 9: d_send('9');break;
}
}
*/
delay() //延时
{
int i;
for(i=0;i<1000;i++);
}
void l_delay(unsigned int t) //延时
{
unsigned int p;
unsigned int j;
for(j=0;j<t;j++)
{
for(p=0;p<1000;p++);
}
}
void reset(void) // reset LCD
{
delay();
c_send(0x38);
c_send(0x01);
c_send(0x06);
c_send(0x0c);
c_send(0x80);
}
void clrlcd(void) // clr LCD
{
delay();
c_send(0x01);
}
void pos(unsigned char pos) //设定显示位置
{
c_send(pos | 0x80);
}
void c_send(unsigned char y) //发命令
{
unsigned char i;
EN=1;
RS=0;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(y,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void d_send(unsigned char x) //发数据
{
unsigned char i;
EN=1;
RS=1;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(x,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void ret(void) //初始化计数器
{ TMOD=0x22; //设置定时器计数器1为工作方式2
TH0=0xc6; //设置计数初值高字节
TL0=0xc6; //设置计数初值低字节
count=0;
IE=0x00; //禁止中断
TF0=0; //溢出标志位清零
TR0=1; //打开定时器1
rect_wave=1;
EA=1; //打开中断
IP=0x01; //外部中断0为高中断优先级
IT0=0; //外部中断低电平触发シ?
EX0=1;
}
void retcont(void)
{ TF0=0; //溢出标志位清零
TR0=1; //打开定时器1
EA=1; //打开中断
IP=0x01; //外部中断0为高中断优先级
IT0=0; //外部中断下降沿触发
EX0=1;
rect_wave=1;
}
/**************主程序************/
void main(void)
{ rect_wave=0;
reset();
l_delay(10);
ret();
init();
math();
for(;;)
{
if(TF0)
{
time0over();
}
work();
}
}
德晟智能
2024-09-04 广告
2024-09-04 广告
舵机伺服电机是一种在自动控制系统中广泛应用的执行元件。它具有快速响应、精准定位的特点,能够将电压信号转化为转矩和转速,以驱动控制对象。在东莞市德晟智能科技有限公司的产品中,舵机伺服电机扮演着重要的角色,广泛应用于各种精密电子设备、交通运输工...
点击进入详情页
本回答由德晟智能提供
展开全部
但用单片机是不够的,关键是要有个专用的驱动芯片,驱动芯片含有每相电流检测,当收到单片机相位开关信号时打开电流通路,由电机电感形成三角波电流,到达电机额定电流即停止而维持等待下个相位信号,并且该芯片还有停转保持半电流控制脚等功能,具体可参考芯片资料,才能根据芯片功能编程,步进电机越转越快可通过单片机对相应相位脚发控制脉冲,使脉冲频率变快就可实现,但最高速度受给驱动芯片的主电源电压有关,电压低时电感中的三角波电流到不了额定就可能发生不同步。
如果带有电机控制器的,控制器只有步进输入脉冲脚,正反转控制脚,就可对控制器的这两脚控制,在步进输入脚脉冲加快就可使转速加快。
如果带有电机控制器的,控制器只有步进输入脉冲脚,正反转控制脚,就可对控制器的这两脚控制,在步进输入脚脉冲加快就可使转速加快。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
l298 可以控制两个电机的正反转 如果你不用调速的话那就相当简单了
程序例如:
input a ,input b,enable(这三个都是芯片引脚的名字) 分别用单片机的
p1.0 p1.1 p1.2控制 output a(引脚名字) 接电机
程序:
clr p1
setb p1.0
setb p1.1(正转)
clr p1
setb p1.1
setb p1.1 (反转)
另外:
电路图所在位置:
http://hi.baidu.com/tianhj2001/album/item/c0dc7d4fc718aed7d1c86a98.html
;文件名:DJ15-4.ASM
;程序功能:开关控制步进电机正反转
K1 EQU P3.2
K2 EQU P3.3
K3 EQU P3.4
STOP: MOV P0, #0FFH
LOOP: JNB K1, Z_M2
JNB K2, F_M2
JNB K3, STOP1
JMP LOOP
;-----------------------------
STOP1: ACALL DELAY
JNB K3, $
ACALL DELAY
JMP STOP
Z_M2: ACALL DELAY
JNB K1, $
ACALL DELAY
JMP Z_M
F_M2: ACALL DELAY
JNB K2, $
ACALL DELAY
JMP F_M
;---------------------------
Z_M: MOV R0,#00H
Z_M1: MOV A, R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
JZ Z_M
MOV P0,A
JNB K3, STOP1
JNB K2, F_M2
ACALL DELAY
INC R0
JMP Z_M1
RET
;-----------------------------
F_M: MOV R0,#05H
F_M1: MOV A, R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
JZ F_M
MOV P0,A
JNB K3, STOP1
JNB K1, Z_M2
ACALL DELAY
INC R0
JMP F_M1
RET
;-----------------------------
DELAY: MOV R1,#40
D1: MOV R2,#248
DJNZ R2,$
DJNZ R1,D1
RET
;-----------------------------
TABLE: DB 0FCH, 0F9H, 0F3H, 0F6H
DB 00
DB 0F7H, 0F3H, 0FBH, 0F9H
DB 0FDH, 0FCH, 0FEH, 0F6H
DB 00
;-------------------------------
END
参考资料:http://zhidao.baidu.com/question/78678249.html?
程序例如:
input a ,input b,enable(这三个都是芯片引脚的名字) 分别用单片机的
p1.0 p1.1 p1.2控制 output a(引脚名字) 接电机
程序:
clr p1
setb p1.0
setb p1.1(正转)
clr p1
setb p1.1
setb p1.1 (反转)
另外:
电路图所在位置:
http://hi.baidu.com/tianhj2001/album/item/c0dc7d4fc718aed7d1c86a98.html
;文件名:DJ15-4.ASM
;程序功能:开关控制步进电机正反转
K1 EQU P3.2
K2 EQU P3.3
K3 EQU P3.4
STOP: MOV P0, #0FFH
LOOP: JNB K1, Z_M2
JNB K2, F_M2
JNB K3, STOP1
JMP LOOP
;-----------------------------
STOP1: ACALL DELAY
JNB K3, $
ACALL DELAY
JMP STOP
Z_M2: ACALL DELAY
JNB K1, $
ACALL DELAY
JMP Z_M
F_M2: ACALL DELAY
JNB K2, $
ACALL DELAY
JMP F_M
;---------------------------
Z_M: MOV R0,#00H
Z_M1: MOV A, R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
JZ Z_M
MOV P0,A
JNB K3, STOP1
JNB K2, F_M2
ACALL DELAY
INC R0
JMP Z_M1
RET
;-----------------------------
F_M: MOV R0,#05H
F_M1: MOV A, R0
MOV DPTR, #TABLE
MOVC A,@A+DPTR
JZ F_M
MOV P0,A
JNB K3, STOP1
JNB K1, Z_M2
ACALL DELAY
INC R0
JMP F_M1
RET
;-----------------------------
DELAY: MOV R1,#40
D1: MOV R2,#248
DJNZ R2,$
DJNZ R1,D1
RET
;-----------------------------
TABLE: DB 0FCH, 0F9H, 0F3H, 0F6H
DB 00
DB 0F7H, 0F3H, 0FBH, 0F9H
DB 0FDH, 0FCH, 0FEH, 0F6H
DB 00
;-------------------------------
END
参考资料:http://zhidao.baidu.com/question/78678249.html?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
回答共分为3部分:
1.步进电机的驱动原理:切换每相电流及顺序,做到控制步进电机的目的。信号是脉冲信号,通过改变脉冲频率可以控制转速。
2.编程是要靠自己的,搞清楚电机资料,单片机资料。就可以了,做一次,很快就会成为单片机高手了。
1.步进电机的驱动原理:切换每相电流及顺序,做到控制步进电机的目的。信号是脉冲信号,通过改变脉冲频率可以控制转速。
2.编程是要靠自己的,搞清楚电机资料,单片机资料。就可以了,做一次,很快就会成为单片机高手了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
改变脉冲的顺序
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |