[image]

Курс: программирование МК AVR "с нуля"

 
1 6 7 8 9 10 11 12
RU termostat #13.02.2004 12:55
+
-
edit
 

termostat

аксакал

Yaro, 10.02.2004 07:17:10:
Люди, где взять прогу, что когда-то на www.123pcb.com валялась?
 

вот сдесь она: http://www.tucows.com/preview/267999.html

но лучше зарегится на сайте производителя и скачать там еще 5.5 Мег библиотек компонентов.

А еще лучше диск OrCAD купить за 3 бакса.
   
RU termostat #13.02.2004 12:55
+
-
edit
 

termostat

аксакал

12 февраля 2004 года получил посылку с Контеста ATMEL
Atmel AVR 2004 Design Contest (заказывал 31.01.2004 - очень быстро прислали!)

1. Программатор фирменный AVRISP на COM порт, с кабелем COM 9 на 9 и с кабелями на плату на 6 и 10 штырьков - я его рскрыл конечно - там два AVR'а s1200 и s8535 т.е. схема не хилая.

2. Два! МК AVR ATmega16 - возможности у него отличные, придется теперь на них эксперементировать.

3. Диск ATMEL AVR - там 450 мБ - все Апноуты и все ДатаШиты, обзор софта и прчая инфа.

Ну и коробочка красивая... все изображено по ссылке выше. А кто не заказал когда я советовал - тот апоздал...

Если будете заказывать, то заказывайте МК поддерживаемые эмулятором VMLAB.

Я на днях поупражнялся с новой версией 3.9 - наконец то она АВТОматически интегрируется с зконно Бесплатным Компилятором GCC WinAVR. Т.е. я просто установил компилятор и больше не лазил в него, все из VMLAB делал. все работает и шагание программы по коду Си и перекомпиляция при редактировании кода.

WinAVR - можно скачать отсюда: у меня файл - WinAVR-20030424-bin-install.exe

WinAVR - Browse Files at SourceForge.net

WinAVR (tm) is a suite of executable, open source software development tools for the Atmel AVR series of RISC microprocessors hosted on the Windows …

// sourceforge.net
 


и кучу исходного кода на Си по ссылке уже данной.
avrlib - можно одним ЗИПом закачать.
   
Это сообщение редактировалось 13.02.2004 в 13:02
+
-
edit
 

coolnik

новичок
Обработка External Interrupt в AVR. Или как чайнику справиться со стеком.
Извиняюсь если не в тему, просто по таким форумам не лазил еще.

Буквально пару дней начал заниматься МК AVR, в частности AT90S8535. Сочинил программку для АЦП, который по трем каналам будет чекать напругу и отдавать ее через PORTB компу на LPT. Для того чтобы переключать каналы АЦП, используется сигнал с LPT. По этому сигналу вызывается обработчик, меняющий MUX АЦП. Эмулирую в Visual Micro Lab. Вроде все работает, но после определенного времени, точнее количества импульсов на INT0, окно Messages этой программы начинает ругаться вот такими матерными словами
[PC = $00A6, Time = 190.27 ms]: Attempt to write in an forbidden position
[PC = $00A7, Time = 190.27 ms]: Stack Pointer address beyond the valid data space
[PC = $00A8, Time = 190.27 ms]: Attempt to read in a forbidden/reserved position
[PC = $00B5, Time = 190.28 ms]: Stack Pointer address beyond the valid data space
[PC = $00B6, Time = 190.28 ms]: Program counter at unprogrammed flash location
[PC = $00B7, Time = 190.28 ms]: Program counter at unprogrammed flash location
и т.д. и т.п.
Наблюдается обратная пропорция между размером стека, количеством ругани и временем работы.
Увеличил размер стека в установках пректа CodeVision AVR со 128 до 256, получил следующее:
[PC = $00A1, Time = 410.27 ms]: Attempt to write in an forbidden position
[PC = $00A7, Time = 410.27 ms]: Suspicious Stack Pointer address at I/O space
а дальше все Ok. Типа работает. Только есть большие сомнения, что будет работать в железе.
И, кстати, при 128k до вызывалось 8 прерываний и все дохло, а при 256k – 16.
Помогите, кто знает, в чем тут дело и как программировать стек на Си. Если имеет значение обработчик такой:

interrupt [EXT_INT0] void ext_int0_isr(void){
 counter++;
 if (counter<3)
  {
   changemux:
   ADCSR = 0x00; //disable adc
   ADMUX = (unsigned char) counter;//выбор канала АЦП
   ADCSR = 0x8E;//1000 1110
   //ADCSR|=0x40;
   #asm("RETI");
  }
 else
  {
   counter=0;// выбор нулевого канала
   goto changemux;
  }
}
   
RU Poputchik #13.02.2004 14:41
+
-
edit
 

Poputchik

новичок
if [color=#808030; ]([/color]counter[color=#808030; ]<[/color][color=#008c00; ]3[/color][color=#808030; ])[/color]   [color=#808030; ]{[/color]   changemux[color=#808030; ]:[/color]   ADCSR [color=#808030; ]=[/color] 0x00[color=#808030; ];[/color] [color=#808030; ]/[/color][color=#808030; ]/[/color]disable adc   ADMUX [color=#808030; ]=[/color] [color=#808030; ]([/color]unsigned char[color=#808030; ])[/color] counter[color=#808030; ];[/color][color=#808030; ]/[/color][color=#808030; ]/[/color]выбор канала АЦП   ADCSR [color=#808030; ]=[/color] 0x8E[color=#808030; ];[/color][color=#808030; ]/[/color][color=#808030; ]/[/color][color=#008c00; ]1000[/color] [color=#008c00; ]1110[/color]   [color=#808030; ]/[/color][color=#808030; ]/[/color]ADCSR[color=#808030; ]|[/color][color=#808030; ]=[/color]0x40[color=#808030; ];[/color]   #asm[color=#808030; ]([/color][color=#0000e6; ]"RETI"[/color][color=#808030; ])[/color][color=#808030; ];[/color] [color=#808030; ]/[/color][color=#808030; ]/[/color] [color=#808030; ]<[/color][color=#808030; ]-[/color][color=#808030; ]-[/color][color=#808030; ]-[/color][color=#808030; ]-[/color][color=#808030; ]-[/color][color=#808030; ]-[/color][color=#808030; ]-[/color][color=#808030; ]-[/color]  убей это   [color=#808030; ]}[/color]  else   [color=#808030; ]{[/color]   counter[color=#808030; ]=[/color][color=#008c00; ]0[/color][color=#808030; ];[/color][color=#808030; ]/[/color][color=#808030; ]/[/color] выбор нулевого канала   goto changemux[color=#808030; ];[/color]   [color=#808030; ]}[/color] #asm[color=#808030; ]([/color][color=#0000e6; ]"RETI"[/color][color=#808030; ])[/color][color=#808030; ];[/color] [color=#808030; ]/[/color][color=#808030; ]/[/color] [color=#808030; ]<[/color][color=#808030; ]-[/color][color=#808030; ]-[/color] поставь тут
Created with colorer-take5 library. Type 'text'
   
RU Poputchik #13.02.2004 14:54
+
-
edit
 

Poputchik

новичок
И скорее всего это совсем не нужно

#asm[color=#808030; ]([/color][color=#0000e6; ]"RETI"[/color][color=#808030; ])[/color][color=#808030; ];[/color]
Created with colorer-take5 library. Type 'text'


Ся сам выполнит выход из п/п
а если он еще и что то в стек напихал перед то возврат по "RETI" у тебя получет х.з. куда.
   
RU termostat #13.02.2004 16:22
+
-
edit
 

termostat

аксакал

В курсе есть задача-пример применения АЦП AT90S8535 из компилятора CodeVision.

На "ругань" VMLAB можно не обращать внимания если прога не зависает.

#asm("RETI"); действительно не нужно

Общий принцип - в процедуре прерывания выполняй необходимые операции, как можно короче! затем выходи из обработки прерывания и выполняй то что не доделал.

программировать стек на Си не нужно - компилятор это делает сам.
   
+
-
edit
 

coolnik

новичок
termostat
Во-первых, большое спасибо за этот курс. Самое то, рулез!
Кстати прогу-то эту я из задачи 5 и взял, только переделываю под себя.
Poputchik, termostat
Спасибо за совет без #asm(RETI) все стало нормально. После ASM-а не привычно, что компилятор СИ все за тебя сам делает, вот и затупил.
И еще вопрос, как работать с PINB? Просто нужно выдавать результат в порт только по разрешению, а то на нем еще много чего висит. Подскажите, Please, как бы проще (точнее, правильнее) это устроить, может еще одно прерывание завести.
Идея какая, результат преобразования дожидается когда порт будет свободен. Об этом ему скажет сигнал с LPT. Так вот, как бы этот сигнал обработать. Думаю(просто плохо знаю, но догадываюсь), что PIND для этого и предназначен.

Добавление от 13.02.2004 16:52:
   
RU termostat #13.02.2004 18:23
+
-
edit
 

termostat

аксакал

coolnik, 13.02.2004 17:34:28:
вопрос, как работать с PINB?

Просто нужно выдавать результат в порт только по разрешению, а то на нем еще много чего висит. Подскажите, Please, как бы проще (точнее, правильнее) это устроить, может еще одно прерывание завести.

Идея какая, результат преобразования дожидается когда порт будет свободен. Об этом ему скажет сигнал с LPT. Так вот, как бы этот сигнал обработать. Думаю(просто плохо знаю, но догадываюсь), что PIND для этого и предназначен.

Добавление от 13.02.2004 16:52:
 

PINB - из этого регистра только читаешь уровни на соотв. выводах МК

см. задачу 1 курса: "Каждому порту в МК AVR соответствуют минимум три регистра: ..."

\\\

Нужно подать сигнал разрешения от LPT на вход МК аналогично частоте в Задаче 3 - там и прерывание описано.

На название компилятора можно не обращать внимания - важен принцип.
   
RU termostat #14.02.2004 12:01
+
-
edit
 

termostat

аксакал

Обновил я странички 3 и 4 курса - о компиляторах и эмуляторе, а так же обновил Задачу5 по АЦП на AVR8535.
   
+
-
edit
 

coolnik

новичок
Осмелюсь, кой чаго поправить, может я не прав, тогда буду очень признателен, если поправите меня. Итак Задача 5:
Строчка для вывода значения:

PORTB=(unsigned char) ADCW;//извиняюсь, убрал инверсию. Она мне не нужна

Порт-то 8 битный! По-моему таким образом мы теряем старшие 2 бита и получаем совсем не то, что хотели, ведь ADCL будет без этих двух битов принимать кучу одинаковых значений, из которых мы не сможем понять 3,24 Вольта или 5,24В, например. Не лучше ли сделать так:

result=(int)ADCL >> 2; // теряем младшие 2 бита, все-равно учитывая
                                     //погрешность АЦП они - нечестные.
result|=(int)ADCH << 6; //вместо появившихся нулей делаем два бита из
                                     // ADCH.
PORTB=(unsigned char) result;// имеем 8-ми битный, по-моему,
                                             //правильный результат

Жду комментариев...
   
+
-
edit
 

coolnik

новичок
И еще хочу спросить. AT90S8535, по-моему слишком дорогой МК для решения такой задачи. Что-то мне подсказывает что, можно с таким же успехом использовать Tiny26. Только вот есть несколько проблем с которыми не могу разобраться по причине плохого знания английского.
1.Как в этом МК работать с внешними прерываниями, отдельных выводов типа INT там нет. Как сконфигурировать выводы, если это вообще нужно, для работы в режиме входов прерывания.
2.Почему-то в этом МК я не нашел характеристики ADC типа 15kSPS. Хотелось бы знать насколько скоростные АЦП в этом МК.
3.Самое напрягающее: можно ли как-нибудь проэмулировать работу этого девайса, если его нет в VMLab. Может есть какие-нить дополнения и библиотеки к этой «чудо-программке».
   
RU termostat #14.02.2004 20:21
+
-
edit
 

termostat

аксакал

Читай внимательней ДШ ! стр. 80 "ADC clock frequency of 200 kHz gives the lowest conversion time, 65 µs, equivalent to
15 kSPS."

\\\\\\\\

8-бит нам выше крыши, потому как написано в задаче5:

"Результат измерения будем выводить в портB МК на 5 светодиодов эмулятора - горит "1" не горит "0" - точнее мы будем видеть только 5 младших битов результата."

Версия эмулятора 3.7 имела 5 светодиодов, в. 3.9 имеет уже 8 светодиодов.

AVR8535 был взят потому как эта задача на примере из компилятора CodeVision.

А Тини26 это класс! но эмулятор его не поддерживает, потому я Атмеги16 и заказал бесплатно хоть они и 40-ка ногие.

\\\\\\

По прерываниям - опять, Начинай работу с чтения ДатаШита на МК

Смотри первую страницу:

– External Interrupt
– Pin Change Interrupt on 11 Pins

по русски:

- внешнее прерывание (для 20-ти ногово это 9-я ножка будет - INT0)
- прерывания от изменения уровня но выводе для ОДИННАДЦАТИ ножек!

У тебя есть 11 ножек куда можно закинуть внешний сигнал вызывающий прерывание!


Симулировать Тини26 можно наверно в Астудио - но это не эмуляция как в VMLAB.
 
   
+
-
edit
 

coolnik

новичок
Спасибо за подсказки.
Насчет честного результата, я просто хотел узнать, вообще-то я в правильном направлении рулю, если мне надо 8 бит в порт В, чтобы дальше их обрабатывать на компе, или то что я написал - полная лажа. :unsure:
И еще очень бы хотелось узнать, где бы тоже хоть какой-нить AVR (лучше бы с АЦП) нахаляву заполучить. И как это сделать.
Прощаюсь ненадолго - работа. Заодно, даташит за это время толком постараюсь прочитать, чтобы снять назревшую кучу вопросов или навалить новую. :rolleyes:
P.S. Ты говорил как-то, что у тебя есть тот учебник, который ты выложил в разделе Программирование на Си одним архивом, токо он никак скачиваться не хотел. Может еще где-нить валяется? А то с дорогим коммутируемым Инетом по этим линкам лазить жутко не удобно.
   
привет всем. хотелось бы всетаки увидеть на сайте задачу где кнопки и светодиодный индикатор используются. а вообще бъюсь с задачей многоканального терморегулятора 100-300 гр.цельсия, решений видел много но и стоят они много
 
RU termostat #15.02.2004 21:08
+
-
edit
 

termostat

аксакал

[Дмитрий:],15.02.2004 19:27:53
бъюсь с задачей многоканального терморегулятора 100-300 гр.цельсия, решений видел много но и стоят они много
 

Я тоже щас ПИД регулирование изучаю. У тебя система с запаздыванием - потому и не просто.
   
RU termostat #15.02.2004 21:09
+
-
edit
 

termostat

аксакал

coolnik, 15.02.2004 11:40:07:
Спасибо за подсказки.
Насчет честного результата, я просто хотел узнать, вообще-то я в правильном направлении рулю, если мне надо 8 бит в порт В
 

ADCW >> 2; // в ADCW остались старшие 8 бит
PORTB=(unsigned char) ADCW; // эти старшие 8 бит отправили в PORTB

Одной строкой:

PORTB=(unsigned char) (ADCW >> 2);

Кстати посмотри ДШ - возможно МК может и 8 битном режиме оцифроывать. ATmega16 точно может.

Если поток информации позволит, передавай лучше на COM порт - в дата шите посмотри - AVR с приличными скоростями передает данные по UART.

Примеры есть в задачах курса и в примерак к компилятору и к эмулятору.

развернуто опиши свою задачу. легче подсказать будет.

\\\\

Бесплатные и быстро -ты прозевал - нужно было заказать когда я сообщил, что заказал на контесте.
Теперь заказывй на сайте Atmel:

Atmel Samples Request Form

MicrocontrollersTouchMemoryAutomotiveWireless / RFMore Products
Home > Microcontrollers > Atmel AVR 8- and 32-bit Microcontrollers
Print
Samples Request Form
JavaScript is required to ensure your information gets captured properly.
Please enable JavaScript in your browser preferences.


// Дальше —
www.atmel.com
 
- но они заявку передадут дистрибуторам, а они меня попросили обоснование слишком подробное, если не лень то напишешь и все получишь бесплатно. Купить быстрей наверно.


Учебник по Си больше выкладывать не буду - может за это и удалили мой сайт с Narod.ru
картинок там нет, так что закачай ReGet.com -ом все линки сразу, смотри в курсе где про Си говорится.
   
RU [Дмитрий] #16.02.2004 21:25
+
-
edit
 
дописался в кодевижне до сообщения "вы превысили размер отведенный для Еверсии". кто нибудь может подсказать как это обойти и шагнуть за 1к слов, не тратя $150?
 
RU termostat #17.02.2004 11:26
+
-
edit
 

termostat

аксакал

Поискать неограниченый, например там, где написано в курсе...

Или компилер ИмэйджКрафт скачать дему - она без ограничений на 45 дней.

Или полностью бесплатный WinAVR.
   
+
-
edit
 
На telesys.ru такой форум поганый... лучше бы Ikonboard поставили... так неудобно... :unsure:
 
+
-
edit
 
[Дмитрий:],16.02.2004 21:25:21
дописался в кодевижне до сообщения "вы превысили размер отведенный для Еверсии". кто нибудь может подсказать как это обойти и шагнуть за 1к слов, не тратя $150?
 


Хм... У меня стоит версия "Freeware"... :blink:
 
+
-
edit
 

coolnik

новичок
Полное описание задачи:
Конечное устройство представляет собой тестилку блоков питания АТ и АТХ.
По-сути, активная нагрузка. На ОУ и полевиках собран источник тока. Ток в нагрузке регулируется при помощи трех пятиразрядных ЦАП, подключенных к LPT.(5 – линий задают цифровой эквивалент тока, 3 – выбор ЦАП). Сразу после того, как отрабатывают ЦАП-ы, необходимо чекать напруги по трем основным шинам блока питания +5, +12, +3.3 Вольт. За 1мс нужно опросить все три канала. Этим и занимается Tiny26. Совершает преобразование и прерывается по сигналу от LPT который говорит, что линии свободны можно выдавать значения. Далее собственно передача, перевод выводо в высокоимпендансное состояние и второе прерывание (тоже от сигнала с LPT) для переключения канала АЦП. И далее все по кругу.
Прога следующая(профи не ругайтесь, я Си в первый раз вижу)
// Target : 8535
#include void port_init(void);
void init_devices(void);
void adc_init(void);
void main(void);
unsigned int counter; // счетчик импульсов для мультиплексора АЦП
unsigned int result;
///////////// programm /////////////////
void main(void)
{
init_devices();
ADCSR|=0x40; // start conversion bit6 = 1
while(1)
{
}
}
///////////// interrupt //////////////
interrupt [ADC_INT] void adc_isr(void) {
GIMSK = 0xc0;
}
interrupt [EXT_INT0] void ext_int0_isr(void){
counter++;
if (counter==3) counter=0;
ADCSR = 0x00; //disable adc
ADMUX = (unsigned char) counter;//выбор канала АЦП
ADCSR = 0x8E;//1000 1110
GIMSK = 0x00;
ADCSR|=0x40;
}
interrupt [EXT_INT1] void ext_int1_isr(void){
//result=(unsigned char) ADCW >>2;
result=(int)ADCL >> 2;
result|=(int)ADCH « 6;
PORTB=(unsigned char) result;
GIMSK = 0x00;
ADCSR|=0x40;
}
////////// initialization /////////////

void init_devices(void)
{
counter = 0; //обнуление счетчика
#asm("CLI"); //disable all interrupts
port_init();
adc_init();
GIFR|=0X40; //очищаем флаг прерывания
MCUCR=0x0A; //прерывания по спаду
GIMSK = 0x00; // запрещаем внешние IRQ, чтобы не переключать MUX ока не выполнится преобразование
#asm("SEI"); //re-enable interrupts
}
void port_init(void)
{
PORTA = 0xFF;
DDRA = 0x08;
PORTB = 0xFF;
DDRB = 0x00;
PORTC = 0xFF;
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x00; //select adc input 0 (PA0)
ADCSR = 0x8E;//1000 1110
   
+
-
edit
 

coolnik

новичок
[ViNCE:],17.02.2004 13:32:57
:
 


Vince
Блин, здарово. А мир-то оказывается и правда тесен
   
RU termostat #20.02.2004 01:24
+
-
edit
 

termostat

аксакал

coolnik, 19.02.2004 22:49:00 :
я Си в первый раз вижу
 


Я тоже учусь.

Я б твою задачу решал по COM порту на AVR'e с UART - две линии всего, прием и передача по 1 Мбит сек. уже при кварце 8 МГц.

Передаешь в МК команды что делать, он в ответ данные шлет любой битности.

\\\\\\

Главное я бы делал не три а 6 измерений, например ты задаешь ЦАП-ом ток для 5 вольт. Дак вот вначале сделать АЦП истиного значения тока (не то которое ты скомандовал, а то какой ток получился), и сразу же АЦП напряжения. и по следующей команде от ПК отсылаешь эти два значения на анализ. Ток можно мерять на небольшом резисторе - благо в Тини26 есть входы АЦП с предусилением.

\\\\\\

По программе:

1) какой компилятор?

2) нужно объявить переменную

