打印
[AVR单片机]

想用按键控制Atmega16产生PWM,请指导?谢谢

[复制链接]
1729|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我本来想给INT0一个低电平触发,使得打开T/C1时钟源,当按键弹起的上升沿触发 INT1,从而关断T/C1的时钟源,可是我下面的程序实现不了啊,用示波器检测OC1A和OC1B脚都是混乱的信号。请大家给指导下,对单片机不太会。
#include <iom16v.h>
#include <macros.h>
#pragma interrupt_handler zhuandong:2
#pragma interrupt_handler tingzhi:3
void zhuandong (void) //INT0 低电平触发启动PWM发生
  {
  TCCR1B=0X12;
  }
void tingzhi (void)  //INT1 上升沿触发停止PWM发生
{
  TCCR1B=0X00;
}
void main(void)
{
DDRA|=0x01;
DDRD|=0x30;
MCUCR|=0x0C;
GICR|=0xC0;
TCCR1A=0x63;
TCCR1B=0x00;
OCR1A=1249;
OCR1B=250;
while(1)
  {
   PORTA|=0X01;
  }
}

相关帖子

沙发
qin552011373| | 2013-3-10 20:30 | 只看该作者
代码是你自己写的?

使用特权

评论回复
板凳
qin552011373| | 2013-3-10 20:32 | 只看该作者
试下编译器直接生成程序生成行不行

使用特权

评论回复
地板
studying123|  楼主 | 2013-3-10 21:55 | 只看该作者
qin552011373 发表于 2013-3-10 20:32
试下编译器直接生成程序生成行不行

代码是自己写的。生成程序可以,可是不出PWM波啊。

使用特权

评论回复
5
qin552011373| | 2013-3-10 21:59 | 只看该作者
studying123 发表于 2013-3-10 21:55
代码是自己写的。生成程序可以,可是不出PWM波啊。

建议先调出来PWM  然后再调出来其他的  最后整体拼凑

使用特权

评论回复
6
yklstudent| | 2013-3-11 14:19 | 只看该作者
虽然不了解ICC 但是不得不佩服楼主了

使用特权

评论回复
7
qin552011373| | 2013-3-11 21:35 | 只看该作者
yklstudent 发表于 2013-3-11 14:19
虽然不了解ICC 但是不得不佩服楼主了

如果有较好的程序  可以分享一下哦

使用特权

评论回复
8
yklstudent| | 2013-3-11 23:29 | 只看该作者
#pragma interrupt_handler zhuandong:2
#pragma interrupt_handler tingzhi:3
void zhuandong (void) //INT0 低电平触发启动PWM发生
  {
  TCCR1B=0X12;
  }
void tingzhi (void)  //INT1 上升沿触发停止PWM发生
{
  TCCR1B=0X00;
}
只是对这个有点意见

使用特权

评论回复
9
phoebuss| | 2013-3-12 14:25 | 只看该作者
本帖最后由 phoebuss 于 2013-3-12 14:28 编辑

我前不久写的~~

/*
Config
PIN21(PD7):PWM Output;
PIN18~20: Button1~3 Input;
PIN14~17: Display_Select Output;
PIN1~8: Display_Data Output;
*/

#include <iom16v.h>
#include <macros.h>

#define uchar unsigned char
#define uint unsigned int

#define BUT1 PD4
#define BUT2 PD5
#define BUT3 PD6

const uchar PWM[101]={
0, 2, 4, 7, 9, 12, 14, 17, 19, 22,
25, 27, 30, 32, 35, 37, 40, 43, 45, 48,
50, 53, 55, 58, 60, 63, 66, 68, 71, 73,
76, 78, 81, 83, 86, 89, 91, 94, 96, 99,
101, 104, 107, 109, 112, 114, 117, 119, 122, 124,
127, 130, 132, 135, 137, 140, 142, 145, 147, 150,
153, 155, 158, 160, 163, 165, 168, 171, 173, 176,
178, 181, 183, 186, 188, 191, 194, 196, 199, 201,
204, 206, 209, 211, 214, 217, 219, 222, 224, 227,
229, 232, 235, 237, 240, 242, 245, 247, 250, 252,
254}; //%0~%100 8Bit PWM DATA

uchar display_data[4]={0xBF, 0xBF, 0xBF, 0xBF};

