|
Пишется лажа в память |
|
|
|
Dec 16 2007, 14:45
|
Участник

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

|
Здравствуйте . Проблема вот какая . Написал давно несколько подпрограмм. Решил их вместе заставить работать как какое ни будь фукцианальное устройство. Проблема возникла в следующем. Не записываются данные в память ($60 $61 $62 $63 $64 $65 ) в этих ячейках памяти должны быть цифры от1 до 9 в реале 00 15 00 0E 00 15 иногда что то другое. В блоке подпрограммы RESET я записываю туда единицы (сделал для того чтобы определить в каком блоке портак ) после команды RJAMP перехожу на вывод сигнала в порт у же в памяти портак (другие блоки отключал проверяю передачей по ком порту). В эмуляторе все считается и работает исправно в реале нет. Есть вторая проблема когда к выводам 23 и 24 подвожу сигнал (для обработки ацп процессора ATmega 8) проц молчит сигнал вывода сигнала есть а по ком порту нет . Если 24 вывод посадить на землю то всё передача идёт. Код программы прилагаю . На писан в мнемонике мне так понятнее писать и разбираться . Описал всё как мог что бы понятнее было . Если не понятно то по ходу обсуждения могу подробно описать и объяснить каждую подпрограмму .
Прикрепленные файлы
_____.txt ( 18.34 килобайт )
Кол-во скачиваний: 264
|
|
|
|
Guest_=AVR=_*
|
Dec 16 2007, 18:36
|
Guests

|
Так писать нельзя, потому что так нельзя писать. Совсем. Это не просто безграмотно, что встречается в 90% случаев - это ВОПИЮЩЕ БЕЗГРАМОТНО! [CENSORED] отправляйся на атмел.ру и атмел.сом, и учись пользоваться ассемблером и писать для начала простейший код - на конкретных примерах. Дальше можешь постепенно усложнять задачи, но научись понимать суть происходящего [CENSORED]
Сообщение отредактировал IgorKossak - Dec 24 2007, 11:46
|
|
|
|
|
Dec 16 2007, 23:59
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Sholkin @ Dec 16 2007, 14:45)  Проблема вот какая . Написал давно несколько подпрограмм. Решил их вместе заставить работать как какое ни будь фукцианальное устройство. Проблема возникла в следующем. Не записываются данные в память ($60 $61 $62 $63 $64 $65 ) в этих ячейках памяти должны быть цифры от1 до 9 в реале 00 15 00 0E 00 15 иногда что то другое. В блоке подпрограммы RESET я записываю туда единицы (сделал для того чтобы определить в каком блоке портак ) после команды RJAMP перехожу на вывод сигнала в порт у же в памяти портак (другие блоки отключал проверяю передачей по ком порту). В эмуляторе все считается и работает исправно в реале нет. Есть вторая проблема когда к выводам 23 и 24 подвожу сигнал (для обработки ацп процессора ATmega 8) проц молчит сигнал вывода сигнала есть а по ком порту нет. Если 24 вывод посадить на землю то всё передача идёт. Код программы прилагаю . Написан в мнемонике мне так понятнее писать и разбираться. Описал всё как мог чтобы понятнее было . Если не понятно то по ходу обсуждения могу подробно описать и объяснить каждую подпрограмму 0) .... skipped .... 1) На входе в подпрограммы обработки прерываний надо обязательно сохранять содержимое статус-регистра SREG (если он в подпрограмме портится), а также содержимое используемых регистров (или использовать регистры, назначенные исключительно для данного прерывания) 2) Лучше не использовать зарезервированные слова RXC, UDRE и т.д. в качестве меток.
Сообщение отредактировал zltigo - Dec 17 2007, 00:26
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Dec 17 2007, 06:34
|

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

