Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите с PIC16F84A
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
Asekart
Помогите с усовершенствованием кода help.gif
Код
;*******************************************************************************
*************
;*                   Мигание светодиода               ***************************************
;*******************************************************************************
*************

list p=16f84
  
   #include <p16F84a.inc>

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC


count1 EQU  0x0C
count2 EQU  0x0D
ledset EQU  0x0E


   ORG 0x000
  
   clrf PORTA
   clrf PORTB
      bsf STATUS, RP0
   movlw b'11111100'
   movwf PORTA
   movlw b'00000101'
   movwf PORTB

   bcf OPTION_REG,7
   bcf STATUS,RP0
   clrf ledset

loop   movlw b'00000011'
   xorwf ledset, f
   movf ledset, w
   movwf PORTA
      
      movlw 0x00

   movwf count1
cycle1 movlw 0xFF
      movwf count2
cycle2 decfsz count2, f
      goto cycle2
      
      incfsz count1, f
      goto cycle1
    
      goto loop
      
      end

Значит эта прога заставляет мигать 2 диода...за ножки отвечает эта строчка, она рассчитана и она была дописана мной для двух светиков
movlw b'11111100' ; последние 2 нуля показывают что на 17 и 18 ножках светики
movwf PORTA
Далее инвертируется этот адресс в строчке

movlw b'00000011' ; тут инвертируется значние и выходит так что на 17 и 18 ножках логическая 1....

xorwf ledset, f
movf ledset, w
movwf PORTA

Как дописать, чтоб светики мигали поочередно, а не вместе...??? Кто знает отзовись и помоги юному пиковщику.... Не допру сам никак smile3046.gif
xemul
Цитата(Asekart @ Dec 3 2006, 16:54) *
...
Как дописать, чтоб светики мигали поочередно, а не вместе...??? Кто знает отзовись и помоги юному пиковщику.... Не допру сам никак smile3046.gif

Вместо
Код
   clrf PORTA

напишите, например:
Код
   movlw b'00000001'
   movwf PORTA

Светодиоды будут мигать в противофазе.
Asekart
Цитата(xemul @ Dec 3 2006, 16:04) *
Цитата(Asekart @ Dec 3 2006, 16:54) *

...
Как дописать, чтоб светики мигали поочередно, а не вместе...??? Кто знает отзовись и помоги юному пиковщику.... Не допру сам никак smile3046.gif

Вместо
Код
   clrf PORTA

напишите, например:
Код
   movlw b'00000001'
   movwf PORTA

Светодиоды будут мигать в противофазе.

Как показала практика то не будут...будут опять вместе мигать....так как после вашего присваивания...им дальше как и у меня присаивается опять новое значение... Нужен другой како-то способ....
xemul
Цитата(Asekart @ Dec 3 2006, 18:09) *
Цитата(xemul @ Dec 3 2006, 16:04) *

Цитата(Asekart @ Dec 3 2006, 16:54) *

...
Как дописать, чтоб светики мигали поочередно, а не вместе...??? Кто знает отзовись и помоги юному пиковщику.... Не допру сам никак smile3046.gif

Вместо
Код
   clrf PORTA

напишите, например:
Код
   movlw b'00000001'
   movwf PORTA

Светодиоды будут мигать в противофазе.

Как показала практика то не будут...будут опять вместе мигать....так как после вашего присваивания...им дальше как и у меня присаивается опять новое значение... Нужен другой како-то способ....

Упс-с, извините. Естесно, читать:
Код
   clrf ledset

напишите, например:
Код
   movlw b'00000001'
   movwf ledset

Это я подумал про то, что в данном случае можно и не заводить промежуточную переменную, а работать прямо с PORTA, ну и написал, что думалsmile.gif
Asekart
Цитата(xemul @ Dec 3 2006, 18:44) *
Цитата(Asekart @ Dec 3 2006, 18:09) *

Цитата(xemul @ Dec 3 2006, 16:04) *

Цитата(Asekart @ Dec 3 2006, 16:54) *

...
Как дописать, чтоб светики мигали поочередно, а не вместе...??? Кто знает отзовись и помоги юному пиковщику.... Не допру сам никак smile3046.gif

Вместо
Код
   clrf PORTA

напишите, например:
Код
   movlw b'00000001'
   movwf PORTA

Светодиоды будут мигать в противофазе.

Как показала практика то не будут...будут опять вместе мигать....так как после вашего присваивания...им дальше как и у меня присаивается опять новое значение... Нужен другой како-то способ....

