AVR控制20个舵机的程序

发布者:ww313618最新更新时间:2016-10-20 来源: eefocus关键字:AVR控制2  舵机 手机看文章 扫描二维码
随时随地手机看文章
/*AVR控制20个舵机的程序*/

 

 

#include    

#include    

#include "me.h"               //自定义的通用io简化位 

  

void timer0_init(void);   

void port_init(void);   

void init(void);   

void UART_init(void);           //串口初始化程序   

void UART_rx(void);             //串口接收中断函数   

void send_text(unsigned char *s);   //字符串发送函数   

void sendchar(unsigned char c);     //字符发送函数   

void dog_init(void);           //初始化看门狗   

  

unsigned char RX_data[4]={0};     //串口接收的数据   

unsigned char RX_counter=0;       //串口接收到的字节数计数器   

  

unsigned char pwm1,pwm2,pwm3,pwm4,pwm5,pwm6,pwm7,pwm8,pwm9,pwm10,pwm11,pwm12,pwm13,pwm14,pwm15,pwm16,pwm17,pwm18,pwm19,pwm20; //分别为20个pwm的值   

unsigned char count;           //pwm定位变量   

void main(void)   

{   

oSCCAL=0xAA;                 //系统时钟校准,不同的芯片和不同的频率   

init();   //?

  

  while(1)   

  {   

  WDR();                   //拼命喂狗   

    if(RX_counter==4)         //收到一个完整的命令信息   

    {   

      RX_counter=0;         //清除串口接收到的字节数计数器   

  

        if((RX_data[0]==''''''''S'''''''')&&(RX_data[3]==''''''''E''''''''))//判断头尾是不是符合   

        {     

            

          CLI();           //关闭中断,开始判断数据   

          switch(RX_data[1])   

          {   

            case 0x01:   

            pwm1=RX_data[2];   

            break;   

            case 0x02:   

            pwm2=RX_data[2];   

            break;   

            case 0x03:   

            pwm3=RX_data[2];   

            break;   

            case 0x04:   

            pwm4=RX_data[2];   

            break;   

            case 0x05:   

            pwm5=RX_data[2];   

            break;   

            case 0x06:   

            pwm6=RX_data[2];   

            break;   

            case 0x07:   

            pwm7=RX_data[2];   

            break;   

            case 0x08:   

            pwm8=RX_data[2];   

            break;   

            case 0x09:   

            pwm9=RX_data[2];             

            break;   

            case 0x0a:   

            pwm10=RX_data[2];   

            break;   

            case 0x0b:   

            pwm11=RX_data[2];   

            break;   

            case 0x0c:   

            pwm12=RX_data[2];   

            break;   

            case 0x0d:   

            pwm13=RX_data[2];   

            break;   

            case 0x0e:   

            pwm14=RX_data[2];   

            break;   

            case 0x0f:   

            pwm15=RX_data[2];   

            break;   

            case 0x10:   

            pwm16=RX_data[2];   

            break;   

            case 0x11:   

            pwm17=RX_data[2];   

            break;   

            case 0x12:   

            pwm18=RX_data[2];   

            break;   

            case 0x13:   

            pwm19=RX_data[2];   

            break;   

            case 0x14:   

            pwm20=RX_data[2];   

            break;   

            default:   

            SEI();           //错误时打开中断,以便发送错误信息   

            send_text("ER");   //范围超出20个pwm,就发出大写字母"ER"   

            break;   

            

            

          }     

          SEI();             //恢复中断允许   

          send_text("OK");     //判断处理完毕返回ok;   

        }   

    }   

  }   

}   

  

  

void init(void)   

{   

CLI(); //disable all interrupts   

port_init();   

timer0_init();   

TIMSK = 0x01; //定时器中断源   

UART_init();   

SEI(); //re-enable interrupts   

}   

  

  

void port_init(void)   

{   

PORTB = 0x00;   

DDRB = 0xFF;   

PORTC = 0x00;   

DDRC = 0x7F;   

PORTD = 0x00;   

DDRD = 0xFF;   

}   

  

  

void send_char(unsigned char c)     //发送单字符函数   

{   

  while (!(UCSRA&(1 << UDRE)));   //判断上次发送有没有完成   

  UDR = c;                 //发送数据   

}   

  

#pragma interrupt_handler UART_rx: iv_USART_RX //将串口接收中断,指给UART_rx   

/********************************************************   

通讯协议:S+PWM?+Volue+E   

标志说明:   S : 头标志   16进制:0x53   

标志说明: PWM? : PWM标号,?范围:0x01~0x14 指20个pwm输出   

标志说明: Volue: PWM占空比,范围0x00~0xff 关闭pwm则为0x00   

标志说明:   E : 结束标志 16进制:0x45   

其他说明: 完整一个数据占4个byte,头尾必须分别为S、E方为有效   

如果pwm位超出20个,返回字母ER;   

********************************************************/   

void UART_rx(void)                     //串口接收中断函数   

