[AVR单片机] 想用按键控制Atmega16产生PWM,请指导?谢谢

[复制链接]
2164|11
 楼主| studying123 发表于 2013-3-9 22:16 | 显示全部楼层 |阅读模式
我本来想给INT0一个低电平触发,使得打开T/C1时钟源,当按键弹起的上升沿触发 INT1,从而关断T/C1的时钟源,可是我下面的程序实现不了啊,用示波器检测OC1A和OC1B脚都是混乱的信号。请大家给指导下,对单片机不太会。
  1. #include <iom16v.h>
  2. #include <macros.h>
  3. #pragma interrupt_handler zhuandong:2
  4. #pragma interrupt_handler tingzhi:3
  5. void zhuandong (void) //INT0 低电平触发启动PWM发生
  6.   {
  7.   TCCR1B=0X12;
  8.   }
  9. void tingzhi (void)  //INT1 上升沿触发停止PWM发生
  10. {
  11.   TCCR1B=0X00;
  12. }
  13. void main(void)
  14. {
  15. DDRA|=0x01;
  16. DDRD|=0x30;
  17. MCUCR|=0x0C;
  18. GICR|=0xC0;
  19. TCCR1A=0x63;
  20. TCCR1B=0x00;
  21. OCR1A=1249;
  22. OCR1B=250;
  23. while(1)
  24.   {
  25.    PORTA|=0X01;
  26.   }
  27. }
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波啊。
qin552011373 发表于 2013-3-10 21:59 | 显示全部楼层
studying123 发表于 2013-3-10 21:55
代码是自己写的。生成程序可以,可是不出PWM波啊。

建议先调出来PWM  然后再调出来其他的  最后整体拼凑
yklstudent 发表于 2013-3-11 14:19 | 显示全部楼层
虽然不了解ICC 但是不得不佩服楼主了
qin552011373 发表于 2013-3-11 21:35 | 显示全部楼层
yklstudent 发表于 2013-3-11 14:19
虽然不了解ICC 但是不得不佩服楼主了

如果有较好的程序  可以分享一下哦
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;
}
只是对这个有点意见
phoebuss 发表于 2013-3-12 14:25 | 显示全部楼层
本帖最后由 phoebuss 于 2013-3-12 14:28 编辑

我前不久写的~~

  1. /*
  2. Config
  3. PIN21(PD7):PWM Output;
  4. PIN18~20: Button1~3 Input;
  5. PIN14~17: Display_Select Output;
  6. PIN1~8: Display_Data Output;
  7. */

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

  10. #define uchar unsigned char
  11. #define uint unsigned int

  12. #define BUT1 PD4
  13. #define BUT2 PD5
  14. #define BUT3 PD6

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

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

  28. void Display_integer(uint itg)
  29. {
  30.         const uchar seg7[10]={
  31.         0xC0, 0xF9, 0xA4, 0xB0, 0x99,
  32.         0x92, 0x82, 0xF8, 0x80, 0x90};
  33.         const uint exp10[4]={1, 10, 100, 1000};
  34.         uchar i, j;
  35.         
  36.         display_data[1]=0xFF;
  37.         display_data[2]=0xFF;
  38.         display_data[3]=0xFF;
  39.         
  40.         if(itg > 9999)
  41.         {
  42.                 display_data[0]=0xBF;
  43.                 return; //判断是否超过4位
  44.         }
  45.         
  46.         j=1;
  47.                
  48.         if(itg > 999)
  49.                 j=4;
  50.         else if(itg > 99)
  51.                 j=3;
  52.         else if(itg > 9)
  53.                 j=2;
  54.         
  55.         for(i=0;i<j;i++)
  56.                 display_data = seg7[(itg % exp10[i+1] /exp10)];                        
  57. }
  58.         
  59. void Delayms(uint MS)
  60. {
  61.         uint i,j;
  62.         for( i=0;i<MS;i++)
  63.                 for(j=0;j<2282. ;j++);        //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
  64. }

  65. void port_init(void)
  66. {
  67.         DDRD  = 0x8F;
  68.          PORTD = 0xFF;
  69.         DDRB = 0xFF;
  70.         PORTB = 0xFF;
  71. }

  72. void timer0_init(void)
  73. {
  74.         TCCR0 = 0x00;
  75.         TCNT0 = 128;
  76.          TCCR0 = 0x04; //start timer
  77. }

  78. #pragma interrupt_handler timer0:iv_TIMER0_OVF
  79. void timer0(void)
  80. {
  81.         static unsigned char i=0;
  82.          TCNT0 = 128; //reload counter value
  83.          
  84.         
  85.         if(i > 3)
  86.                 i=0;
  87.         
  88.         PORTD = BIT(i)|0b11110000;
  89.         PORTB = display_data;
  90.         i++;         
  91. }

  92. //TIMER2 initialize - prescale:1
  93. // WGM: PWM Fast
  94. // desired value: 31250Hz
  95. // actual value: 31250.000Hz (0.0%)
  96. void timer2_init(void)
  97. {
  98.          TCNT2 = 0x00; //setup
  99.          OCR2  = 127;        //50%
  100.          TCCR2 = BIT(WGM20)|BIT(WGM21)|BIT(COM21)|BIT(CS20); //start
  101. }

  102. //call this routine to initialize all peripherals
  103. void init_devices(void)
  104. {
  105.          //stop errant interrupts until set up
  106.          CLI(); //disable all interrupts
  107.          port_init();
  108.          timer2_init();
  109.         timer0_init();
  110.         TIMSK = 0x01;
  111.          SEI(); //re-enable interrupts
  112.          //all peripherals are now initialized
  113. }

  114. void main(void)
  115. {
  116.         uint percent=50;
  117.         Display_integer(50);
  118.         init_devices();
  119.         
  120.         while(1)
  121.         {
  122.                 if(!(BIT(BUT1)&PIND))
  123.                 {
  124.                         Delayms(10);
  125.                         if(!(BIT(BUT1)&PIND))
  126.                         {
  127.                                 if(percent == 100)
  128.                                         continue;
  129.                                 
  130.                                 Delayms(200);
  131.                                 percent++;
  132.                                 OCR2 = PWM[percent];
  133.                                 Display_integer(percent);
  134.                         }
  135.                 }
  136.                
  137.                 if(!(BIT(BUT2)&PIND))
  138.                 {
  139.                         Delayms(10);
  140.                         if(!(BIT(BUT2)&PIND))
  141.                         {
  142.                                 if(percent == 0)
  143.                                         continue;
  144.                                 
  145.                                 Delayms(200);
  146.                                 percent--;
  147.                                 OCR2 = PWM[percent];
  148.                                 Display_integer(percent);
  149.                         }
  150.                 }
  151.                
  152.                 if(!(BIT(BUT3)&PIND))
  153.                 {
  154.                         Delayms(10);
  155.                         if(!(BIT(BUT3)&PIND))
  156.                         {                        
  157.                                 Delayms(200);
  158.                                 percent = 50;
  159.                                 OCR2 = PWM[percent];
  160.                                 Display_integer(percent);
  161.                         }
  162.                 }                        
  163.         }        
  164. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 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 ...

我刚接触这东西,还不懂,希望指点下。这样写有什么问题吗?真心求教
yklstudent 发表于 2013-3-12 16:23 | 显示全部楼层
ICC真的不了解 只是一开始对你的中断写法感觉奇怪 哪个是INT1函数 哪个是INT2函数而已
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

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