реклама на сайте
подробности

 
 
> Программирование АЦП на atmega16L-16AI, Помогите разобраться с считыванием данных с АЦП
abitwise
сообщение Apr 7 2011, 06:26
Сообщение #1





Группа: Участник
Сообщений: 14
Регистрация: 1-04-11
Пользователь №: 64 056



Доброго времени суток.
Поскольку я не профессиональный программист и до этого момента с микроконтроллерами общался постольку поскольку, то обращаюсь к знающим и опытным людям с просьбой помочь разобраться с поставленной передо мной задачей.

Исходные данные:

Есть - мк Atmega16L-16AI (TQFP)
- два вентилятора Jamicon (JF0825B1H), Evercool (EC6010H12B)
- два дачитка температуры типа NTC

Задача: необходимо считывать информацию с датчиков и выдавать на вентиляторы напряжения, соответствующие температурным диапазонам.
Так как я в этом деле новичок, то разбил задачу на три.
1) Научиться выдавать ШИМ на вентиляторы. С этим я худо бедно разобрался!

Вот код
Код
  Chip type           : ATmega16L
Program type        : Application
Clock frequency     : 8,00000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/


#include <mega16.h>
#include <delay.h>

// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
OCR1A=0x00;
OCR1B=0x00;
TCNT1L=0x00;  
PORTD=0b00110000;
}

//Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
   PORTD=0b00110000;

}

// Timer 1 output compare B interrupt service routine
interrupt [TIM1_COMPB] void timer1_compb_isr(void)

{
  PORTD=0b00110000;
    
}

void main(void)
{


// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x30;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8192,000 kHz
// Mode: Fast PWM top=00FFh
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: On
TCCR1A=0xA1;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x1C;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 64,000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: Timer1 Overflow
// Only the 8 most significant bits of
// the AD conversion result are used
//ADMUX=0b00000000;
//ADCSRA=0xF7;
//SFIOR&=0x1F;
//SFIOR|=0xC0;
SPCR=0x40;
SPSR=0x01;

#asm("sei")

while (1)
{
   OCR1B=100;
   OCR1A=100;
};
}


По части теории вопросов у меня пока что нет. Перед решением этой задачи были проведены расчёты и получены соответствующие значения регистров сравнения таймера/счётчика1, соответствующих температурным диапазонам. Также согласно формуле из даташита на атмегу получено число ADC.
Вот эти значения (приведу только один диапазон в целях экономии времени):

температура, С измерительное напряжение, В ADC OCR1A OCR1B
25 1.196 299 0 0
26 1.159 290 0 0
27 1.123 281 0 0
28 1.087 272 0 0
29 1.053 263 0 0
30 1.020 255 0 0

и т. д.
Со второй задачей справиться не получается. Заключается она в том, чтобы научиться работать с АЦП.
А именно как правильно считывать информацию из АЦП, где и какие прерывание нужны в данной задаче? То есть я хочу понять структуру кода на Си, которая позволяет это делать и как такую структуру писать.
Дело в том, что я пользуюсь CodeVisionAvr, который генерит код, если использовать Wizard. Это на мой взгляд удобно, но только в том, случае если есть полное понимание сгенеренного кода. У меня такого понимания нету.
Я пытался самостоятельно решить эту проблему и протестировать полученный результат в Протеус, как в решении первой задачи, но ничего не вышло
Вот код (всё тоже самое только с добавлением сгенеренного кода для АЦП):
Код


1-   #define ADC_VREF_TYPE 0x04                                
2-   // Read the 8 low significant bits
3-   // of the AD conversion result
4-   unsigned char read_adc(unsigned char adc_input)
5-   {
6-    ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);  
7-    Delay needed for the stabilization of the ADC input voltage
8-    delay_us(10);
9-    // Start the AD conversion
10-  ADCSRA=0b11100110;
11-  // Wait for the AD conversion to complete
12-  while ((ADCSRA & 0x40)==0);
13-  ADCSRA|=0x10;
14-  return ADCL;
15-  }





16-   // ADC interrupt service routine
17-   interrupt [ADC_INT] void adc_isr(void)
18-   {
19-   unsigned char adc_data_l;
20-   // Read the 8 low significant bits
21-   // of the AD conversion result
22-   adc_data_l = ADCL;

23-   if(adc_data_l==0xFF)
24-     {
25-       OCR1A = 255 - adc_data_l;
26-       OCR1B = 255 - adc_data_l;
27-     }
28-   else
29-     {
30-      OCR1A = adc_data_l;
31-      OCR1B = adc_data_l;
32-      };
33-   }


Хотелось бы узнать от опытных людей, для чего необходимо и что означают 1 и 6 строчки кода, а также 12 и 13.
Далее хотелось бы понять правильно ли я сделал, что в процедуре прерывания АЦП написал последовательность действий по присвоению значений регистрам сравнения ?

3) Третья задача пока вообще не рассматриволась. Заключается она в передаче данных из АЦП в процедуру сравнения полученного из АЦП числа.
У меня процедура сравнения выглядит следующим образом:
Код
int range[9]={299, 255, 217, 184, 132, 112, 95, 81};

if (range[0] <= adc_data_l)
  {
   OCR1AL=0;
   OCR1BL=0;
  };
if (range[1] <= adc_data_l)
  {
   OCR1AL=0;
   OCR1BL=0;
  };
if (range[2] <= adc_data_l < range[1])  
  {
   OCR1AL=128;
   OCR1BL=85;
  };
if (range[3] <= adc_data_l< range[2])  
  {
   OCR1AL=149;
   OCR1BL=96;
  };    
if (range[4] <= adc_data_l < range[3])  
  {
   OCR1AL=170;
   OCR1BL=106;
  };    