{   

  RX_data[RX_counter] = UDR;   

      

  if (RX_data[RX_counter]==''''''''S'''''''')         //纠正错位用,和RX_counter溢出。   

    {   

      RX_data[0]=RX_data[RX_counter];   

      RX_counter=0;   

    }   

      

  RX_counter++;                     //接收的字节数计数   

}   

  

  

void send_text(unsigned char *s)           //字符串发送函数   

{   

  while (*s)   

    {   

      send_char(*s);   

      s++;   

    }   

}   

    

  

void UART_init(void)                   //串口初始化程序   

{   

  UCSRB = BIT(RXCIE)| BIT(RXEN) |BIT(TXEN);   //允许串口发送和接收,并响应接收完成中断   

  UBRR = 51;                       //时钟8Mhz,波特率9600   

  UCSRC = BIT(URSEL)|BIT(UCSZ1)|BIT(UCSZ0);   //8位数据+1位stop位   

}   

  

  

/********************************************   

设计思路:舵机典型需要20mS的频率,即50Hz的频率   

为了实现8位的pwm精度,需将20mS的时间再平均分正   

256份,即78.125u秒,在一次中断的时候与目标定义   

需要的pwm占空比的值(pwm1~20)比较,判断io是否该   

输出0电平,如果不是则输出高电平   

目标中断时间: 78.125uSec (加上0.2%误差)   

实际中断时间: 78.000uSec   

如果想提高频率,只需要修改定时器的溢出时间   

如果想提高pwm的分辨率,则修改count的值   

********************************************/   

void timer0_init(void)         //定时器初始化程序   

{   

TCCR0 = 0x00;             //停止定时器   

TCNT0 = 0xB4;             //设置初始值   

TCCR0 = 0x02;             //开动定时器   

}   

  

#pragma interrupt_handler timer0_ovf_isr:10 //将定时器溢出中断指到timer0_ovf_isr中,好比汇编中的ORG   

void timer0_ovf_isr(void)     //定时器溢出中断程序   

