搜索
bottom↓
回复: 19

mega8,折磨我一周的问题,求解惑。有ATMEL工程师?

[复制链接]

出0入0汤圆

发表于 2013-3-17 11:03:02 | 显示全部楼层 |阅读模式
本帖最后由 wxwdxx 于 2013-3-17 11:28 编辑

想做一个自动浇花的东西。用mega8L做的,
逻辑一点也不复杂,没想到这么简单的东西,一直调不通,折磨了我一周。
因为涉及到AD,刚开始以为是板子的问题,一发狠,把原来的板子掰碎了,另焊了一个。(洞洞板啊!!全是飞线啊!!!)
结果情况依旧。

最后没办法,我把程序瘦身到只剩一根肠子了——变成了一秒一亮的闪烁灯。
发现还是不能运行。
问题貌似出在timer0的中断上。
我实在是看不出来了,求大家帮我看看吧。
下面是秒闪烁灯的思路以及程序。


之所以做这么多的标记位,是因为我每2ms要做一些事情,每200ms要做另一些事情,每隔几分钟又要做一些事情。

奇怪的是,我用mega16做的秒闪烁灯,可以正常运行,但一样的程序,用mega8,就是不行。
我甚至怀疑是mega8的硬件有问题。有没有ATMEL的工程师,可以帮我看看吗?

代码发在下边,很简单,麻烦大家了。

注:标亮的是我写的程序,其他都是CVavr自动生成的代码。

本帖子中包含更多资源

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

x

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-3-17 11:03:51 | 显示全部楼层
本帖最后由 wxwdxx 于 2013-3-17 11:27 编辑

这个是mega16的秒闪烁灯,运行完全没问题:


#include <mega16.h>

bit time_2ms_ok;
bit time_200ms_ok;
bit time_1s_ok;


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
time_2ms_ok=1;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

int i;
int j;


// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=0
PORTB=0x00;
DDRB=0x01;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62.500 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x03;
TCNT0=0x83;
OCR0=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
       if(time_2ms_ok)
         {time_2ms_ok=0;
          if(++i>=100)
            {i=0;
             time_200ms_ok=1;
            }
         }
      
       if(time_200ms_ok)
         {time_200ms_ok=0;
          if(++j>=5)
            {j=0;
             time_1s_ok=1;
            }
         }
      
       if(time_1s_ok)
         {time_1s_ok=0;
          PORTB.0= ~PORTB.0;

         }
      };
}

出0入0汤圆

 楼主| 发表于 2013-3-17 11:04:40 | 显示全部楼层
本帖最后由 wxwdxx 于 2013-3-17 11:08 编辑

这个是mega8的秒闪烁灯。不能运行。


#include <mega8.h>


bit time_2ms_ok;
bit time_200ms_ok;
bit time_1s_ok;


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
time_2ms_ok=1;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

int i;
int j;


// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=0
PORTB=0x00;
DDRB=0x01;


// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62.500 kHz
TCCR0=0x03;
TCNT0=0x83;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
      if(time_2ms_ok)
         {time_2ms_ok=0;
          if(++i>=100)
            {i=0;
             time_200ms_ok=1;
            }
         }
      
       if(time_200ms_ok)
         {time_200ms_ok=0;
          if(++j>=5)
            {j=0;
             time_1s_ok=1;
            }
         }
      
       if(time_1s_ok)
         {time_1s_ok=0;
          PORTB.0= ~PORTB.0;
         }

      };
}


出0入0汤圆

发表于 2013-3-17 11:09:57 | 显示全部楼层
mega8板子坏了呗

出0入0汤圆

 楼主| 发表于 2013-3-17 11:12:03 | 显示全部楼层
本帖最后由 wxwdxx 于 2013-3-17 11:15 编辑

把最开始的程序也贴上吧,有趣的是,timer0的中断在这里是好的,每200ms启动一次AD转换。
但实际运行的时候,AD采样没问题,显示也没问题,就是对PORTB.4的控制不能。

#include <mega8.h>

flash char led_7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
flash char position[4]={0xf7,0xfb,0xfd,0xfe};
unsigned char dis_buff[4];
unsigned char posit;

unsigned int adc_data;
unsigned int adc_v;

bit time_2ms_ok;
bit time_200ms_ok;
bit time_1s_ok;
bit time_10s_ok;
bit time_10m_ok;

bit irrigation=0;

void adc_to_disbuffer(unsigned int adc)
{char i;

for(i=0;i<=3;i++)
{dis_buff=adc % 10;
  adc /= 10;
}
}


