|
Пишется лажа в память |
|
|
|
Jan 22 2008, 06:26
|

Местный
  
Группа: Свой
Сообщений: 409
Регистрация: 29-10-07
Пользователь №: 31 836

|
Ну что вы все фанатично записываете адреса регистров значениями? Код ldi r23,0b00000000;установка режима порт С out $14,r23 ldi r23,0b11111111;установка режима порт B out $17,r23 ldi r23,0b00010011;установка режима порт D out $11,r23 ldi r16,0b11110010 ldi r17,0b00001101 out $11,r16;установка регистра DDR_D out $12,r17;установка регистра PORT_D Удобнее/читабельней же так: Код ldi tmp,0b00000000;установка режима порт С out ddrc,tmp ldi tmp,0b11111111;установка режима порт B out ddrb,tmp ldi tmp,0b11110010;установка режима порт D out ddrd,tmp ldi tmp,0b00001101 out portd,tmp;установка регистра PORT_D По wdt советую установить сброс только в одном месте, и лучше в прерывании от таймера! Причем ,естественно, время срабатывания wdt должно быть больше периода срабатывания таймера. Так вы гарантированно защитите защитите свою программу от таких ошибок как зацикливание программы в основном цикле при запрещенных прерываниях, случайный сброс настроек/отключение таймера и т.п.
--------------------
Умный программист пишет тупым кодом гениальные вещи, а не наоборот...
|
|
|
|
|
Jan 29 2008, 03:48
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Здравствуйте. Исправил всё как вы мне подсказали. 1 Векторы объявил 2 Про порты свою фанатичность убрал. 3 Сброс вачдока оставил только после прерывания по таймеру. Немного переделал программу reset (сделал по шаблону как у вас Александр. Цикл вывода сигнала сброс переместил в подпрограмму reset)/ Не понял как правильно реализовать прерывания по таймеру . Мне нужно забрать по всем 6 каналам значения через определённый промижуток времени (это основное в программе). Я понял вы мне советуете По прерыванию от таймера сначало взять данные, потом переопредилить канал и выйти . Следующее прерывание по таймеру я уже точно заберу со второго и преобразования точно завершаться (что бы впустую не ждать пока преобразует АЦП). Пока не допёр . Попробую подумать сам сегодня ещё раз. Привожу описание и прогу Программа reset ;программа перезагрузки и установки режимов. После по rjmp aa вы выдаем импульсы (проц работает) на 4 пин порта D.После переполнения нуль таймера получаем с помощью ацп с 0и 1 каналов значение перемножаем их и ложим в накопитель старший или младший . Если старший разряд накопителя (младшего или старшего) больше константы младшего или старшего накопителя, в форме дисятичного значения прибавляем 1 (программа rcall form) остальные программы вспомогательные. С помощью программы ;программа приёма номера счётчика / передачи данный по USART по компьютеру смотрим десятичное значение. Забыл исправить ошибку. PS: Так дело не пойдёт. В прерывании start я вообще не нашёл reti. И величина её запредельная. Тебе придётся полностью изменить логику работы программы. Опиши алгоритм хотябы общими словами Сейчас заметил ёщё хотел исправить забыл. (может в ней то и собака зарыта)
Прикрепленные файлы
sav.txt ( 18.73 килобайт )
Кол-во скачиваний: 61
|
|
|
|
|
Jan 29 2008, 22:44
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Прерывание - это уникальное средство. Его надо понять. И понять правильно. Прерывание вызывается из любого места основной проги. В начале прерывания (средствами компилятора) осуществляется сохранение состояния процессора, а по завершению прерывания восстановление состояния. Таким образом основная программа "как бы не замечает" работы прерывания и может быть написана как логически завершённая задача (и это правильный подход). С другой стороны прерывание - тоже является логически законченой процедурой. Так сказать фоновым процессом. Если у вас несколько прерываний - то получается несколько фоновых задач. Возможно также построение, когда в голове имеется несколько независимых задач, а в прерывании осуществляется переключение между ними. Тогда говорят об ОС. Из этого видно, что само прерывание в той или иной степени "как бы распаралеливает задачи на несколько". Это надо понять. И найболее правильным подходом является общение между этими независимыми программами через данные. Тогда ваши задачи будут максимально независимы, а значит их будет легко отлаживать и они приобретут прозрачность построения. Ну например. Фоновая задача в прерывании по таймеру читает значение АЦП и ложит их в соответствующие глобальные переменные. После того,как данные обновлены она выставляет флаг завершения измерения. Голова ждёт флага завершения измерения и обрабатывает данные из глобальных переменных после чего сбрасывает флаг. Если через пол года вы измените измерение каналов АЦП на измерение частотных датчиков, к примеру, то вам необходимо будет только переписать прерывание. (Это как пример) Теперь надо понимать ещё один момент. Во время когда работает прерывание (берём общий случай и берём AVR для простоты картины) останавливается работа головы, а также задерживаются остальные прерывания. Это, естественно, не есть хорошо. К примеру если за время работы прерывания по UART придут 3 символа, то один будет потерян. Более того, если вы вызываете прерывание от таймера скажем каждые 100 мкс, а обработка этого прерывания будет занимать более 100 мкс, то очевидно, что часть прерываний будет потеряна. Короче, из этого проистекает, что прерывания должны быть максимально короткими. Этого добиваются разными способами. Например вам надо читать 6 каналов АЦП. Найболее частым решением будет следующее: 1) За одно прерывание читаем только 1 канал. 2) Процедура следующая: читаем канал - переключаем канал на следующий - выходим. Прога будет выглядеть примерно так. (Это конечно от балды выдумано) Код #pragma vector=TIMER1_OVF_vect __interrupt static void pvPWMEnd(void) { // Перезапуск таймера на той же частоте TCNT1=-KPWM; // Период следования 16МГц/3200 = 5кГц Adc[TekChan++]=ADCH; // Прочитать значение АЦП if(TekChan==MAXADC) { TekChan=0; // начать сначала Flag.fADCConv=1; // Результат измерений получен } ADMUX=KADMUX | TekChan; // Выбрать канал ADCSRA =KADCSRA; // Начать отсчёт заново } Ой простите. На асме - так Код Tim0_Ovf: push wl in wl,sreg push wl push Xl push Xh
ldi wl, -KPWM out TCNT0,wl
ldi Xl, low(MemAdc) ldi Xh, high(MemAdc) add Xl, TekChan ldi wl, 0 adc Xh, wl
in wl, ADCH st X, wl
inc TekChan
ldi wl, MAXADC cp TekChan, wl brne Tim0_Ovf_0 clr TekChan sbr Flag, exp2(fADCConv) Tim0_Ovf_0: ldi wl, KADMUX or wl, TekChan out ADMUX,wl ldi wl, KADCSRA out ADCSRA, wl
pop Xh pop Xl pop wl out sreg,wl pop wl reti Простите делал на скорую руку. Прямо тут. Естественно не самым оптимальным образом. Всё зависит от проекта. От распределения памяти и свободных регистров. Всё это естественно можно ужать.
|
|
|
|
|
Feb 3 2008, 14:03
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Спасибо за ответ. До вашего ответа я немного набрасал как оптимально сделать прерывание . Проанализирую с вашим вариантом.
|
|
|
|
|
Feb 12 2008, 04:08
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Здравствуйте. Переделал прерывание от таймера следующим оброзом. В программе инициализации (reset)запускаю ацп выставляю 0 канал . Когда приходит прерывание по таймеру (start) смотрю флаг что преобразование закончилось считываю значение . Потом смотрю если это был 1 или 3 или 5 канал то на программу переумножения выставляю следующий и выхожу. Если 5 канал то выставляю 0 канал и выхожу. Получилось много условий . можно запутаться . Оставил предыдущий вариант (линейный ) тупо выстовляю канал жду флаг равершения и тд. Оставил потому что как бы это его оснавная программа и он только и ей должен заниматься.
но дело в том, я её зашил в проц . Он вообще не работает ни как .
первый вариан (самый первый хоть как то работал ) второй который без строчки волшебной изменялась только первый разряд до 2 и всё сначало. Чего делать ............. весь мозг сломал. Я вот подумал может он сбрасываеться из за того что преобразование дольше идёт чем настроен таймер или ещё что ....................................
Сообщение отредактировал Sholkin - Feb 12 2008, 04:10
|
|
|
|
|
Feb 20 2008, 05:07
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Привет всем. Что то уже больше недели смотрю тема моя опускаеться ниже ниже. И Александр с adc перестал мне помогать. Вроде сейчас то написано более менее. Ребята помогайте . А то прогу переписал, типа научился писать всё хоре. Хочеться до конца довести а не бросить .
|
|
|
|
|
Feb 26 2008, 05:16
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Ребята помогите пожалуйста ? Код программы есть . Что не так написано? Или напишите ,что не будете смотреть . Я тогда отстану. Буду что нибудь дальше думать. Или в другую конференцию обращусь.
|
|
|
|
|
Feb 26 2008, 07:35
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Да дело то в том , что в имуляторе работает , я бы не кричал зря. То что мне советовали и как переделать я сделал (кроме забора данных с ацп оставил ленейно в лоб. Хочу потом массивом сделать как предлогали раньше , но немного не так . Но что бы зделать более грамотно надо хоть это заставить работать). Она не работает в проце . Я не знаю как выловить ошибку. Сейчас она после переделки вообще не работает, ни как. У меня опыта не хватает, как что сейчас предпринять не знаю. Имулятор ошибки не показывает. Индикатор на компе ни каких данных не пренимает . Диод не горит. Как будто он мёртвый . Зашиваю старый вариант . Он работает не так как надо, но проц чего то делает. А новый вариант болт.
|
|
|
|
|
Feb 28 2008, 06:35
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
Здравствуйте. Во вторник с человеком поговорил . По его мнению ошибку нужно искать в прерывании по таймеру. Вчера посидел примерно набросал програмку прерывания по таймеру . Дело в том щас не могу отлаживать программу из за того , что при зашивании в проц, она не работает вообще. Помогите хотя бы в этом . Программу периписал по этому шаблону , который предоставил Александр include "m8def.inc" ; объявили МК ... ; объявляем переменные и константы ... .cseg ; начинаем сегмент кода .org 0; с начала rjmp init ; Переходим на инициализацию .org INT0addr ; Описываем вектор прерывания от INT0 (если есть) rjmp j_int0; Переходим к обработке прерывания INT0 ; Описываем все другие вектора прерывания, задействованные в программе .... init: ; метка начали инициализации программы ldi tmpl,low(RAMEND);инициализация стека out SPL,tmpl ldi tmpl,high(RAMEND) out SPH,tmpl ; Прочая инициализация оборудования .... main: ; главный цикл .... ; работа ... rjmp main INT0addr:; метка обработки прерывания от INT0 ... ; обработка прерывания ... reti ; возврат из прерывания Может я его не правильно понял. Старый вариант в проце работает. Старый и новый предоставляю . Там только переместилась подпрограмма антисброса . Я её запихал в программу reset . Выши было сказано, что величина запредельная jamp и старт не быстрый я и переделал. Где 01_v1 старый вариант
Прикрепленные файлы
sav01_v1.txt ( 15.1 килобайт )
Кол-во скачиваний: 77
sav.txt ( 18.75 килобайт )
Кол-во скачиваний: 149
|
|
|
|
|
Mar 3 2008, 10:10
|
Участник