Упс-с, извините. Естесно, читать:
Код
   clrf ledset

напишите, например:
Код
   movlw b'00000001'
   movwf ledset

Это я подумал про то, что в данном случае можно и не заводить промежуточную переменную, а работать прямо с PORTA, ну и написал, что думалsmile.gif


sad.gif Теперь картина чуток иная, спасиба и на этом! Но цель всёже не достигнута, второй диод не мигает, а мигает только первый, кторый записан у вас (т.е который на 18 ножке.....)... так вот smile.gif Может есть всё таки еще какие-то идеи на реализацию этого примера....нужная штука в просторах сети такого нет, может кто увидит и использует по назначению smile.gif Хелп короче! Пасиба огромное за идеи!!!!
Asekart
Первый мигает, второй горит! - вот что выйдет на практике если применить ваши дополнения...еффект чуток опять не тот.... smile.gif
xemul
Цитата(Asekart @ Dec 4 2006, 02:42) *
Первый мигает, второй горит! - вот что выйдет на практике если применить ваши дополнения...еффект чуток опять не тот.... smile.gif

Приведите текст программы полностью.
Мое предложение - не более чем изменить инициализацию ledset перед входом в цикл - никак не могло отразиться на способности моргать светодиодами.
Asekart
Цитата(xemul @ Dec 4 2006, 13:55) *
Цитата(Asekart @ Dec 4 2006, 02:42) *

Первый мигает, второй горит! - вот что выйдет на практике если применить ваши дополнения...еффект чуток опять не тот.... smile.gif

Приведите текст программы полностью.
Мое предложение - не более чем изменить инициализацию ledset перед входом в цикл - никак не могло отразиться на способности моргать светодиодами.

Вот код, я ошибался....
Код
;*******************************************************************************
*************
;*                   Мигание светодиода               ***************************************
;*******************************************************************************
*************

    list p=16f84
    
    #include <p16F84a.inc>

    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC


count1    EQU  0x0C
count2    EQU  0x0D
ledset    EQU  0x0E


       ORG    0x000
    
       clrf PORTA
       clrf PORTB
       bsf STATUS, RP0
       movlw b'11111100'
       movwf PORTA
       movlw b'00000101'
       movwf PORTB

       bcf OPTION_REG,7
       bcf STATUS,RP0
       movlw b'00000001'
       movwf ledset

loop   movlw b'00000011'
       xorwf ledset, f
       movf ledset, w
       movwf PORTA

       movlw 0xFF
    
       movwf count1
cycle1 movlw 0xD9
       movwf count2
cycle2 decfsz count2, f
       goto cycle2
      
       decfsz count1, f
       goto cycle1
      
       goto loop
      
       end

ОГРОМНЕЙШЕЕ ВАМ СПАСИБО ЗА ПРОГУ!!! a14.gif a14.gif Я только щас заново попробывал, загнал сначало в Протеус...и мое удивление было ооочень большим когда заработало, наверно не работало из-за невнимательности...яэти занимался пол первого ночи, вот и ошибся в куче файлов и выбрал не тот наверно....Щас вот на практике еще проверил.....всё чудно работает.... Теперь и этот вариант есть в сети.... Так сказать мультивибратор на PIC16F84A!!!!

Вот кстати ещё один вариант который мне посоветовали на другом форуме, но он немного отличается, получается что-то вроде бегущих огней на 2 светодиодаз, то еть они продолжают какбы работу друг-друга, но из-за быстроты внимания, это не так уж сильно и заметно....Но этот вариант - Ваш всиысле значительно лучше....
Вот ихний вариант:
Код
        list p=16f84

        #include <p16F84a.inc>

        __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC


        count1 EQU 0x0C
        count2 EQU 0x0D
        ledset EQU 0x0E


        ORG 0x000

        clrf PORTA
        clrf PORTB
        bsf STATUS, RP0
        movlw b'11111100'
        movwf PORTA
           movlw b'00000101'
        movwf PORTB

        bcf OPTION_REG,7
        bcf STATUS,RP0
        clrf ledset

loop    movlw b'00000010'
        xorwf ledset, f
        movf ledset, w
        movwf PORTA

        movlw 0x00

        movwf count1
cycle1  movlw 0xFF
        movwf count2
cycle2  decfsz count2, f
        goto cycle2

        incfsz count1, f
        goto cycle1



         movlw b'00000001'
        xorwf ledset, f
        movf ledset, w
        movwf PORTA

        movlw 0x00

        movwf count1