void display(void)
{PORTB |= 0x0f;
PORTD = led_7[dis_buff[posit]];

if(posit==0&&(irrigation||PINB.5))
    PORTD |= 0x80;
if(posit==3)
    PORTD |= 0x80;

PORTB &= position[posit];

if(++posit>=4)
    posit=0;
}



// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
time_2ms_ok=1;
}

#define ADC_VREF_TYPE 0x40

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
// Place your code here
adc_v=(unsigned long)adc_data*5000/1024;
      
adc_to_disbuffer(adc_v);

}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

int i;
int j;
int k;
int s;


// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=0 State3=1 State2=1 State1=1 State0=1
PORTB=0x0F;
DDRB=0x1F;


// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62.500 kHz
TCCR0=0x03;
TCNT0=0x83;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;


// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x8A;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
       if(time_2ms_ok)
         {display();
          time_2ms_ok=0;
          if(++i>=100)
            {i=0;
             time_200ms_ok=1;
            }
         }
      
       if(time_200ms_ok)
         {time_200ms_ok=0;
          ADCSRA|=0x40;            //请看这里,每200ms启动一次AD,完全没问题啊。
          if(++j>=5)
            {j=0;
             time_1s_ok=1;
            }
         }
      
       if(time_1s_ok)
         {time_1s_ok=0;
          PORTB.4= ~PORTB.4;
          if(++k>=600)
            {k=0;
             time_10m_ok=1;
            }
          if(irrigation)
            {s++;
             if(s>=10)
               {s=0;
                time_10s_ok=1;
               }
            }
         }
      
       if(time_10m_ok)
         {time_10m_ok=0;
          if(adc_v>2500)
            irrigation=1;
         }
      
       if(time_10s_ok)
         {time_10s_ok=0;
          irrigation=0;
         }
      
       if(irrigation||PINB.5)
         PORTB.4=1;
       else
         PORTB.4=0;

               
      };
}

出0入0汤圆

发表于 2013-3-17 11:19:00 | 显示全部楼层
用gcc时,中断里面的变量,如果主程序有使用的话,定义时需要加关键字volatile
楼主可以试下

出0入0汤圆

 楼主| 发表于 2013-3-17 11:19:29 | 显示全部楼层
星星亮了夜空 发表于 2013-3-17 11:09
mega8板子坏了呗

我用的是马潮老师的mega16的实验板。用飞线接的mega8.
如果你说是板子不兼容,这个还是有一点点可能的。

但是我用洞洞板搭了两遍电路,两遍啊!!
电路也不复杂,就是一个四位LED,一个继电器。
还不至于出错吧。


对了,我用了个折中的办法,使用了delay_ms()函数,功能完全没问题(不仅在实验板上还是在我焊的电路上)
这个就说明了我的电路板没问题。

一会我把程序贴出来。

出0入0汤圆

 楼主| 发表于 2013-3-17 11:21:00 | 显示全部楼层
sync765 发表于 2013-3-17 11:19
用gcc时,中断里面的变量,如果主程序有使用的话,定义时需要加关键字volatile
楼主可以试下 ...

谢谢,可是我没用过GCC,我用的是CVavr。
同样的思路,mega16没问题,mega8却死了。
目前最有可能是两方面:mega8的硬件问题;CVavr有问题?

出0入0汤圆

 楼主| 发表于 2013-3-17 11:21:57 | 显示全部楼层
本帖最后由 wxwdxx 于 2013-3-17 11:24 编辑

这个是我折中的办法,可以正常运行了。
把200ms的AD采样放在了timer0的中断里。


/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.7e Professional
Automatic Program Generator
?Copyright 1998-2005 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com
e-mail:office@hpinfotech.com

Project :
Version :
Date    : 2013/3/14
Author  : F4CG                           
Company : F4CG                           
Comments:


Chip type           : ATmega8L
Program type        : Application
Clock frequency     : 4.000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>

flash char led_7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
flash char position[4]={0xf7,0xfb,0xfd,0xfe};
unsigned char dis_buff[4];
unsigned char posit;

unsigned int adc_data;
unsigned int adc_v;

int i;

bit irrigation=0;

void adc_to_disbuffer(unsigned int adc)
{char i;

for(i=0;i<=3;i++)
{dis_buff=adc % 10;
  adc /= 10;
}
}


void display(void)
{PORTB |= 0x0f;
PORTD = led_7[dis_buff[posit]];

if(posit==0&&(irrigation||PINB.5))
    PORTD |= 0x80;
if(posit==3)
    PORTD |= 0x80;

PORTB &= position[posit];

if(++posit>=4)
    posit=0;
}


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value
TCNT0=0x83;
// Place your code here
display();
if(++i>=100)
  {i=0;
   ADCSRA|=0x40;
  }
if(irrigation||PINB.5)
  PORTB.4=1;
else
  PORTB.4=0;

}

#define ADC_VREF_TYPE 0x40

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
// Place your code here
adc_v=(unsigned long)adc_data*5000/1024;
      
adc_to_disbuffer(adc_v);

}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

int j;

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=0 State3=1 State2=1 State1=1 State0=1
PORTB=0x0F;
DDRB=0x1F;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62.500 kHz
TCCR0=0x03;
TCNT0=0x83;


// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;


// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=0x8A;

// Global enable interrupts
#asm("sei")

while (1)
      {
      // Place your code here
       for(j=0;j<600;j++)
          delay_ms(1000);
      
       if(adc_v>=2500)
         irrigation=1;
      
       if(irrigation)
         {for(j=0;j<40;j++)
             delay_ms(1000);
          irrigation=0;

         }
               
      };
}

出0入0汤圆

 楼主| 发表于 2013-3-17 11:56:40 | 显示全部楼层
秀一下我做的浇花装置吧。

点击查看大图。

本帖子中包含更多资源

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

x

出0入0汤圆

发表于 2013-3-17 12:23:29 | 显示全部楼层
wxwdxx 发表于 2013-3-17 11:56
秀一下我做的浇花装置吧。

点击查看大图。

不错嘛!

出0入0汤圆

发表于 2013-3-17 12:50:37 | 显示全部楼层
这就是所谓的成长的烦恼,等你过了这一关,你就会发现问题不过如此而已。使用Mega8要学会用模拟调试,还要学会看汇编。入门者最好先从汇编开始,至少要写一个二百行以上的稍具功能的汇编程序,才算过关。然后用C写程序,就不会如此困惑,才不会被陷在某一个问题上,一星期都出不来。

出0入12汤圆

发表于 2013-3-17 12:58:34 | 显示全部楼层
我就想看看那个浇花的东东
有大图吗??

出0入0汤圆

发表于 2013-3-17 13:28:09 | 显示全部楼层
理论上用m16的程序,用m8改动基本不用,除非硬件有问题

出0入0汤圆

发表于 2013-3-17 14:24:39 | 显示全部楼层
12楼说的很好
另外楼主的浇花图太小了
看不清楚

出0入0汤圆

 楼主| 发表于 2013-3-17 14:58:02 | 显示全部楼层
skynet 发表于 2013-3-17 12:58
我就想看看那个浇花的东东
有大图吗??

下载下来就是大图。

出0入0汤圆

 楼主| 发表于 2013-3-17 15:00:31 | 显示全部楼层
悲剧了,传感探头用镀锌板做的,插到土里变成了原电池。根本测不到电阻

我用什么材料做探头比较好呢?

出0入4汤圆

发表于 2013-3-17 16:22:21 | 显示全部楼层
是不是晶振频率问题啊(熔丝配置不对),我之前碰过,由于晶振不对(偏快),所以导致频敏时进中断,主程序一直无法执行,看来好像死机。

楼主如果有条件,在软件中断里,把一个引脚固定取反,然后用示波器测一下频率是否对。

出0入0汤圆

 楼主| 发表于 2013-3-17 17:18:01 | 显示全部楼层
tarzar 发表于 2013-3-17 16:22
是不是晶振频率问题啊(熔丝配置不对),我之前碰过,由于晶振不对(偏快),所以导致频敏时进中断,主程序一直 ...

好办法,有可能。
我设置的是内部4M RC振荡器。难道是Mega8的内部RC有问题?
我换了两只Mega8,都是同样的问题。

可惜我木有示波器 验证不了了。

出0入0汤圆

发表于 2013-3-17 17:29:35 | 显示全部楼层
太多if,M8判断不了。比如M48的,有时候很简单的逻辑分支都做不过,尤其是时序逻辑,比如在一个时间片周期内做逻辑分支,大多时候是可以编译通过,但是执行错误。
所以写程序要以单片机的状态做为出发点去编程,而不是以人的思维逻辑模式为出发点编程,尤其是这种第一时间干啥,第二时间干啥的事情上。我写代码不行,但是我一般是将设计思想说给写代码的人的,就像平面设计师会用ps,而创意总监未必会用一样。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-24 03:16

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

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