Anexo 1: Programa em Assembly para Microcontrolador PIC16F628 ;********************************************************************* ; ; Projeto de um Robô comandado pelo computador ; ********************************************************************** CBLOCK 0X70 ; Definição de variáveis - posição comum a todos bancos TEMP RBID OK PWM1 PWM2 COUNT1 COUNT2 ENDC #INCLUDE P16F628.inc #DEFINE BANK1 BSF STATUS,RP0 ; Seleciona Banco 1 para RAM RAM #DEFINE BANK0 BCF STATUS,RP0 ; Seleciona Banco 0 para RAM ORG 0X00 GOTO INICIO ORG 0X04 ; Vetor de início das interrupções BTFSC INTCON,T0IF ; Verifica se ocorreu interrupção de Timer GOTO TIMER0 ; Se sim, desvia para rotina do Timer0 BTFSS PIR1,RCIF ; Verifica interrupção de recepção USART RETFIE RX MOVF RCREG,W ; Tratamento da interrupção pela USART MOVWF TEMP MOVLW .1 ; Byte de Controle já recebido? SUBWF OK,W BTFSC STATUS,Z GOTO RECEBE ; Sim, então desvia p/ receber dados PWM MOVLW 0XC3 ; Caso seja o primeiro byte recebido (byte ; de controle) ANDWF TEMP,W ; Verifica padrão 11XXYY11. SUBLW 0XC3 BTFSS STATUS,Z GOTO SAI ; Se não, sai do procedimento. MOVLW B’00110000’ ; Ajuste XX = 11 (máscara p/ código robô) ANDWF TEMP,W SUBWF RBID,W BTFSS STATUS,Z ; Caso não seja para esse robô, GOTO SAI ; sai do procedimento INCF OK,F ; Se for, incrementa 1 na variável OK, ; indicando que recebeu o byte de controle MOTOR1 BTFSC TEMP,2 ; Verifica sentido motor 1 GOTO REVERTER ; Caso seja para trás, pula para rotina de ; reversão BSF PORTB,3 BCF PORTA,1 MOTOR2 BTFSC TEMP,3 ; Verifica sentido motor 2 GOTO REVERTER2 ; Caso seja para trás , pula para rotina BSF PORTB,5 BCF PORTB,6 GOTO SAI REVERTER BSF PORTA,1 ; Inverte acionamento dos bits para motor 1 BCF PORTB,3 GOTO MOTOR2 REVERTER2 BSF PORTB,6 ; Inverte acionamento dos bits para motor 2 BCF PORTB,5 GOTO SAI RECEBE ; Recebe informação dos PWMs ; (velocidade dos motores) MOVLW 0X0F ANDWF TEMP,W ; Lê byte PWMs MOVWF PWM1 ; Separa parte baixa referente ao PWM1 MOVLW 0XF0 ANDWF TEMP,F ; Separa parte alta referente ao PWM2 RRF TEMP,F RRF TEMP,F RRF TEMP,F ; Rotaciona 4 vezes para ajustar RRF TEMP,F ; parte alta do byte (PWM2) MOVFW TEMP MOVLW 0X0F ANDWF TEMP,W MOVWF PWM2 ; Guarda o valor em PWM2 SAI1 DECF OK,F ; Zera OK; indica recebimento byte PWM SAI BCF PIR1,RCIF ; Limpa flag da interrupção por USART RETFIE TIMER0 ; Interrupção de Timer0 INCF COUNT1,F ; Incrementa COUNT1 (PWM do Motor1) MOVLW 0X0F ANDWF COUNT1,F ; Verifica se COUNT1 passou de 15. INCF COUNT2,F ; Incrementa COUNT2 (PWM do Motor 2) ANDWF COUNT2,F ; Rotina do PWM1 MOVF COUNT1,W BTFSC STATUS,Z ;Verifica se COUNT está em 0 BSF PORTB,4 ; Se estiver, liga o PWM SUBWF PWM1,W ; Testa para ver se o COUNT1=PWM1 BTFSC STATUS,Z BCF PORTB,4 ; Se for, desliga PWM ; Rotina do PWM2 MOVF COUNT2,W ;Mesmo procedimento para o PWM2 BTFSC STATUS,Z BSF PORTB,7 SUBWF PWM2,W BTFSC STATUS,Z BCF PORTB,7 BCF INTCON,T0IF ; Limpa flag da interrupção por timer RETFIE ; Programa Principal INICIO BANK0 MOVLW B'10010000' ; Habilita USART para recepção contínua e MOVWF RCSTA ; Modo Assíncrono (TXSTA = 0 inicial) BANK1 MOVLW B'11111100' MOVWF TRISA ; Configura direção das portas A MOVLW B'00000111' MOVWF TRISB ; Configura direção das portas B MOVLW .25 ; Controle do gerador BAUD RATE MOVWF SPBRG ; ~2400 bits/s MOVLW B'00000001' ; Habilita Timer 0 para trabalhar com MOVWF OPTION_REG ; freqüência 1:4 MOVLW B'11100000' ; Habilita interrupção por overflow Timer 0 MOVWF INTCON ; e interrupção de grupo de periféricos BSF PIE1,RCIE ; Habilita interrup. recepção pela USART BANK0 MOVLW .15 MOVWF COUNT1 ; Inicia os PWMs MOVWF COUNT2 MOVLW B'00XX0000' ; Identificação do robô: p/ robô 1 XX=01, MOVWF RBID ; para robô 2 XX=10, e assim por diante. VOLTA GOTO VOLTA ; Fica aguardando interrupção: Timer ou ; Recepção. END