PIC16F684 реализация отсчета времени

Тема в разделе "WASM.ELECTRONICS", создана пользователем 0x00786F72, 7 мар 2007.

  1. 0x00786F72

    0x00786F72 New Member

    Публикаций:
    0
    Регистрация:
    30 авг 2006
    Сообщения:
    30
    Здравствуйте!
    Помогите реализовать отсчет времени с помощью TMR0 на контроллере PIC16F684. Я понимаю, что заниматься сексом с железом - это конечно круто и желательно заниматься этим самостоятельно, но сил у меня уже больше нет (трахаюсь уже 4-й день в одной и той же позе:'( ).
    Вот что я для примера состряпал:
    Код (Text):
    1. list p=pic16f684
    2. #include <p16f684.inc>
    3.  
    4. __CONFIG _IESO_OFF & _BOD_OFF & _WDT_OFF & _XT_OSC & _MCLRE_OFF & _PWRTE_ON & _CP_OFF & _FCMEN_OFF
    5.  
    6. ;регистры для сохранения контекста прерываний
    7. W_temp              equ     0x20
    8. FSR_temp            equ     0x21
    9. STATUS_temp         equ     0x22
    10. ;another regs
    11. TMR0_counter        equ     0x23
    12. tmp1                equ     0x24
    13. cbuf                equ     0x25
    14. int_flags           equ     0x26
    15. minute              equ     0x27
    16. bit_cntr            equ     0x28
    17. sec1_counter        equ     0x29
    18. ;флаги регистра int_flags
    19. sec1                equ     0x00
    20. ms10                equ     0x01
    21.  
    22.  
    23. PUSHAD_MACRO        MACRO              ;Макрос сохранения контекста
    24.         movwf       W_temp             ;сохранить регистр W
    25.         movf        STATUS, W          ;сохранить
    26.         movwf       STATUS_temp        ;регистр STATUS
    27.         movf        FSR, W             ;сохранить
    28.         movwf       FSR_temp           ;регистр FSR
    29. ENDM
    30.  
    31. POPAD_MACRO         MACRO              ;Макрос восстановления контекста
    32.         movf        FSR_temp, W        ;Восстановить
    33.         movwf       FSR                ;регистр FSR
    34.         movf        STATUS_temp, W     ;Восстановить
    35.         movwf       STATUS_temp        ;регистр STATUS
    36.         movf        W_temp, W          ;Восстановить регистр W
    37. ENDM
    38.  
    39. org    0
    40.         goto    start
    41.         nop
    42.         nop
    43.         nop
    44.  
    45. ;обработчик прерываний.
    46.         PUSHAD_MACRO                   ;сохранить контекст
    47.         bcf         STATUS, RP0        ;выбрать банк 0
    48.         btfsc       INTCON, T0IF       ;Прерывание от TMR0?
    49.         goto        TMR0_int           ;Да
    50.         btfsc       PIR1, ADIF         ;Нет, прерывание от АЦП?
    51.         goto        AD_int             ;Да
    52.         goto        ERROR_int          ;Нет, переход к процедуре восстановления при ошибке
    53. END_ISR:
    54.         POPAD_MACRO
    55.         retfie                         ;возврат с разрешением прерываний
    56.  
    57. ;обработчик прервыания от ADC:        
    58. AD_int:
    59.  
    60. ;обработчик прерывания от TMR0:
    61. TMR0_int:
    62. ;Предделитель перед TMR0 == 64 => на частоте 4 МГц прерывание вызывается каждые (256 - 100)* 64 == 10 мсек.
    63.         bcf         STATUS, RP0
    64.         movlw       0x64                ;
    65.         movwf       TMR0                ;
    66.         bcf         INTCON, T0IF        ;сброс флага прерывания от TMR0
    67.         incf        TMR0_counter, F     ;инкремент счетчика прерываний
    68.         movf        TMR0_counter, W     ;сравнить счетчик прерываний
    69.         xorlw       0x64                ;со 100d
    70.         btfss       STATUS,Z            ;если TMR0_counter != 100d
    71.         goto        END_ISR             ;выход
    72.  
    73.         clrf        TMR0_counter        ;сброс TMR0_counter
    74.         bsf         int_flags, ms10     ;устанавливается флаг сообщающий о прошествии 10 мсек
    75.  
    76.         incf        sec1_counter, F     ;инкремент и проверка
    77.         movf        sec1_counter, W     ;на переполнение регистра sec1_counter
    78.         xorlw       0x64                ;Если регистр
    79.         btfss       STATUS, Z           ;не переполнился,
    80.         goto        notofl_sec1         ;то инкрементить его и выйти
    81.         clrf        sec1_counter        ;иначе очистить его,
    82.         bsf         int_flags, sec1     ;сообщить, что прошла 1 секунда
    83.         goto        END_ISR             ;иначе выход из прерывания
    84. notofl_sec1:      
    85.         goto        END_ISR             ;выход из обработчика прерываний
    86. ERROR_int:
    87.         goto        END_ISR
    88.  
    89. org 0xDF
    90. ;Процедура преобразования hex-кода в 7-сегментный
    91. ;Перед вызовом в аккумулятор необходимо занести HEX-код
    92. ;Процедура в аккумуляторе возвращает 7-сегментный код
    93. ;Обязательно должна находиться в первой странице памяти. Макс.
    94. ;количество команд 0x20.
    95. hex_to_7seg:
    96.         addwf       PCL, F          ;к счетчику команд прибавить смещение в таблице
    97.         retlw       B'00000010'     ; 0
    98.         retlw       B'10011110'     ; 1
    99.         retlw       B'00100100'     ; 2
    100.         retlw       B'00001100'     ; 3
    101.         retlw       B'10011000'     ; 4
    102.         retlw       B'01001000'     ; 5
    103.         retlw       B'01000000'     ; 6
    104.         retlw       B'00011110'     ; 7
    105.         retlw       B'00000000'     ; 8
    106.         retlw       B'00001000'     ; 9
    107.         retlw       B'00010000'     ; A
    108.         retlw       B'11000000'     ; b
    109.         retlw       B'01100010'     ; C
    110.         retlw       B'10000100'     ; d
    111.         retlw       B'01100000'     ; E
    112.         retlw       B'01110000'     ; F
    113.         retlw       B'11111110'     ; Пустое место (код 10h)
    114.         retlw       B'11111100'     ; Прочерк (код 11h)
    115.         retlw       B'10000010'     ; U    (код 12h)
    116.         retlw       B'11110010'     ; I    (код 13h)
    117.  
    118. start:
    119. ;################## M A I N   F O O #############################
    120. ;Очистка SFR
    121.         bcf         STATUS, RP0         ;выбрать банк 0
    122.         movlw       0x20                ;занести в FSR
    123.         movwf       FSR                 ;адрес первого регистра GPR
    124. clr_reg:                
    125.         clrf        INDF                ;очистить регистр
    126.         incf        FSR, F              ;инкремент FSR
    127.         btfss       FSR, 7              ;если FSR == 0x80 - пропуск,
    128.         goto        clr_reg             ;иначе переход к след. итерации
    129. ;Инициализация TMR0
    130.         bcf         STATUS, RP0         ;Выбрать банк 0
    131.         movlw       0x64                ;64h == 100d
    132.         movwf       TMR0                ;сбросить TMR0 и предделитель
    133.         clrf        INTCON              ;Выключть прерывания, и сбросить T0IF
    134.         bsf         STATUS, RP0         ;Выбрать банк 1
    135.         movlw       b'10000101'         ;Внутренний тактовый сигнал(бит 5) ; подтягивающие резисторы отключены (бит 7)
    136.         movwf       OPTION_REG          ;предделитель включен перед TMR0 (бит 3)        
    137.         bcf         STATUS, RP0         ;Переход в банк 0
    138.         bsf         INTCON, T0IE        ;разрешить прерывание по переполнению TMR0
    139.         bsf         INTCON, GIE         ;разрешить все немаскированные прерывания
    140. ;
    141. ;Инициализация порта C
    142.         bcf         STATUS, RP0         ;выбрать банк 0
    143.         clrf        PORTC               ;инициализация защелок порта C
    144.         movlw       0x3F                ;установить RA<5:0> для цифрвого I/0
    145.         movwf       CMCON0              ;
    146.         bsf         STATUS, RP0         ;выбрать банк 1
    147.         clrf        ANSEL               ;digital I/O
    148.         movlw       b'10000000'         ;подтягивающие резисторы отключены
    149.         movwf       TRISC               ;все биты PORTC настроены на выход
    150. ;
    151. main_loop:
    152.         btfsc       int_flags, sec1     ;Прошла одна секунда?
    153.         call        refresh_disp_       ;Да
    154.    goto main_loop
    155.  
    156. refresh_disp_:
    157.         bcf         int_flags, sec1 ;
    158.         incf        minute, F       ;
    159.         movlw       0x09
    160.         xorwf       minute, W       ;
    161.         btfsc       STATUS, Z       ;
    162.         clrf        minute
    163.         movf        minute, W
    164.         call        hex_to_7seg
    165.         xorlw       0xFF            ;инверсия для индикаторов с общим катодом
    166.         movwf       tmp1
    167.         movlw       0x08            ;
    168.         movwf       bit_cntr        ;
    169. refresh_disp_loop_:
    170.         bsf         cbuf, 0         ;установить на DATA "1"
    171.         btfss       tmp1, 0         ;если 0-й разряд == 0
    172.         bcf         cbuf, 0         ;сбросить DATA
    173.         movf        cbuf, W         ;
    174.         movwf       PORTC           ;перенести значение буфера в регистр
    175.         bsf         cbuf, 1         ;
    176.         movf        cbuf, W         ;
    177.         movwf       PORTC           ;подать тактовый импульс
    178.         bcf         cbuf, 1         ;
    179.         movf        cbuf, W         ;
    180.         movwf       PORTC           ;на CLK
    181.         bcf         STATUS, C       ;сброс флага C
    182.         rrf         tmp1, F         ;сдвиг кода символа на 1 разряд вправо
    183.         decf        bit_cntr, F     ;декремент счетчика
    184.         btfss       STATUS, Z       ;Если bit_cntr обнулился - пропуск
    185.         goto        refresh_disp_loop_
    186.         movlw       0x00
    187.         movwf       PORTC
    188.         return
    189. end
    Что здесь не так?
    Ответы типа "бери AVR и ниипи моск", "PIC гамно - AVR-ы и MSP руляд" и т.п. не принимаются:)
    Также не принимается ответ вроде "У тебя бракованный проц, бери другой" (скорее у меня мозг бракованный:))
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    а ты примеры искать не пробовал.
    Года 3 назад, я такой же фигней занимался, примеров находил немало, в том числе там был и таймер.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    0x00786F72
    Здесь отличные переводы мануалов по PIC, только я прочитав их , всё равно перешёл на AVR :)))
     
  4. 0x00786F72

    0x00786F72 New Member

    Публикаций:
    0
    Регистрация:
    30 авг 2006
    Сообщения:
    30
    Y_Mur, та страничка мне прекрасно знакома, но все равно спасибо:) 4 дня мучался из-за глупой ошибки в коде:
    в обработчике прерывания я дважды считал до 100, т.е. фактически вместо одной секунды он отсчитывал примерно 100 секунд:)
    На AVR, тоже собираюсь перейти, но только как закончу проект:)
    З.Ы. тему можно закрыть