|
Цитата(Sholkin @ Dec 16 2007, 17:45)  какое ни будь фукцианальное устройство. Не записываются данные в память ($60 $61 $62 $63 $64 $65 ) в этих ячейках памяти должны быть цифры от1 до 9 в реале 00 15 00 0E 00 15 иногда что то другое. В блоке подпрограммы RESET я записываю туда единицы (сделал для того чтобы определить в каком блоке портак ) Что то я не нахожу у Вас ГДЕ Вы в "блоке подпрограммы RESET" записываете туда единицы? По коду записываете данные(($60 $61 $62 $63 $64 $65 ) из ЕЕПРОМ. Почему бы Вам не отладить код последовательно по блокам? Сначало передачу данных по USART. Потом работу с ЕЕПРОМ. Добавте в "подпрограмму RESET" загрузку ваших ячеек памяти конкретными значениями.. к примеру так: Код ldi r23,1 sts $60,r23 ldi r23,2 sts $61,r23 ldi r23,3 sts $62,r23 ;и т.д. оставьте только инициализацию передачи по USART и минимально необходимые функции. И добейтесь правильной передачи и ПОНИМАНИЯ своего кода! зы: я бы посоветовал резервировать байты в памяти и работать с метками: Код .def tmp = r23 .dseg mydata: .byte 1;мои данные .cseg . . //гдето в коде.. lds tmp,mydata //загрузить мои данные в РОН r23 (tmp) Есть еще такая замечательная вещь как директива ".include": Код .device ATmega8 .INCLUDE "m8def.inc" ; Пишите сие в начале и не нужно вашего: Код ;описание переменных памяти EEPROM .equ EECR = $1C .equ EEARH = $1F .equ EEARL = $1E .equ EEDR = $1D .equ EEMWE = 2 .equ EEWE = 1 .equ EERE = 0 .def VAR =r20 .def DATA =r21
;описание переменных USART
Сообщение отредактировал adc - Dec 17 2007, 07:22
--------------------
Умный программист пишет тупым кодом гениальные вещи, а не наоборот...
|
|
|
|
|
Dec 18 2007, 13:47
|
Участник

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

|
Здравствуйте. ADC вы не нашли где я записываю единици в память в блоке ресет я его убрал так как он мне не помог (там действительно с EEPROM данные беруться сначала я думал от туда лажа но потом стал записывать). ldi r16,1 sts $60,r16 sts $61,r16 sts $62,r16 sts $63,r16 sts $64,r16 sts $65,r16 rjmp aa оставил настроики подпрограмму передачи по USART и вывод сигнал
aa:sbic $12,4 ; сравнение Pd(0)=1 rjmp outr0 ; пограмма передачи низкого уровня символа rjmp outr1 outr0:cbi $12,4 ;вывод сигнала анти сброс (0) rjmp aa outr1:sbi $12,4 ;вывод сигнала анти сброс (1) wdr ;сбрасывать WDT(вачдок таймер) rjmp aa
передачи по USART оставил для того чтобы смотреть чего в проце делаеться подпрограмму передачи по USART работает точно (зашивал отдельно в проц и передавал данные) Так эе пробовал отключать полпрограмму где используеться АЦП (она у меня начинает работать когда переполнение таймера 0 идёт) rjmp start ;прерывание по таймеру Timer 0 и его отключил
Оставил вот эти 3 блока . Выходит такая сетуация Питания пошло выполняется программа ресет выполняются настройки потом записались единицы в ячейки памяти выполняеться команда rjmp aa
выполняется подпрограмма вывода сигнала анти сброс я считываю данные там ерунда. Выходит в этот момент и портак. дело в том я потом блок подключал только считывание с 0 и 1 канала ацп подключаю e1:rjmp test по етои метке перехожу для записи данных в память sts $69,r5 по этой ячейки сужу выполняласли программа умножения (данные ячейки меняется) sts $66,r22 по этоя ячейки сужу выполнилас ли программа считывания (данные такжи меняються )
не мяняются только ячейки sts $60,r16 sts $61,r16 sts $62,r16 sts $63,r16 sts $64,r16 sts $65,r16 и там не еденици как я туда писал а 00 15 00 0E 00 15 и ещё sts $67,r24 sts $68,r27
Вот эти ячеки я использую что ацп насчитало так при считывании в них данные 00 15 или 00 0E они как бы отражаются в ячейках 61-65 во какой парадокс не могу понять пока связь как так вообще происходит
|
|
|
|
|
Dec 24 2007, 07:57
|
Участник

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

|
Здравствуйте. Не упорство. Конечно вы все здесь провессионалы спору нет и пишите по другому но я то нет. Вы прогромируете 24 часа в сутки и по этому вам уже почи всё понятно. Я пробовал на си Но так как я его не очень то ещё больше стал путаться и не совсем понимать чего делать по этому написал пока так как мне понятно а не как вы привыкли писать по профессианальному. В таком виде а хотябы знаю что как происходит немного. что бы воловить ошибку. Хочю получить работающий код а потом уже как надо переписать на си чтоб было что работающее. По моему ошибку локолизовал пока на 100 не знаю прогроматор отказал пока его починил. Сегодня попробую. По моему напутано у меня с прерывание по таймеру нулевому кода его задействую то лажа идет попробую без него посмотреть.
|
|
|
|
|
Dec 26 2007, 14:09
|
Участник

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

|
Здравствуйте. Александр моей целью не было каго то аскобить или выразить не уважение своим кодом. А совсем другое. Я писал почему написал такой код. Прошу прощение за такое написательство постораюсь всё исправить. Посмотрел несколько примеров как пишиться на асме . Разобраться пока трудновато без поддержки и без советов. повторюсь свой код программы исправлю. Александр просьба вот какая. Как бы вы написали вот этот кусок моей программы на асме ? Если не трудно с подробными коментариями . По вашему примеру буду переделывать.
ldi r16,0b10000110 ;установка режима АЦП out $06,r16 ldi r17,0b11000000 out $07,r17 ;установка 1 канала sbi $06,6 ;получение значене 1 канала c1:sbis $06,4 rjmp c1 in r27,$04 ;запись значения напряжения 1 фазы in r28,$05 Или какой другой кусок.
По совету участника abc . Оставил передачу и умножение всё зациклил (умножение данных и преобразование в десетичный) проц работает делает несколько преобразовании в ресет уходит.
|
|
|
|
|
Dec 26 2007, 19:42
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Давайте попробуем ещё раз. Придерживайтесь следующих советов. 1) Используйте для всего мнемонические имена. а) Поименуйте регистры б) Поименуйте ячейки памяти в) Поименуйте порты ввода/вывода 2) Используйте коментарии везде где это возможно. ( не надо писать "сложить r14 и r15" это и так видно. Описывайте смысл того, что вы делаете) приведу пример моего написания В начале идёт подробное описание проекта с указанием версии и распиновки сигналов. Код ;**************************************************************** ;* * ;* Приборный щиток для трактора "Беларусь". * ;* Версия 1.16. * ;* * ;* На шаговых двигателях. Шесть приборов. * ;* Без использования внешних регистров. * ;* Цифровая фильтрация входных данных. * ;* * ;* * ;* PC2 - ADC2 - Температура охладителя. * ;* 3 - ADC3 - Давление масла в двигателе. * ;* 4 - ADC4 - Давление воздуха в пневмосистеме. * ;* 5 - ADC5 - Давление масла в КПП. * ;* 6 - ADC6 - Уровень топлива. * ;* 7 - ADC7 - Напряжение. * ;* * ;* * ;* Двигатель MS1. * ;* PB1 - Общий провод обмоток (-). * ;* PB0 - Провод обмотоки 1 (1+). * ;* PB2 - Провод обмотоки 2 (2+). * ...... Далее объявление имён портов и констант Код .equ SCL = pb5; Для I2C (Двигатель 5) .equ SDA = pb4; Для I2C (Двигатель 5)
.equ Fclk = 8000; Частота микрокотроллера 8МГц .equ Tclk = 125; Период микрокотроллера 125нс Далее объявление регистров (обратите внимание на объявление регистра флагов r15 и рабочие регистры wl,wh. Рабочие регистры не имею специального предназначения и используются для промежуточного хранения. Я даю всегда такие наименования из проекта в проект. Поэтому в тексте сразу чётко вижу, что данный регистр - рабочий (work). Я его могу изменить во всём проекте изменив только одну строчку. Код .def Faz0 = r8; Фаза в которой находится двигатель 0 .def Faz1 = r9; Фаза в которой находится двигатель 1 .... .def bitp = r15; .equ bendc = 0 ; Конец расчётам в прерывании .equ bwdr = 1 ; Сброс от WatchDog-а .equ boff = 2 ; Возврат по провалу питания .... .def wl = r24 .def wh = r25 Объявление памяти Код .dseg Nint: .byte 1 ; Счётчик прерываний speed: .byte 1 ; скорость движения стрелки ... Далее у меня идут вектора, подпрограммы и прерывания. ну например подпрограммы Код ;======================================================================== ; Инициализация вторичных буферов произвольной длины. ;------------------------------------------------------------------------ ; Входные регистры: wl - номер буфера, Y - адрес буфера ; Выходные регистры: Y - адрес следующего буфера ; Портятся регистры: wh, wil, wih, Zl, Zh, Xl, Xh, r0, r1 ; Занято стэка : -
bufinit: ldi Xh,0 mov Xl,wl ; номер канала в Xl lsl Xl ; умножить на 512 ldi Zl,low(TabStrel*2); Загрузить адрес таблицы пересчёта ldi Zh,high(TabStrel*2) add Zh,Xl ; найти начало таблицы данных
lpm wh,Z tst wh breq bufinit0 ldi wh,$ff ; В начале обрыв !!! .... Приведу пример инициализации примерно аналогичной вашей Код .if chip == 88 .equ kadcsra = exp2(aden)+exp2(adsc)+exp2(adate)+exp2(adps1)+exp2(adps2) .else .equ kadcsra = exp2(aden)+exp2(adsc)+exp2(adfr)+exp2(adps1)+exp2(adps2) .endif ; Для внутреннего АЦП ;.equ kadmux = exp2(refs1)+exp2(refs0)+exp2(adlar) ; Для внешнего АЦП .equ kadmux = exp2(adlar)
ldi chan,0 ldi wl,kadcsra+exp2(adif) .if chip == 88 sts adcsra,wl; сбросить флаг завершения преобразования .else out adcsr,wl; сбросить флаг завершения преобразования .endif mov wl,chan subi wl,-2 ; начать с канала 2 ori wl,kadmux .if chip == 88 sts admux,wpl; включить новый канал .else out admux,wpl; включить новый канал .endif Вы выработаете свой стиль, но вы должны сразу видеть что именно происходит. Как понятнее скажите? Или так ldi r16,0b10000110 ;установка режима АЦП out $06,r16 Или так, к примеру? ldi wl, (ADEN<<1)+(ADPS1<<1)+(ADPS2<<1) out ADCSR,wl sbis $06,4 или sbis ADCSR,ADIF lds r16,$64 sts $74,r16 или так? .equ lenbuf = $10 ... .dseg InBuf: .byte lenbuf OutBuf: .byte lenbuf .... lds wl,InBuf sts OutBuf,wl
|
|
|
|
|
Dec 29 2007, 08:24
|
Участник

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

|
Здравствуйте. Первое большое спасибо за ответ . Разбираться буду и учиться. Второе Поздравляю всех с новым годом
|
|
|
|
|
Jan 6 2008, 15:08
|
Участник

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

|
Здравствуйте. Александр я и так почти везде использовал мнемонические имена. Регистры я не переменовал так как для каждой подпрограммы использую свои (описаны выше сейчас всё переименовал кроме ячеек памяти). Коментарии и так где можно написал и подробно если чтол то не понятно могу словестно описать как и что каждая подпрограмма делает. Что где в программе происходит я сам понимаю (я же её написал) Свами согласен так
ldi wl, (ADEN<<1)+(ADPS1<<1)+(ADPS2<<1) out ADCSR,wl понятнее но у меня выдаёт ошибку при таком написании (в документации не нашёл где у меня ошибка) пишит E:\AVR\ATmega8V2\sav01_v1.asm(108): error: Undefined symbol: ADEN E:\AVR\ATmega8V2\sav01_v1.asm(658): No EEPROM data, deleting E:\AVR\ATmega8V2\sav01_v1.eep не знаю как индифицировать. Просьба подсказать? Посмотреть не могу не где пока программу стал переделывать 30 декабря комп накрылся Не везуха. щас праздники отремонтировать ни как запчасть нужна. Ну эта моя проблема.
|
|
|
|
|
Jan 6 2008, 16:15
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Компилятор вам сообщает, что он не знает такого имени ADEN. Надо понимать, что компилятор по умолчанию вообще ни чего не знает. Никаких имён. Имена либо объявляются заранее, либо подключаются с помощью директивы #include из заранее подготовленного файла. Такие файлы поставляются вместе с AvrStudio. Например Код .include "8515def.inc" . Как понятно из примера здесь подключен файл определений имён для микросхемы at90s8515. Сам файл можно найти и просмотреть. Там всё совершенно понятно. Если, к примеру, у вас какая то переменная отсутствует, то можно просмотреть такой файл и вычислить в чём загвоздка. Поймите, мы вам не навязываем какие-то надуманные правила. Это вам существенно облегчит жизнь. Особенно при программировании на ассемблере. Приведу пример. Например у вас есть линия управления COM портом "CTS". Вы объявляете в начале файла Код .equ CTS = pd7; Готовность к передаче модема .equ PortCTS = portd .equ DdrCTS = ddrd И далее работаете с ним по всему тексту. Например Код sbi DdrCTS,CTS ; Готовность на вывод ..... sbi PortCTS,CTS ; Установить готовность ..... cbi PortCTS,CTS ; снять готовность ...... Какие преимущества? 1) вы сразу видите, что вы в данном месте делаете 2) вы однозначно избежите такой распространнённой ошибки как "cbi portd,pb7" 3) при изменении схемы и платы либо при переносе программы на другой камень вам не придётся выискивать все места связанные с тем или иным портом по всему тексту программы. Вам просто придётся внести изменения только в объявления переменной По поводу имён. 1) Допускается (и я, к примеру использую) назначение нескольких имён одному и тому же регистру. Наложение. Правда компилятор выдаёт предупреждение об этом. 2) Если данный регистр используется как рабочий (то есть не имеет определённого предназначения), то его лучше так и обозначить, чтобы это было сразу видно. Обычно для этого используют "w" (сокращение от "work"). В некоторых МК такие регистры есть. Либо его модификации. Например wl, wh (work low, work high) или w0,w1,w2,w3. Можно использовать любую вам удобную мнемонику. Не надо писать r16,r17. Регистра 32. Если программа хотябы средняя, то очень скоро вы абсолютно запутаетесь что это за регистры, какие используются в том или ином месте, а какие можно использовать. До всего этого вы и сами дойдёте, только сначала понабиваете шишек.
|
|
|
|
|
Jan 9 2008, 03:37
|
Участник

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

|
Привет всем. Я не говорю что вы навязываете. Просто возмущает в конфе агрессивность к новичкам (в часности ко мне). Я готов вас внимательно слушать . Вечером сегодня посмотрю обязательно этот фаил. Я эту переменую пробовал обьявить как остальные , в начале программы, не вышло. Сегодня попробую исправить. А шишки готов набивать Александр пока я исправляю кракозябы я паралельно всё же пытаюсь заставить проц работать . Вопрос (я уже писал выше какие монипуляции проделал) из за чего в ресет уходит проц какие причины могут быть, так из опыта ? (напоминаю прога в имуляторе работает как надо) Уже всё по отключал. оставил настроики ( прога PESET вывод сигнала сброс считывание с ацп 0и 1 каналов их перемножаю и вывод FORM программа ) . Происходит следуещее забивает ячеики памяти 111111 где то 20 чиклов проходит (снимаю по комп порту 121111) потом опять все единицы. Тоеть ыходит в ресет и опять записывает все 1
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|