[AVR单片机] mega16产生PWM正常但是比较中断的服务函数无法响应

[复制链接]
 楼主| 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的,里面有涉及到配置,楼主可以看看
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include "myboard.h"

  4. static uint8_t cx1 = 0;

  5. uint8_t dr1,dr2;

  6. char  ux_rx_fifo[UX_RX_FIFO_SIZE];
  7. unsigned short ux_rx_insert_idx, ux_rx_extract_idx;

  8. char cmd_buff[16];
  9. char cmd_index;

  10. int16_t ux_rx_check_q(void)                //usb
  11. {
  12.         uint16_t rx_data;
  13.           if (ux_rx_insert_idx == ux_rx_extract_idx) // check if character is available
  14.     return -1;

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

  17.         return rx_data;
  18. }

  19. void ux_rx_in_q(char data)
  20. {
  21.         uint16_t temp;

  22.         // calc next insert index & store character
  23.         temp = (ux_rx_insert_idx + 1) % UX_RX_FIFO_SIZE;
  24.         ux_rx_fifo[ux_rx_insert_idx] = data;
  25.          
  26.         // check for more room in queue
  27.         if (temp != ux_rx_extract_idx)
  28.         ux_rx_insert_idx = temp; // update insert index
  29. }


  30. void duty_ratio(void)
  31. {
  32.         dr1 = eeprom_read_byte((const uint8_t *)0x0);
  33.         dr2 = eeprom_read_byte((const uint8_t *)0x1);
  34. }

  35. ISR(USART_RX_vect)
  36. {
  37.         uint8_t rx_data;
  38.         rx_data = UDR;
  39.         ux_rx_in_q(rx_data);
  40. }

  41. ISR(TIMER1_COMPA_vect)
  42. {
  43.         TIFR = (0x01 << TOV1);
  44.         TCNT1 = 0xf800;  //(0x10000 - 0xf800)*1024/8e6 = 262ms
  45.         PORTC ^= 0x03;
  46.        
  47.         switch(cx1++)
  48.         {
  49.                 case 0:
  50.                         PORTD ^= 0x10;
  51.                         break;
  52.                 case 1:
  53.                         PORTD ^= 0x20;
  54.                         break;
  55.                 case 2:
  56.                         PORTD ^= 0x40;
  57.                         break;
  58.                 case 3:
  59.                         PORTD ^= 0x80;
  60.                         break;
  61.                 default:
  62.                         break;
  63.         }
  64.        
  65.         cx1 &= 0x3;
  66. /*
  67.         if(cx1++ == 0x03)
  68.         {
  69. //                PORTD ^= (0x01 << 5) | (0x01 << 6) |  (0x01 << 7);
  70.                 PORTD ^= 0xf0;
  71.                 cx1 = 0;
  72.         }
  73. */
  74. }

  75. ISR(TIMER1_OVF_vect)
  76. {
  77. //code
  78.         TIFR = (0x01 << OCF1A);
  79.         PORTC ^= 0x03;
  80. }

  81. void tm1_init(void)
  82. {
  83.         //TCCR1A COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
  84.         //TCCR1B ICNC1  ICES1  –      WGM13  WGM12 CS12  CS11  CS10
  85. #if TM1_OVERFLOW
  86.         TCNT1 = 0xff00;
  87.         TIMSK = (0x01 << TOIE1);
  88.         TCCR1B = 0x05;
  89. #elif TM1_CTC
  90.         TCNT1 = 0;
  91. //        TCCR1A = 0x01 << 6; //A比较
  92.         TCCR1A = 0; //
  93.         OCR1A = 0x00ff;
  94.         OCR1B = 0x01ff;
  95.         TCCR1B = 0x04 | (0x01 << 3);
  96.         TIMSK = (0x01 << OCIE1A);
  97. #elif TM1_FPWM //--Fast PWM, 8-bit
  98.         //周期计算 0x100*1024/8e6 = 32.768ms
  99.         //频率计算 8e6/(0x100*1) = 31250.0hz
  100.         TCNT1 = 0;
  101.         OCR1A = dr1;
  102.         OCR1B = dr2;
  103.         TCCR1A = (0x00 << WGM11) | (0x01 << WGM10) | (0x2 << COM1A0)  | (0x2 << COM1B0);
  104.         TCCR1B = (0x00 << WGM13) | (0x01 << WGM12) |\
  105.                         0x01;
  106.         DDRE |= (0x01 << PE2);
  107. #endif
  108. }

  109. void tm0_init(void)
  110. {
  111. #if TM0_CTC
  112.         TCNT0 = 0;
  113.         OCR0 = 0xef;
  114.         TCCR0 = (0x01 << WGM01) | (0x01 << COM00) | 0x05;
  115. #elif TM0_FPWM
  116.         //周期计算 0x100*1024/8e6 = 32.768ms
  117.         //频率计算 8e6/(0x100*1024) = 30.5hz
  118.         TCNT0 = 0;
  119.         OCR0 = 0x30;
  120.         TCCR0 = (0x01 << WGM01) | (0x01 << WGM00) |\
  121.                         (0x01 << COM01) |\
  122.                         0x05;
  123. #elif TM0_PCPWM
  124.         //周期计算 0x100*1024*2/8e6 = 65.536ms
  125.         //频率计算 8e6/(2*0x100*1024) = 15.25hz
  126.         TCNT0 = 0;
  127.         OCR0 = 0x30;
  128.         TCCR0 = (0x01 << WGM00) |\
  129.                         (0x01 << COM01) |\
  130.                         0x05;
  131. #endif       
  132. }

  133. void ux_init(void)
  134. {
  135.         UBRRH = 0;
  136.         UBRRL = 25;//38400
  137.         UCSRA = (0x01 << U2X);
  138.         UCSRB = (0x01 << RXCIE)|(0x01 << TXEN)|(0x01 << RXEN);
  139.         UCSRC = (0x01 << URSEL)|(0x03 << UCSZ0);
  140. }

  141. void ux_tx_bytes(char *ptr, char len)
  142. {
  143.         uint8_t i;
  144.         for(i=0;i<len;i++)
  145.         {
  146.                 while(!(UCSRA & (0x01 << UDRE)));
  147.                 UDR = *ptr++;
  148.         }
  149. }


  150. void bsp_init(void)
  151. {
  152.     //pa0...pa3作为遥控输入端
  153.     DDRA = 0x00;
  154.     PORTB |= 0x0f << 2;
  155.     DDRB |= 0x0f << 2;
  156.     PORTB &= ~(DIR1 | DIR2);
  157.    
  158.     DDRB |= 0x01; //PB0 as OCR0
  159.    
  160.     DDRC = 0x0f;
  161.     PORTC = 0;
  162. /*   
  163.     DDRD |= (0x01 << 5) | (0x01 << 6) | (0x01 << 7);
  164.     PORTD |= (0x01 << 5) | (0x01 << 6) | (0x01 << 7);
  165. */
  166.     DDRD = 0xf0;
  167.     PORTD = 0x00;
  168.    
  169.     duty_ratio();
  170.     tm0_init();
  171.     tm1_init();
  172.     ux_init();
  173.     sei();
  174.     cmd_index = 0;
  175. }

  176. void ux_mon(void)
  177. {
  178.         int16_t rx_val;
  179.         rx_val = ux_rx_check_q();
  180.        
  181.         if(-1 == rx_val)return;
  182.                
  183.         if(cmd_index < 16)
  184.         {
  185.                 cmd_buff[cmd_index++] = rx_val & 0xff;
  186.         }
  187.        
  188.         if(cmd_index == cmd_buff[0])
  189.         {
  190.                 cmd_index = 0;
  191.                 if(0 == ux_cmd(cmd_buff))
  192.                 {
  193.                         ux_tx_bytes(cmd_buff, sizeof(cmd_buff));
  194.                 }
  195.         }
  196. }

评分

参与人数 1威望 +6 收起 理由
qin552011373 + 6 很给力!

查看全部评分

qin552011373 发表于 2013-12-18 08:25 | 显示全部楼层
建立楼主拿ICC直接生成一个定时器文件看看是不是配置出了问题
SLEET1986 发表于 2013-12-18 08:49 | 显示全部楼层
没开中断
 楼主| feiyinglala 发表于 2013-12-19 19:01 | 显示全部楼层
qin552011373 发表于 2013-12-18 08:25
建立楼主拿ICC直接生成一个定时器文件看看是不是配置出了问题

生成定时器文件?是指hex文件吗?
qin552011373 发表于 2013-12-20 08:40 | 显示全部楼层
feiyinglala 发表于 2013-12-19 19:01
生成定时器文件?是指hex文件吗?

c文件
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

224

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

21

主题

224

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部