Я работаю над школьным проектом. Это включает в себя программирование сборки PIC. Я использую демонстрационную плату с 44 контактами, PIC16F887.
Мне нужно сделать ИК-приемник, у которого есть выход, изменяющий яркость светодиода. Я пока знаю, что для этого мне нужно сделать ШИМ-регулятор. Однако я все еще борюсь с расшифровкой кнопок. Я использую эмиттер с кодировкой NEC. Моя настройка входа - цифровая, подтянутая внутренним резистором PORTB, 0. Я пытаюсь опросить вход прерываниями TMR0.
Настройка системы - генератор 4 МГц, TMR0 увеличивается каждые Osc / 4. Предделитель 1: 2, поэтому каждые 2 мкс таймер увеличивается на 1. Предварительная нагрузка Timer0 равна D’206 ’, поэтому она прерывается 50 * 2 мкс = 100 мкс. Согласно протоколу NEC, логика 0 имеет низкий уровень 562,5 мкс, логика 1 имеет низкий уровень сигнала 1687,5 мкс после сигнала 562,5 мкс HIGH.
Итак, 1687,5 мкс / 100 мкс = 16 и 562,5 мкс / 100 мкс = 5. Я пытался вычесть их из 8. Итак, я могу проверить, что означает СТАТУС, НУЛЕВОЙ бит активен или низкий.
Я не знаю, в какой части я ошибаюсь. Я оставлю свой код внизу. В этом коде мигает светодиод, при этом предполагается, что индикатор PORTD, 0 загорится при нажатии кнопки громкости +. Таким образом, я бы знал, могу ли я обнаруживать кнопки и работать с ШИМ.
Мы ценим каждый ответ.
ISR: ;IF ISR GLOBAL INT 0
btfss INTCON,T0IF
retfie ;if there is no interrupt
banksel 0 ;ISR occur in Bank0
movwf W_save ;save WORK register's value
movf STATUS,W
movwf STATUS_save ;save STATUS register's value
call IR ;call IR
goto ISR_EXIT
ISR_EXIT:
bcf INTCON,T0IF ;TMR0 interrupt flag clear
movlw b'01100110' ;preload 206
movwf TMR0
movf STATUS_save,W
movwf STATUS ;STATUS register original value reload
swapf W_save,f ;WORK register original value reload
swapf W_save,W
retfie ;retfie -> global int = 1
IR:
btfss PORTB,0 ;testing IR input
bsf ir_reg,0 ;button was pressed
btfss ir_reg,0 ;button was pressed?
goto NO_BUTTON
btfsc PORTB,0 ;HIGH signal?
goto HIGH_P
btfss ir_reg,1 ;previous was HIGH?
goto HIGH_TO_LOW
incf time,f ;increment time
goto ISR_EXIT
HIGH_P:
btfsc ir_reg,1 ;was previous LOW?
goto LOW_TO_HIGH
incf time,f ;increment time
goto ISR_EXIT
HIGH_TO_LOW: ;transition between HIGH to LOW pulses
bsf PORTD,3
movf time,W
movwf high_pulse ;saving HIGH pulse's time
clrf time ;time variable clear
bcf ir_reg,1 ;previous pulse was HIGH
goto CALC
CALC:
movf high_pulse,W ;high pulse's time into Work
bcf STATUS,Z ;STATUS ZERO CLEAR
sublw D'10' ;LOW_P -> 5-10 = -5,HIGH_P - > 16-10 = 6
btfsc STATUS,Z ;if subtraction = +
bsf ir_reg,3 ;subtraction ended positive -> LOGIC 1
bcf ir_reg,3 ;subtraction ended negative -> LOGIC 0
goto ADD_BITS
ADD_BITS:
bsf PORTD,2
btfsc ir_reg,3 ;if LOGIC 1
bsf STATUS,C ;carry bit 1
bcf STATUS,C ;carry bit 0
goto ROTATE
ROTATE:
bsf PORTD,1
rlf naddress ;Carry is rotated to naddress LSB
rlf address ;naddress MSB rotated to address LSB through Carry
rlf ncommand ;address MSB rotated to ncommand LSB through Carry
rlf command ;ncommand MSB rotated to command LSB through Carry
incf pulses ;every time we have a rotation increment variable
movf pulses,W
bcf STATUS,Z ;status zero clear
sublw D'32' ;33-pulses,we have a decoded signal
btfss STATUS,Z ;if Zero set
goto ISR_EXIT ;goto NO_button
goto LED_FLASH
LED_FLASH:
movf command,W
bcf STATUS,Z
sublw b'10101000' ;+ button command: b'10101000'
btfss STATUS,Z
goto NO_BUTTON
bsf PORTD,0
goto ISR_EXIT
LOW_TO_HIGH: ;transition between LOW to HIGH pulses
movf time,W
movwf low_pulse ;saving LOW pulse's time
clrf time ;time variable clear
bsf ir_reg,1 ;previous pulse was LOW
goto ISR_EXIT
NO_BUTTON:
btfsc PORTB,0
goto ISR_EXIT
clrf pulses ;clearing variables
clrf ir_reg
clrf time
clrf address
clrf naddress
clrf address
clrf ncommand
clrf command
goto ISR_EXIT
INIT:
;OSCCON INIT
banksel OSCCON
movlw b'01100000' ;4Mhz oscillator
movwf OSCCON
;OUTPUT INIT
banksel TRISD
clrf TRISD ;TRISD OUTPUT
banksel PORTD
clrf PORTD ;PORTD LOW
;INPUT INIT
banksel TRISB
bsf TRISB,RB0 ;RB0 INPUT
bsf WPUB,RB0
movlw 0x00
banksel ANSELH
movwf ANSELH ;RB0 DIGITAL
call Delay
;OPTION REG INIT / TMR0
banksel OPTION_REG
movlw b'00000000' ;TMR0 prescale 1:2 increment every 2us
movwf OPTION_REG
movlw b'01100110' ;preload 206
movwf TMR0 ;50 tick until overflow 50*2us = 100us
;INTCON INIT
banksel INTCON
bcf INTCON,T0IF ;TMR0 overflow flag clear
bsf INTCON,T0IE ;TMR0 overflow enable
bsf INTCON,GIE ;global interrupt enable
return
MAIN:
call INIT
call FLASH ;LED FLASH
goto $-1
END