打印
[AVR单片机]

mega16产生PWM正常但是比较中断的服务函数无法响应

[复制链接]
1721|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feiyinglala|  楼主 | 2013-12-16 23:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 feiyinglala 于 2013-12-17 00:07 编辑

用mega16的定时器1来产生PWM(相位修正模式),现在产生的PMW波没有问,但是iv_TIM1_COMPA的中断服务函数里的程序缺没有执行。
代码如下(编译环境是icc7.22)

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

#define uint unsigned int
#define uchar unsigned char

static void Timer1_INIT(void)
{
TCCR1B = 0x00;                                 //停止定时器
TCCR1A = 0x82;                                 //工作模式10,相位修正PWM,OC1A引脚在上升匹配时,置低电平

ICR1H = 0x20;                                 //设定了定时器1比较的峰值,同时也确定了PWM的周期
ICR1L = 0x20;

OCR1AH = 0x10;
OCR1AL = 0x10;

TCNT1H = 0x00;                                 //计数器置0
TCNT1L = 0x00;
TCCR1B = 0x13;                                 //启动定时器1,时钟不分频
}

void main()
{

Timer1_INIT();
DDRD |= 0xa0;
PORTD = 0x7f;
SEI();                   //使能全局中断
while(1);
}

#pragma interrupt_handler Timer1_ComA:iv_TIMER1_COMPA
void Timer1_ComA (void)
{
PORTD ^= 0x80;
}

相关帖子

沙发
huangxz| | 2013-12-17 15:17 | 只看该作者
这个以前我用过是可以的(我用的是winavr),楼主还是看看程序哪里有没有问题

使用特权

评论回复
板凳
feiyinglala|  楼主 | 2013-12-17 21:25 | 只看该作者
huangxz 发表于 2013-12-17 15:17
这个以前我用过是可以的(我用的是winavr),楼主还是看看程序哪里有没有问题 ...

应该是程序的问题

使用特权

评论回复
地板
huangxz| | 2013-12-17 22:45 | 只看该作者
feiyinglala 发表于 2013-12-17 21:25
应该是程序的问题

我这有个类似的程序,不过是用winavr的,里面有涉及到配置,楼主可以看看
#include <avr/io.h>
#include <avr/interrupt.h>
#include "myboard.h"

static uint8_t cx1 = 0;

uint8_t dr1,dr2;

char  ux_rx_fifo[UX_RX_FIFO_SIZE];
unsigned short ux_rx_insert_idx, ux_rx_extract_idx;

char cmd_buff[16];
char cmd_index;

int16_t ux_rx_check_q(void)                //usb
{
        uint16_t rx_data;
          if (ux_rx_insert_idx == ux_rx_extract_idx) // check if character is available
    return -1;

          rx_data = ux_rx_fifo[ux_rx_extract_idx++]; // get character, bump pointer
          ux_rx_extract_idx %= UX_RX_FIFO_SIZE; // limit the pointer

        return rx_data;
}

void ux_rx_in_q(char data)
{
        uint16_t temp;

        // calc next insert index & store character
        temp = (ux_rx_insert_idx + 1) % UX_RX_FIFO_SIZE;
        ux_rx_fifo[ux_rx_insert_idx] = data;
         
        // check for more room in queue
        if (temp != ux_rx_extract_idx)
        ux_rx_insert_idx = temp; // update insert index
}


void duty_ratio(void)
{
        dr1 = eeprom_read_byte((const uint8_t *)0x0);
        dr2 = eeprom_read_byte((const uint8_t *)0x1);
}

ISR(USART_RX_vect)
{
        uint8_t rx_data;
        rx_data = UDR;
        ux_rx_in_q(rx_data);
}

ISR(TIMER1_COMPA_vect)
{
        TIFR = (0x01 << TOV1);
        TCNT1 = 0xf800;  //(0x10000 - 0xf800)*1024/8e6 = 262ms
        PORTC ^= 0x03;
       
        switch(cx1++)
        {
                case 0:
                        PORTD ^= 0x10;
                        break;
                case 1:
                        PORTD ^= 0x20;
                        break;
                case 2:
                        PORTD ^= 0x40;
                        break;
                case 3:
                        PORTD ^= 0x80;
                        break;
                default:
                        break;
        }
       
        cx1 &= 0x3;
/*
        if(cx1++ == 0x03)
        {
//                PORTD ^= (0x01 << 5) | (0x01 << 6) |  (0x01 << 7);
                PORTD ^= 0xf0;
                cx1 = 0;
        }
*/
}

ISR(TIMER1_OVF_vect)
{
//code
        TIFR = (0x01 << OCF1A);
        PORTC ^= 0x03;
}

