[image]

Курс: программирование AVR - часть IV

 
1 6 7 8 9 10 11 12
+
-
edit
 

mishok

новичок
Господа, подскажите как :
1) поставить в VMLAB потенциометр(напряжение от 0 до 0.1В), затем подать сигнал с него на операционный усилитель, при том последний должен усилить сигнал в 50 раз. С ОУ сигнал идет на вход АЦП(мк AT90s8535), а потом используя UART выводится в писюк.
2) Как вывести полученный результат после оцифровывания в писюк, чтобы это красиво выглядело(в каждой строчке одно число и не <1><230>, а 1,230).
3)По какому принципу производятся следующие расчеты: обеспечение требуемых токов и потенциалов для используемых элементов, определение временных соотношений, нагрузки микросхем, потребляемой мощности.

Надеюсь на ваше понимание и помощь. Мои вопросы наверняка покажутся вам чайниковскими, но исходя из того, что схемотехнику и электронику нам преподают на от**бись, они все же имеют место быть(как и курсачи по этим предметам).

Буду признателен за любого рода инфу, ссылки, советы и т.д.
   
RU termostat #10.01.2005 17:19
+
-
edit
 

termostat

аксакал


mishok> Надеюсь на ваше понимание и помощь. Мои вопросы наверняка покажутся вам чайниковскими
 


повторяю - для чайников и создан краткий курс AVR и топик в конфе. прошу! перечитай еще раз 1-ю страничку курса avr123.nm.ru - там растолковано что делать когда не знаешь как делать.

mishok> как поставить в VMLAB потенциометр(напряжение от 0 до 0.1В)
 


Открываешь ХЭЛП VMLAB и смотришь:

VMLAB help>
Interactive slider dependant voltage generator

Syntax:
V[<instName>] <nodeName> <powerNode> SLIDER_<sliderNumber>(<vLow> <vHigh>)