{   

TCNT0 = 0xB4;             //从新调入初始值   

count++;                 //每中断一次加1   

if (count

{   

portc5_1;   

}else{                 //不是则输出0   

portc5_0;   

}   

  

if (count

{   

portc4_1;   

}else{   

portc4_0;   

}   

  

if (count

{   

portc3_1;   

}else{   

portc3_0;   

}   

  

if (count

{   

portc2_1;   

}else{   

portc2_0;   

}   

  

if (count

{   

portc1_1;   

}else{   

portc1_0;   

}   

  

if (count

{   

portc0_1;   

}else{   

portc0_0;   

}   

  

if (count

{   

portb5_1;   

}else{   

portb5_0;   

}   

  

if (count

{   

portb4_1;   

}else{   

portb4_0;   

}   

  

if (count

{   

portb3_1;   

}else{   

portb3_0;   

}   

  

if (count

{   

portb2_1;   

}else{   

portb2_0;   

}   

  

if (count

{   

portb1_1;   

}else{   

portb1_0;   

}   

  

if (count

{   

portd2_1;   

}else{   

portd2_0;   

}   

  

if (count

{   

portd3_1;   

}else{   

portd3_0;   

}   

  

if (count

{   

portd4_1;   

}else{   

portd4_0;   

}   

  

if (count

{   

portb6_1;   

}else{   

portb6_0;   

}   

  

if (count

{   

portb7_1;   

}else{   

portb7_0;   

}   

  

if (count

{   

portd5_1;   

}else{   

portd5_0;   

}   

  

if (count

{   

portd6_1;   

}else{   

portd6_0;   

}   

  

if (count

{   

portd7_1;   

}else{   

portd7_0;   

}   

  

if (count

{   

portb0_1;   

}else{   

portb0_0;   

}   

}   

  

  

void dog_init(void)   //看门狗初始化   

{   

WDR();     //看门狗计数清零   

WDTCR=0x0F; //使能看门狗,并且,采用2048分频,溢出时间5V时2.1S   

 

 

 

 

 

 

 

//定时器T0中断,向8253发送控制字和数据

void T0Int() interrupt 1

{

TH0 = 0xB1;

TL0 = 0xE0;   //20ms的时钟基准

//先写入控制字,再写入计数值

SERVO0 = 0x30; //选择计数器0,写入控制字

PWM0 = BUF0L; //先写低,后写高

PWM0 = BUF0H;

SERVO1 = 0x70; //选择计数器1,写入控制字

PWM1 = BUF1L;

PWM1 = BUF1H;

SERVO2 = 0xB0; //选择计数器2,写入控制字

PWM2 = BUF2L;

PWM2 = BUF2H;

}

关键字:AVR控制2  舵机 引用地址:AVR控制20个舵机的程序

上一篇:AVR绝对定位面面观
下一篇:AVR单片机端口操作

推荐阅读最新更新时间:2024-03-16 15:16

stc12c5a60s2单片机驱动舵机程序
#include stc12c5a60s2.H //STC12C5A系列单片机 #define uchar unsigned char #define uint unsigned int //宏定义 #define ulint unsigned long int //宏定义 void delay(uint time); void Timer_init(); void Timer0(unsigned long int us); uint pwm_valu=500; sbit dj=P1^0; void main() { Timer_init(); //定时器初始化 Timer0(31); //通过一个定时值进入定时循环
[单片机]
stm32控制舵机旋转到不同角度
最近学习了stm32,就想用它来控制舵机,然后写下这篇文章分享给大家,如果有理解不到位的地方欢迎大家指正。(我使用的是stm32f103ve型号的开发板,即使和你的型号不同,也有参考价值) 想要控制舵机的转动,首先你得知道舵的工作原理。 舵机的主要组成部分为伺服电机,所谓伺服就是服从信号的要求而动作。在信号来之前,转子停止不动;信号来到之后,转子立即运动。因此我们就可以给舵机输入不同的信号,来控制其旋转到不同的角度。 舵机接收的是PWM信号,当信号进入内部电路产生一个偏置电压,触发电机通过减速齿轮带动电位器移动,使电压差为零时,电机停转,从而达到伺服的效果。简单来说就是给舵机一个特定的PWM信号,舵机就可以旋转到指定的位置
[单片机]
stm32<font color='red'>控制</font><font color='red'>舵机</font>旋转到不同角度
使用AVR单片机驱动舵机
1.舵机驱动的基本原理   (可以参考http://blog.sina.com.cn/s/blog_8240cbef01018hu1.html)    控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。 简单的来讲,就是输出一个周期为20Ms,不同的占空比对应舵机转过不同的角度。 难点主要在于 舵机控制信号需要保持,这样就比用脉冲控制步进电机要复杂一些。 你需要
[单片机]
使用<font color='red'>AVR</font>单片机驱动<font color='red'>舵机</font>
Dynamixel数字舵机驱动
好久没更新技术类日志了,今天更新下,这是一个韩国robotics机器人Dynamixel数字舵机的驱动,采用C语言编写,支持Dynamixel 通信协议 ,案例是AVR单片。实际上可以采用FPGA,例如SOPC系统上,可控制小型机器人。 在这也拆解下CM-5的控制器,是一片atmega128A 哦!哈哈。这PCB做工一般,感觉韩国人是科技领域爆发户,但我们有什么资格嘲笑棒子呢,至少人家都能造CPU了,我们呢? #include avr/io.h #include util/delay.h void InitUart0(void) { UCSR0A = 0x02; // 设置为倍速模式 UBRR0H = 0;
[单片机]
Dynamixel数字<font color='red'>舵机</font>驱动
AVR单片机视觉智能寻迹车设计与实现
0 引 言 智能运输系统是未来交通运输系统发展的趋势,智能汽车在智能运输系统中扮演着十分重要的角色。作者提出智能寻迹车作为构建未来智能交通运输系统中重要部分,针对未来交通运输系统有导航线的环境命题假设下智能汽车的自主寻迹问题,提出一种基于视觉的智能寻迹车模设计方案,作为该假设问题的解决方案。 基于视觉的智能寻迹车模设计方案能够在线型复杂,转弯半径不确定性大的情况下,利用视觉自主寻迹前进,分级精确转向。 1 系统总体设计 基于视觉的智能寻迹车模系统以AVR单片机MEGAl6为核心,由单片机模块、路径识别模块、直流电机驱动模块、舵机驱动模块等组成,如图1所示。 直流电动机为车辆的驱动装置,转向电动机用于控
[单片机]
实验8 舵机
舵机如上图所示,左图为9g舵机,右图为55g舵机,与直流减速电机不同,它的工作方式是根据脉冲宽度转到对应的角度,转角范围是180度。PWM波控制信号的脉冲宽度对应的舵机转角如下图所示。 舵机有一个三线的接口。脉冲信号端连接橙色线(或者黄色线),+4.8V~+6V电源连接红线接,地线连接绿色线(或者棕色线)。 舵机可用作机械手、人形机器人、六足机器人、码垛机器人的执行元件。 一、库函数 1、打开DAHUME MINI.stw文件; 2、在STVD左侧Workspace窗口Source Files目录下找到main.c,双击打开; 3、编写如下代码; #include main.h void s
[单片机]
实验8 <font color='red'>舵机</font>
多路舵机控制PWM发生器的设计与Proteus仿真
摘要:PWM脉宽信号调制是现代电子行业中使用较为广泛的一种脉冲信号,其典型应用就是舵机控制。以Proteus和Keil软件为基础,介绍了在Proteus环境下利用51单片机产生多路PWM脉冲的实现方法。最后以一个典型的应用实例验证了设计的可行性与可靠性。实验证明,本系统可在单片机定时器资源有限的情况下同时对多个舵机的输出转角进行控制。 关键词:PWM;舵机控制;Proteus;Keil;单片机 0 引言 单片机是现代仪器仪表、家用电器、工业仪器等领域应用十分广泛的可编程器件之一,有着价格低廉、编程灵活、体积小、可扩展性强等优点。单片机功能的飞速发展,其应用范围日益广泛,小到玩具,大到机器人,无论从数据采集,过程控制,模糊控制等
[工业控制]
多路<font color='red'>舵机</font><font color='red'>控制</font>PWM发生器的设计与Proteus仿真
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved