|
|
|
|
49187 149 0 0 |
|
Опции темы | Поиск в этой теме |
04.10.2010, 16:44 | 41 |
Увлеченный
|
|
04.10.2010, 18:51 | 42 |
Увлеченный
|
Разобрался с АЦП. Всем спасибо за ответы.
|
04.10.2010, 20:10 | 43 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Код:
_main: LDI R27, 255 OUT SPL+0, R27 LDI R27, 0 OUT SPL+1, R27 ;Migalka.c,1 :: void main() { ;Migalka.c,3 :: PORTB.F0 = 0; IN R27, PORTB+0 CBR R27, 1 OUT PORTB+0, R27 ;Migalka.c,4 :: PORTB.F1 = 0; IN R27, PORTB+0 CBR R27, 2 OUT PORTB+0, R27 ;Migalka.c,5 :: PORTB.F2 = 0; // Выставляем все порты в 0. IN R27, PORTB+0 CBR R27, 4 OUT PORTB+0, R27 ;Migalka.c,6 :: PORTB.F3 = 0; IN R27, PORTB+0 CBR R27, 8 OUT PORTB+0, R27 ;Migalka.c,7 :: PORTB.F4 = 0; IN R27, PORTB+0 CBR R27, 16 OUT PORTB+0, R27 ;Migalka.c,9 :: DDRB.F0 = 1; IN R27, DDRB+0 SBR R27, 1 OUT DDRB+0, R27 ;Migalka.c,10 :: DDRB.F1 = 1; IN R27, DDRB+0 SBR R27, 2 OUT DDRB+0, R27 ;Migalka.c,11 :: DDRB.F2 = 1; // Выставляем направление порта на выход. IN R27, DDRB+0 SBR R27, 4 OUT DDRB+0, R27 ;Migalka.c,12 :: DDRB.F3 = 1; IN R27, DDRB+0 SBR R27, 8 OUT DDRB+0, R27 ;Migalka.c,13 :: DDRB.F4 = 1; IN R27, DDRB+0 SBR R27, 16 OUT DDRB+0, R27 ;Migalka.c,15 :: while( 1 ) { // Циклим программу. L_main0: ;Migalka.c,16 :: PORTB.F0 = 1; // Включаем первый светодиод. IN R27, PORTB+0 SBR R27, 1 OUT PORTB+0, R27 ;Migalka.c,17 :: Delay_ms( 500 ); // Ждем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main2: DEC R16 BRNE L_main2 DEC R17 BRNE L_main2 DEC R18 BRNE L_main2 NOP NOP ;Migalka.c,18 :: PORTB.F0 = 0; // Выключаем первый светодиод. IN R27, PORTB+0 CBR R27, 1 OUT PORTB+0, R27 ;Migalka.c,19 :: PORTB.F1 = 1; // Включаем второй светодиод. IN R27, PORTB+0 SBR R27, 2 OUT PORTB+0, R27 ;Migalka.c,20 :: Delay_ms( 500 ); // Ждем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main4: DEC R16 BRNE L_main4 DEC R17 BRNE L_main4 DEC R18 BRNE L_main4 NOP NOP ;Migalka.c,21 :: PORTB.F1 = 0; // Выключаем второй светодиод. IN R27, PORTB+0 CBR R27, 2 OUT PORTB+0, R27 ;Migalka.c,22 :: PORTB.F2 = 1; // Включаем третий светодиод. IN R27, PORTB+0 SBR R27, 4 OUT PORTB+0, R27 ;Migalka.c,23 :: Delay_ms( 500 ); // Ждем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main6: DEC R16 BRNE L_main6 DEC R17 BRNE L_main6 DEC R18 BRNE L_main6 NOP NOP ;Migalka.c,24 :: PORTB.F2 = 0; // Выключаем третий светодиод. IN R27, PORTB+0 CBR R27, 4 OUT PORTB+0, R27 ;Migalka.c,25 :: PORTB.F3 = 1; // Включаем четвертый светодиод. IN R27, PORTB+0 SBR R27, 8 OUT PORTB+0, R27 ;Migalka.c,26 :: Delay_ms( 500 ); // Ждем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main8: DEC R16 BRNE L_main8 DEC R17 BRNE L_main8 DEC R18 BRNE L_main8 NOP NOP ;Migalka.c,27 :: PORTB.F3 = 0; // Выключаем четвертый светодиод. IN R27, PORTB+0 CBR R27, 8 OUT PORTB+0, R27 ;Migalka.c,28 :: PORTB.F4 = 1; // Включаем пятый светодиод. IN R27, PORTB+0 SBR R27, 16 OUT PORTB+0, R27 ;Migalka.c,29 :: Delay_ms( 500 ); // ЖЖдем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main10: DEC R16 BRNE L_main10 DEC R17 BRNE L_main10 DEC R18 BRNE L_main10 NOP NOP ;Migalka.c,30 :: PORTB.F4 = 0; // Выключаем пятый светодиод. IN R27, PORTB+0 CBR R27, 16 OUT PORTB+0, R27 ;Migalka.c,32 :: PORTB.F3 = 1; // Включаем четвертый светодиод. IN R27, PORTB+0 SBR R27, 8 OUT PORTB+0, R27 ;Migalka.c,33 :: Delay_ms( 500 ); // Ждем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main12: DEC R16 BRNE L_main12 DEC R17 BRNE L_main12 DEC R18 BRNE L_main12 NOP NOP ;Migalka.c,34 :: PORTB.F3 = 0; // Выключаем четвертый светодиод. IN R27, PORTB+0 CBR R27, 8 OUT PORTB+0, R27 ;Migalka.c,35 :: PORTB.F2 = 1; // Включаем третий светодиод. IN R27, PORTB+0 SBR R27, 4 OUT PORTB+0, R27 ;Migalka.c,36 :: Delay_ms( 500 ); // Ждем 0.5 секунд. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main14: DEC R16 BRNE L_main14 DEC R17 BRNE L_main14 DEC R18 BRNE L_main14 NOP NOP ;Migalka.c,37 :: PORTB.F2 = 0; // Выключаем третий светодиод. IN R27, PORTB+0 CBR R27, 4 OUT PORTB+0, R27 ;Migalka.c,38 :: PORTB.F1 = 1; // Включаем второй светодиод. IN R27, PORTB+0 SBR R27, 2 OUT PORTB+0, R27 ;Migalka.c,39 :: Delay_ms( 500 ); // Ждем 1 секунду. LDI R18, lo_addr(R3) LDI R17, 138 LDI R16, 86 L_main16: DEC R16 BRNE L_main16 DEC R17 BRNE L_main16 DEC R18 BRNE L_main16 NOP NOP ;Migalka.c,40 :: PORTB.F1 = 0; // Выключаем второй светодиод. IN R27, PORTB+0 CBR R27, 2 OUT PORTB+0, R27 ;Migalka.c,42 :: } JMP L_main0 ;Migalka.c,43 :: } L_end_main: JMP L_end_main ; end of _main Не, не,не. Не заставите вы меня пересесть на язык высокого уровня. Это же жесть полная!.. Как освобожусь - напишу эту мигалку на ассемблере, для сравнения ... |
04.10.2010, 21:05 | 44 |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
|
04.10.2010, 22:04 | 45 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
|
05.10.2010, 00:05 | 46 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Написал бегущий огонёк на ассемблере :
Код:
;Бегущий огонь на ATtiny13. Тактовая 128кГц. .INCLUDE "tn13def.inc" ;Векторы прерываний: rjmp RESET .ORG 0x0006 rjmp compA .ORG 0x000A ;Конфигурация: RESET: ldi R16, 0b10000000 ;Отключить аналоговый компаратор out ACSR, R16 ldi R16, 0b100000 ;Разрешить Sleep, режим idle out MCUCR, R16 ser R16 ;Все порты на выход out DDRB, R16 ldi R16, 0b100 ;Включить прерывание compA out TIMSK0, R16 ldi R16, 0b101 ;Предделитель таймера на 1024 out TCCR0B, R16 ldi R16, 1 ;Начинать с PB0 ;Программа: compA: out PORTB, R16 ;Вывести бит в порт lsl R16 ;Сдвинуть бит влево sbrc R16, 5 ;При зашкаливании переместить бит в начало ldi R16, 1 in R17, TCNT0 ;Установить компаратор на срабатывание через 125 тактов таймера subi R17, -125 out OCR0A, R17 sei ;Разрешить прерывания Sleep |
05.10.2010, 00:21 | 47 | |
Завсегдатай Фонарёвки
|
Цитата:
|
|
09.10.2010, 20:16 | 48 | |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
Код:
#include <avr/io.h> void main () { PORTB.F3 = 0; // Выставляем ноль на выходе порта. F3 - это порт PB3. DDRB.F3 = 1; // Выставляем порт на выход. while (1) // Циклим прогу. { PORTB.F3 = 1; // Включаем светодиод Delay_ms (600); // Ждем 600 мСек. PORTB.F3 = 0; // Выключаем светодиод. Delay_ms (600); } } Код:
blinke.c:3: error: return type of ‘main’ is not ‘int’ blinke.c: In function ‘main’: blinke.c:4: error: request for member ‘F3’ in something not a structure or union blinke.c:4:19: error: C++ style comments are not allowed in ISO C90 blinke.c:4:19: error: (this will be reported only once per input file) blinke.c:5: error: request for member ‘F3’ in something not a structure or union blinke.c:9: error: request for member ‘F3’ in something not a structure or union blinke.c:10: error: implicit declaration of function ‘Delay_ms’ blinke.c:11: error: request for member ‘F3’ in something not a structure or union |
|
09.10.2010, 20:36 | 49 | |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
Что же касается таймеров, то загвоздка в том, что количество аппаратных таймеров ограничено. Если какая-то там мигалка светодиодом хавает целый таймер под свои нужды без возможностей заменить его на программную реализацию при необходимости, в сложной программе возможна катастрофа. К сожалению, реально решить эту проблему может только C++. Вот так на нем выглядит мигалка с аппаратным таймером: Код:
int main() { PulseGenerator<OutSinglePin<PortB, 0>, HardwareDelay> generator; generator.generate(500, 500); return 0; } Код:
int main() { PulseGenerator<OutSinglePin<PortB, 0>, SoftwareDelay> generator; generator.generate(500, 500); return 0; } Вот пример простейшего кода, демонстрирующий работу компилятора. Код:
#include <avr/io.h> int main() { DDRB |= (1 << 3); while (1) { PORTB |= (1 << 3); asm volatile ("nop"); PORTB &= ~(1 << 3); asm volatile ("nop"); } return 0; } Код:
sbi 55-32,3 .L2: sbi 56-32,3 nop cbi 56-32,3 nop rjmp .L2 |
|
09.10.2010, 21:33 | 50 | |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
#define - объявление макроса. Например: #define foo abc+def - примерно то же самое, что нажать в редакторе "найти foo, заменить везде на abc+def". Использование #define может привести к очень неочевидным результатам, поэтому его не рекомендуется использовать никогда (или почти никогда). |
|
10.10.2010, 13:36 | 51 |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Gall, какие есть стандартные библиотеки C++ для программирования авр, совместимые с avr-gcc, и где почитать к ним инструкции?
|
10.10.2010, 14:29 | 52 | |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
Чтобы не было неочевидных результатов, достаточно писать #define foo (abc+def), и тогда никаких неочевидных результатов (типа foo*bar -> abc+def*bar) не будет. Вся avr-libc это почти что одни макросы, и ничего, работает. |
|
11.10.2010, 04:53 | 53 |
Завсегдатай Фонарёвки
|
Gall Хорошо, когда человек разбирается в предмете как ты. У него и Си может скомпилиться не хуже, чем человек напишет на ассемблере.
Но, как правило, многие пишут мигалки на Си, даже не зная про опции оптимизации компилятора. И общая тенденция такова, что средняя прошивка на Си - это нечто обьёмное, медленное, а программист даже понятия не имеет, что эти действия могли бы выполниться быстрее (даже если он и заглянет в листинг ассемблера (а большинство про него и не вспоминают), он всё равно не сможет оценить результат (потому что не знает, много это или мало для ассемблера. потому что и ассемблер большинство Сишников совершенно не знает!)). А вот на ассемблере прошивка никогда не получится слишком утяжелённой. Человек физически не сможет наплохокодить так, как может по дефолту Си |
11.10.2010, 14:12 | 54 |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
Код:
#define max(a,b) (a > b ? a : b) c = max(a++, b++); |
11.10.2010, 14:24 | 55 | |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Цитата:
Что касается кода на Ассемблере, то основная его проблема - это то, что его тяжело переделывать. В процессе отладки схемы на макетке часто приходится, например, поменять местами пару проводов для удобства разводки платы - или наоборот, для удобства программирования. Иногда в программу приходится добавлять совершенно новую функциональность - подключили что-то дополнительное. Ассемблерный код тут плохой помощник. Не говоря уже про то, что на Си можно написать 100 строк нетривиальной программы, скомпилировать, прошить - и оно СРАЗУ начнет правильно работать, потому что ошибки отловит компилятор. Добавлено через 3 минуты Цитата:
Большое количество различных готовых библиотек можно скачать на http://avrfreaks.net |
|
11.10.2010, 17:25 | 56 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Gall прав. Ассемблер хорош, пока не приходилось перетаскивать код на другой процессор/ платформу. Любому поклоннику ассемблера oбычно хватает одного раза. Лучше сразу Си учить
|
11.10.2010, 20:11 | 57 |
Увлеченный
Регистрация: 12.02.2010 Последняя активность: 15.02.2011 20:41
Сообщений: 273
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
На avrfreaks именно плюсовых библиотек не густо, причём все они для AVR32. Сделать на основе avr-libc что-то вроде описанного таймера или драйвера UART можно, но не хотелось бы изобретать велосипед.
|
18.10.2010, 22:18 | 58 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Народ, кто-нибудь связывался с HV программированием? С протоколом разобрался, но не могу вывести МК в режим программирования. В даташите говорится, что надо плясать с бубном над временными интервалами. Мол включили 5V, подождали 20...60мкс, подали на ресет 12V, подождали ещё столько-то и т.д. Это получается мне надо городить огород на ключах, и ставить вместо 13-й тиньки сороконожку, чтоб ими рулить. У меня под рукой только 8-ми лапые МК, я могу включать преобразователь, но он явно за 20мкс не успеет набрать 12V (LM27313). Смотрю на готовые схемы HV программаторов - там особо с этим и не заморачиваются. +5V вообще не коммутируется. Просто я не хочу лепить лишний огород, если в нём нет необходимости. Кто что подскажет мне интересного по этому поводу?..
|
19.10.2010, 16:06 | 59 |
Увлеченный
Регистрация: 21.06.2010 Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
На самом деле важно, чтобы после подачи питания 5 вольт и до подачи 12 вольт контроллер успел "прогреться" и начать работать. Подавать 12 вольт надо резко, качать преобразователем нельзя, нужен отдельный ключ. В остальном ничего особенного нету. В принципе можно подавать 5 и 12 вольт через оптроны 4N35 в качестве реле, чтобы проще. Тока хватит. Или даже питать прошиваемый МК от обычного порта прошивающего.
Как правило, HV-программатор нужен для перепрошивки контроллера после неправильно прошитых фуз, чтобы не выбрасывать хорошую вещь. Поэтому можно сделать упрощенный программатор, который умеет только стирать контроллеры, а шить прошивку уже обычным внутрисхемным. Особенно это ценно для многоногих контроллеров, где такой подход позволяет не подключать индивидуально каждый вывод прошиваемого МК, а параллелить выводы. |
20.10.2010, 00:30 | 60 |
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Я восстановитель фьюзов и собрал. Просто мне нужно запрограммировать RSTDISBL, но к чему это приведёт думаю можно не объяснять...
Я уже влепил в схему два ключа на сдвоенном полевике. Рулить ими буду с одной лапы МК. Один закрывается, другой открывается. Преобразователь работает постоянно и МК программатора подождёт пока он накопит достаточное напряжение. Я подавал резко 12V. МК сбрасывается, но не шьётся. Как я понял - есть у него таймер на 64мс, который заводится при подаче питания, и если время истекло - МК не войдёт в режим программирования. Подавать же на ресет 12V, если на Vcc меньше вольта - недопустимо. Вот и приходится плясать с бубном. Во всяком случае так в даташите сказано. Соберу схему с ключами и думаю она заведётся . Спасибо за внимание, вопросов пока не имею... Добавлено: Запустил, работает . Фьюзы шьются и верифицируются за доли секунды. |