搜索
bottom↓
回复: 14

控制舵机的多路PWM波 最多可以达到32路

[复制链接]

出0入0汤圆

发表于 2012-10-14 18:09:01 | 显示全部楼层 |阅读模式
本帖最后由 强者归来 于 2012-10-14 18:16 编辑

    最经需要做个仿生六足机器人,选择ATmega16做控制,需要产生18路完全独立的PWM波。产生PWM波有很多方法,Atmega16片设就有PWM模块,但是由于产生计时器0和计时器2产生的PWM波的频率和晶振的大小有关系,大概是除一个数和分频数,所以,要得到50Hz的控制舵机的PWM不可能,不过,计时器1可以产生产生频率和相位都改变的PWM波,不过,由于只有两个比较寄存器,所以,最多只能出两路,而且是在固定的OC1A和OC1B产生,不够用。下面简单介绍一下几种不同的PWM波产生的方法,大概有三种方法产生多路PWM波。
   第一种,是我自己采用的,最多可以产生32路(所以IO口都用上)。舵机控制是用50HZ的脉冲控制的,50HZ,周期即20ms,这是,你可以将这20ms分为若干份,分得越多,精确度就越高,假设你打算分为300份(晶振越高,可以选择大些)。这是,你可以选择用一定时器,也可以用两个定时器,我选择用两个定时器。计时器0每个20ms中断一次,另一个20/N ms中断一次,在函数里设一个全局变量count ,每一个20/N ms中断里,count加一,要输出的PWM波的占空比的就是与count比,当小于count时,选择任意端口(最多32)置1,大于count时,选择置0,这样就可以产生从不同占空比的PWM波。关键在于理解count与要求的PWM占空比比较的理解,你可以这样理解,20ms,最多N份,你可以选择从0份到N份置1,到是w份时,所得的PWM波的占空比就是w/N。讲不清楚,直接上程序吧。
#include <iom16.h>
#include <intrinsics.h>
#include <iom16.inc>
#include <iomacro.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define PWM11 PORTA_Bit0  //用两位数定义18个舵机
#define PWM12 PORTA_Bit1
#define PWM13 PORTA_Bit2
#define PWM21 PORTA_Bit3
#define PWM22 PORTA_Bit4
#define PWM23 PORTA_Bit5
#define PWM31 PORTA_Bit6
#define PWM32 PORTA_Bit7
#define PWM33 PORTD_Bit0
#define PWM41 PORTD_Bit1
#define PWM42 PORTD_Bit2
#define PWM43 PORTD_Bit3
#define PWM51 PORTD_Bit4
#define PWM52 PORTD_Bit5
#define PWM53 PORTD_Bit6
#define PWM61 PORTD_Bit7
#define PWM62 PORTC_Bit0
#define PWM63 PORTC_Bit1
void timer0_init(void);
void timer1_init(void);
void port_init(void);   
void init(void);   

void  Quickprepare(void);
void delay_ms(uint k);
void forward_go(void);
void hop_round(void);//           下面几个是不同的动作函数  我在最下面贴了一个back_go的函数
void hello(void);
void back_go(void);
uchar scan_key(void);
void turn(void);
void fly(void);
void low(void);
void game_over(void);
void right_round(void);
void left_round(void);
uchar pwm11,pwm12,pwm13,pwm21,pwm22,pwm23,pwm31,pwm32,pwm33,pwm41,pwm42,pwm43,pwm51,pwm52,pwm53,pwm61,pwm62,pwm63; //分别18个pwm的值  
uchar count=0;      

void main(void)   
{
      uchar keycode;  
      init(); //初始化
    Quickprepare();//舵机初始复位
   
    while(1)  //该不同的端口设定不同占空比的pwm波
   {      

     
     back_go();
               
      }
   }

}
void init(void)   
{   
    SREG_Bit7=0; //中断停止   
    port_init();  // 端口初始化
    timer0_init();  //计时器0初始化
    timer1_init();  //计时器1初始化
    SREG_Bit7=1; //中断启用   
}   
  
void port_init(void)   
{
   DDRA = 0xFF;
   PORTA = 0x00;
   DDRD = 0xFF;   
   PORTD = 0x00;   
   DDRC = 0x3;
   PORTC = 0x00;


}   
  void timer0_init(void)         //定时器0初始化程序 (产生20ms的周期)  
{   
   TIMSK|=(1<<OCIE0);
   TCCR0|=(1<<WGM01);
   OCR0=233;  
   TCCR0|=(1<<CS00)|(1<<CS02);//        初始化函数里  计时器0开始计数}   
void timer1_init(void)         //定时器1初始化程序   
{   
   TIMSK|= (1<<OCIE1A); //定时器中断源   
   TCCR1B|= (1<<WGM12); //CTC模式
   OCR1A = 99;      /////////////////////注意  初始时计时器1不要开始计数  不要开始计数  要到计时器0的中断函数里开始计数(产生20/N  ms周期)


}   

#pragma vector= TIMER0_COMP_vect  
__interrupt void timer0_compa_isr(void)
{   
    TCCR1B|= (1<<WGM12); //CTC模式
    TIMSK|= (1<<OCIE1A); //定时器中断源   
    OCR1A = 99;
    TCCR1B|=(1<<CS11);  //计数器1经过8分频开始计时
    count=0;
}
  

//下面就是计时器0每个中断里比较输出函数



#pragma vector=TIMER1_COMPA_vect   
__interrupt void timer1_compa_isr(void)
{   
                     
    count++;      //每中断一次加1   
if (count<pwm11)   
    {   
     PWM11=1;   
    }
    else
    {   
      PWM11=0;   
    }   
if (count<pwm12)   
    {   
      PWM12=1;   
    }
    else
    {   
      PWM12=0;   
    }   
if (count<pwm13)   
    {   
      PWM13=1;   
    }
    else
    {   
      PWM13=0;
    }   
if (count<pwm21)   
    {   
      PWM21=1;   
    }
else
    {   
      PWM21=0;
    }   
if (count<pwm22)   
    {   
      PWM22=1;   
    }
else
    {   
      PWM22=0;   
    }   
if (count<pwm23)   
    {   
      PWM23=1;   
    }
else
    {   
      PWM23=0;   
    }   
  if (count<pwm31)   
    {   
      PWM31=1;   
    }
else
    {   
      PWM31=0;   
    }   
if (count<pwm32)   
    {   
      PWM32=1;   
    }
  else
    {   
      PWM32=0;   
    }   
if (count<pwm33)   
    {   
      PWM33=1;   
    }
else
    {   
      PWM33=0;   
    }   
  if (count<pwm41)   
    {   
      PWM41=1;   
    }
    else
    {   
     PWM41=0;   
    }   
   if (count<pwm42)   
    {   
      PWM42=1;   
    }
    else
    {   
      PWM42=0;   
    }   
   if (count<pwm43)   
    {   
      PWM43=1;   
    }
    else
    {   
      PWM43=0;   
    }   
  if (count<pwm51)   
    {   
      PWM51=1;   
    }
    else
    {   
      PWM51=0;   
    }   
if (count<pwm52)   
    {   
      PWM52=1;   
    }
    else
    {   
      PWM52=0;   
    }   
   if (count<pwm53)   
    {   
      PWM53=1;   
    }
    else
    {   
      PWM53=0;   
    }   
  if (count<pwm61)   
    {   
      PWM61=1;   
    }
    else
    {   
      PWM61=0;   
    }   
if (count<pwm62)   
    {   
      PWM62=1;   
    }
    else
    {   
      PWM62=0;   
    }   
  if (count<pwm63)   
    {   
      PWM63=1;   
    }
    else
    {   
      PWM63=0;   
    }   
   
   if(count>=37) //2.5ms脉冲后停止计数 等待到下一个20ms
     {
        TCCR1B&=~(1<<CS11);//停止计时
     }  
}
   

void delay_ms(uint k)

出0入0汤圆

发表于 2012-10-14 18:21:29 | 显示全部楼层
AVR的性能还是不错的 软件模拟精度还可以

出0入0汤圆

发表于 2012-11-12 00:18:03 | 显示全部楼层
参考学习一下,最近正在做。

出0入0汤圆

发表于 2012-11-13 09:12:03 | 显示全部楼层
不错,挺好的,支持一下

出0入0汤圆

发表于 2012-11-16 10:20:05 | 显示全部楼层
很有创造力~

出0入0汤圆

发表于 2012-11-18 13:53:57 | 显示全部楼层
不错。


出0入0汤圆

发表于 2012-11-18 17:11:38 | 显示全部楼层
谢谢分享  非常不错

出0入0汤圆

发表于 2012-11-18 18:10:27 | 显示全部楼层
想法很好,学习一下~~~~~~

出0入0汤圆

发表于 2012-11-18 23:41:24 | 显示全部楼层
以前用51做过  不过51太慢了

出0入0汤圆

发表于 2013-4-8 16:37:21 来自手机 | 显示全部楼层
学习一下....

出0入0汤圆

发表于 2013-7-3 23:42:30 | 显示全部楼层
非常感谢分享

出0入0汤圆

发表于 2013-8-9 08:29:21 | 显示全部楼层
支持下,正准备弄个小六玩玩~~

出0入0汤圆

发表于 2013-8-27 14:30:53 | 显示全部楼层
有没有一款强大的单片机硬件就能输出18路PWM

出0入0汤圆

发表于 2014-4-11 11:09:01 | 显示全部楼层
很强大很不错

出0入0汤圆

发表于 2017-9-21 16:29:56 | 显示全部楼层
想法很好,我也学习下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 08:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表