Examples:
Vth minus vss SLIDER_1(0 5) ; 0 to 5 volts (Slider #1)
V v_node vss SLIDER_3(1.5 2.5) ; 1.5 0 to 2.5 volts (Slider #3)
 


вот первый пример как раз для тебя:

V1 pot VSS SLIDER_1(0 0.1)

; в узле "pot" напряжение меняется от 0 до 100 мВ движком
; переменника который 1-й в контрольной панели VMLAB



mishok> затем подать сигнал с него на операционный усилитель
 


Соединить два узла напрямую в VMLAB нельзя, используем резистор 1 ом:

R100 pot in_plus 1 ; соединили движок переменника с входом "+" ОУ резистором 1 Ом


X1 OPAMP in_plus in_minus op_out ; ОУ описали как в help


mishok> при том последний должен усилить сигнал в 50 раз
 


А давай усилим сигнал так чтоб 100 мВ соответсвовал код АЦП = 1000

т.е. усилим не в 50, а
в (50 * 1000 / 1023) раз = 48,876 раз

значит резистор с выхода ОУ на его "-" будет в 47,876 раз больше
чем резистор с "-" на "землю".

Итак 47,876 кОм сделаем из двух последовательно резисторов 47К и 876

R200 op_out dva_rezist 47K ; это резистор 47 кОм с выхода ОУ к точке
; спайки с резистором 876 Ом

R220 dva_rezist in_minus 876 ; это резистор 876 Ом от точки спайки
; с резистором 47 кОм к входу "-" ОУ


Теперь нужен резистор 1 кОм от входа "-" ОУ на "землю"

R300 in_minus VSS 1K ;



mishok> с ОУ сигнал идет на вход АЦП (PA0 в МК AT90s8535)
 


УансМоо: Соединить два узла напрямую в VMLAB нельзя,
снова используем резистор 1 ом:

R400 op_out PA0 1 ; соединили выход ОУ с входом АЦП резистором 1 Ом

Выведем напряжения на движке переменника и на
входе AЦП в виртуальный осцилограф:

.PLOT V(pot) V(PA0)

mishok> потом используя UART выводится в писюк.
 


Можно выводить как в примерах к CodeVision функцией printf (папки MAX1241 THERM75),
можно как в задаче 4 курса.

X_MyRS232 TTY(9600 8) PD0 PD1; все верно, только обычно в примерах скорость 9600

Важно чтоб в проге был правильно настроен UART по частоте кварца.

// enable the transmitter

UCR=8;
// Baud=9600 @ 3.6864 MHz

UBRR=23;

и еще сделай переодичность измерений пореже - хотяб 0.3 сек, иначе в реальном
устройстве не уследишь за результатами.

mishok> По какому принципу производятся следующие расчеты: обеспечение требуемых токов и потенциалов для используемых элементов, определение временных соотношений, нагрузки микросхем, потребляемой мощности.
 


Ну какого размера будет ответ на такой вопрос? как ты думаешь?
Я ж привел тебе ссылку где книги скачать и какие, или купи книжку-учебник по электронике или в библиотеке возьми.
   
+AlS+>>Может всетаки глюк Algorithm Builder
Guest> Очень может быть, какая версия? [»]

Algorithm Builder v. 4.43

 
+
-
edit
 

coolnik

новичок
Блин… понимается со скрипом. Туплю, конечно, но хотелось бы всё-таки добить эту проблему.

Что значит
>«вычисляю 10мкс как задержку на инкремент для r18 (получаю 2)»?
Типа, время на инкремент регистра = 10мкс? Или инкрементируем столько раз, чтобы задержка была 10 мкс?
Почему именно r18? От фонаря?
>«Получаю 2»
2 – это что? Два инкремента?
>«Загружаю ЕЁ …»
кого её? Задержку? Двойку, которую насчитали?
>«Вычисляю 50 мкс (получаю 5)»
а как вычисляю? Судя по первым расчетам, один инкремент = 5мкс умножаем на 2 получаем 10мкс. Во втором случае не стыкуется: 5мкс * 5 получаем 25 (а не 50)


По коду я может быть и разобрался бы, но вот только синтаксис непонятен. (привык к СИ)

0 -> I //???
r18-- //декремент?
r19--
? r18 -= r0 ? jmp end10 // что значат знаки вопроса и знак «-=»
лял лял код для 10 мкс
end10:
? r19 -= r0 ? jmp end50
лял лял код для 50 мкс
end50:
лял лял код для 5 мкс
reti

Переписал, с учётом того, как понял. Поправьте, please:
code text
  1.  
  2. interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
  3.  
  4. x=2; // типа того, что в r18 загружается задержка
  5. y=5;
  6.  
  7.  while (x>0)
  8.  {
  9.    x--; // если один декремент = 5мкс и пренебрегаем временем выполнения команды while
  10.           // то этот кусок кода даст задержку 10 мкс
  11.  }
  12.  
  13.  ////////       код для 10 мкс //////////
  14.  
  15. while (y>0)  {y--; } ///////// задержка 50 мкс
  16. ////////        код для 50 мкс //////////
  17.  
  18. TCNT0=255; // устанавливаем время тиканья TIM0 = 5 мкс //хотя оно уже далеко не 5.
  19. }


или еще проще:

code text
  1. interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
  2. delay_us(10); // задержка 10 мкс
  3. //код для 10 мкс///////////
  4. delay_us(50);  
  5. //код для 10 мкс///////////
  6. TCNT0=255;
  7. }


и получается фигня полная.

извините за тупость, но очень хочется разобраться. :huh:

P.S.
Yuran, я вообще в этом направлении не обучался . хотя... можно сказать, что прошел курс Термостата "AVR с нуля". Насчет маскирования, один таймер с самой высокой частотой и приоритетом, запрещающий прерывания от других таймеров, просто не даст им случиться вообще.
   
RU termostat #11.01.2005 20:14
+
-
edit
 

termostat

аксакал

coolnik >
я вообще в этом направлении не обучался
 


"... мы гимназий не кончали ..." (Митрич. "Золотой теленок")


coolnik > можно сказать, что прошел курс Термостата "AVR с нуля".

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


Почитай еще раз задачу 3 курса, там о прерываниях чуток

Да запрещеные прервания не случатся, но в большинстве случаев (уточняй по ДШ) флаг прерывания выставляется не зависимо от того разрешено оно или нет.

