icando778 发表于 2011-5-25 10:46:32

马老师,AD的8通道转换中断里变量不能自加问题

马老师你好,我按照你书上改的程序。对AD8通道连续采样,每取一个数换一个通道,到第七通道后 再换到0通道。
但是我在中断中出现了一个很不解的问题,就是我在中断中的计数总是不能够大于7。下面是我的中断程序
interrupt void adc_int()   //转换完成进入中断
{                                    
unsigned long int data;
   data=ADCW;                     //读取数据
adc_disbuffer=data*5000/1024;//数据转换
// ADMUX&=0XE7;
    admux++;                     //通道加1
if(count>7)         
{
   PORTC=0X00;         //外接共阳led灯
   count=0;            //计数清0
   adcflag=1;            //8通道取值完成 标志位
   admux=0x40;          // 重新复为 0 通道
   }   
    ADMUX=admux;         //改变的通道付给 寄存器
   // ADMUX|=0X08;
}


用的CVAVR编译的,TC0比较匹配,4MS启动一次转换。如果我的IF判断成立的话那adcflag为1,外面led灯会亮,但实际灯没亮,标志位也不为1,其他地方没有用count 这个变量的。如果我改成if(count>0),灯就亮了,改成其他的都不亮,如果把 PORTC=0X00;拿到IF外面,灯会亮,说明进了中断。
我不知道是怎么回事,从来没遇到过。 发了一个贴了 没人回,我想直接问一下马老师。

machao 发表于 2011-5-25 18:06:34


adc_disbuffer=data*5000/1024;//数据转换

先注释掉,换成count++,然后测试下

yayayong 发表于 2011-5-25 18:20:13

4ms进来一次中断,时间太快了,可能4MS的时间你根本看不到灯是亮的。

icando778 发表于 2011-5-25 18:37:59

不行啊,还是那样子,我把整个程序都附上来. 主程序也很简单啊。这是哪里的问题?
#include <mega16.h>
#define uint unsigned int
#define uchar unsigned char
uchar count,adcflag,admux;
void delayms(uint x)
{
uint j,k;
for(j=x;j>0;j--)
for(k=1140;k>0;k--);

}

interrupt void adc_int()   //转换完成进入中断
{                                    
unsigned long int data;
   data=ADCW;                     //读取数据
//adc_disbuffer=data*5000/1024;//数据转换
    admux++;                     //通道加1
if(count>7)         
{   
      PORTD=~PORTD;      //外接共阳led灯
   count=0;            //计数清0
   adcflag=1;            //8通道取值完成 标志位
   admux=0x40;          // 重新复为 0 通道
   }   
    ADMUX=admux;         //改变的通道付给 寄存器
   
}
void main()
{
   DDRD=0XFF;
   PORTD=0XfF;
   
   DDRA=0X00;
   PORTA=0X00;
   
   DDRB=0XFF;
   PORTB=0X00;
   
    TCCR0=0X0C;//TC0初始化,256分频,CTC,8M晶振
    OCR0=62;   //4毫秒
    TIMSK=0X02;//比较匹配允许中断
   
    ADMUX=0x40;//参考电源AVCC、ADC0单端输入
    SFIOR&=0X1F;
    SFIOR|=0X60;//选择TC0比较匹配为ADC触发源
   
    ADCSRA=0XAD;//ADC允许,自动触发,ADC转换中断允许
    SREG|=0X80;   // 开总中断
   
   while (1);
    }

machao 发表于 2011-5-25 20:37:30

interrupt void adc_int()   //转换完成进入中断
{                                    
unsigned long int data;
   data=ADCW;                     //读取数据
//adc_disbuffer=data*5000/1024;//数据转换

    count++;

    admux++;                     //通道加1
if(count>7)            
{   
      PORTD=~PORTD;      //外接共阳led灯
   count=0;            //计数清0
   adcflag=1;            //8通道取值完成 标志位
   admux=0x40;          // 重新复为 0 通道   
   }   
    ADMUX=admux;         //改变的通道付给 寄存器
   
}   

是这样测试

jianchangd 发表于 2011-5-25 20:44:37

在这里买书真好呀.还可以和原作者请教.

icando778 发表于 2011-5-25 22:02:49

回复【4楼】machao
-----------------------------------------------------------------------
还是不行啊,而且我发现 当我判断count>0时 灯是亮的, 其他值都不行,所以我猜这个count 只有两个值 0和1,每次进中断都为0了。这是怎么回事?我程序看了很多遍了,我没找出错误。另外 马老师能把你写过的8通道连续取值的中断程序贴出来让我参考一下吗?我问过好几个人了,他们都只写过单通道的。

icando778 发表于 2011-5-26 14:51:36

回复【4楼】machao
---------------------------------------------------------------------
找到问题了,手册上说“被选中的中断标志在其上升沿触发ADC转换。从一个中断标志清零的触发源切换到中断标志置位的触发源会使触发信号产生一个上升沿。”我理解就是一定要中断才能触发AD的转换,但是我设置了中断允许,没写中断程序,这样也不行,所以TC0的中断程序是要有的,我猜是要在中断程序中硬件清标志位,这样下次才会继续置位有上升沿,我当时写直接是把TC0的中断程序屏蔽了的,所以总是只有进一次AD中断。另外马老师AD那一章在说SFIOR寄存器的时候,你说的很简单哦,没有提到要中断。

machao 发表于 2011-5-26 16:00:00

你参考的代码应该就是书中的ADC例子10-3简易电压表,它就是连续取值的,也是采用TC0比较中断触发。只是是单通道,与多通道没有大的区别。这个例子中,TC0是有中断程序的。

在P314页的第二段文字已经解释了连续触发的过程,就是你提到手册上的概念,只是没有具体谈正确的做法,考虑软件例子有的。你提的建议非常好,等下次第2版有再次加印的机会,我会在 10.2.5这节中加上一条连续触发需要注意点。
页: [1]
查看完整版本: 马老师,AD的8通道转换中断里变量不能自加问题