智能小车舵机转向程序

智能小车舵机转向程序,第1张

#include<reg52h>

#define uint unsigned int

#define uchar unsigned char

uint count;

uchar jd;

sbit le1=P1^0; //光电传感器//

sbit PWM=P3^5; //舵机pwm//

init()

{

TMOD=0x01;//设定定时器

TH0 = 0xFE;

TL0 = 0x0c;//设定定时初始值

EA=1;

ET0=1;

TR0=1;

}

void delay(uint z) //延时

{

uint x,y;

for(x=z;x>0;x--)

for(y=125;y>0;y--);

}

void timer0() interrupt 1 //产生pwm信号控制舵机,周期20ms

{

TH0 = 0xFE;

TL0 = 0x0c; //设定定时初始值

if(count<jd) //判断05ms次数是否小于角度标识

{

PWM=1; //确定小于,pwm输出高电平

// delay(180); //延时一会,可以减慢舵机转速

}

else

PWM=0; //大于则输出低电平

count=count+1; //05ms次数加1

count=count%40; //次数始终保持为40即保持周期为20ms

}

void xunji() //循迹函数,读取光电管状态

{

if(le1!=0)

{

delay(10);

if(le1==0)

{

jd++;

count=0;

while(le1==0);

}

} //分析光电管状态,看你的电路检测到黑线输出1或者是0

else

{

count=0;

jd=3; //舵机归中

}

}

void main()

{

jd=3; //角度初始化90°: 1=05ms 舵机为0° 2=1ms 舵机为45°3、4、5、同上

count=0; //初始化赋值零

init(); //定时器初始化

while(1)

{

xunji(); //舵机检测

}

}

这个应该是通过串口发送数据信息的,发送和接收在一根信号线上,手上没有现成的程序,你看看这个在其他网上的行不行,

最好根据手册自己写

#include <avr/ioh>

#include <util/delayh>

void InitUart0(void)

{

UCSR0A = 0x02; // 设置为倍速模式

UBRR0H = 0;

UBRR0L = 1;

UCSR0B = (1<<RXEN)|(1<<TXEN);// 接收器与发送器使能

UCSR0C = (3<<UCSZ0);

DDRE &= ~_BV(PE0); // 初始化RX 端口默认方向为输入

PORTE &= ~_BV(PE0); // 初始化RX 端口默认状态为高阻

DDRE |= _BV(PE1); // 初始化TX 端口默认方向为输出

PORTE |= _BV(PE1); // 初始化TX 端口默认状态为高电平

DDRA |= _BV(PA0); // 初始化使能端口状态方向为输出

PORTA &= ~_BV(PA0); // 初始化使能端口状态为RX 状态

DDRA |= _BV(PA1); // 初始化使能端口状态方向为输出

PORTA |= _BV(PA1); // 初始化使能端口状态方为TX 状态

}

void SendUart0Byte(unsigned char data)

{

while ( !( UCSR0A & (1<<UDRE)) );// 等待发送缓冲器为空

UDR0 = data;/ 将数据放入缓冲器,发送数据/

}

void SetServoLimit(unsigned char id, unsigned short int cw_limit, unsigned short int ccw_limit)

{

unsigned short int temp_ccw = 0; // 临时速度,用于进行方向判别

unsigned short int temp_cw = 0;

unsigned char temp_ccw_h = 0; // 待发送数据h 位

unsigned char temp_ccw_l = 0; // 待发送数据l 位

unsigned char temp_cw_h = 0;

unsigned char temp_cw_l = 0;

unsigned char temp_sum = 0; // 校验和寄存变量

if (ccw_limit > 1023)

{

temp_ccw = 1023; // 限制速度值在可用范围内

}

else

{

temp_ccw = ccw_limit;

}

if (cw_limit > 1023)

{

temp_cw = 1023;

}

else

{

temp_cw = cw_limit;

}

temp_ccw_h = (unsigned char)(temp_ccw >> 8);

temp_ccw_l = (unsigned char)temp_ccw; // 将16bit 数据拆为2个8bit 数据

temp_cw_h = (unsigned char)(temp_cw >> 8);

temp_cw_l = (unsigned char)temp_cw; // 将16bit 数据拆为2个8bit 数据

PORTA &= ~_BV(PA1);

PORTA |= _BV(PA0); // 使总线处于主机发送状态

UCSR0A |= (1<<TXC0); // 清除UART0写完成标志

SendUart0Byte(0xFF); // 发送启动符号0xFF

SendUart0Byte(0xFF); // 发送启动符号0xFF

SendUart0Byte(id); // 发送id

SendUart0Byte(7); // 发送数据长度为参数长度+2,参数长度为3

SendUart0Byte(0x03); // 命令数据为“WRITE DATA”

SendUart0Byte(0x06); // 舵机控制寄存器首地址

SendUart0Byte(temp_cw_l); // 发送顺时针位置限制低位

SendUart0Byte(temp_cw_h); // 发送顺时针位置限制高位

SendUart0Byte(temp_ccw_l); // 发送逆时针位置限制低位

SendUart0Byte(temp_ccw_h); // 发送逆时针位置限制高位

temp_sum = id + 7 + 0x03 + 0x06 + temp_cw_l + temp_cw_h + temp_ccw_l + temp_ccw_h;

temp_sum = ~temp_sum; // 计算校验和

SendUart0Byte(temp_sum); // 发送校验和

while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成

{ // (Waiting for finishing sending)

;

}

PORTA |= _BV(PA1);

PORTA &= ~_BV(PA0); // 使总线处于主机接收状态

_delay_ms(2); //送完成后,总线会被从机占用,反馈应答数据,所以进行延时

}

void SetServoPosition(unsigned char id, unsigned short int position, unsigned short int

velocity)

{

unsigned short int temp_velocity = 0; // 临时速度,用于进行方向判别

unsigned short int temp_position = 0;

unsigned char temp_velocity_h = 0; // 待发送数据h 位

unsigned char temp_velocity_l = 0; // 待发送数据l 位

unsigned char temp_position_h = 0;

unsigned char temp_position_l = 0;

unsigned char temp_sum = 0; // 校验和寄存变量

if (velocity > 1023)

{

temp_velocity = 1023; // 限制速度值在可用范围内

}

else

{

temp_velocity = velocity;

}

if (position > 1023)

{

temp_position = 1023;

}

else

{

temp_position = position;

}

temp_velocity_h = (unsigned char)(temp_velocity >> 8);

// 将16bit 数据拆为2个8bit 数据

temp_velocity_l = (unsigned char)temp_velocity;

temp_position_h = (unsigned char)(temp_position >> 8);

// 将16bit 数据拆为2个8bit 数据

temp_position_l = (unsigned char)temp_position;

PORTA &= ~_BV(PA1);

PORTA |= _BV(PA0); // 使总线处于主机发送状态

UCSR0A |= (1<<TXC0); // 清除UART0写完成标志

SendUart0Byte(0xFF); // 发送启动符号0xFF

SendUart0Byte(0xFF);

SendUart0Byte(id); // 发送id

SendUart0Byte(7); // 发送数据长度为参数长度+2,参数长度为3

SendUart0Byte(0x03); // 命令数据为“WRITE DATA”

SendUart0Byte(0x1E); // 舵机控制寄存器首地址

SendUart0Byte(temp_position_l); // 发送速度数据低位

SendUart0Byte(temp_position_h); // 发送速度数据高位

SendUart0Byte(temp_velocity_l); //发送位置低字节

SendUart0Byte(temp_velocity_h); // 发送位置高字节

temp_sum = id + 7 + 0x03 + 0x1E + temp_position_l + temp_position_h + temp_velocity_l +

temp_velocity_h;

temp_sum = ~temp_sum; // 计算校验和

SendUart0Byte(temp_sum); // 发送校验和 (Send the checksum)

while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成

{ // (Waiting for finishing sending)

;

}

PORTA |= _BV(PA1);

PORTA &= ~_BV(PA0); // 使总线处于主机接收状态

_delay_ms(2); // 发送完成后,总线会被从机占用,反馈应答数据,所以进行延时

}

