Страница 1 из 1

Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 15:09:44
vsegdaprav
Решил я тут изучить этого страшного зверя. Книжек накачал, программ наустанавливал, короче приступил.
В Протеусе наваял схему для начала. Взял за основу программу мультивибратора, поигрался с ним в своё удовольствие, поморгал светодиодом. Понравилось.
Решил пойти дальше. Захотел погонять светодиодик по всему порту. Получилось. Пищал от восторга, радовался 5 минут и пошёл дальше.
Решил научиться переключать направление сдвига. Научился, НО... Проклятое "но", оно всегда вылезает наружу... Короче, переключиться смог только в самом начале программы, в процессе запуска. В процессе работы не получается. То есть получается, НО светодиоды ПО ОЧЕРЕДИ гаснут и больше не загораются, пока не нажмёшь Reset. Если недопустить погасания всех светодиодов в линейке, то можно переключить направление их сдвига во время исполнения программы. Всё переключается как надо. Остатки непогашенных диодов бегают по порту туда-сюда. СтОит отпустить их в свободный полёт и они по очереди гаснут и всё...

Опытные Коты, помогите. Ткните носом, что я делаю не так. Я не диплом пишу, мне не надо готовых решений. Я учусь для себя и хочу досконально со всем разобраться.

В приложенном архиве находятся проект для протеуса и тексты программ. Тот который multi работает безупречно. Надо разобраться с multi3. Сразу скажу: блок команд опроса кнопок я вставлял в разные места программы. Этот вариант самый рабочий. В других случаях диоды либо просто не горят или горят постоянно, либо вообще горят какие захотят. Разбирался в симуляторе с регистром Sdvig после выполнения команды сдвига он не сдвигается как положено, а в него по очереди записываются нули.
Использую программы Протеус 7.6 и Mplab 5.70.40.

В Протеусе за изменение направления сдвига отвечает кнопка left.
Схема ни к чему не обязывает. Это тренажёр. Просто все начинают со светодиодного моргала, ну и я не стал отступать от традиций. Названия кнопок также ни о чём не говорят. С тем же успехом их можно было назвать 1;2;3;4;5 или ещё как.

Уже три дня бьюсь головой о стену. :cry: Идеи кончились. ПОМОГИТЕ!!!!!!

Только пожалуйста отвечайте по делу. Не надо глупых вопросов типа "а почему Пик, а почему не Авр" и подобных. :kill:

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 15:31:32
wws63
Не сочтите за рекламу, купите Самоучитель Корабельникова http://ikarab.narod.ru/ и забудете все НО :)

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 15:38:04
vsegdaprav
Гы!!! По нему и учусь. Правда пока только по бесплатной его части. А всё-таки, в чём дело?

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 17:37:41
E71
Баг тут:
  • Pause_1 decfsz SecL,F
    goto Pause_1
    decfsz SecM,F
    goto Pause_1
    decfsz SecH
    goto Pause_1
    rlf Sdvig,1
    goto Metka_1 ; Переход на новый полный цикл программы.
когда rlf или rrf делаешь, байт двигается не из 0 в 7 или из 7 в 0 бит. Он проходит через С. Поэтому при таких вращениях и теряются светодиоды.. :)

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 17:38:36
uldemir
Очень дурной скус. Опасно программируете.

Код: Выделить всё

            movf        PortA,W
            addwf       PC,F
            goto        Metka_3
            goto        Metka_4
Откуда вы знаете, что все разряды кроме младшего равны 0? Даже если вы и припаяли их всех к земле, что будет, если случайно вывод отпаяется? Если делаете такие таблицы, рекомендуется всегда проводить или проверку или "обрезание" аргумента, чтобы программа не вылетела куда-нибудь на неизвестные адреса. Если вы этим куском кода проверяете состояние переключателя, то чем вам не нравится такая конструкция:

Код: Выделить всё

 btfss porta, 0
 goto metka1
 goto metka2
Второе, вы в курсе, что операция сдвиги идет через бит "C" регистра status? Если бы мне нужно было бы гонять один огонек, я бы крутил индекс от 0 до 7 и по индексу выдавал бы состояние на порт. Операции чтение-модификация-запись для порта очень опасны. Потому что прочитать можно не то что выведено!
p.s. я, разумеется, не вникал, почему у вас там что-то не бегает. просто высказал то, что бросилось в глаза.

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 17:55:01
vsegdaprav
uldemir писал(а):Очень дурной скус. Опасно программируете.
Откуда вы знаете, что все разряды кроме младшего равны 0?
Так ведь это моя первая попытка освоить МК. А программа учебно-тренировочная. За пределы Протеуса она вряд ли выйдет ибо на фиг не нужна в реальности.
uldemir писал(а):вы в курсе, что операция сдвиги идет через бит "C" регистра status?
В курсе. И в симуляторе он задействуется. (Видны его изменения в пошаговом режиме)