Если ты подозреваешь что можешь пропустить прерывания, то просто проанализируй флаги предпологаемо-пропущеных прерываний.

Главное в таких напряженных по времени процедурах - время надо эвономить, и не засиживаться в прерывании, вот пример из задачи:


void timer0_ovf_isr(void)
{ //TIMER0 has overflowed
TCNT0 = 0xB8; //обновить число начал счета
}

Короткое действие и выскакиваем из прерывания, а действия следующие из факта прерывания выполняем жидая новые, другие прерывания.

Ну и еще раз скажу что с повышением частоты МК развести много прерываний по времени легче будет.
   
coolnik> Блин… понимается со скрипом. Туплю, конечно, но хотелось бы всё-таки добить эту проблему.

Все правильно я спешил потому везде чуть чуть но не дописал, кое где сократил в надежде что ты поймешь.

coolnik> Что значит
>>«вычисляю 10мкс как задержку на инкремент для r18 (получаю 2)»?

Тут вот какая задача определили на какой частоте должен работать таймер, раз так отталкиваемся от его периода таким образом что бы обычным декрементом (или инкрементом) любого регистра (ну конечно лучше из второй половины, так как они больше операций над собой допускают) можно было бы набрать те задержки которые тебе требуются, а именно 10мкс и 50 мкс. Получается что основной период выбранный нами 5 мкс, тогда 10мкс это 2 (10мкс/5мкс), и 50 мкс это 10 (50мкс/5мкс). Значит дважлы попав в прерывания по таймеру с периодом 5 мкс мы получим период 10 мкс и соотвественно 10 раз попав в 5 мкс получим 50 мкс. Как установить кол-во попаданий в одно и тоже прерывание? Либо декрементом регистра отвественного за период 10мкс, 50мкс до 0, либо его инкрементом до заданного значения. Есстественно после декремента регистр нужно будет загрузить констанотой ( в нашем случае 2 и 10).

coolnik> Типа, время на инкремент регистра = 10мкс? Или инкрементируем столько раз, чтобы задержка была 10 мкс?

Да. Инкрементируем или декрементируем, с той лишь разницей что при декременте до нуля, при инкреенте до высчитаной задержки.

coolnik> Почему именно r18? От фонаря?

не совсем. Во первых r18 из набора регистров позволяющих непосредсвенно грузить в них константу, а поскольку мы используем прерывание то по времени работы оно должно длиться как можно меньше.

>>«Получаю 2»
coolnik> 2 – это что? Два инкремента?

Да 2 это два инкремента или два декремента.

>>«Загружаю ЕЁ …»
coolnik> кого её? Задержку? Двойку, которую насчитали?

В целом да, но зависит от политики сравнения (пост или пре) этого регистра.

>>«Вычисляю 50 мкс (получаю 5)»
coolnik> а как вычисляю? Судя по первым расчетам, один инкремент = 5мкс умножаем на 2 получаем 10мкс. Во втором случае не стыкуется: 5мкс * 5 получаем 25 (а не 50)

Нет нет, смудил моленько конечно 10, но выше я объяснил уже про вычисление кол-ва декремнтов или инкрементов. Не понятно?

coolnik> По коду я может быть и разобрался бы, но вот только синтаксис непонятен. (привык к СИ)
coolnik> 0 -> I //???

запрет прерывания

coolnik> r18-- //декремент?

да

coolnik> r19--
coolnik> ? r18 -= r0 ? jmp end10 // что значат знаки вопроса и знак «-=»

сравнение r18 с r0 переход сна end10 в случае неравенства. Дело в том что сравнение с регистром и пропуск в случае выполнеия/невыполнения условия это одна команда AVR CPSE (если я ничего не путаю, так как я чаще использую граф. представление команды).

