打印
[AVR单片机]

请教ATmega640模拟器和比较器的使用

[复制链接]
2222|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jjl3|  楼主 | 2007-5-10 15:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请帮我看看下面的程序:

#include<avr/io.h>
#include<avr/interrupt.h>

#define __disable_interrupt()       asm("cli")  //Turn off global interrupt
#define __enable_interrupt()        asm("sei")  //Turn on global interrupt

unsigned char ADC_valH = 0;
unsigned char ADC_valL = 0;
unsigned char first1 = 0;
unsigned char first2 = 0;


void ADC2_ini(void)
{
    
    ADCSRB = 0x40;
         ADMUX  = 0x42;
    ADCSRA = 0xEF;                   // ADC2使能,free run模式
}

SIGNAL(ADC_vect)                                      // ADC Conversion Complete interrupt service routine 

    if(ADC_valH != (ADCH& 0x03) || ADC_valL != ADCL)
      {
       ADC_valH = ADCH & 0x03;
            ADC_valL = ADCL;
            UART_transmit(ADC_valH);
            UART_transmit(ADC_valL);             //如果ADC转换值变化就发送新值
      }

}

void Comparator_ini(void)
{
    ACSR = ACSR & 0xF7;                               //ensure interrupt is off before changing
    ADCSRB = 0x40;
    DIDR1  = 0x03;
    ADMUX  = 0x00;
    ACSR   = 0x08;                              // AIN0接正输入,ADC0接负输入,比较器变化就产生中断
}

SIGNAL(ANALOG_COMP_vect)                              // Analog Comparator interrupt service routine 

    sends("Comparator changed!");
    UART_transmit('\n');
}

void UART3_ini(void)
{
    //UART3 口
    UCSR3B = 0x00;                                  //disable while setting baud rate
    UCSR3C = 0x06;                                  //异步,8位数据,无奇偶校验,一个停止位,无倍速
    UBRR3L = 0x67;                                  //baudrate = 9600 at system clk = 16MHz 
    UBRR3H = 0x00;                               
    UCSR3B = 0x98;                                  //接收中断使能,接收允许,发送允许


void UART_transmit(unsigned char dat)
{
   while ( !( UCSR3A & (1<<UDRE3)) );
    UDR3 = dat;
}

void sends(unsigned char *ptr)
{
    while (*ptr)
    {
        UART_transmit(*ptr++);
    }
}

int main(void)
{
    __disable_interrupt();
    //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
    PORTA = 0xFF;               //不用的管脚使能内部上拉电阻
    DDRD  = 0xC0;
    PORTD = 0xC0;

    UART3_ini();
    __enable_interrupt();

    while(1)
    {

      if(PINJ & 0x04)
         {
           if(first1 ==0)
            {
              ADCSRA = 0x00;
              Comparator_ini();
              first1 = 0xaa;
              first2 = 0;
              sends("Comparator enable! ADC disable!");
              UART_transmit('\n');
             }
            PORTD = 0x80;
          }
        else 
          {
            if(first2 == 0)
             {
              ACSR = 0x00;
              ADC2_ini();
              first1 = 0;
              first2 = 0xaa;
              sends("ADC enable! Comparator disable!");
              UART_transmit('\n');
              ADCSRA = (1<<ADSC);                      // 启动ADC
             }
             PORTD = 0x40;
           }

     }

    return 0;

}

SIGNAL(USART3_RX_vect)                              // USART Receiver interrupt service routine 

     UART_transmit(UDR3);
}


PJ2是个摇杆开关,用于选择使能比较器使能或ADC使能.
当使能比较器时,输出如下:
Comparator changed!
Comparator enable! ADC disable!
然后再怎么改变负端的电压也不会再产生输出了.
不知为什么?


当使能ADC时,输出如下:
ADC enable! Comparator disable!
改变ADC2的输入电压没输出,
好象没有进入到ADC的中断中.

请帮忙,谢谢!!

相关帖子

沙发
jjl3|  楼主 | 2007-5-10 22:44 | 只看该作者

现在比较器可以产生中断了,但是。。。

有时调节比较器的输入端电压产生中断,但会产生很多次中断,
我在中断服务程序改为:
SIGNAL(ANALOG_COMP_vect)                              // Analog Comparator interrupt service routine 

    ACSR   = (1<<ACI);
    sends("Comparator changed!");
    UART_transmit('\n');
}

增加了一句ACSR   = (1<<ACI);
竟然再也产生不了中断了.

晕死了!:(

使用特权

评论回复
板凳
szxw| | 2007-5-11 16:10 | 只看该作者

多次中断可能是正负端电压差接近零伏时的临界抖动所致

使用特权

评论回复
地板
xwj| | 2007-5-11 19:52 | 只看该作者

正是有钱人啊...

使用特权

评论回复
5
jjl3|  楼主 | 2007-5-13 13:19 | 只看该作者

我又修改了中断程序

SIGNAL(ANALOG_COMP_vect)                              

    if ((ACSR&(1<<ACO))==0)
      {
        sends("Voltage is higher than VREF!");
        UART_transmit('\n');
       }
       else{
             ("Voltage is lower than VREF!");
             UART_transmit('\n');             
            }
}

(注:Voltage 是接ADC0的电压;VREF是接AIN0的电压)

发现怎么调节比较器两端电压只有当Voltage > VREF时,有如下输出:
Voltage is higher than VREF!
Voltage is higher than VREF!

。。。
Voltage is higher than VREF!

当Voltage < VREF时,无输出

为什么呀?这个比较器快搞疯我了:((((((((

使用特权

评论回复
6
enjoy21cn| | 2008-6-26 20:31 | 只看该作者

强人啊!

强人啊!见识了!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

266

帖子

2

粉丝