AVRmega16通过一个定时器实现多路IO口输出多路可调的PWM

时间:2021-06-23 18:51:32
       本人在做舞蹈机器人时,想到了通过一个定时器实现多路IO口输出多路可调的PWM,用于控制舞蹈机器人各部分的舵机。这个方法比较简洁而且实现自己的要求,且易于理解。
      /*角度值:15度500us(10)——215度2500us(50)
 端口A0——A5   B0——B5    C0——C5   */
#include<iom16v.h>
#include<macros.h>
#define uint unsigned int
#define uchar unsigned char 
#define dt 70
#define sp 18
#pragma interrupt_handler  timer0:10
#pragma interrupt_handler timer1:9
uint base0=0,base1=0;
uchar i,k;
uint j=0;
uchar  s[18]={14,15,14,2,17,13,13,13,5,14,12,5,14,6,8,17,12,14};
uchar  std[18]={14,6,14,2,14,13,13,13,5,5,12,5,14,6,10,17,12,12};
void  chushi()                                                                                                                                      
{
 uchar i;
 for(i=0;i<18;i++)
    s[i]=std[i];
}
void timer_init()  //中断初始化
{                                 
  TCNT1H=0XFF;      //定时器1 初始化
TCNT1L=0XD2;       //0.05ms定时初值,准确
TCCR1B=0X02;       //8分频



    TCCR0=0X02;//计数器0 8分频
    TCNT0=0XD2;//计数器0 50us中断一次
    TIMSK=0X05;//开启中断溢出中断0
    SREG=0X80;//开启总中断 
}
void main()
{
        chushi();
timer_init();
}
void timer0()//每50us中断一次产生占空比可调的pwm
{
  
  TCNT0=0XD2;//计数器0 50us中断一次
  base0++;
if(base0==378)
     {   base0=0;
  PORTA=0xff;
  PORTC=0xff;
     } 
for(i=0;i<12;i++)//A口 s[0]——s[5] C口 s[6]——s[11]端口输出脉冲
  {
    if(i<=5)
    {
          if(base0==s[i])
      PORTA&=~BIT(i); 
    }
    if(i>5)
    {
          if(base0==s[i])
  {
    j=i-6;
      PORTC&=~BIT(j); 
  }
    }
     } 
}




void timer1(void)
{
   
     TCNT1H=0XFF;
TCNT1L=0XD2;      //重装初值

base1++;
if(base1==378)
     {   base1=0;
PORTB=0xff;

for(k=12;k<18;k++)   //B  口S[12]——s[17]
{
        if(base1==s[k])
{