coolnik>
code text
  1. coolnik> interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
  2. coolnik> x=2; // типа того, что в r18 загружается задержка
  3. coolnik> y=5;
  4.  
  5. задержки нужно грузить до того как войти первый раз в прерывание!!!! Иначе все время будешь инкрементировать или декрементировать ее 1 раз!!!
  6.  
  7. coolnik>  while (x>0)
  8. coolnik>  {
  9. coolnik>    x--; // если один декремент = 5мкс и пренебрегаем временем выполнения команды while
  10. coolnik>           // то этот кусок кода даст задержку 10 мкс
  11. coolnik>  }
  12.  
  13. Вот это в корне не верно, задержка в 5 мкс обеспечивается таймером, а не циклом!!!!!!!! Т.е. для оебеспечения 10 мкс надо дважды побывать в таймере.
  14.  
  15. coolnik>  ////////      код для 10 мкс //////////
  16. coolnik> while (y>0)  {y--; } ///////// задержка 50 мкс
  17. coolnik> ////////       код для 50 мкс //////////
  18. coolnik> TCNT0=255; // устанавливаем время тиканья TIM0 = 5 мкс //хотя оно уже далеко не 5.
  19. coolnik> }
  20.  
  21. Ну и далее соответсвенно то же самое. И потом где запрет прерываний?
  22.  
  23. coolnik> [CODE]
  24. coolnik> interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
  25. coolnik> delay_us(10); // задержка 10 мкс
  26. coolnik> //код для 10 мкс///////////
  27. coolnik> delay_us(50);  
  28. coolnik> //код для 10 мкс///////////
  29. coolnik> TCNT0=255;
  30. coolnik> }
  31. coolnik>

coolnik> и получается фигня полная.

Кончено, ты не понял смысла счетчиков задержки. Видимо я хреновый объясняльщик.

coolnik> извините за тупость, но очень хочется разобраться. :huh:

Да ничего все когда-нибудь чего нибудь не допонимают.

coolnik> P.S.
coolnik> Yuran, я вообще в этом направлении не обучался . хотя... можно сказать, что прошел курс Термостата "AVR с нуля". Насчет маскирования, один таймер с самой высокой частотой и приоритетом, запрещающий прерывания от других таймеров, просто не даст им случиться вообще. [»]

Единственное что в этом таймере можно будет анализировать результаты выставления прерываний из GIFR или TIMSK (надо смотреть доку), но это не вариант так как неизвестно сколько раз проверяемый флаг таймер успел сгенерировать. Фронты при этом у сигналов с портов будут гулять гораздо сильнее.

 
+
-
edit
 
termostat> Да запрещеные прервания не случатся, но в большинстве случаев (уточняй по ДШ) флаг прерывания выставляется не зависимо от того разрешено оно или нет.

И сколько раз выставятся? ;-) Вот тут самое тонкое место, а как известно где тонко там и рвется.

termostat> Если ты подозреваешь что можешь пропустить прерывания, то просто проанализируй флаги предпологаемо-пропущеных прерываний.

Это может мало что дать если к примеру 1 таймер перекроет 2 таймер два раза подряд. А это реально может случится если прерывания в обработчике 1 тамера запрещены и он имеет не 0 длинну (как минимум вход в прерыавние 2 такта + 4 такта reti, об необходимости сохранять ФЛАГИ пока молчу) прескаллер 2 таймера будет честно отрабатывать эти такты внутри 1 таймера при этом при проверке флага 2 таймера прескаллер еще не сработает а вот после проверки срабатывает и следующий анализ может случиться ой как не скоро.

termostat> Главное в таких напряженных по времени процедурах - время надо эвономить, и не засиживаться в прерывании, вот пример из задачи:

Совершенно в дырочку, но отложенные прерывания это не для платформы AVR согласен?

termostat> void timer0_ovf_isr(void)
termostat> { //TIMER0 has overflowed
termostat> TCNT0 = 0xB8; //обновить число начал счета
termostat> }

Если мне не изменяет память даташит рекомендует такие выкрутасы с таймером делать при запрещенных прерыавниях, нет? И потом некоторые задержки могут быть недостижимы на overflowed. И еще ж-) сам говоришь время надо экономить и зачем то тратишь такты на запись в порт, когда проще использовать таймер по совпадению и сбросом прескаллера и счетчика по входу в прерывание аппаратно. Я не прав?

termostat> Короткое действие и выскакиваем из прерывания, а действия следующие из факта прерывания выполняем жидая новые, другие прерывания.

Ну в целом верно, только для картины с 3 таймерами не совсем подходящее, я так понял что приходы фронтов должны быть синхронизированы, т.е. пусть плавают по периоду но все вместе.

termostat> Ну и еще раз скажу что с повышением частоты МК развести много прерываний по времени легче будет. [»]
У... вопрос спорный ж-) Да и на сколько с повышением? Предел 20-40МНz и то для моделей AVR + PLD, а для AVR придел 20MHz (и то оверклок).
 
+
-
edit
 

mishok

новичок
Здравствуйте, господа, благодарю termostat за оказанную помощь, но тут появился еще один вопросик, по попводу VMLAB.
В окошке Scope(осциллографа) в Micro Trace дисплее фиолетовым цветом показываются какие-то колебания. И как я заметил, происходят они именно когда считывается сигнал с ноги аналогового входа. Кстати сказать программа выводит результат измерения напряжения с потенциометра через усилитель с делителем напряжения и последовательно после него включенного конденсатора на аналоговую землю, чтобы меньше чувствовался дребезг движка потенциометра. После оцифровки сигнал через UART поступает в СОМ-порт, именно когда результат преобразования выводится в терминал, я получаю импульсы на Trace/Prio. Посмотрел в Хелпе для Trace Section амплитуда колебаний - глубина стэка(в примере колебания сигнал -вниз, у меня-вверх), Instruction time frame-какой-то временной отрезок, подскажите какой?
В Priority Section показано, что Normal(Lowest), NMI(Highest) и Interrupt(Middle)что это означает, к тому же у меня опять наоборот амплитуда не вверх, как в примере, а вниз? Чем это вызвано и как объяснить такой результат на графиках.
Пожалуйста, не судите меня строго, я еще новичок. За любого рода информацию и помощь заранее благодарен.
   
+AlS+>>>Может всетаки глюк Algorithm Builder
Guest>> Очень может быть, какая версия? [»]
+AlS+> Algorithm Builder v. 4.43 [»]

Уже есть 4.45 и бета 4.46

url: Algorithm Builder
 
RU termostat #12.01.2005 12:29
+
-
edit
 

termostat

аксакал

А "таблетки" есть к ним?
   
+
-
edit
 
termostat> А "таблетки" есть к ним? [»]

ж-) А зачем? Мне кажется что вполне хватит 1КСлов на эксперементы и даже на серъезные программы, нет? Ну а если говортиь о таблетах, так на 4.43 тоже нет лекарств, или есть?
 

Yuran

опытный

Guest> ж-) А зачем? Мне кажется что вполне хватит 1КСлов на эксперементы и даже на серъезные программы, нет? Ну а если говортиь о таблетах, так на 4.43 тоже нет лекарств, или есть? [»]

Мне 1К слов мало =)
   
Guest>> ж-) А зачем? Мне кажется что вполне хватит 1КСлов на эксперементы и даже на серъезные программы, нет? Ну а если говортиь о таблетах, так на 4.43 тоже нет лекарств, или есть? [»]
Yuran> Мне 1К слов мало =) [»]

Мне ж-) тоже мало, но пока даже самый крупный проект входит ж-) Продукт русский, очень неплохой по характеристикам, можно попробовать договориться с автором. Помоему для частных лиц стоит ощутимо, но не дорого для тех случаев когда не хватает 1 КСлов ж-) Самому хочется таблетку - вот что я скажу, хотя подумываю о выплате все же ж-) видя как его неъотя ломают ж-)

 

+AlS+

новичок
Guest>> ж-) А зачем? Мне кажется что вполне хватит 1КСлов на эксперементы и даже на серъезные программы, нет? Ну а если говортиь о таблетах, так на 4.43 тоже нет лекарств, или есть? [»]
Yuran> Мне 1К слов мало =) [»]

Yuran тебе как профессионалу может и мало, а мне как и впрочем все начинающим этого объема поуши хватит. Я написал программу на нем- часы с выводом на знакосинтезирующий LCD, так она заняла всего около 300 слов памяти, это при моем скромном познании программирования. А на CV AVR только вывод на экран одной строчки (стандартными функциями) занял порядка 1,5К (с оптимизацией по длинне кода).

Хотя ты все это прекрасно знаешь. :-)
   

SAA

втянувшийся

Yuran>> Мне 1К слов мало =) [»]
+AlS+> Yuran тебе как профессионалу может и мало, а мне как и впрочем все начинающим этого объема поуши хватит. Я написал программу на нем- часы с выводом на знакосинтезирующий LCD, так она заняла всего около 300 слов памяти, это при моем скромном познании программирования. А на CV AVR только вывод на экран одной строчки (стандартными функциями) занял порядка 1,5К (с оптимизацией по длинне кода).
+AlS+> Хотя ты все это прекрасно знаешь. :-) [»]

Сделал многофункциональный генератор огибающей на 8 ступенек (ATTiny 26L) + управляемый ШИМ 4-х значный симисегментый индикатор, 4 клавиши, система меню. Возможность менять огибающую и на задавать посылку из 256 различных огибающих по буферу на 16 байт (каждый байт кодирует огибающую) это для телеметрии как многофункциональный тестер задумывался и для импульсников ШИМ контроллер. Сначало думал не хватит и стал узнавать сколько стоит у автора (искал кряки, думал схалявить ж-)) но потом оказалось что всего 763 слова. Я сам поразился и кстати еще есть куда уменьшать ж-) Между прочим есть одна возможность если размещаещь данные в коде (как бы сокращая лимит слов) то можно потом это долить в bin или hex сверх 1К Слов.

AAS,SAA, он же Guets
   
спасибо, за то, что так красиво всё разжевали. Подытожу (заодно проверю, точно ли я всё правильно понял):
по-сути, мы делаем программный делитель частоты. Два раза попадая в прерывание таймера (5мкс), проходит 10 мкс и следовательно, каждое второе прерывание таймера переходим на процедуру обработки кода 10 мкс. Пять раз попадая в процедуру 10 мкс проходит 50 мкс и т.д.
Чтобы фронты не начали гулять, весь код обработчика IRQ (вместе с расчётом задержек и их кодом) должен уложиться в 5 мкс - минус такты на вход и выход из прерывания. Если не уложится, то фронт будет гулять на кол-во времени, необходимое для окончания выполнения обработчика.
 

SAA

втянувшийся

Guest> спасибо, за то, что так красиво всё разжевали. Подытожу (заодно проверю, точно ли я всё правильно понял):
Guest> по-сути, мы делаем программный делитель частоты. Два раза попадая в прерывание таймера (5мкс), проходит 10 мкс и следовательно, каждое второе прерывание таймера переходим на процедуру обработки кода 10 мкс. Пять раз попадая в процедуру 10 мкс проходит 50 мкс и т.д.
Guest> Чтобы фронты не начали гулять, весь код обработчика IRQ (вместе с расчётом задержек и их кодом) должен уложиться в 5 мкс - минус такты на вход и выход из прерывания. Если не уложится, то фронт будет гулять на кол-во времени, необходимое для окончания выполнения обработчика. [»]

Во теперь все правильно понял. Я тебе сейчас самое главное скажу ж-), да боюсь опять загружу слегка. Можно сделать так что бы и фронты у 5мкс не плавали вообще, для этого надо разрешить прерывания в обработке таймера 5мкс и использовать только однокомандные сравнения для обработки задержек на 10мкс и 50мкс (вроде CPSE и дргуих проверок на бит), догадываешься почему? Ксатит что показывает простейший расчет твоего контроллера, соклько будет тактов на 5 мкс укладываться?
   
+
-
edit
 

coolnik

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

насчет тактов: никогда их не высчитывал (особо ни к чему было, потому, что не знаю какая команда сколько тактов занимает. кстати, как это выяснить?)
1/16Мгц=0,0625 мкс на один такт. 5/0,0625=80 тактов. (по-моему, так должно высчитываться)


ещё один вопрос. Математическая задачка:
За определенное кол-во времени (отмечается внешним прерыванием) таймер совершает С тиков с периодом (255-TCN)/1748. (в числах: за 17 мс совершается 656 тиков по 25,9мкс т.е. TCN=210).
Время может гулять (например, от 10 до 60 мс) но количество тиков должно остаться постоянным. Т.е. необходимо увеличить или уменьшить период тика.
вывел закономерность: TCN=255-0,07*С


code text
  1. interrupt [TIM0_OVF] void timer0_ovf_isr(void)
  2. {
  3. PORTD.0=1;
  4. PORTD.0=0;
  5. ///////////////////////код
  6. c++;
  7.  
  8. TCNT0=z;
  9. }
  10.  
  11.  
  12. interrupt [EXT_INT0] void ext_int0_isr(void)
  13. {
  14.  TIMSK=0x01;
  15.  if ((c<690)&(c>640)){goto end;}  
  16.  c=c*0.07;
  17.  z=255-c;
  18.  end:
  19.  c=0;
  20.  
  21. }


Проэмулировал в VMLAB.
От 16 мс до 30мс всё работает. Погрешность с теоритическими расчетами = 0,1...0,2. Но вот когда даю прерывание с периодом меньше 10мс или больше 60мс закономерность исчезает (вернее увеличивается погрешность). И далее С не вписывается в эталонный интервал (который было бы неплохо было бы уменьшить или в идеале свести к одному числу). А раз не вписалось, то более менее нормальный результат корректируется и в результате становится еще хуже, а потом еще.... и еще...

Вопрос: как избавиться от погрешности?
Есть предположение, что начинает гулять С (кол-во тиков). В коэффициент оно заложено как эталонное 656 (но я его не считал, а рассчитывал), поэтому оно не совсем точно
Как в VMLAB посмотреть значение переменной С, например, чтобы точно знать в чем дело? Добавит ли точности коэффициент не 0,07 а 0,069887.....?



Прикреплённые файлы:
 
   

SAA

втянувшийся

coolnik> не понял смысл разрешения прерываний... Если брать однокомандные сравнения, что код будет меньше 5 мкс и фронты и так не будут гулять, потому что обработчик выполниться раньше, чем придет следующее прерывание. А если код обработчика будет больше 5 мкс, то разрешив прерывания, мы его недовыполнив начнем выполнять опять.

Ну я не знал что размер кода отрабатываемого в самом худшем случае (т.е. 5мкс + 10мкс + 50 мкс, произойдет тогда когда будет уже 9 вхождений
) укладывается в 5 мкс. Тгда все хорошо и эта уловка тебе не нужна.

coolnik> насчет тактов: никогда их не высчитывал (особо ни к чему было, потому, что не знаю какая команда сколько тактов занимает. кстати, как это выяснить?)

Открыть даташит и на последней странички есть табличка в конце каждой строки приведены такты.

coolnik> 1/16Мгц=0,0625 мкс на один такт. 5/0,0625=80 тактов. (по-моему, так должно высчитываться)

Да конечно.

coolnik> ещё один вопрос. Математическая задачка:
coolnik> За определенное кол-во времени (отмечается внешним прерыванием) таймер совершает С тиков с периодом (255-TCN)/1748. (в числах: за 17 мс совершается 656 тиков по 25,9мкс т.е. TCN=210).
coolnik> Время может гулять (например, от 10 до 60 мс) но количество тиков должно остаться постоянным. Т.е. необходимо увеличить или уменьшить период тика.

Э а нельзя ли более подробно озвучить задачу. Я что то не совсем "всосал" необходимость выкладывать С тиков в заданный интервал.
   
+
-
edit
 

coolnik

новичок
что это такое - Электронное табло Бегущая строка. Табло курсов валют. Стеллы для АЗС, Спортивное табло
как это работает - Электронное табло Бегущая строка. Табло курсов валют. Стеллы для АЗС, Спортивное табло