void tm1_init(void)
{
        //TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
        //TCCR1B ICNC1  ICES1  –      WGM13  WGM12 CS12  CS11  CS10
#if TM1_OVERFLOW
        TCNT1 = 0xff00;
        TIMSK = (0x01 << TOIE1);
        TCCR1B = 0x05;
#elif TM1_CTC
        TCNT1 = 0;
//        TCCR1A = 0x01 << 6; //A比较
        TCCR1A = 0; //
        OCR1A = 0x00ff;
        OCR1B = 0x01ff;
        TCCR1B = 0x04 | (0x01 << 3);
        TIMSK = (0x01 << OCIE1A);
#elif TM1_FPWM //--Fast PWM, 8-bit
        //周期计算 0x100*1024/8e6 = 32.768ms
        //频率计算 8e6/(0x100*1) = 31250.0hz
        TCNT1 = 0;
        OCR1A = dr1;
        OCR1B = dr2;
        TCCR1A = (0x00 << WGM11) | (0x01 << WGM10) | (0x2 << COM1A0)  | (0x2 << COM1B0);
        TCCR1B = (0x00 << WGM13) | (0x01 << WGM12) |\
                        0x01;
        DDRE |= (0x01 << PE2);
#endif
}

void tm0_init(void)
{
#if TM0_CTC
        TCNT0 = 0;
        OCR0 = 0xef;
        TCCR0 = (0x01 << WGM01) | (0x01 << COM00) | 0x05;
#elif TM0_FPWM
        //周期计算 0x100*1024/8e6 = 32.768ms
        //频率计算 8e6/(0x100*1024) = 30.5hz
        TCNT0 = 0;
        OCR0 = 0x30;
        TCCR0 = (0x01 << WGM01) | (0x01 << WGM00) |\
                        (0x01 << COM01) |\
                        0x05;
#elif TM0_PCPWM
        //周期计算 0x100*1024*2/8e6 = 65.536ms
        //频率计算 8e6/(2*0x100*1024) = 15.25hz
        TCNT0 = 0;
        OCR0 = 0x30;
        TCCR0 = (0x01 << WGM00) |\
                        (0x01 << COM01) |\
                        0x05;
#endif       
}

void ux_init(void)
{
        UBRRH = 0;
        UBRRL = 25;//38400
        UCSRA = (0x01 << U2X);
        UCSRB = (0x01 << RXCIE)|(0x01 << TXEN)|(0x01 << RXEN);
        UCSRC = (0x01 << URSEL)|(0x03 << UCSZ0);
}

void ux_tx_bytes(char *ptr, char len)
{
        uint8_t i;
        for(i=0;i<len;i++)
        {
                while(!(UCSRA & (0x01 << UDRE)));
                UDR = *ptr++;
        }
}


void bsp_init(void)
{
    //pa0...pa3作为遥控输入端
    DDRA = 0x00;
    PORTB |= 0x0f << 2;
    DDRB |= 0x0f << 2;
    PORTB &= ~(DIR1 | DIR2);
   
    DDRB |= 0x01; //PB0 as OCR0
   
    DDRC = 0x0f;
    PORTC = 0;
/*   
    DDRD |= (0x01 << 5) | (0x01 << 6) | (0x01 << 7);
    PORTD |= (0x01 << 5) | (0x01 << 6) | (0x01 << 7);
*/
    DDRD = 0xf0;
    PORTD = 0x00;
   
    duty_ratio();
    tm0_init();
    tm1_init();
    ux_init();
    sei();
    cmd_index = 0;
}

void ux_mon(void)
{
        int16_t rx_val;
        rx_val = ux_rx_check_q();
       
        if(-1 == rx_val)return;
               
        if(cmd_index < 16)
        {
                cmd_buff[cmd_index++] = rx_val & 0xff;
        }
       
        if(cmd_index == cmd_buff[0])
        {
                cmd_index = 0;
                if(0 == ux_cmd(cmd_buff))
                {
                        ux_tx_bytes(cmd_buff, sizeof(cmd_buff));
                }
        }
}

使用特权

评论回复
评分
参与人数 1威望 +6 收起 理由
qin552011373 + 6 很给力!
5
qin552011373| | 2013-12-18 08:25 | 只看该作者
建立楼主拿ICC直接生成一个定时器文件看看是不是配置出了问题

使用特权

评论回复
6
SLEET1986| | 2013-12-18 08:49 | 只看该作者
没开中断

使用特权

评论回复
7
feiyinglala|  楼主 | 2013-12-19 19:01 | 只看该作者
qin552011373 发表于 2013-12-18 08:25
建立楼主拿ICC直接生成一个定时器文件看看是不是配置出了问题

生成定时器文件?是指hex文件吗?

使用特权

评论回复
8
qin552011373| | 2013-12-20 08:40 | 只看该作者
feiyinglala 发表于 2013-12-19 19:01
生成定时器文件?是指hex文件吗?

c文件

使用特权

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

本版积分规则

20

主题

222

帖子

1

粉丝