Собираю прибор - звук с электретного микрофона преобразуется в синусоидальный сигнал, который усиливается и поступает на АЦП - 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;
}
}
}