帮忙写一个单片机控制直流电机和舵机的程序

帮忙写一个单片机控制直流电机和舵机的程序,第1张

#include<reg52h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#define KeyPort P3

#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换

sbit LATCH1=P2^2;//定义锁存使能端口 段锁存

sbit LATCH2=P2^3;// 位锁存

sbit DCOUT1 = P1^1;//定义电机信号输出端口1

sbit DCOUT2 = P1^2;//定义电机信号输出端口2

unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9

unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码

unsigned char TempData[8]; //存储显示值的全局变量

/------------------------------------------------

函数声明

------------------------------------------------/

void DelayUs2x(unsigned char t);//us级延时函数声明

void DelayMs(unsigned char t); //ms级延时

void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数

unsigned char KeyScan(void);//键盘扫描

void Init_Timer0(void);//定时器初始化

/------------------------------------------------

主函数

------------------------------------------------/

void main (void)

{

unsigned char num;

Init_Timer0(); //初始化定时器0,主要用于数码管动态扫描

TempData[0]=0x5E; //'d'

TempData[1]=0x39; //'C'

TempData[2]=0x06; //'1'

TempData[5]=0x5E; //'d'

TempData[6]=0x39; //'C'

TempData[7]=0x5b; //'2'

while (1) //主循环

{

num=KeyScan(); //循环调用按键扫描

switch(num)

{

//电机1改变运行状态,数码管显示运行状态

case 1:DCOUT1=!DCOUT1;

TempData[0]=0x5E; //'d'

TempData[1]=0x39; //'C'

TempData[2]=0x06; //'1'

if(DCOUT1)

{

TempData[5]=0x3F; //'O'

TempData[6]=0x54; //'n'

TempData[7]=0;

}

else

{

TempData[5]=0x3F; //'O'

TempData[6]=0x71; //'F'

TempData[7]=0x71; //'F'

}

break;

//电机2改变运行状态,数码管显示运行状态

case 2:DCOUT2=!DCOUT2;

TempData[0]=0x5E; //'d'

TempData[1]=0x39; //'C'

TempData[2]=0x5B; //'2'

if(DCOUT2)

{

TempData[5]=0x3F; //'O'

TempData[6]=0x54; //'n'

TempData[7]=0;

}

else

{

TempData[5]=0x3F; //'O'

TempData[6]=0x71; //'F'

TempData[7]=0x71; //'F'

}

break;

default:break;

}

}

}

/------------------------------------------------

uS延时函数,含有输入参数 unsigned char t,无返回值

unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编,大致延时

长度如下 T=tx2+5 uS

------------------------------------------------/

void DelayUs2x(unsigned char t)

{

while(--t);

}

/------------------------------------------------

mS延时函数,含有输入参数 unsigned char t,无返回值

unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编

------------------------------------------------/

void DelayMs(unsigned char t)

{

while(t--)

{

//大致延时1mS

DelayUs2x(245);

DelayUs2x(245);

}

}

/------------------------------------------------

显示函数,用于动态扫描数码管

输入参数 FirstBit 表示需要显示的第一位,如赋值2表

示从第三个数码管开始显示,如输入0表示从第一个显示。

Num表示需要显示的位数,如需要显示99两位数值则该值

输入2

------------------------------------------------/

void Display(unsigned char FirstBit,unsigned char Num)

{

static unsigned char i=0;

DataPort=0; //清空数据,防止有交替重影

LATCH1=1; //段锁存

LATCH1=0;

DataPort=dofly_WeiMa[i+FirstBit]; //取位码

LATCH2=1; //位锁存

LATCH2=0;

DataPort=TempData[i]; //取显示数据,段码

LATCH1=1; //段锁存

LATCH1=0;

i++;

if(i==Num)

i=0;

}

/------------------------------------------------

定时器初始化子程序

------------------------------------------------/

void Init_Timer0(void)

{

TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响

//TH0=0x00; //给定初值

//TL0=0x00;

EA=1; //总中断打开

ET0=1; //定时器中断打开

TR0=1; //定时器开关打开

}

/------------------------------------------------

定时器中断子程序

------------------------------------------------/

void Timer0_isr(void) interrupt 1

{

TH0=(65536-2000)/256; //重新赋值 2ms

TL0=(65536-2000)%256;

Display(0,8); // 调用数码管扫描

}

pw1=1;

while(num!=Servo1_loop_num); /电机运行直到num=Servo1_loop_num/

pw1=0;

