AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
12.06.2013, 16:02
|
|
Частый гость
Регистрация: 09.07.2007
Сообщений: 22
Сказал спасибо: 1
Сказали Спасибо 3 раз(а) в 2 сообщении(ях)
|
странное поведение АЦП на ATmega32A
При первом измерении выдается правильное значение, при втором и последующих 1023. Я использую макетную плату USB-ATmega32. Чтобы использовать опорное напряжение от внутреннего источника, в макетке был выпаян резистор R7 на выводе AREF. До удаления резистора результаты АЦП были правильными, но с опорным напряжением = VCC
Схема:
http://mail.kosmodrom.com.ua/pdf/ATMEGA32-USB.pdf
Исходник
Код:
|
#define LED_PORT_DDR DDRB
#define LED_PORT_OUTPUT PORTB
#define LED_BIT 0
#include ‹avr/io.h›
#include ‹avr/wdt.h›
#include ‹avr/interrupt.h› /* for sei() */
#include ‹util/delay.h› /* for _delay_ms() */
#include ‹avr/eeprom.h›
#include ‹avr/pgmspace.h› /* required by usbdrv.h */
#include "usbdrv.h"
#include "oddebug.h" /* This is also an example for using debug macros */
#include "requests.h"
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
PROGMEM const char usbHidReportDescriptor[22] = { /* USB report descriptor */
0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Vendor Usage 1)
0xa1, 0x01, // COLLECTION (Application)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x80, // REPORT_COUNT (128)
0x09, 0x00, // USAGE (Undefined)
0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf)
0xc0 // END_COLLECTION
};
//Программа инициализации АЦП
void init_ADC (void)
{
ADCSRA=(1‹‹ADEN)|(1‹‹ADPS1)|(1‹‹ADPS0);
/*Включаем АЦП, тактовая частота преобразователя =/8
от тактовой чистоты микроконтроллера*/
ADMUX=(1‹‹REFS1)|(1‹‹REFS0);
//Внутренний источник опорного напряжения Vref=2,56
}
//Функция считывания результатов АЦП
unsigned int getADC(void)
{
ADMUX=(0‹‹MUX0);// устанавливаем входом ADC0
ADCSRA|=(1‹‹ADSC); //Начать преобразование
while ((ADCSRA&_BV(ADIF))==0x00); //Дождаться окончания преобразования
return ADCW; // возвращаем результат
}
/* ------------------------------------------------------------------------- */
/* usbFunctionRead() is called when the host requests a chunk of data from
* the device. For more information see the documentation in usbdrv/usbdrv.h.
*/
uchar usbFunctionRead(uchar *data, uchar len)
{
unsigned int u = getADC();
data[0] = (uchar)u;
data[1] = (uchar)(u ›› 8);
return len;
}
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
if((rq-›bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ // HID class request
if(rq-›bRequest == USBRQ_HID_GET_REPORT){ // wValue: ReportType (highbyte), ReportID (lowbyte)
return USB_NO_MSG; // use usbFunctionRead() to obtain data
}
}
else if((rq-›bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR)
{
DBG1(0x50, &rq-›bRequest, 1); // debug output: print our request
if(rq-›bRequest == CUSTOM_RQ_SET_STATUS){
if(rq-›wValue.bytes[0] & 1){ // set LED
LED_PORT_OUTPUT |= _BV(LED_BIT);
}else{ // clear LED
LED_PORT_OUTPUT &= ~_BV(LED_BIT);
}
}else if(rq-›bRequest == CUSTOM_RQ_GET_STATUS){
static uchar dataBuffer[1]; // buffer must stay valid when usbFunctionSetup returns
dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0);
usbMsgPtr = dataBuffer; //tell the driver which data to return
return 1; // tell the driver to send 1 byte
}
}
return 0;
}
/* ------------------------------------------------------------------------- */
int main(void)
{
uchar i;
init_ADC();
wdt_enable(WDTO_1S);
odDebugInit();
DBG1(0x00, 0, 0); // debug output: main starts
usbInit();
usbDeviceDisconnect(); // enforce re-enumeration, do this while interrupts are disabled!
i = 0;
while(--i){ // fake USB disconnect for › 250 ms
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
sei();
DBG1(0x01, 0, 0); // debug output: main loop starts
for(;;){ // main event loop
wdt_reset();
usbPoll();
}
return 0;
}
/* ------------------------------------------------------------------------- */ |
|
|
|
|
12.06.2013, 16:05
|
|
Частый гость
Регистрация: 09.07.2007
Сообщений: 22
Сказал спасибо: 1
Сказали Спасибо 3 раз(а) в 2 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Измеряемое напряжение подается на PA0 переменным резистором 1к
|
|
|
|
12.06.2013, 16:34
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 18,856
Сказал спасибо: 2,532
Сказали Спасибо 11,772 раз(а) в 5,896 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Вот так читает CV:
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
12.06.2013, 16:58
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Сообщение от vitmailru
|
При первом измерении выдается правильное значение, при втором и последующих 1023.
|
Так и должно быть, судя по коду.
Сообщение от vitmailru
|
странное поведение АЦП на ATmega32A
|
Это странное поведение программиста. Что написал - то и делает.
PHP код:
|
ADMUX=(1‹‹REFS1)|(1‹‹REFS0);
//Внутренний источник опорного напряжения Vref=2,56
}
//Функция считывания результатов АЦП
unsigned int getADC(void)
{
ADMUX=(0‹‹MUX0);// устанавливаем входом ADC0
|
Сообщение от akegor
|
Вот так читает CV:
....
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
|
А что в это время делает голова??
|
|
|
|
12.06.2013, 16:59
|
|
Частый гость
Регистрация: 09.07.2007
Сообщений: 22
Сказал спасибо: 1
Сказали Спасибо 3 раз(а) в 2 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Что при adc_input=0 эквивалентно моей функции getADC, кроме установки при каждом преобразовании VREF_TYPE а не при инициализации АЦП, и нет delay и установки ADIF=1 после преобразования. Вечером попробую этот вариант, спасибо
|
|
|
|
12.06.2013, 16:59
|
|
Гражданин KAZUS.RU
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Сообщение от vitmailru
|
При первом измерении выдается правильное значение, при втором и последующих 1023. Я использую макетную плату USB-ATmega32. Чтобы использовать опорное напряжение от внутреннего источника, в макетке был выпаян резистор R7 на выводе AREF. До удаления резистора результаты АЦП были правильными, но с опорным напряжением = VCC
|
Из выложенного вами кода не ясно где и как читается АЦП.
Функция usbFunctionRead не вызывается нигде.
|
|
|
|
12.06.2013, 17:06
|
|
Частый гость
Регистрация: 09.07.2007
Сообщений: 22
Сказал спасибо: 1
Сказали Спасибо 3 раз(а) в 2 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Сообщение от _Артём_
|
Из выложенного вами кода не ясно где и как читается АЦП.
Функция usbFunctionRead не вызывается нигде.
|
Она вызывается драйвером usb, могу позже выложить весь проект, если остальной код как-то влияет на работу АЦП
|
|
|
|
12.06.2013, 17:08
|
|
Частый гость
Регистрация: 09.07.2007
Сообщений: 22
Сказал спасибо: 1
Сказали Спасибо 3 раз(а) в 2 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Сообщение от omercury
|
Сообщение от vitmailru
При первом измерении выдается правильное значение, при втором и последующих 1023.
Так и должно быть, судя по коду.
|
Хорошо, спрошу по-другому, как должен выглядеть код, читающий всегда текущее напряжение?
|
|
|
|
12.06.2013, 17:13
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Сообщение от vitmailru
|
Хорошо, спрошу по-другому, как должен выглядеть код, читающий всегда текущее напряжение?
|
PHP код:
|
unsigned int getADC(void)
{
// ADMUX=(0‹‹MUX0);// устанавливаем входом ADC0
ADCSRA|=(1‹‹ADSC); //Начать преобразование
while ((ADCSRA&_BV(ADIF))==0x00); //Дождаться окончания преобразования
return ADCW; // возвращаем результат
}
|
|
|
|
Сказали "Спасибо" omercury
|
|
|
12.06.2013, 17:16
|
|
Частый гость
Регистрация: 09.07.2007
Сообщений: 22
Сказал спасибо: 1
Сказали Спасибо 3 раз(а) в 2 сообщении(ях)
|
Re: странное поведение АЦП на ATmega32A
Сообщение от omercury
|
PHP код:
|
unsigned int getADC(void)
{
// ADMUX=(0‹‹MUX0);// устанавливаем входом ADC0
ADCSRA|=(1‹‹ADSC); //Начать преобразование
while ((ADCSRA&_BV(ADIF))==0x00); //Дождаться окончания преобразования
return ADCW; // возвращаем результат
}
|
|
До меня уже дошло, спасибо)
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 19:22.
|
|