Группа: Новичок
Сообщений: 41
Регистрация: 2-04-07
Пользователь №: 26 711

|
sav.txt ( 18.94 килобайт )
Кол-во скачиваний: 240Частично заставил работать. Я вот только понять не могу . Алгоритм одинаково написан. А один работает так другой вообще не так. Вобщем посидел в пятницу суботу. Вот чего родил. vet вам спасибо за ответ не надеялся , что кто нибудь ответит, поэтому воял до вашего поста. Регистры я не сохроняю, потому что для каждой программы свои. Вот с флагами сказали не обязательно. Но послушаюсь вашего совета , мне и раньше это говорили . Просто один одно говорит другой другое. Раньше советовали Александр и abc Сейчас они пропали А каждый по своему советует. Некоторые советы я просто не понимаю , а человека рядом нет, всё труба у кого разьяснение получить. по существу. Отключил вачдок . Не знаю правильно или нет . Вопрос по нему . Писал прогу записи в еепром. Я его сначало задействовал , потом убрал команду . Осталось всё по прежнему . Потом я его стал сбрасывать. Всё пошло. У меня вопрос как его заглушить ? Он что, если его не настроить он по умолчанию какие то настройки имеет ? Сохронять флаги после прерывания сразу первой строчкой в программе прерывания ? разрешаете прерывания внутри прерываний - неоправданное усложнение Частично убрал. свой код прилогаю. Замыкалось всё на чтении. Когда убрал чтение и вочдок диод стал гореть очень очень тускло (зажигает программа сброса чтоб проц не завис). Когда частично перенёс подпрограммы в основную из подпрограммы START стал гореть ярко. Тоже не понятно. Сейчас после модификации программы свето диод горит . Нет передачи по ком порту . Так и не понял почему. отключил таймер пока. Вопросы Как правильно записать флаги (наверно в память в начале подпрограммы потом обратно в конце)? Что значит метки на ячейки памяти и как правильно? Как отключить вачдок ? Сейчас работаю с этим вариантом.
Сообщение отредактировал Sholkin - Mar 3 2008, 10:14
|
|
|
|
|
Mar 3 2008, 19:31
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Sholkin @ Mar 3 2008, 14:10)  Просто один одно говорит другой другое. Раньше советовали Александр и abc Сейчас они пропали А каждый по своему советует. Посмотрите внимательно. Вот советы (совершенно правильные) vet, которые он даёт в 41 (!!!) посте от рождества темы. Итак. Цитата не сохраняете регистры и флаги, используемые в прерываниях - программа почти гарантированно не будет работать. Посмотрите пост 2(!!!) GM и 33 мой. Ну просто один в один!!! Цитата включили ватчдог - зачем он вам во время отладки? лишняя сложность и потенциальный источник трудноотлавливаемых сбросов. Посмотрите пост 29 мой. Слово в слово. Два разных человека. Цитата циклы ожидания в прерываниях, запись в еепром в прерывании - плохая практика. прерывание должно выполняться как можно быстрее, все медленные процессы должны выполняться в программе. Почитайте внимательно и вдумчиво мой пост 29 Цитата разрешаете прерывания внутри прерываний - неоправданное усложнение. Вложенные прерывания - это нормальный вариант для меня. Но для вас это просто смерть. Возможно это тоже скрывает ошибку учитывая размер прерывания, который вы раздули!!! Цитата стек инициализировали с ошибкой. И это после поста 19, 21 от adc и моего примера!!! Я в шоке! Цитата из прерываний возвращаться нужно командой reti, а не ret. Это после моего поста 29!!! перечитайте. Слово в слово. Более 10 постов!!!! Вы их вообще читаете??? Цитата касательно оформления - продолжаете записывать адреса ячеек памяти цифрами, вместо меток. при обозначении регистров смешиваете Rxx и идентификаторы. всё это усложняет понимание и отладку. Про это просто промолчу. Несколько моих постов с примерами и вариантами оформления. Прерывание я просто написал. Посмотрите. Там сохранение регистров, их восстановление (включая SREG) и reti. Так как вам ещё написать, чтобы дошло? И стоит ли вообще это делать? Мне кажется, в мире есть сотни разных профессий. Займитесь другим делом.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|