void Display_integer(uint itg)
{
        const uchar seg7[10]={
        0xC0, 0xF9, 0xA4, 0xB0, 0x99,
        0x92, 0x82, 0xF8, 0x80, 0x90};
        const uint exp10[4]={1, 10, 100, 1000};
        uchar i, j;
        
        display_data[1]=0xFF;
        display_data[2]=0xFF;
        display_data[3]=0xFF;
        
        if(itg > 9999)
        {
                display_data[0]=0xBF;
                return; //判断是否超过4位
        }
        
        j=1;
               
        if(itg > 999)
                j=4;
        else if(itg > 99)
                j=3;
        else if(itg > 9)
                j=2;
        
        for(i=0;i<j;i++)
                display_data = seg7[(itg % exp10[i+1] /exp10)];                        
}
        
void Delayms(uint MS)
{
        uint i,j;
        for( i=0;i<MS;i++)
                for(j=0;j<2282. ;j++);        //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}

void port_init(void)
{
        DDRD  = 0x8F;
         PORTD = 0xFF;
        DDRB = 0xFF;
        PORTB = 0xFF;
}

void timer0_init(void)
{
        TCCR0 = 0x00;
        TCNT0 = 128;
         TCCR0 = 0x04; //start timer
}

#pragma interrupt_handler timer0:iv_TIMER0_OVF
void timer0(void)
{
        static unsigned char i=0;
         TCNT0 = 128; //reload counter value
         
        
        if(i > 3)
                i=0;
        
        PORTD = BIT(i)|0b11110000;
        PORTB = display_data;
        i++;         
}

//TIMER2 initialize - prescale:1
// WGM: PWM Fast
// desired value: 31250Hz
// actual value: 31250.000Hz (0.0%)
void timer2_init(void)
{
         TCNT2 = 0x00; //setup
         OCR2  = 127;        //50%
         TCCR2 = BIT(WGM20)|BIT(WGM21)|BIT(COM21)|BIT(CS20); //start
}

//call this routine to initialize all peripherals
void init_devices(void)
{
         //stop errant interrupts until set up
         CLI(); //disable all interrupts
         port_init();
         timer2_init();
        timer0_init();
        TIMSK = 0x01;
         SEI(); //re-enable interrupts
         //all peripherals are now initialized
}

void main(void)
{
        uint percent=50;
        Display_integer(50);
        init_devices();
        
        while(1)
        {
                if(!(BIT(BUT1)&PIND))
                {
                        Delayms(10);
                        if(!(BIT(BUT1)&PIND))
                        {
                                if(percent == 100)
                                        continue;
                                
                                Delayms(200);
                                percent++;
                                OCR2 = PWM[percent];
                                Display_integer(percent);
                        }
                }
               
                if(!(BIT(BUT2)&PIND))
                {
                        Delayms(10);
                        if(!(BIT(BUT2)&PIND))
                        {
                                if(percent == 0)
                                        continue;
                                
                                Delayms(200);
                                percent--;
                                OCR2 = PWM[percent];
                                Display_integer(percent);
                        }
                }
               
                if(!(BIT(BUT3)&PIND))
                {
                        Delayms(10);
                        if(!(BIT(BUT3)&PIND))
                        {                        
                                Delayms(200);
                                percent = 50;
                                OCR2 = PWM[percent];
                                Display_integer(percent);
                        }
                }                        
        }        
}

QQ截图20130312142521.jpg (175.19 KB )

QQ截图20130312142521.jpg

使用特权

评论回复
10
studying123|  楼主 | 2013-3-12 16:11 | 只看该作者
yklstudent 发表于 2013-3-11 23:29
#pragma interrupt_handler zhuandong:2
#pragma interrupt_handler tingzhi:3
void zhuandong (void) //IN ...

我刚接触这东西,还不懂,希望指点下。这样写有什么问题吗?真心求教

使用特权

评论回复
11
yklstudent| | 2013-3-12 16:23 | 只看该作者
ICC真的不了解 只是一开始对你的中断写法感觉奇怪 哪个是INT1函数 哪个是INT2函数而已

使用特权

评论回复
12
qin552011373| | 2013-3-13 00:09 | 只看该作者
yklstudent 发表于 2013-3-11 23:29
#pragma interrupt_handler zhuandong:2
#pragma interrupt_handler tingzhi:3
void zhuandong (void) //IN ...

我看着也别扭  

使用特权

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

本版积分规则

6

主题

18

帖子

0

粉丝