char counter; // ЧАР по умолчанию беззнаковая и не нужно ее приводить в дальнейшем.

int - это огромные числа!

3) Зачем у тебя АЦ преобразование стартует до ВАЙЛ(1); ?

ADCSR|=0x40; // start conversion bit6 = 1

Онож у тебя по прерыванию должно стартовать.


4) пиши без фигурных скобок, просто: while(1);

5) в инициализации у тебя 4 порта а у тини26 только 2 - А и В а в начале проги у тебя 8535 забит.
   
+
-
edit
 

coolnik

новичок
Насчет портов: во-первых, по-моему, не очень удобно, что устройство будет подключаться к LPT и COM одновременно, во вторых, я абсолютно не умею работать с COM-портами. Ведь для них же протоколы существуют какие-то, а я работаю просто с уровнями 1 и 0. Но это в принципе не важно. Просто часть устройства(управление током) уже собрана в железе и работает она с LPT, а переделывать все на COM сложнее, да и просто нет желания.
Насчет 6 измерений – здорово придумано. Я что-то поздно спохватился, что реакция источника тока может быть не мгновенная, да и он может ошибаться в силу разных, как говориться, дестабилизирующих факторов.
Насчет остального:
1.Компилятор CodeVisionAVR C Compiler 1.24.0 Evalution.
2.Насчет сhar counter и integer(int) – информацию принял, спасибки.
3.«Зачем у тебя АЦ преобразование стартует до ВАЙЛ(1); ?»: а пускай он постоянно работает, как только подали питание. Пока установятся токи, может пройти длительное время, а результат будет постоянно обновляться. Т.е., когда компу понадобятся данные, он просто их возьмет и не будет ждать, когда завершится преобразование. И еще, внешние прерывания разрешаются в обработчике прерывания от АЦП. Если он не будет работать, то и прерываний не будет. А сделал я это для того, чтобы пока не завершилось АЦП в порт ничего не выдавать. В противном случае, в ADCW может оказаться совсем не то, что требуется.
4.Про фигурные скобки информацию принял. Насчет 8535, просто его можно проэмулировать в VMLAB. Программа-то в принципе почти такая же получается, а новичку без эмуляции работать ну очень не интересно. Я же не могу быть уверен, что все заработает, опираясь только на свои (почти нулевые) знания. Про порты я в курсе.

