打印

请教大家一个关于用atmega16产生PWM波的c程序

[复制链接]
6937|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jjbbqq|  楼主 | 2010-7-22 09:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
因为暑期实践的需要,初次接触PWM波
为了了解PWM波,我想让单片机的一个I/O口输出一个占空比一直在变化的PWM波,用来控制led的明亮程度
现在遇到的问题是,我大致是知道:
CMO1A1,COM1A0:这两位决定了输出通道A的比较模式。
COM1B1,COM1B1:这两位决定了输出通道B的比较模式。
WGM13,WGM12:这两位联合TCCR1A的WGM11,WGM10一起决定定时器TC1的工作模式。
CS12,CS11,CS10:这三位决定了定时器TC1时钟源的分频系数。
输出比较寄存器1A- OCR1A:此寄存器中的值为通道A的输出比较值。
输出比较寄存器1B-OCR1B:此寄存器中的值为通道B的输出比较值。
定时器TC1的数据寄存器TCNT1:此寄存器存储了定时器当前的数据。
最后还有中断标志寄存器TIMSK中的OCIE1A 、OCIE1B,使能PWM比较匹配中断。
这些内容,但是不清楚他们在mega16的c语言中用什么来表示
我在网上找到了一些程序
但是他们的语言都不一样
第一种是这个
这个我没有用usb传到我的实验板上,所以不知道行不行
#include <mega16.h>
void main(void)
{     
  TCCR1A = 0b10100010;   //快速PWM
  TCCR1B = 0b00011001;   //时钟1分频
  ICR1H  = 0xFF;         //TCNT计数上限(最高16位)
  ICR1L  = 0xFF;  
  DDRD   = 0x30;         //PWM输出
   
  while (1)
  {   
   
    OCR1AH=0x7F;         //设置OCR0A的占空比1:2
    OCR1AL=0xFF;
     
    OCR1BH=0x3F;         //设置OCR0B的占空比1:4
    OCR1BL=0xFF;
     
  };
}

第二种是这个
//实例:利用pwm控制led光暗及峰鳴器音量大小
//ICC-AVR application builder : 2005-4-18 12:46:03  
// Target : M16  
// Crystal: 4.0000Mhz  
#include <iom16v.h>  
#include <macros.h>  
#define uchar unsigned char
#define uint unsigned int
void port_init(void);
void timer0_init(void);
void init_devices(void);
void delay_short(uint t);
uchar scan_key(void);
void port_init(void)  
{  
PORTA = 0x00;  
DDRA    = 0x00;  
PORTB = BIT(PB3);  
DDRB    = BIT(PB3);  
PORTC = 0x00; //m103 output only  
DDRC    = 0x00;  
PORTD = 0x00;  
DDRD    = 0x00;  
}  
// WGM: PWM Phase correct
// desired value: 1KHz
// actual value:    0.980KHz (-2.0%)
void timer0_init(void)  
{  
TCCR0 = 0x00; //stop  
TCNT0 = 0x01; //set count  
OCR0    = 0xFF;    //set compare  
TCCR0 = 0x62; //start timer ; 相位修正, 8分頻
}  
//call this routine to initialize all peripherals  
void init_devices(void)  
{  
//stop errant interrupts until set up  
CLI(); //disable all interrupts  
port_init();  
timer0_init();  
MCUCR = 0x00;  
GICR    = 0x00;  
TIMSK = 0x00; //timer interrupt sources  
SEI(); //re-enable interrupts  
//all peripherals are now initialized  
}
void delay_short(uint t) // 短延時
{
    uint i;
    for (i=0;i<t;i++);
}
uchar scan_key(void)    // 按鍵掃瞄
{  
    uchar v;
   
    v = 0;      
   
    if ((PIND & 0x07) != 0x07)
    {
  
    if ((PIND & 0x01) == 0)  
    {
     v = 1;
      delay_short(1000);   
    }
   
    if ((PIND & 0x2) == 0)  
    {
      v = 2;
      delay_short(1000);   
    }
   
    if ((PIND & 0x4) == 0)  
    {
      v = 3;
      delay_short(1000);   
    }
    };
    while((PIND & 0x07) != 0x07);     // 判斷按鍵是不是放開   
    return v;   
}
//  
void main(void)  
{   
uchar key, OCR0_V;
  
init_devices();  
OCR0_V = 0xff;
  
while(1)
{
     key = scan_key();
   
     if (key > 0)
     {
       if (key==1) // 減少佔空比
      {  
        OCR0_V -= 10;
        OCR0 = OCR0_V;
      };
     
       if (key==2) // 增加佔空比
      {  
        OCR0_V += 10;
        OCR0 = OCR0_V;
      };     
     
       if (key==3) // 全黑,佔空比為100%  
      {  
        OCR0_V = 0xff;
        OCR0 = OCR0_V;
      };      
     }
};  
}

这个我下到实验板上了
并且可以运行
但是我发现这两个程序里的涉及到寄存器之类的初始化语句都是不一样的
请高手指导一下
谢谢了
最好能帮我编一下一开始的那个简单程序
看帖子说去翻datasheet
我确实能找到
但是还是看不出我初始化那些东西的时候应该用怎样的变量名称。
比如
TCCR0 = 0x00; //stop  
TCNT0 = 0x01; //set count  
OCR0    = 0xFF;    //set compare  
TCCR0 = 0x62; //start timer ; 相位修正, 8分頻



OCR1AH=0x7F;         //设置OCR0A的占空比1:2
OCR1AL=0xFF;
OCR1BH=0x3F;         //设置OCR0B的占空比1:4
OCR1BL=0xFF;

不知道他们是哪里来的
谢谢了!

相关帖子

沙发
夏夜暖风| | 2013-10-6 17:57 | 只看该作者
好 不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

1

帖子

1

粉丝