Страница 1 из 2
ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 17:53:53
shurikss123
Ребят помогите запустить на 8-ке АЦП 2-х каналов.
Код: Выделить всё
int main(void)
{
USART_Init();
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
ADMUX=(1<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3);
sei();
PORTB = 0xff;
while (1)
{
//tower_left
USART_Transmit(device);
USART_Transmit(ch);
USART_Transmit(0x1);
ADCSRA |= (1 << ADSC)|(1<<ADFR); //Начинаем преобразование
ADMUX = (1<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1);
while ((ADCSRA&_BV(ADIF))==0x00); //Ждем флага окончания преобразования
USART_Transmit(ADCH);
USART_Transmit(ADCL);
_delay_ms(1000);
};
}
Первый замер шлет нормально последующие, либо ноль либо 1024. и вот понять не могу что не так
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 18:50:00
U235
Обычно сначала переключают канал, а потом запускают измерение.
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 19:09:14
shurikss123
U235 писал(а):Обычно сначала переключают канал, а потом запускают измерение.
я уже по всякому пробывал первый замер делат а потом тупо повторяет
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 19:13:37
ILYAUL
И ещё обычно , раз не работают с прерываниями , ручками сбрасывают флаг ADIF Сбрасывается он записью 1
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 19:21:14
s_black
shurikss123 писал(а):Ребят помогите запустить на 8-ке АЦП 2-х каналов.
Вот
пример и для трёх каналов. СмотрИте исходник.
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 19:22:59
shurikss123
ILYAUL писал(а):И ещё обычно , раз не работают с прерываниями , ручками сбрасывают флаг ADIF Сбрасывается он записью 1
не то, в протеусе ругается на заблокированный бит?
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 19:29:41
shurikss123
s_black писал(а):shurikss123 писал(а):Ребят помогите запустить на 8-ке АЦП 2-х каналов.
Вот
пример и для трёх каналов. СмотрИте исходник.
в твоем случае 48 мега, в моем 8 мега, есть разница.
Re: ATmega8 2 АЦП
Добавлено: Пн июл 30, 2012 23:19:06
siamds
По Вашей просьбе написал код для двух каналов ADC для ATMega8. Чтобы не возиться с написанием кода программы, программа создана при помощи генератора кодов CV_AVR. Программа промоделирована в Proteus’e. Программа снабжена подробными комментариями. Файлы программы и рисунки генератора кодов во вложении.
Re: ATmega8 2 АЦП
Добавлено: Вт июл 31, 2012 06:11:44
shurikss123
siamds писал(а):По Вашей просьбе написал код для двух каналов ADC для ATMega8. Чтобы не возиться с написанием кода программы, программа создана при помощи генератора кодов CV_AVR. Программа промоделирована в Proteus’e. Программа снабжена подробными комментариями. Файлы программы и рисунки генератора кодов во вложении.
вечерком посмотрю
Re: ATmega8 2 АЦП
Добавлено: Вт июл 31, 2012 19:10:13
shurikss123
ниче не пойму не работает хоть убей
Re: ATmega8 2 АЦП
Добавлено: Вт июл 31, 2012 21:09:45
U235
Попробуйте так
Код: Выделить всё
int main(void)
{
USART_Init();
ADCSRA=(1<<ADPS1)|(1<<ADPS0);
ADMUX=(1<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1)|(0<<MUX2)|(0<<MUX3);
sei();
PORTB = 0xff;
while (1)
{
//tower_left
USART_Transmit(device);
USART_Transmit(ch);
USART_Transmit(0x1);
ADCSRA |= (1 << ADSC); //Начинаем преобразование
while ((ADCSRA&_BV(ADIF))==0x00); //Ждем флага окончания преобразования
ADMUX = (1<<REFS1)|(1<<REFS0)|(0<<MUX0)|(0<<MUX1);
ADCSRA |= (1 << ADIF);
USART_Transmit(ADCL);
USART_Transmit(ADCH);
_delay_ms(1000);
};
}
Re: ATmega8 2 АЦП
Добавлено: Вт июл 31, 2012 21:15:05
siamds
shurikss123 писал(а):ниче не пойму не работает хоть убей
Давайте разбираться почему не работает. Каким компилятором Вы пользуетесь, и какой симулятор установлен на Вашем компьютере? Программу скачали 11 наших коллег – обратиться к ним работает ли программа у них?
Re: ATmega8 2 АЦП
Добавлено: Вт июл 31, 2012 23:45:21
C@at
siamds пробовал в протеусе ваш проект
ADC_Mega8.rar , у меня все работает

Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 00:33:21
siamds
Уважаемый C@at!
Спасибо за сообщение. Благодаря Вам будет легче искать “глюки” в программе shurikss123.
Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 00:40:01
C@at
Вот если найдется тут такой человек, который подскажет ему, что для поиска "глюка" нужно выложить полностью секретный проект, тогда это действительно поможет.....
Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 11:14:42
Jack_A
C@at писал(а):Вот если найдется тут такой человек, который подскажет ему, что для поиска "глюка" нужно выложить полностью секретный проект, тогда это действительно поможет.....
Да ни в жисть, сопрут ! Копирайт, панимеш

Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 13:27:53
C@at
Jack_A как вы узнали

что все сопрут?
Уже все стырено в личное пользование