В общем все. По Tiny26 хотел спросить. Что это за прерывания по Change Pin. Я так понимаю, что по изменению состояния любого из выводов в одной из двух групп вырабатывается прерывание.(может я и заблуждаюсь). Так вот, как ими управлять, и что за Change: Фронт, спад или уровень?
   
AD Реклама Google — средство выживания форумов :)
+
-
edit
 

coolnik

новичок
Я понимаю, что не очень красиво выкладывать в форуме целые проги. ;) Есть предложение: может отдельный Topic открыть или по E-mail общаться?
Но пока представляю вашему вниманию следующее. Это я уже написал для Tiny26 с учетом его особенностей. B) С нетерпением жду комментариев. И вообще, будет ли это работать. От идеи с 6-преобразованиями пришлось отказаться по причине нехватки линий. Жалко, конечно :unsure: , но не принципиально. Почему не COM я уже говорил. К вопросам прибавлю, если, например с PB0 выдавать подсветку, о том что результат готов это скажется на загадочном PinChange?
Итак, прога:

/*
В проге используется ADC контроллера Tiny26 для
АЦП напряжений по трем каналам (ADC7,ADC8,ADC10).
По прерыванию от LPT (INT0) выбирается канал ADC.
По прерыванию Pin Change преобразованные 8-ми битные значения выдаются в порт A.
*/
#include void port_init(void);
void init_devices(void);
void adc_init(void);
void main(void);
unsigned char counter; // счетчик импульсов для мультиплексора АЦП
unsigned char result;