cycle3  movlw 0xFF
        movwf count2
cycle4  decfsz count2, f
        goto cycle4

        incfsz count1, f
        goto cycle3

        goto loop

        end


Интересно, а никак нельзя было бы это всё зделать на таймере так чтобы можно был бы ихнее время мигания задавать.... т.к. это вариант на простых задержках...время только быстрей можно зделать, а медленнее нельзя... Еще раз огромное спасибо!

Добавлю исходную схему! Собрать просто...там есть кнопки, для усовершенствования...
xemul
Главное, чтобы во благоsmile.gif.
Чтобы менять частоту мигания, задействуйте таймер, настройте прескалер для получения желаемой частоты переполнения таймера (скорее всего придется расширить таймер программным счетчиком), и по прерыванию таймера (точнее, по желаемому состоянию программного счетчика) переключайте светодиоды.
Кнопками можно изменять частоту мигания. Можно добавить еще одну - для изменения характера мигания. Творитеsmile.gif.

ЗЫЖ pull-up'ы (внутренние привязочные резисторы по PORTB), надеюсь, включены? Без привязки кнопки обработать не удастся.
Asekart
Цитата(xemul @ Dec 4 2006, 18:44) *
Главное, чтобы во благоsmile.gif.
Чтобы менять частоту мигания, задействуйте таймер, настройте прескалер для получения желаемой частоты переполнения таймера (скорее всего придется расширить таймер программным счетчиком), и по прерыванию таймера (точнее, по желаемому состоянию программного счетчика) переключайте светодиоды.
Кнопками можно изменять частоту мигания. Можно добавить еще одну - для изменения характера мигания. Творитеsmile.gif.

ЗЫЖ pull-up'ы (внутренние привязочные резисторы по PORTB), надеюсь, включены? Без привязки кнопки обработать не удастся.

А вы можете привести пожалуста простенькое дополнение к уже существующей проге, только с использованием таймера...буду бескрайне благодарен...нужно просто увидеть пример, а потом поковырятся в нем....огромное спасибо!!!!
DL36
Цитата(Asekart @ Dec 4 2006, 23:28) *
А вы можете привести пожалуста простенькое дополнение к уже существующей проге, только с использованием таймера...буду бескрайне благодарен...нужно просто увидеть пример, а потом поковырятся в нем....огромное спасибо!!!!

Посмотрел, вспомнил себя, нашел старый проект покромсал. Только лучше использовать PIC16F628A поновее будет.
Тут тебе файл с рабочим таймером, и твои светодиоды мигают, поочереди. Попытался файл прикрепить не прошло будет так.
Код
    list p=16f84A
    include <p16f84A.inc>

    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC



sys_t        EQU  0x0C;
led            EQU  0x0D;
sys_k        EQU  0xF0;Константа счета

;-----------------------------------------------------------------
; Вектор сброса
;-----------------------------------------------------------------
RESET_VECTOR    org    0x000        ;Адрес вектора сброса

                                ;Банк 1
                                 ;Сброс при включении питания?
        goto    start            ;Да
        goto    OTHER_RESET        ;НЕТ, WDT или сброс MCLR
;------------------------------------------------------------------
;
;Подпрограмма обработки прерываний перифирийных устройств
;Определяется источник прерывания. Разрешены следующие

;    4.Прерывание по переполнению TMR1
;
INT_VECTOR    org    0x004        ;Адрес первичного вектора прерываний
        
VECTOR_INT
;--------------------------------------------------------------------
;    Сохранение регистров и переменных

;
        
;---------------------------------------------------------------------
;
    bcf     STATUS, RP0    ;Банк 0
    btfss    STATUS, NOT_TO;
    goto    ERROR_WDT    ;Сработал сторожевой таймер

    btfsc    INTCON, T0IF;Переполнение таймера 1?
    goto    T1_Overfl    ;ДА, обслуживание

    ;Тут вставляются другие проверки

                
T1_Overfl
    movlw    sys_k        ;Загрузить таймер  
    movwf    TMR0        ;
    clrf    sys_t        ;Сбрасываем флаг

;    Восстанавливаем


;--------------------------------------------------------------------
;     Конец обработки прерывания
;----------------------------------------------------------------
    bcf        INTCON, T0IF;Переполнение таймера 1?
    retfie                ;Выходим, с разрешением прерываний

;main org
;// Обработка ошибок
ERROR_WDT
    clrf    STATUS        ;
    clrf    INTCON        ;Запретить
                        ;прерывания
    clrwdt                ;
    goto $-1            ;Зациклить на ошибке