А конструкцию твою я безусловно проверю на практике. Спасибо, что откликнулся.

ЗЫ. На выходные уезжаю на дачу. Там интернета нет. Так что если у кого ещё появятся идеи, я их обязательно проверю на практике начиная с понедельника. :)

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 18:17:50
uldemir
Еще хотелось бы добавить. Такое ощущение, что эти книжки пишут преподаватели информатики. Совет. Взамен долгого определения регистров микроконтроллера используйте инклюды: #include p16f84a.inc. оно само определит и porta, и trisa. И заодно конфигурацию можно задать более наглядно: __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC. Выбор банков тоже писать проще BSF status, RP0 - и не надо ломать голову какой это был бит. А можно использовать и макрогенерацию: banksel trisB - оно само сгенерит две команды установки бит RP0 и RP1, чтобы была выбрана страница, на которой находится указанный регистр. Ну эт на будущее, для 84-го это не очень актуально, а вот перейдя на более развесистые ПИКи - очень облегчит жизнь. Но советую об этом думать уже сейчас.

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 19:41:57
vsegdaprav
Eddy71 писал(а):когда rlf или rrf делаешь, байт двигается не из 0 в 7 или из 7 в 0 бит. Он проходит через С. Поэтому при таких вращениях и теряются светодиоды.. :)
А почему они не теряются когда я не опрашиваю кнопку после каждого сдвига?

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 19:47:18
krant
извините что влезаю со своими советами, но почему асм? С проще и нагляднее, разве нет?

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 19:52:23
vsegdaprav
krant, я ва-аще не программист. Какой учебник нашёл по такому и учусь. Мне без разницы чем голову ломать :) Я одновременно учусь конструировать схемы и программировать.

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 04, 2010 20:38:50
uldemir
То есть получается, НО светодиоды ПО ОЧЕРЕДИ гаснут и больше не загораются,
Дык причина уже 3 раза здесь озвученная - свиг происходит через бит C. После этого куска:

Код: Выделить всё

            movf        PortA,W
            addwf       PC,F
Флаг переноса сбрасывается... Если устанавливается - снова приплыли, вернее улетели. Короче - сбрасывается. после чего выполняя rlf Sdvig имеем, что младшему биту присваивается значение бита переноса, а оно в данном случае всегда 0, а старший бит уходит в бит переноса. И разумеется он так же потеряется после первой же команды которая влияет на этот бит. Чтобы так небыло, надо делать в два хода - сделать один сдвиг чтобы уходящий бит вошел в бит переноса, но результат проигнорировать, а потом уже сделать настоящий сдвиг, результат которого сохранить:

Код: Выделить всё

  rlf  Sdvig, w
  rlf  Sdvig, f
Аналогично со сдвигом вправо. Короче, внимательно смотрим на флаги и на команды.

Re: Помогите начинающему программисту ПИКов

Добавлено: Вс июн 06, 2010 16:41:24
vsegdaprav
uldemir, спасибо за совет. Я, видимо, не заметил как единица при сдвиге переходит в ноль. Постараюсь быть внимательнее :)

Re: Помогите начинающему программисту ПИКов

Добавлено: Пн июн 07, 2010 10:17:52
vsegdaprav
uldemir, спасибо большое. Сделал как ты сказал и всё получилось :)) . Буду двигаться дальше. :write:
uldemir писал(а):Совет. Взамен долгого определения регистров микроконтроллера используйте инклюды: #include p16f84a.inc. оно само определит и porta, и trisa.
Я правильно понял, что регистры общего назначения я должен сам прописывать, но если я использую инклюд, то избавляюсь от необходимости прописывать ВСЕ регистры спец. назначения?

Re: Помогите начинающему программисту ПИКов

Добавлено: Пн июн 07, 2010 11:19:17
uldemir
Ну этот инклюд можно открыть и посмотреть, что там написано. И зачем писать самому, если производитель уже сам написал. Тогда остается только выучить как оно правильно зовется, а где находится - уже не важно (Жаль только что в какой странице, все равно имеет значение). И можно писать код, который легко переносится на другой микроконтроллер. Например чтение EEPROM везде одинаково, но адреса EEDATA, EEADR у разных контроллеров - разные.