void SetServoVelocity(unsigned char id, signed short int velocity)

{

unsigned char temp_sign = 0; // 临时符号,用于进行方向判别

unsigned short int temp_velocity = 0; // 临时速度,用于进行方向判别

unsigned char temp_value_h = 0; // 待发送数据h 位

unsigned char temp_value_l = 0; // 待发送数据l 位

unsigned char temp_sum = 0; // 校验和寄存变量

if (velocity < 0)

{

temp_velocity = -velocity; // 如果为负数,则取绝对值

temp_sign = 1; // 设置负数符号标志

}

else

{

temp_velocity = velocity;

temp_sign = 0; // 设置正数符号标志

}

if (temp_velocity > 1023)

{

temp_velocity = 1023; // 限制速度值在可用范围内

}

temp_velocity |= (temp_sign << 10);

temp_value_h = (unsigned char)(temp_velocity >> 8);

// 将16bit 数据拆为2个8bit 数据

temp_value_l = (unsigned char)temp_velocity;

PORTA &= ~_BV(PA1);

PORTA |= _BV(PA0); // 使总线处于主机发送状态

UCSR0A |= (1<<TXC0); // 清除UART0写完成标志

SendUart0Byte(0xFF); // 发送启动符号0xFF

SendUart0Byte(0xFF); // 发送启动符号0xFF

SendUart0Byte(id); // 发送id

SendUart0Byte(5); // 发送数据长度为参数长度+2,参数长度为3

SendUart0Byte(0x03); // 命令数据为“WRITE DATA”

SendUart0Byte(0x20); // 舵机控制寄存器首地址

SendUart0Byte(temp_value_l); // 发送速度数据低位

SendUart0Byte(temp_value_h); // 发送速度数据高位

temp_sum = id + 5 + 0x03 + 0x20 + temp_value_l + temp_value_h;

temp_sum = ~temp_sum; // 计算校验和

SendUart0Byte(temp_sum); // 发送校验和

while ( !( UCSR0A & (1<<TXC0)) ) // 等待发送完成

{

;

}

PORTA |= _BV(PA1);

PORTA &= ~_BV(PA0); // 使总线处于主机接收状态

_delay_ms(2); // 发送完成后,总线会被从机占用,反馈应答数据,所以进行延时

}

int main(void)

{

InitUart0();

SetServoLimit(2,0,1023);

while(1)

{

_delay_ms(1000); //延时1s

SetServoPosition(2, 1000, 500); //控制舵机以500的速度运动到1000的位置

_delay_ms(1000); //延时1s

SetServoPosition(2, 200, 100); //控制舵机以100的速度运动到200的位置

}

}

//12MHz

#include <reg51h>

void InitTimer0(void)

{

TMOD = 0x01;

TH0 = 0x0B1;

TL0 = 0x0E0;

EA = 1;

ET0 = 1;

TR0 = 1;

}

void delay(void) //误差 0us 延时1ms 此处可以修改高电平周期

//修改此处的延时可以更改舵机转的角度 ,45度具体是多少 你可以试试

{

unsigned char a,b,c;

for(c=1;c>0;c--)

for(b=142;b>0;b--)

for(a=2;a>0;a--);

}

void main(void)

{

InitTimer0();

P1_2=0;

while(1);

}

void Timer0Interrupt(void) interrupt 1

{

//20ms中断

TH0 = 0x0B1;

TL0 = 0x0E0;

P1_2=1;

delay();

P1_2=0;

}

以上就是关于智能小车舵机转向程序全部的内容,包括:智能小车舵机转向程序、求stm32控制四自由度舵机的程序、单片机控制舵机程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/9481283.html

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

发表评论

登录后才能评论

评论列表(0条)

保存