;Проверка типа сброса
OTHER_RESET     
    btfss STATUS, NOT_TO;Сброс WDT?
WDT_TIMEOUT
    goto ERROR_WDT        ;Да, превышение WDT.
    goto start            ;Внешний сброс
    goto ERROR_WDT
ERROR1
    nop
    nop
    goto ERROR1            ;

;-----------------------------------------------------------------
;
; Начало, инициализация микроконтроллера
;
;-----------------------------------------------------------------
        
start
        clrf    STATUS        ;
        clrf    INTCON        ;Запретить
        clrwdt                ;
;---------------------------------------------------------------------
;    Начальная установка ПОРТОВ
        clrf    STATUS        ;Установить банк 0
          clrf     PORTA
           clrf     PORTB
        movlw    b'11111100'    ;
        bsf        STATUS,    RP0    ;Установить банк 1
        movwf    TRISA        ; 0-1 выход адреса
           movlw     b'00000001'
        banksel PORTA
           movwf     PORTA
        movwf    led


;------------------------------------------------------------------------
;    Инициация таймера TMR0
;------------------------------------------------------------------------    
        clrf     TMR0        ;
        clrf     INTCON        ;
        movlw    b'11000111'        ;
        banksel    OPTION_REG    ;
        movwf    OPTION_REG    ;
        
        movlw    sys_k        ;
        banksel TMR0        ;
        movwf    TMR0        ;значение 1/8 секунды при
        banksel    INTCON        ;

        bsf        INTCON, T0IE;Разрешить
        bsf        INTCON, GIE    ;Разрешить прерывания перифирийных устройств


main;Главный цикл

        banksel PORTA
        btfsc    sys_t, 0
        goto    main        ;
        comf    led, W
        movwf    led
        movwf     PORTA
        bsf        sys_t, 0
        goto    main        ;
        end
Asekart
Цитата(DL36 @ Dec 25 2006, 01:12) *
Цитата(Asekart @ Dec 4 2006, 23:28) *

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

Посмотрел, вспомнил себя, нашел старый проект покромсал. Только лучше использовать PIC16F628A поновее будет.
Тут тебе файл с рабочим таймером, и твои светодиоды мигают, поочереди. Попытался файл прикрепить не прошло будет так.
Код
    list p=16f84A
    include <p16f84A.inc>

    __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC



sys_t        EQU  0x0C;
led            EQU  0x0D;
sys_k        EQU  0xF0;Константа счета

;-----------------------------------------------------------------
; Вектор сброса
;-----------------------------------------------------------------
RESET_VECTOR    org    0x000    ;Адрес вектора сброса

                            ;Банк 1
                             ;Сброс при включении питания?
        goto    start        ;Да
        goto    OTHER_RESET    ;НЕТ, WDT или сброс MCLR
;------------------------------------------------------------------
;
;Подпрограмма обработки прерываний перифирийных устройств
;Определяется источник прерывания. Разрешены следующие

;    4.Прерывание по переполнению TMR1
;
INT_VECTOR    org    0x004    ;Адрес первичного вектора прерываний
        
VECTOR_INT
;--------------------------------------------------------------------
;    Сохранение регистров и переменных

;
        
;---------------------------------------------------------------------
;
    bcf     STATUS, RP0;Банк 0
    btfss    STATUS, NOT_TO;
    goto    ERROR_WDT;Сработал сторожевой таймер

    btfsc    INTCON, T0IF;Переполнение таймера 1?
    goto    T1_Overfl;ДА, обслуживание

;Тут вставляются другие проверки

                
T1_Overfl
    movlw    sys_k    ;Загрузить таймер  
    movwf    TMR0    ;
    clrf    sys_t    ;Сбрасываем флаг

;    Восстанавливаем


;--------------------------------------------------------------------
;     Конец обработки прерывания
;----------------------------------------------------------------
    bcf        INTCON, T0IF;Переполнение таймера 1?
    retfie            ;Выходим, с разрешением прерываний

;main org
;// Обработка ошибок
ERROR_WDT
    clrf    STATUS    ;
    clrf    INTCON    ;Запретить
                    ;прерывания
    clrwdt            ;
    goto $-1        ;Зациклить на ошибке


;Проверка типа сброса
OTHER_RESET     
    btfss STATUS, NOT_TO;Сброс WDT?
WDT_TIMEOUT
    goto ERROR_WDT    ;Да, превышение WDT.
    goto start        ;Внешний сброс
    goto ERROR_WDT