if (range[5] <= adc_data_l < range[4])  
  {
   OCR1AL=191;
   OCR1BL=138;
  };
if (range[6] <= adc_data_l < range[5])  
  {
   OCR1AL=213;
   OCR1BL=149;
  };  
if (range[7] <= adc_data_l < range[6])  
  {
   OCR1AL=234;
   OCR1BL=170;
  };
if (range[8] <= adc_data_l < range[7])  
  {
   OCR1AL=255;
   OCR1BL=255;
  };

Массив из значений регистров сравнения ввёл для удобства. Хотя может быть оно и сомнительное.
В какой части кода необходимо писать эту процедуру ? В бесконечном цикле while(1){}? Или в прерываниях? Поскольку переменная adc_data_l объявлена внутри функции, то использовать её как глобальную переменную нельзя. Как решается эта проблема?. То есть, допустим я прочитал АЦП и записал число в эту переменную, что нужно сделать чтобы можно было пользоваться этой переменной в процедуре сравнения?

Заранее благодарю за помощь! Если на форуме или в интернете уже есть идентичные темы, в которых предложены решения данных проблем, то прошу поделиться ссылкой. Я обыскался в инете на эту тему, но не нашёл ничего, чтобы мне объяснило или подсказало как решать и что делать.
Надеюсь на вашу помощь!
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- abitwise   Программирование АЦП на atmega16L-16AI   Apr 7 2011, 06:26
- - Палыч   Цитата(abitwise @ Apr 7 2011, 10:26) Хоте...   Apr 7 2011, 07:06
- - abitwise   Спасибо за ответ. Если я вас правильно понял, то ...   Apr 7 2011, 09:19
|- - Палыч   Цитата(abitwise @ Apr 7 2011, 13:19) Если...   Apr 7 2011, 09:50
- - abitwise   С каждым вашим ответом, ситуация в голове проясняе...   Apr 7 2011, 10:51
|- - Палыч   Цитата(abitwise @ Apr 7 2011, 14:51) биты...   Apr 7 2011, 14:42
- - abitwise   Ясно! Уже учёл. Спасибо! Вот код, которы...   Apr 7 2011, 17:37
|- - Палыч   Проверку на попадание в диапазон Вы записали в вид...   Apr 8 2011, 04:04
|- - Xenia   Цитата(abitwise @ Apr 7 2011, 21:37) По п...   Apr 9 2011, 20:29
- - XVR   Цепочка из if'ов - это жесть. Для кого в С ц...   Apr 8 2011, 08:56
- - abitwise   Можете предложить другой вариант решения ? Цепочка...   Apr 8 2011, 09:01
|- - Палыч   Цитата(abitwise @ Apr 8 2011, 13:01) Цепо...   Apr 8 2011, 09:34
|- - Палыч   Ещё обратите внимание, что Ваша программа "за...   Apr 8 2011, 11:21
- - abitwise   Спасибо. Уже обратил) Буду пробовать прошивать......   Apr 8 2011, 11:42
- - abitwise   Прошил атмегу. Но программа по заданному алгоритму...   Apr 9 2011, 18:36
- - нечитатель   "Высокая точность не нужна" = "инте...   Apr 9 2011, 21:36
- - abitwise   Именно так. Достаточно битов регистра ADCL. Xenia...   Apr 10 2011, 12:00
|- - Палыч   Цитата(abitwise @ Apr 10 2011, 16:00) Мне...   Apr 11 2011, 08:06
|- - Xenia   Цитата(abitwise @ Apr 10 2011, 16:00) Мне...   Apr 11 2011, 09:17
- - нечитатель   "Участники форума обязаны: ... 2.1в высказыва...   Apr 11 2011, 06:09
- - abitwise   Нашёл решение данной проблемы. В даташите написан...   Apr 11 2011, 09:19
|- - Палыч   Цитата(abitwise @ Apr 11 2011, 13:19) Буд...   Apr 11 2011, 09:55
|- - Xenia   Цитата(abitwise @ Apr 11 2011, 13:19) Наш...   Apr 11 2011, 10:28
- - SysRq   Цитата(abitwise @ Apr 11 2011, 13:19) Код...   Apr 11 2011, 09:37
- - abitwise   Интересно. Я думал, что этот бит, совместно с ком...   Apr 11 2011, 09:56
|- - Палыч   Цитата(abitwise @ Apr 11 2011, 13:56) Инт...   Apr 11 2011, 10:02
- - abitwise   Не забыл. Код#define ADC_VREF_TYPE 0x20 и ADMUX=ad...   Apr 11 2011, 10:36
|- - Палыч   Цитата(abitwise @ Apr 11 2011, 14:36) Над...   Apr 11 2011, 11:36
- - SysRq   Цитата(abitwise @ Apr 11 2011, 13:56) У м...   Apr 11 2011, 11:45
- - abitwise   Спасибо за уточнения. Эту часть материала я усвои...   Apr 11 2011, 12:09
|- - Палыч   Цитата(abitwise @ Apr 11 2011, 16:09) С т...   Apr 11 2011, 12:24
- - abitwise   1. Мне нужно 8 разрядов. Насколько я понял, выйгр...   Apr 11 2011, 12:37
|- - Палыч   Цитата(abitwise @ Apr 11 2011, 16:37) 1. ...   Apr 11 2011, 12:59
- - abitwise   Ясно. То есть, чтобы не было этого конфликта нужно...   Apr 11 2011, 13:07
- - Палыч   Цитата(abitwise @ Apr 11 2011, 17:07) нуж...   Apr 11 2011, 13:15


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01402 секунд с 7
ELECTRONIX ©2004-2016