Re: Помогите начинающему программисту ПИКов

Добавлено: Пн июн 07, 2010 11:42:54
vsegdaprav
И снова СПАСИБО!!! :)) :beer:

Re: Помогите начинающему программисту ПИКов

Добавлено: Пт июн 11, 2010 15:28:24
БАТАРЕЙКУС
доброе время суток уважаемые коты (МЯУУ)

подскажите пожайлусто.

Недавно начал изучать компилятор Си для PIC и напоролся на проблему как организовать опрос флага на си например :

btfss SSPSTAT,BF ; ожидание поднятия флага
goto $-1 ;

Re: Помогите начинающему программисту ПИКов

Добавлено: Сб июн 12, 2010 01:24:52
vovik15
ну например

bit flag;// флаг

поднимаем флаг:
if ( тра - ля -ля) flag = 1;

в бесконечном цикле
if (flag == 1)
{ flag = 0; // опускаем флаг
выполняем то что нужно;
}

Re: Помогите начинающему программисту ПИКов

Добавлено: Вс июн 13, 2010 00:09:26
pazak
To vsegdaprav
Здравствуйте :beer:
Заранее прошу прощения у модераторов за флуд :oops:
Я тоже учился по Корабельникову, за 1,5 месяца "скушал" 1-ю часть Самоучителя, потом приобрёл диск (слов нет в прямом смысле), если интересно напишите в личку, пообщаемся.

С уважением.

Re: Помогите начинающему программисту ПИКов

Добавлено: Вс июн 13, 2010 02:52:22
БАТАРЕЙКУС
pazak я тож учюсь по Корабельникову щяс изучаю вторую часть та что на диске, имоции только положительные (понятно даже блондинкаммммм)
но, он описывает тольно экологически чистый асеммблер, шо канечно и правельно только на чистом асеммблере можно лицизреть истинное лицо детаюлюшки (конкретно пика, ну всего другово)


vovik15 извеняюсь за непонимание, но мне несавсем понятен ваш пример
ситуация такая, мне надо передать некое число по SPI модулю, это происходит так я с аккумулятора загружаю его в регистор под названием SSPBUF (с адресом 0х13) далее передача происходит без моего вмешательства, мне нужно лиш ждать поднятие флага размещённого в регистре SSPSTAT (0х94) нуливой бит. в асеммблере это выглядит так.

movlw 0x40 ;
movwf SSPBUF ; и запись его в модуль для передачи

bsf Status,RP0 ; bank - 1
bcf SSPSTAT,0 ; сброс флага передачи/приёма
btfss SSPSTAT,0 ; ожидание конца передаци
goto $-1 ;
bcf Status,RP0 ; bank - 0


movfw SSPBUF ; считываем принятый байт

вопрос как это всё обьявить и организовать как и где писать всякие там #define итд.

заранее спасибо за помощь. :roll:

Re: Помогите начинающему программисту ПИКов

Добавлено: Вс июн 13, 2010 11:26:22
FlySnake
БАТАРЕЙКУС писал(а): movfw SSPBUF ; считываем принятый байт
Вот ещё один человек, который на этом попался :) Интуитивность команд делают своё дело :) На самом деле такой команды контроллера нет, это ассемблер её преобразует в правильную movf SSPBUF,w По крайней мере в моём случае это работало, хз как в разных версиях ассемблера будет.
вопрос как это всё обьявить и организовать как и где писать всякие там #define итд.
Подпрограммой, например. #define в ассме определяет строку для подстановки чтобы вместо ABCDEF можно было написать AB, а ассм подставил вместо этого нужное ABCDEF. Это необязательная директива, а лишь для облегчения жизни когда есть необходимость

Код: Выделить всё

...
movlw 0x40           ; байт для передачи можно в тексте основной проги разместить и передать через W - удобнее если надо регулярно слать разные значения
call sendspi            ; вызываем подпрограмму sendspi
movwf куда-нибудь     ; считаный байт так же передан из подпрограмы через W и теперь его можно сохранить куда-нибудь
...

Код: Выделить всё

 
sendspi   
   movwf SSPBUF ; и запись его в модуль для передачи
  bsf Status,RP0 ; bank - 1
  bcf SSPSTAT,0 ; сброс флага передачи/приёма
  btfss SSPSTAT,0 ; ожидание конца передаци
  goto $-1 ;
  bcf Status,RP0 ; bank - 0
  movf SSPBUF,w ; считываем принятый байт 
  return