while(!(num==100)); /电机停止后一直等待num=100后才继续下面 *** 作/

首先开明白你的舵机控制原理,它要求输入的脉冲期是20ms,其中高电平在15ms时舵臂在0位

在20ms时舵臂在右90度位 在15ms时舵臂在左90度位 舵机有3根线,一根线是电源正,另一根电源负,还有一根(一般为白线)是控制线,就是输入的脉冲信号的

程序中可以用两个定时器,一个定时20ms,另外一个定时1到2ms可变,就可以让舵机动作

下面程序供参考,先不考虑按键问题,能让舵机动作就 成功一大半

/双定时器产生PWM波,控制舵机

//定时器0负责置高电平和控制定时器1的开停,定时器1负责置低电平

#include<STC12C5AH>

#define uchar unsigned char

#define uint unsigned int

sbit PWM=P3^7;//经试验,此引脚信号可以直接送舵机不用放大

uchar b=1500;//定时15ms的初值

void Delay1ms(uint i) //1ms延时程序

{

uint j;

for(;i>0;i--)

{

for(j=0;j<125;j++)

{;}

}

}

void main()

{

b=1500;

TMOD=0X11;

TH0=(65536-20000)/256;

TL0=(65536-20000)%256;

TH1=(65536-b)/256;

TL1=(65536-b)%256;

ET0=1;

EA=1;

TR0=1;

PWM=1;

P1M0=0X0F; //低4位配置为推挽输出 ,普通51单片机无此寄存器

P1M1=0X00;

while(1)

{

P1=0; //这是让行走电机正向转动的,用的是L298N模块

b=1500;Delay1ms(2000);//直行

b=1000;Delay1ms(1000);//左转

b=1500;Delay1ms(2000);//直行

b=2000;Delay1ms(1000);//右转

b=1500;Delay1ms(2000);//直行

P1=0x05;//这是让行走电机反向转动的

b=1500;Delay1ms(2000);//后退

b=1000;Delay1ms(1000);//后左转

b=1500;Delay1ms(2000);//后退

b=2000;Delay1ms(1000);//后右转

b=1500;Delay1ms(2000);//后退

}

}

void timer0()interrupt 1//定时器0中断

{

TH0=(65536-20000)/256;

TL0=(65536-20000)%256;

PWM=1;

TR1=1;

ET1=1;

}

void timer1()interrupt 3//定时器1中断

{

TH1=(65536-b)/256;//改变b的值就可转向

TL1=(65536-b)%256;

PWM=0;

TR1=0;

ET1=0;

}

VisionPro可以通过串口或者IO口控制舵机,具体步骤如下:

1 选择合适的舵机控制模块,比如常用的舵机驱动板,该板可以将串口信号转换为舵机控制信号。

2 在VisionPro中编写程序,通过串口或者IO口控制舵机。例如,如果您使用舵机驱动板,可以使用串口发送指令,驱动板会自动将指令转换为舵机控制信号。如果您使用IO口控制舵机,可以使用VisionPro内置的IO控制命令,将IO口输出高电平或低电平,从而控制舵机的方向和角度。

3 在程序中设置舵机的角度或者位置。可以使用VisionPro提供的命令或者函数来设置舵机的角度或者位置,例如"SetServoPosition"或者"SetServoAngle"等。

4 调试和优化程序。在测试舵机控制程序时,需要注意调试和优化程序,确保舵机能够按照预期的角度或者位置运动。可以使用调试工具或者示波器等设备来检查舵机控制信号的波形和参数,以确定参数设置是否正确。

需要注意的是,在控制舵机时,需要谨慎 *** 作,以免对舵机或者其他设备造成损坏。同时,舵机的角度或者位置控制也需要根据实际的应用需求进行调整和优化,以实现最佳的控制效果。

可以用任意一个IO引脚和舵机连接,程序上,用两个定时器,定时器1定时20ms,中断时让IO管脚输出高电平,并启动定时器2,定时器2定时15至25ms,对应舵机的角度,中断时让该管脚输出低电平,并关闭自身。改变定时器2的定时时间,即改变了舵机的转角。

以上就是关于帮忙写一个单片机控制直流电机和舵机的程序全部的内容,包括:帮忙写一个单片机控制直流电机和舵机的程序、提高分求助。我有一个单片机控制四个舵机的程序。请各位帮我解释一下程序,我看不太明白。、那个大神帮写一个89c52rc单片机控制9g舵机程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9692671.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存