mega8,折磨我一周的问题,求解惑。有ATMEL工程师?
本帖最后由 wxwdxx 于 2013-3-17 11:28 编辑想做一个自动浇花的东西。用mega8L做的,
逻辑一点也不复杂,没想到这么简单的东西,一直调不通,折磨了我一周。
因为涉及到AD,刚开始以为是板子的问题,一发狠,把原来的板子掰碎了,另焊了一个。(洞洞板啊!!全是飞线啊!!!)
结果情况依旧。
最后没办法,我把程序瘦身到只剩一根肠子了——变成了一秒一亮的闪烁灯。
发现还是不能运行。
问题貌似出在timer0的中断上。
我实在是看不出来了,求大家帮我看看吧。
下面是秒闪烁灯的思路以及程序。
之所以做这么多的标记位,是因为我每2ms要做一些事情,每200ms要做另一些事情,每隔几分钟又要做一些事情。
奇怪的是,我用mega16做的秒闪烁灯,可以正常运行,但一样的程序,用mega8,就是不行。
我甚至怀疑是mega8的硬件有问题。有没有ATMEL的工程师,可以帮我看看吗?
代码发在下边,很简单,麻烦大家了。
注:标亮的是我写的程序,其他都是CVavr自动生成的代码。 本帖最后由 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 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;
}
};
}
本帖最后由 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 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;
}
};
}
mega8板子坏了呗 本帖最后由 wxwdxx 于 2013-3-17 11:15 编辑
把最开始的程序也贴上吧,有趣的是,timer0的中断在这里是好的,每200ms启动一次AD转换。
但实际运行的时候,AD采样没问题,显示也没问题,就是对PORTB.4的控制不能。
#include <mega8.h>
flash char led_7={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
flash char position={0xf7,0xfb,0xfd,0xfe};
unsigned char dis_buff;
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];
if(posit==0&&(irrigation||PINB.5))
PORTD |= 0x80;
if(posit==3)
PORTD |= 0x80;
PORTB &= position;
if(++posit>=4)
posit=0;
}
// Timer 0 overflow interrupt service routine
interrupt 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 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;
};
}
用gcc时,中断里面的变量,如果主程序有使用的话,定义时需要加关键字volatile
楼主可以试下 星星亮了夜空 发表于 2013-3-17 11:09 static/image/common/back.gif
mega8板子坏了呗
我用的是马潮老师的mega16的实验板。用飞线接的mega8.
如果你说是板子不兼容,这个还是有一点点可能的。
但是我用洞洞板搭了两遍电路,两遍啊!!
电路也不复杂,就是一个四位LED,一个继电器。
还不至于出错吧。
对了,我用了个折中的办法,使用了delay_ms()函数,功能完全没问题(不仅在实验板上还是在我焊的电路上)
这个就说明了我的电路板没问题。
一会我把程序贴出来。 sync765 发表于 2013-3-17 11:19 static/image/common/back.gif
用gcc时,中断里面的变量,如果主程序有使用的话,定义时需要加关键字volatile
楼主可以试下 ...
谢谢,可是我没用过GCC,我用的是CVavr。
同样的思路,mega16没问题,mega8却死了。
目前最有可能是两方面:mega8的硬件问题;CVavr有问题? 本帖最后由 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={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
flash char position={0xf7,0xfb,0xfd,0xfe};
unsigned char dis_buff;
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];
if(posit==0&&(irrigation||PINB.5))
PORTD |= 0x80;
if(posit==3)
PORTD |= 0x80;
PORTB &= position;
if(++posit>=4)
posit=0;
}
// Timer 0 overflow interrupt service routine
interrupt 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 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;
}
};
}
秀一下我做的浇花装置吧。
点击查看大图。{:lol:} {:lol:} {:lol:}
wxwdxx 发表于 2013-3-17 11:56 static/image/common/back.gif
秀一下我做的浇花装置吧。
点击查看大图。
不错嘛! 这就是所谓的成长的烦恼,等你过了这一关,你就会发现问题不过如此而已。使用Mega8要学会用模拟调试,还要学会看汇编。入门者最好先从汇编开始,至少要写一个二百行以上的稍具功能的汇编程序,才算过关。然后用C写程序,就不会如此困惑,才不会被陷在某一个问题上,一星期都出不来。 我就想看看那个浇花的东东
有大图吗?? 理论上用m16的程序,用m8改动基本不用,除非硬件有问题 12楼说的很好
另外楼主的浇花图太小了
看不清楚 skynet 发表于 2013-3-17 12:58 static/image/common/back.gif
我就想看看那个浇花的东东
有大图吗??
下载下来就是大图。 悲剧了,传感探头用镀锌板做的,插到土里变成了原电池。根本测不到电阻{:cry:}
我用什么材料做探头比较好呢? 是不是晶振频率问题啊(熔丝配置不对),我之前碰过,由于晶振不对(偏快),所以导致频敏时进中断,主程序一直无法执行,看来好像死机。
楼主如果有条件,在软件中断里,把一个引脚固定取反,然后用示波器测一下频率是否对。
tarzar 发表于 2013-3-17 16:22 static/image/common/back.gif
是不是晶振频率问题啊(熔丝配置不对),我之前碰过,由于晶振不对(偏快),所以导致频敏时进中断,主程序一直 ...
好办法,有可能。
我设置的是内部4M RC振荡器。难道是Mega8的内部RC有问题?
我换了两只Mega8,都是同样的问题。
可惜我木有示波器{:mad:} 验证不了了。 太多if,M8判断不了。比如M48的,有时候很简单的逻辑分支都做不过,尤其是时序逻辑,比如在一个时间片周期内做逻辑分支,大多时候是可以编译通过,但是执行错误。
所以写程序要以单片机的状态做为出发点去编程,而不是以人的思维逻辑模式为出发点编程,尤其是这种第一时间干啥,第二时间干啥的事情上。我写代码不行,但是我一般是将设计思想说给写代码的人的,就像平面设计师会用ps,而创意总监未必会用一样。
页:
[1]