///////////// programm /////////////////
void main(void)
{
init_devices();
ADCSR|=0x40; // start conversion bit6 = 1
while (1);
}


// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
ADCSR = 0x00; //disable adc
counter++;

if (counter==1)
ADMUX = 0x27;//ADC7
goto exit;

if (counter==2)
ADMUX = 0x28;//ADC8
goto exit;

if (counter==3)
counter=0;
ADMUX = 0x2A;//ADC10
goto exit;

exit:
ADCSR = 0x8E;//1000 1110
GIMSK = 0x00;//запрет.IRQ пока нет рез-та АЦП
ADCSR|=0x40;//запустить АЦП
}

interrupt [PIN_CHANGE] void pin_change_isr(void)
{
// Read the 8 most significant bits
// of the AD conversion result
result=ADCH; // 8-ми битный результат
PORTA=result;// отправить в порт A
GIMSK = 0x00;//запретить IRQ пока не вып-ся АЦП
ADCSR|=0x40;// запустить АЦП
}

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
GIMSK = 0xc0; //Enable INT0,
//ChangePin PB3:0
//Disable PB7:4;PA7:6;PA3;
//разрешаем IRQ т.к.резульат уже есть
}


////////// initialization /////////////
void init_devices(void)
{
counter = 0; //обнуление счетчика
#asm("CLI"); //disable all interrupts

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFh
// OC1A output: Disconnected
// OC1B output: Disconnected
PLLCSR=0x00;
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x00;
OCR1C=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;

// INT0 Mode: Rising Edge
// Interrupt on any change on pins PA3, PA6, PA7 and PB4-7: Off
// Interrupt on any change on pins PB0-3: On
MCUCR=0x03;//00000011(Rising INT0)
GIFR=0x60;//01100000(разрешаем прерывания)

port_init();
adc_init();
GIMSK = 0x00; // запрещаем внешние IRQ, чтобы не переключать MUX ока не выполнится преобразование(0x50 (01010000)разрешаем)
#asm("SEI"); //re-enable interrupts
}

void port_init(void)
{
PORTA=0x00;
DDRA=0xFF;
PORTB=0x00;
DDRB=0x00;
}

void adc_init(void)
{
// ADC Clock frequency: 62,500 kHz
// ADC Voltage Reference: AVCC pin
// Only the 8 most significant bits of
// the AD conversion result are used
ADCSR = 0x00; //disable adc
ADMUX = 0x27; //select adc input 0 (PA0)0*20
//00 - REF = AVCC
//1 - 8 BIT
//27=00100111 - ADC7; 28=00101000 - ADC8; 2A=00101010 - ADC10;
ADCSR = 0x8E;//1000 1110
/*
Bit 7 - ADEN: Enabled ADC
Bit 6 - ADSC: Start ADC (у меня Stop)
Bit 5 - ADFR: Non FreeRun
Bit 4 - ADIF: Interrupt Flag "1" - reset flag if "1" set
Bit 3 - ADIE: Enabled Interrupt
Bits 2..0 - ADPS2..ADPS0: Prescaler 4000/64=62.5kHz
*/
}
   
1 6 7 8 9 10 11 12

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru