搜索
bottom↓
回复: 4

AVR STUDIO4仿真中定时器T1工作在模式9(相位与频率可调模式)的奇怪问题.

[复制链接]

出0入0汤圆

发表于 2008-3-24 11:47:33 | 显示全部楼层 |阅读模式
马老师:
    我刚刚接触AVR单片机,目前我在做一个程序,使用M8输出频率和占空比均可调节的波形.
    选用相位与频率可调模式,使用OCB1为输出;PORTD为输入端(低5位分别对应5个不同的频率值,高3位对占空比进行调节)
    使用ICCAVR编译C代码,用AVR STUDIO4进行仿真,但在对定时器1初始化后,OCR1AH,OCR1BH和TCNT1H的值均自动清零;而在后面对OCR1A的写入时,都是写入高位和低位后执行下一条指令后,OCR1AH自动清零.难道是访问16位寄存器时出的问题,可我写入时都是先写高八位,再写低八位,不清楚,求教.

    程序代码如下:
    //ICC-AVR application builder : 2008-3-20 15:39:09
// Target : M88
// Crystal: 8.0000Mhz


#include<iom88v.h>
#include<macros.h>

void port_init(void)
{
PORTB = BIT(PB2);
DDRB  = BIT(PB2);
PORTC = 0x00; //m103 output only
DDRC  = 0x00;
PORTD = 0xfe;
DDRD  = 0x00;
PIND  = 0xFE;
}

//TIMER1 initialize - prescale:1
// WGM: 9) PWM phz freq correct, TOP=OCRnA
// desired value: 73Hz
// actual value: 73.001Hz (0.0%)
void timer1_init(void)
{
TCCR1B = 0x10; //stop
TCNT1H = 0x29; //setup
TCNT1L = 0xF6;
OCR1AH = 0xD6;
OCR1AL = 0x0A;
OCR1BH = 0x6B;
OCR1BL = 0x05;
TCCR1A = 0x11;
TCCR1B = 0x11; //start Timer

}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer1_init();

MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EIMSK = 0x00;

TIMSK0 = 0x00; //timer 0 interrupt sources
TIMSK1 = 0x00; //timer 1 interrupt sources
TIMSK2 = 0x00; //timer 2 interrupt sources

PCMSK0 = 0x00; //pin change mask 0
PCMSK1 = 0x00; //pin change mask 1
PCMSK2 = 0x00; //pin change mask 2
PCICR = 0x00; //pin change enable
PRR = 0x00; //power controller
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void delay_short(int t) // 短延時
{
  int i;
  for (i=0;i<t;i++);
}
char scan_key1(void)  // 按鍵掃瞄
{  
  char s;
   s = 0;
  if ((PIND & 0x1f) != 0x1f)
  {
  
  if ((PIND & 0x01) == 0)  
  {
    s = 1;
    delay_short(1000);   
  }
   
  if ((PIND & 0x2) == 0)  
  {
    s = 2;
    delay_short(1000);   
  }

  if ((PIND & 0x4) == 0)  
  {
    s = 3;
    delay_short(1000);   
  }
    if ((PIND & 0x8) == 0)  
  {
    s = 4;
    delay_short(1000);   
  }
    if ((PIND & 0x10) == 0)  
  {
    s = 5;
    delay_short(1000);   
  }
  PIND=0xff;
  };
  while((PIND & 0x1f) != 0x1f);   // 判斷按鍵是不是放開   
  return s;   
}
char scan_key2(void)  // 按鍵掃瞄
{  
  char v;
   v = 0;
  if ((PIND & 0xe0) != 0xe0)
  {
  
  if ((PIND & 0x20) == 0)  
  {
    v = 1;
    delay_short(1000);   
  }
   
  if ((PIND & 0x40) == 0)  
  {
    v = 2;
    delay_short(1000);   
  }
   
  if ((PIND & 0x80) == 0)  
  {
    v = 3;
    delay_short(1000);   
  }
  };
  while((PIND & 0xe0) != 0xe0);   // 判斷按鍵是不是放開   
  return v;   
}
void main(void)  
{   
char key1,key2,OCR1_VH,OCR1_VL;
init_devices();  
OCR1_VL = OCR1AL;
OCR1_VH = OCR1AH;
while(1)
{
   key1 = scan_key1();
   if (key1 > 0)
   {
     if (key1==1) // 设定频率值
    {  
      OCR1AH = 0x6B;
      OCR1AL = 0x05;
      OCR1BH = 0x35;
      OCR1BL = 0x82;       
          
    };
     
     if (key1==2) // 设定频率值
    {  
      OCR1AH = 0x35;
      OCR1AL = 0x82;
          OCR1BH = 0x1A;
      OCR1BL = 0xC1;
    };     
     
     if (key1==3) //设定频率值
    {  
      OCR1AH = 0x1A;
      OCR1AL = 0xC1;
          OCR1BH = 0x0D;
      OCR1BL = 0x60;
    };      
         if (key1==4) // 设定频率值
    {  
      OCR1AH = 0x0D;
      OCR1AL = 0x60;
          OCR1AH = 0x06;
      OCR1AL = 0xB0;
    };  
         if (key1==5) // 设定频率值
    {  
      OCR1AH = 0x06;
      OCR1AL = 0xB0;
          OCR1AH = 0x03;
      OCR1AL = 0x5B;
    };  
   }
   key2 = scan_key2();
   if (key2 > 0)
   {
     if (key2==1) // 減少佔空比
    {  
          if(OCR1_VL > 100)
      {
            OCR1_VL -= 100;
          }
          else
          {
            if (OCR1_VH > 0)
            {
                  OCR1_VH -= 1;
                  OCR1_VL += 156;
                }
                else
                {
                  OCR1_VH = 0;
                  OCR1_VL= 0;
                }
          }
              OCR1BH = OCR1_VH;
                  OCR1BL = OCR1_VL;
      };
     
     if (key2==2) // 增加佔空比
    {  
        if(OCR1_VL < 156)
      {
            OCR1_VL += 100;
          }
          else
          {
            if (OCR1_VH < 255)
            {
                  OCR1_VH += 1;
                  OCR1_VL -= 156 ;
                }
                else
                {
                  OCR1_VH = 0xFF;
                  OCR1_VL = 0xFF;
                }
          }
              OCR1BH = OCR1_VH;
                  OCR1BL = OCR1_VL;
    };     
     
     if (key2==3) // 全黑,佔空比為100%  
    {  
      OCR1_VH = OCR1AH;
          OCR1_VL = OCR1AL;
      OCR1BH = OCR1_VH;
          OCR1BL = OCR1_VL;
    };      
   }
};  
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2008-3-24 20:43:31 | 显示全部楼层
在C里面最好直接用16位的赋值语句,如:OCRA1 = 0Xxxxx.分成高位和低位写的话,中间被中断打断就出问题了.

出0入0汤圆

 楼主| 发表于 2008-3-25 19:14:53 | 显示全部楼层
老师:
   我使用直接赋值语句:OCRA1 = 0Xxxxx,结果还是不行.
   定时器初始化代码:
  void timer1_init(void)
{
TCCR1B = 0x10; //stop
// TCNT1H = 0x29; //setup
// TCNT1L = 0xF6;
   TCNT1=0x29F6;
//OCR1AH = 0xD6;
//OCR1AL = 0x0A;
   OCR1A = 0xD60A;
// OCR1BH = 0x6B;
//OCR1BL = 0x05;
   OCR1B = 0x6B05;
TCCR1A = 0x11;
TCCR1B = 0x11; //start Timer
}
寄存器TCNT1,OCR1A,OCR1B中的内容均能写入,只是在执行 "TCCR1B = 0x11; //start Timer"后自动将三个16位寄存器的高位清零.
还有,我在主程序中将key1设为1,在执行语句:
if (key1==1) // 设定频率值
    {   
     OCR1A = 0x6B05;
     OCR1B = 0x3582;        
           
    };
 发现:低8位能写入,但高8位不能写入,即执行语句后:OCR1A 内容为0005H;OCR1B内容为0082H.
 应该不会是AVR STUDIO本身模拟存在的问题吧?
 

出0入0汤圆

发表于 2008-3-25 21:55:11 | 显示全部楼层
AVR STUDIO4软仿真定时器不准确。

出0入0汤圆

 楼主| 发表于 2008-3-26 11:33:27 | 显示全部楼层
那有没有其它的仿真软件??
    这个程序有没有出错的地方,能不能直接转为HEX文件,烧写入单片机?
    我目前在做毕业设计,时间比较紧,请各位多多帮忙.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 14:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表