...... и спрятано
здесь.
Спасибо
siamds за труд, весьма простой наглядный пример + коментарии!
Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 16:15:01
Angmar
Для ICCAVR есть готовое решение. Несложно портировать в WinAVR, CodeVisionAVR etc.
Привожу сразу с функциями УАРТА, так как применяется отсылка строк из Флеша и РАМа. Проверял на ATMega8 и 32 (никакой разницы).
Главная функция в проекте для чтения АЦП и отправки по УАРТУ -
ADC_transmitValue(). Остаётся в функции main вписать её в нужном вместе. Ну и инициализауию АЦП и УАРТа - ADC_init() и uart0_init()
PS - В функции ADC_transmitValue() надо поставить необх. кол-во каналов.
Спойлер
Код: Выделить всё
//Controller: ATmega32 (16MHz Crystal). Compiler: ICCAVR
#include <iom32v.h>
#include <macros.h>
#define ADC_ENABLE ADCSRA |= (1<<ADEN)
#define ADC_DISABLE ADCSRA &= 0x7F
#define ADC_START_CONVERSION ADCSRA |= (1<<ADSC)
#define TX_NEWLINE {transmitByte(0x0d); transmitByte(0x0a);}
void ADC_init(void);
int ADC_read(void);
float ADC_calculateTemp(int);
unsigned char* updateTempDisplay(float);
unsigned char* temporary(void);
void ADC_transmitValue(void);
unsigned char receiveByte(void);
void transmitByte(unsigned char);
void transmitString_F(const unsigned char*);
void transmitString(unsigned char*);
unsigned char valueDisplay[]=": . volt";
float Vref = 5.00; // Напряжение на Vref АЦП
// Initialize the ADC ******************************************************
void ADC_init(void)
{
ADCSRA = 0x00; //disable adc
ADMUX = 0x40; //select adc input 0
ADCSRA = 0x86;
}
// Do a Analog to Digital Conversion **********************************************
int ADC_read(void)
{
char i;
int ADC_temp, ADCH_temp;
int ADC_var = 0;
ADC_ENABLE;
ADC_START_CONVERSION; //первый раз вычитываем всякий мусор из АЦП
while(!(ADCSRA & 0x10)); //Ждём, флага окончания преобразования. ADIF flag active
ADCSRA|=(1<<ADIF);
for(i=0;i<8;i++) //Считывание 8 раз для усреднения и повышения точности (потом поделим на 8)
{
ADC_START_CONVERSION;
while(!(ADCSRA & 0x10)); // wait for conversion done, ADIF flag active
ADCSRA|=(1<<ADIF);
ADC_temp = ADCL; // read out ADCL register
ADCH_temp = ADCH; // read out ADCH register
ADC_temp +=(ADCH_temp << 8);
ADC_var += ADC_temp; // accumulate result (8 samples) for later averaging
}
ADC_var = ADC_var >> 3; //усредняем выборку из 8 преобразований
ADC_DISABLE;
return ADC_var;
}
//To calculate Voltage *************************************************
float ADC_calculateValue(int inputValue)
{
float actualValue;
actualValue=(inputValue * Vref/1024.0); //calculates the voltage present
return actualValue;
}
//To update the valueDisplay string based on the latest voltage read ************************
unsigned char* updateDisplay(float actualValue)
{
int temp;
unsigned char c;
temp=(int)(actualValue*100.0); //to include decimal point for display
if((actualValue*100.0 - temp) >= 0.5) temp=temp+1;
valueDisplay[5] = ((unsigned char)(temp%10)) | 0x30;
temp=temp/10;
valueDisplay[4] = ((unsigned char)(temp%10)) | 0x30;
temp=temp/10;
valueDisplay[2] = ((unsigned char)(temp%10)) | 0x30;
temp=temp/10;
return valueDisplay;
}
//to transmit the voltage values at 8 ADC channels *******************************
void ADC_transmitValue(void)
{
int value;
float value1;
unsigned char i;
for(i=0; i<8; i++) // вместо 8 устанавливаем необходимое кол-во или выбранные номера каналов АЦП !!!
{
ADMUX &= 0xe0;
ADMUX |= i; //ВЫБИРАЕМ КАНАЛ
value = ADC_read();
value1 = ADC_calculateValue(value);
//following three functions are part of the UART routines, sending the
//voltage values to serial port. UART must be initialized before
//calling them
transmitString_F(" Channel ");
transmitByte(i | 0x30);
transmitString(updateDisplay(value1));
TX_NEWLINE;
}
}
//******** FUNCTIONS FOR SERIAL COMMUNICATION USING UART *******
//Function to initialize UART **************************
//UART0 initialize
// desired baud rate: 19200
// actual: baud rate:19231 (0.2%)(at 16MHz crystal)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x33; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
//Function to receive a single byte **********************
unsigned char receiveByte( void )
{
unsigned char data, status;
while(!(UCSRA & (1<<RXC))); // Wait for incomming data
status = UCSRA;
data = UDR;
return(data);
}
//Function to transmit a single byte *************************
void transmitByte( unsigned char data )
{
while ( !(UCSRA & (1<<UDRE)) )
; //Wait for empty transmit buffer
UDR = data; //Start transmition
}
//Function to transmit a string stored in Flash *****************
void transmitString_F(const unsigned char* string)
{
while (*string)
transmitByte(*string++);
}
//Function to transmit a string from RAM
//***************************************************
void transmitString(unsigned char* string)
{
while (*string)
transmitByte(*string++);
}
Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 19:10:50
shurikss123
siamds писал(а):shurikss123 писал(а):ниче не пойму не работает хоть убей
Давайте разбираться почему не работает. Каким компилятором Вы пользуетесь, и какой симулятор установлен на Вашем компьютере? Программу скачали 11 наших коллег – обратиться к ним работает ли программа у них?
gcc-avr 1:4.5.3-3
avr-libs 1:1.7.1-2
proteus не важно, я в железе пробывал, на двух atmega8, кстате на atmega168 завелось без проблем по даташиту.
вот исходник
https://code.google.com/p/sfag/source/b ... po=tank-tx
Re: ATmega8 2 АЦП
Добавлено: Ср авг 01, 2012 20:06:00
ILYAUL