ERROR1
    nop
    nop
    goto ERROR1        ;

;-----------------------------------------------------------------
;
; Начало, инициализация микроконтроллера
;
;-----------------------------------------------------------------
        
start
        clrf    STATUS    ;
        clrf    INTCON    ;Запретить
        clrwdt            ;
;---------------------------------------------------------------------
;    Начальная установка ПОРТОВ
        clrf    STATUS    ;Установить банк 0
          clrf     PORTA
           clrf     PORTB
        movlw    b'11111100';
        bsf        STATUS,    RP0;Установить банк 1
        movwf    TRISA    ; 0-1 выход адреса
           movlw     b'00000001'
        banksel PORTA
           movwf     PORTA
        movwf    led


;------------------------------------------------------------------------
;    Инициация таймера TMR0
;------------------------------------------------------------------------    
        clrf     TMR0    ;
        clrf     INTCON    ;
        movlw    b'11000111'    ;
        banksel    OPTION_REG;
        movwf    OPTION_REG;
        
        movlw    sys_k    ;
        banksel TMR0    ;
        movwf    TMR0    ;значение 1/8 секунды при
        banksel    INTCON    ;

        bsf        INTCON, T0IE;Разрешить
        bsf        INTCON, GIE;Разрешить прерывания перифирийных устройств


main;Главный цикл

        banksel PORTA
        btfsc    sys_t, 0
        goto    main    ;
        comf    led, W
        movwf    led
        movwf     PORTA
        bsf        sys_t, 0
        goto    main    ;
        end


Огромное спасибо за ответ, уж и не думал что больше ответят... я так понял чтио вот эта строчка
Код
movlw    b'11000111'

задаёт как-бы частоту прерываний в данном случае 1/8, правильно?
DL36
Цитата(Asekart @ Dec 27 2006, 10:46) *
Огромное спасибо за ответ, уж и не думал что больше ответят... я так понял чтио вот эта строчка
Код
movlw    b'11000111'

задаёт как-бы частоту прерываний в данном случае 1/8, правильно?

Код
movlw    b'11000111'

Комментарии от другого проекта остались.
Три последние 1 коэффициент деления предделителя, почитай ДАТА ШИТ раздел OPTION_REG.
Spag
Помогите пожалуйста с программой для PIC16F84A. Задача такая: Нужно написать программу которая обеспечивала бы мигание светодиода подключенного к порту В с частотой 2Гц. При поступлении низкого сигнала на порт В5 загорался второй светодиод подключенный к порту А. Попеременное мигание осуществить с помощью прерываний инициируемых таймером. Программу написал но сердцем чувствую что что-то не так.
Цитата
List p=16F84a
Include <c:\P16F84a.inc>
_w equ 0x00b;
_status equ 0x00d;
PAGE;
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON &_WDT_OFF
org 0;
goto Mainline
org 4
int
movwf_w;
movf STATUS,w;
movwf STATUS;
bcf INTCON, T0IF
movlw B'00000001'
xorwf PORTB
movwf STATUS;
swapf_w;
swapf_ww;
retfie;
Mainline
bsf STATUS, RP0;
movlw B'11111110'
movlw TRISA;
movlw B'11010111'
movlw OPTION_REG;
movlw B'11111110'
movlw TRISB;
bcf STATUS, RP0;
movlw B'10100000'
movwf INTCON;
Loop
btfsc PORTB, 5;
goto Setbit;
bcf PORTA,0;
goto Loop;
Setbit;
Bsf PORTA, 0;
goto Loop;
end
fox2trot
Цитата(Spag @ Dec 17 2011, 00:40) *
Программу написал но сердцем чувствую что что-то не так.

Правильно чувствуете. Внимательно почитайте описания команд, особенно - непосредственной загрузки (MOVLW) и поймете сразу ошибку.
xemul
Цитата(Spag @ Dec 17 2011, 00:40) *
Попеременное мигание осуществить с помощью прерываний инициируемых таймером.

Если FOSC > 524288 Гц, то Вы забыли посчитать минимальную частоту прерываний TMR0 (при FOSC = 4MHz, тактировании от CLKOUT и заданных Вами PS0..PS2 - 4MHz/4/256/256 ~= 15.3 Гц) и ввести программный счётчик для получения требуемых 2 Гц.

Для сорцов пользуйтесь, плз, иконкой со свитком и маленькой зелёной стрелочкой, а не пузыриком с тремя линиями.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.