как-то здесь поднимали эту тему. Я эту хреновину собрал, а сейчас появилось время, хочется проапгрейдить. Фишка вот в чём: двигатель - асинхронник ~220В очень зависит от напряжения в розетке и нагрева. Например, включаю чайник и бегущая строка начинает бегать не по часовой стрелке, а против.
Как хочу решить проблему: на INT0 повешу опто датчик (например, от компьютерной мыши). Один раз за оборот этот датчик будет генерить прерывание, которое сделает ширину импульсов такой, чтобы их вписалось в оборот прежнее количество. (т.к. скорость и направление вращения бегущей строки прямопропорциональна колличеству тактов за оборот и скорости вращения двигателя.
т.о. 50мс - время одного оборота, в за которое совершится 656 колебаний. Если скорость двигателя упала, время на один оборот - 60 мс (насчитается с=2000 например) - должно быть 656, следовательно период нужно увеличить на значение tcn=255-0,07*2000
   
RU Серокой #13.01.2005 16:04
+
-
edit
 

Серокой

координатор
★★★★
coolnik, а как вы сделали подводку питания - я имею в виду, достоточно надёжный контакт неподвижной и подвижной части?
   
+
-
edit
 

coolnik

новичок
по поводу предыдущего поста,
>Ну я не знал что размер кода отрабатываемого в самом худшем
>случае (т.е. 5мкс + 10мкс + 50 мкс, произойдет тогда когда будет
>уже 9 вхождений) укладывается в 5 мкс.
а разве можно сделать так, чтобы период был 5 мкс, а код в обработчике, например 15мкс? И никаких глюков по фронтам?

>Открыть даташит и на последней странички есть табличка в конце каждой строки приведены такты.
как обычно :) понял. Посмотрел... Только я на асме не пишу... так что опять же реально оценить не получится :(
   
+
-
edit
 

coolnik

новичок
контакт такой - с вращающейся частью вращается медная втулка, изолированная от корпуса двигана. По ней скользят две неподвижные пластины, на которые подается напряжение. Работает оk напрямую, но на всякий случай поставил фильтрики на кондерчиках.
   
RU Серокой #13.01.2005 16:30
+
-
edit
 

Серокой

координатор
★★★★
Сами делали? А из чего? Пластины ж стачиваются в процессе?
   
AD Реклама Google — средство выживания форумов :)

AAS

новичок
coolnik> что это такое - Электронное табло Бегущая строка. Табло курсов валют. Стеллы для АЗС, Спортивное табло
coolnik> как это работает - Электронное табло Бегущая строка. Табло курсов валют. Стеллы для АЗС, Спортивное табло
coolnik> как-то здесь поднимали эту тему. Я эту хреновину собрал, а сейчас появилось время, хочется проапгрейдить. Фишка вот в чём: двигатель - асинхронник ~220В очень зависит от напряжения в розетке и нагрева. Например, включаю чайник и бегущая строка начинает бегать не по часовой стрелке, а против.
coolnik> Как хочу решить проблему: на INT0 повешу опто датчик (например, от компьютерной мыши). Один раз за оборот этот датчик будет генерить прерывание, которое сделает ширину импульсов такой, чтобы их вписалось в оборот прежнее количество. (т.к. скорость и направление вращения бегущей строки прямопропорциональна колличеству тактов за оборот и скорости вращения двигателя.
coolnik> т.о. 50мс - время одного оборота, в за которое совершится 656 колебаний. Если скорость двигателя упала, время на один оборот - 60 мс (насчитается с=2000 например) - должно быть 656, следовательно период нужно увеличить на значение tcn=255-0,07*2000 [»]

Ага ж-) слушай как интересно я только можно сказать думал о такой штуке, мы с
другом в принципе работали в направлении украшения родного предприятия на Новый
Год в частности динамическим табло. И на основании всех автоматов эффектов
которые мы успели наделать за пять лет появилась у нас с идея такая.

Понятно что снхронизация будет лететь, это исходит хотя бы из того что добиться
кратности в нужном угле при переменном импульсе синхронизации будет не просто, а значит
мало того что строчка будет дрожжать, она еще и будет накладываться в разных кадрах
друг на друга. Избежать этого можно (это ход наших мыслей) и даже нужно, мы предположили
что применение ШД позволит абсолютно синхронизировать бегующую строку в одном угле.

Ну а для твоего случая я думаю нужно взять двух байтный таймер и расчитав из длины
кода задержку выбрать как можно меньшее время тактирования, на основании этого времени
высчитывать поправочный коэффициент в каждом круге и ложить в таймер в счетчик уже
поправленный для следующего круга. Если можешь сделай два датчика диаметрально
противоположных, это будет еще лучше.

Кстати можешь скинуть фотки твоего чуда?
   
1 6 7 8 9 10 11 12

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