Программирование АЦП на АТмеге16, подскажите, пожалуйста?

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
yumic2004
Родился
Сообщения: 3
Зарегистрирован: Ср мар 23, 2011 09:52:40

Программирование АЦП на АТмеге16, подскажите, пожалуйста?

Сообщение yumic2004 »

Всем доброго времени суток.
Собираю прибор - звук с электретного микрофона преобразуется в синусоидальный сигнал, который усиливается и поступает на АЦП - ADC0 на ATmega16, источник опорного напряжения внутренний - 2,56, AREF через конденсатор 100 нФ подключен к земле.
К прибору подключен индикатор - LCD WH1602L-PGB - D0-D7 подключены к порту D, а управляющие ноги RS, RW и Е - С0, С1 и C2 соответственно. Написал кое-какую программу.. Текст на экран выводится, все норм (в качестве теста пробовал вывести свое имя - работает). Но не могу разобраться с АЦП. Перед тем как ставить микроконтроллер в панельку, я подключал осциллограф - одним щупом к микрофону, вторым втыкал в панельку, где должен быть ADC0, и говорил в микрофон - осциллограф показывает, что сигнал есть, что он усиливается.

Подскажите, пожалуйста, где проблема? У меня в результате всех манипуляций на экране появляется сначала надпись ADC_s (это я поставил, чтобы видеть, что АЦП начал преобразование), а потом ADC " " " " ... (ADC - это чтобы видеть, что прерывание произошло и на экран выводится значение). После вывода последней надписи больше ничего не происходит.

Схему и код в CodeVision прилагаю! Да, еще ... во многих источниках находил ADMUX= ADC_VREF_TYPE & 0xFF - и вот на это при компиляции ругается "must be lvalue".

Изображение

Вот код:

Код: Выделить всё

#include <mega16.h>  // Подключение библиотеки Atmega16
#include <delay.h> // Подключение библиотеки, выполняющую роль задержки    
#include <stdio.h>                                                         

#asm
        .equ __lcd_port=0x15; PORTC
#endasm

#include <lcd.h>

#define  F_CPU 8000000UL  // Тактовая частота МК

// Шина данных - Порт D
#define Port_data PORTD 
#define Pin_data PIND
#define DDRX_data DDRD

// Управляющие выводы LCD подключены к порту С
#define Port_sig PORTC
#define Pin_sig PINC
#define DDRX_sig DDRC
                                              
//Номера выводов микроконтроллера, к которым
//подключены управляющие выводы LCD

#define RS 0
#define RW 1
#define EN 2

//Макросы для работы с битами
#define ClearBit(reg, bit)        reg &= (~(1<<(bit)))
#define SetBit(reg, bit)          reg |= (1<<(bit)) 
#define _delay_us(us)     __delay_cycles((F_CPU / 1000000) * (us));
#define _delay_ms(ms)     __delay_cycles((F_CPU / 1000) * (ms));   
                          
//Макрос для запуска преобразования
#define StartConvAdc() ADCSRA |=0x40
#define ADC_VREF_TYPE 0xC0;

//Подключаем биты регистров АЦП
#define ADEN 7
#define ADSC 6
#define ADATE 5
#define ADIF 4
#define ADIE 3
#define ADPS2 2
#define ADPS1 1
#define ADPS0 0
                                         
#define ion 2.56 //источник опорного напряжения АЦП
#define _BV(bit) (1<<(bit))   
                                
unsigned char lcd_buffer[33];
unsigned char Stat=0; //Управляющий признак
unsigned char ADC_Data; //Хранит результат измерения      
      
//Функция инициализации периферии

void init(void)
{
//Таймер Т1
TCCR1B|=(1<<2); //Предделитель для Т1=256. Начать счет.
TCNT1H=(0xFF-61); //Старший баит счетчика. Инициализация на 0,5 сек
TCNT1L=(0xFF-9); //Младший байт счетчика
TIMSK|=(1<<2); //Разрешить прерывание по переполнению Т1.

//АЦП
ACSR=0x80;
SFIOR=0x00;
ADMUX=ADC_VREF_TYPE;
ADCSRA|=0xAE;
}

//Описания прерываний
interrupt [TIM1_OVF] void timer1_ovf_isr(void) //обработка прерывания по 

переполнению Т1
{ 
TCNT1H=0xFF-61;
TCNT1L=0xFF-9; //переинициализация счетчика на 500 мс.

Stat=1; //начать измерение
}
interrupt [ADC_INT] void adc_isr(void) //обработка по завершению преобразования 

АЦП
{
ADC_Data=ADCW; //скоприровать выходной код на АЦП
Stat=3; //Преобразование завершено  

}                                                  
      
//Функция вывода команды
void LCD_WriteCommand (unsigned char data)
{
  ClearBit(Port_sig, RS);    // Устанавливаем RS в 0
  Port_data = data;        // Выводим данные на шину
  SetBit(Port_sig, EN);    // Устанавливаем E в 1
  delay_us(2);
  ClearBit(Port_sig, EN);    // Устанавливаем Е в 0
  delay_us(40);
}

  
//Функция вывода данных
void LCD_WriteData (unsigned char data)
{
  SetBit(Port_sig, RS);     //Устанавливаем RS в 1
  Port_data = data;        //Выводим данные на шину     
  SetBit(Port_sig, EN);     //Устанавливаем Е в 1
  delay_ms(20);

  ClearBit(Port_sig, EN);    //Устанавливаем Е в 0
  delay_ms(40);  
  }

//Функция инициализации экрана
void LCD_init (void)
{
  DDRX_data |= 0Xff;
  Port_data |= 0Xff;;
  DDRX_sig |= 0Xff;
  Port_sig |= (1<<RW)|(1<<RS)|(1<<EN);
  ClearBit(Port_sig, RW);
  delay_ms(20);
  LCD_WriteCommand(56); //0b00111000 - 8 разрядная шина, 2 строки

  LCD_WriteCommand(12);  //0b00001110 - дисплей, курсор, мерцание включены
  LCD_WriteCommand(1);  //0b00000001 - очистка дисплея
  delay_ms(2);
  LCD_WriteCommand(6);  //0b00000111 - курсор движется вправо, сдвига нет
}
         
int main( void )
{
  init();   
  LCD_init(); 

  
  #asm("sei"); //Разрешить прерывания в программе  
   
  while(1)
  { 
          if (Stat==1) //Если нужно запустить АЦП
                {  
                StartConvAdc(); //Начать преобразование АЦП 
                LCD_WriteData('A');
                LCD_WriteData('D');
                LCD_WriteData('C');                
                LCD_WriteData(' ');                
                LCD_WriteData('s');            
                Stat=3; //дождаться окончания преобразования
                }    
                  
          if (Stat==3) //Если АЦП завершил преобразование
                {
                ADC_Data=100*(ADC_Data);
                LCD_WriteCommand(1);
                LCD_WriteData('A');
                LCD_WriteData('D');
                LCD_WriteData('C');                
                LCD_WriteData(' ');
                sprintf(lcd_buffer,"Stat = %i", Stat);
                lcd_gotoxy(0,1);                 
                sprintf (lcd_buffer,"ADC_Data = %i", ADC_Data);
                lcd_puts(lcd_buffer);
                delay_ms(1500);
                Stat=0;
                }                  
  } 
}

Заранее благодарствую!
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»