;************************************************************** ;* Programa para Robô Explorador - robo_explorador.asm ;* Desenvolvido por Márcio José Soares ;* ;* Controle do robô Explorador ;* Publicado na Revista Mecatrônica Fácil - nº18 ;* Microcontrolador: PIC16F628A-I/P ;* Uso de clock interno ;* Compilador: MPLAB 6.60 ;* ;* Advertencia! ;* Não funciona com PIC16F628-20/P!!! ;* Observe o código do PIC!!!! ;* ;* Descrição da pinagem do PIC ;* RA0 - bumper de colisão 1 ;* RA1 - servo (1) controle de direção do robô ;* RA2 - servo (2) controle do gira da base do braço ;* RA3 - servo (3) controle de elevação do braço ;* RA4 - bumper de colisão 2 ;* RA5 - entrada extra (nível TTL - ativo em "0") ;* RA6 - servo (4) controle da garra do braço ;* RA7 - saída extra (relé) ;* RB0 - Buzzer ;* RB1 - Entrada do sinal de controle ;* RB2 - Saída do sinal de resposta ;* RB3 - lâmpada de navegação e apoio a câmera (opcional) ;* RB4 - controle da ponte H ;* RB5 - controle da ponte H ;* RB6 - controle da ponte H ;* RB7 - controle da ponte H ;* ;************************************************************** radix dec ;padrao->valores decimal se nao informado outro include ;inclue arquivo ;configura bits __CONFIG _LVP_OFF & _MCLRE_OFF & _BODEN_OFF & _LVP_OFF & _CP_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;configura bits ;************************************************************** ;* Definições ;************************************************************** #DEFINE bank0 BCF STATUS,RP0 ;seta banco 0 da memória #DEFINE bank1 BSF STATUS,RP0 ;seta banco 1 da memória PICRES equ 0x00 ;endereço do reset PICRAM equ 0x20 ;endereço da RAM SRV equ PORTA ;define servos na porta A SRV1 equ 0x01 ;endereço do pino do servo 1 SRV2 equ 0x02 ;endereço do pino do servo 2 SRV3 equ 0x03 ;endereço do pino do servo 3 SRV4 equ 0x06 ;endereço do pino do servo 4 BUMPER equ PORTA ;define bumpers na porta A BUMPER1 equ 0x00 ;endereço do pino do bumper 1 BUMPER2 equ 0x04 ;endereço do pino do bumper 2 PTH equ PORTB ;define ponte H na porta B PTH1 equ 0x04 ;endereço para ponte H PTH2 equ 0x05 ;endereço para ponte H PTH3 equ 0x06 ;endereço para ponte H PTH4 equ 0x07 ;endereço para ponte H ACESS equ PORTB ;porta onde serão ligados os acessórios como LP equ 0x00 ;lâmpada para câmera BEEP equ 0x03 ;beep ACES2 equ PORTA ;porta para outros acessórios como RELE equ 0x07 ;relé para saída extra E_EXTRA equ 0x05 ;entrada extra ;************************************************************** ;* Variáveis ;************************************************************** org PICRAM ;inicio da RAM T1 res 1 ;variável para temporizador T2 res 1 ;variável para temporizador T3 res 1 ;variável para temporizador T4 res 1 ;variável para temporizador T5 res 1 ;variável para contador AUX res 1 ;variável para dado recebido P1 res 1 ;variável para posição do servo 1 P2 res 1 ;variável para posição do servo 2 P3 res 1 ;variável para posição do servo 3 P4 res 1 ;variável para posição do servo 4 VAR1 res 1 ;variável auxiliar de recepção de dados VAR2 res 1 ;variável auxiliar de recepção de dados VAR3 res 1 ;variável auxiliar de recepção de dados VAR4 res 1 ;variável auxiliar de recepção de dados VAR_AUX res 1 ;variável auxiliar para VAR1, VAR2, VAR3 e VAR4 FLG_RX res 1 ;flags para recepção dos dados ;protocolo de comunicação LIG_DES res 1 ;Variável para ligar/desligar motor ;bit 0 determina se ligado ou desligado (0 e 1) ;bits 1 e 2 determinam sentido. Se 10 a frente, ;se 11 para tras LD_MT_AUX ;variável backup para variável acima BP res 1 ;variável para guardar estado do bumper 1 e 2 ;bit 0, bp1 e bit 1 bp2 LED res 1 ;variável para guardar o estado do led W2 res 1 ;backup para W PCLATH2 res 1 ;backup para PCLATH STATUS2 res 1 ;backup para STATUS ; ;************************************************************** ;*define memoria de programa e vetor de reset ;************************************************************** org PICRES ;reset meureset: goto inicio ;desvia do endereco 0x04 - interrupcao ;************************************************************** ;* endereço e rotina de interrupção ;************************************************************** org 4 ;toda interrupção aponta para este endereço minhaint: goto IntVector ;desvia para tratamento da INT ; ;************************************************************** ;* inicio do programa ;************************************************************** inicio: movlw 0x00 ;ajuste para os bits INTCON movwf INTCON clrf PORTA ;limpa porta A clrf PORTB ;limpa porta B bank1 ;seleciona banco 1 para options e tris movlw b'00010001' ;ajusta como entrada os bits 0 e 5. movwf TRISA ;o restante é saída movlw b'00000010' ;ajusta os bits em B como saida. RB1 é entrada movwf TRISB ;o restante é entrada bank0 ;volta ao banco 0... (padrão do reset) ;************************************************************** ;* seta canal serial no PIC ;************************************************************** bank1 ;seleciona banco 1 movlw 0X67 ;velocidade selecionada 2400 movwf SPBRG ;8 bits, sem paridade, 1 stop bit bsf TXSTA,TXEN ;habilita transmissao bsf TXSTA,BRGH ;seleiona baud rate alto bcf TXSTA,SYNC ;seleciona modo assincrono bank0 ;volta para banco 0 bsf RCSTA,SPEN ;habilita port serial bsf RCSTA,CREN ;habilita recepcao continua bcf PIR1,RCIF ;limpa flag de interrupcao RCIF bank1 ;seleciona banco 1 bsf PIE1,RCIE ;seta interrupçao RCIE bank0 ;volta para banco 0 bsf INTCON,PEIE ;habilita perifericos bsf INTCON,GIE ;habilita interrupçoes (Global) movlw 0x07 ;desliga os conversores AD internos movwf CMCON ;************************************************************** ; limpa variáveis e prepara inicio da operação ;************************************************************** movlw 0xFF ;carrega variável auxiliar movwf AUX ; clrf BP ;zera variável de estado dos bumpers clrf LIG_DES ;zera variável de estado do motor clrf LD_MT_AUX ;zera variável de estado anterior do motor clrf VAR1 ;zera variável clrf VAR2 ;zera variável clrf VAR3 ;zera variável clrf VAR4 ;zera variável clrf VAR_AUX ;zera variável movlw .175 ;posição inicial para servo 1 movwf P1 movlw .175 ;posição inicial para servo 2 movwf P2 movlw .175 ;posição inicial para servo 3 movwf P3 movlw .175 ;posição inicial para servo 4 movwf P4 bcf PTH,PTH1 ;desliga ponte H bcf PTH,PTH2 ; bcf PTH,PTH3 ; bcf PTH,PTH4 bsf ACESS,BEEP ;liga beep para aviso de setup ok bcf ACESS,LP ;lâmpada de apoio a câmera desligada bcf ACES2,RELE ;relé para ativar/desativar saída extra call delay ;aguarda aproximadamente 1 segundo bcf ACESS,BEEP ;desliga beep após 1 segundo ;************************************************************** ;* loop principal ;* mantem servos na posição enquanto aguarda novo dado ;* motor ligado ou desligado, conforme comando ;* trabalha com a INT de recepção ;* transmite o estado dos bumper's ;************************************************************** loop: call acerta_srvs ;coloca servos na posição goto loop ;faz infinitamente ;*************************************************************** ; subrotina para posicionar servos ; pulsa tempo nas variáveis P1, P2, P3 e P4 e aguarda ; aproximadamente 15ms, dependendo do tamanho máximo para servos ;*************************************************************** acerta_srvs: bsf SRV, SRV1 ;levanta sinal servo movf P1,W ;carrega tempo servo em W call _tsrv ;espera tempo bcf SRV, SRV1 ;abaixa sinal servo bsf SRV, SRV2 ;levanta sinal servo movf P2,W ;carrega tempo servo em W call _tsrv ;espera tempo bcf SRV, SRV2 ;abaixa sinal servo bsf SRV, SRV3 ;levanta sinal servo movf P3,W ;carrega tempo servo em W call _tsrv ;espera tempo bcf SRV, SRV3 ;abaixa sinal servo bsf SRV, SRV4 ;levanta sinal servo movf P4,W ;carrega tempo servo em W call _tsrv ;espera tempo bcf SRV, SRV4 ;abaixa sinal servo call delay_srv ;tempo para novo sinal p/ servos return ;retorna ;*************************************************************** ; subrotina para ligar / desligar motor ; de acordo com variável LIG_DES => variável também determina ; sentido de rotação dos motores ;*************************************************************** acerta_mtr: movf PTH ,W ;colhe valor atual na porta andlw 0x0F ;faz um and para desligar movwf PTH ;ponte H btfss LIG_DES,0 ;testa bit para ver se liga goto reset1 ;não desliga bit bsf PTH,PTH1 ;sim, seta bit goto actprx1 ;continua acerto da ponte reset1: bcf PTH,PTH1 ;desliga bit actprx1: btfss LIG_DES,1 ;testa bit para ver se liga goto reset2 ;não desliga bit bsf PTH,PTH2 ;sim, seta bit goto actprx2 ;continua acerto da ponte reset2: bcf PTH,PTH2 ;desliga bit actprx2: btfss LIG_DES,2 ;testa bit para ver se liga goto reset3 ;não desliga bit bsf PTH,PTH3 ;sim, seta bit goto actprx3 ;continua acerto da ponte reset3: bcf PTH,PTH3 ;desliga bit actprx3: btfss LIG_DES,3 ;testa bit para ver se liga goto reset4 ;não desliga bit bsf PTH,PTH4 ;sim, seta bit goto actprx4 ;continua acerto da ponte reset4: bcf PTH,PTH4 ;desliga bit actprx4: return ;volta ;*************************************************************** ; subrotina para testar bumpes ; guarda estado na variável BP ;*************************************************************** testa_bprs: btfss BUMPER,BUMPER1 ;testa bumper 1 goto Seta1 ;pressionado, seta bit na variável bcf BP,0 ;não pressionado, reseta bit goto next_bpr ;testa o outro Seta1: bsf BP,0 ;seta bit next_bpr: btfss BUMPER,BUMPER2 ;repete operação para bumper 2 goto Seta2 bcf BP,1 goto next_bpr2 ;testa entrada extra Seta2: bsf BP,1 ;seta bit next_bpr2: btfss ACES2,E_EXTRA ;repete operação para entrada extra goto Seta3 bcf BP,2 ;reseta bit goto fim_tst_bp Seta3: bsf BP,2 ;seta bit fim_tst_bp: return ;*************************************************************** ; subrotina para envio do estado dos bumpers ; envia BP - se bit em 1, ligado, se bit em 0 desligado ;*************************************************************** tx_bumper: movlw "S" ;carrega W com S movwf TXREG ;envia caracter call TestTx ;Testa se caracter foi enviado movf BP,W ;carrega W com variável bumper addlw 0x30 ;adapta para ASCII movwf TXREG ;envia caracter call TestTx ;testa se caracter foi enviado return ;retorna ;*************************************************************** ; subrotina para tratamento dos dados recebidos ; recebe bytes e verifica o que fazer ;*************************************************************** trata: btfss FLG_RX,0 ;testa flag de protocolo recebido goto rx_ini ;starta recebimento de caracter goto rx_comando ;testa qual comando ;*************************************************************** ; recebe caracter de protocolo rx_ini: movf AUX,W ;pega novamente dado recebido para comparação xorlw "E" ;compara com E para saber se protocolo ok btfss STATUS,Z ;ok?! return ;fim da int bsf FLG_RX,0 ;seta o flag de protocolo ;movwf TXREG ;envia caracter de echo, manter comentado após testes return ;fim da int. Restaure o contexto se necessario ;*************************************************************** ; recebe caracter de comando rx_comando: movf AUX,W ;prepara para nova comparação xorlw "S" ;compara com S btfsc STATUS,Z ;ok?! goto ajt_servo ;ajusta servo movf AUX,W ;prepara caracter recebido para comparação xorlw "M" ;compara com M btfsc STATUS,Z ;ok?! goto ajt_motor ;ajusta motor movf AUX,W ;prepara caracter recebido para comparação xorlw "B" ;compara com B btfsc STATUS,Z ;ok?! goto ajt_beep ;ajusta beep movf AUX,W ;prepara caracter recebido para comparação xorlw "L" ;compara com L btfsc STATUS,Z ;ok?! goto ajt_lp ;ajusta lp movf AUX,W ;prepara caracter recebido para comparação xorlw "R" ;compara com R btfsc STATUS,Z ;ok?! goto ajt_rele ;ajusta relé da saída extra movf AUX,W ;prepara caracter recebido para comparação xorlw "F" ;compara com L btfsc STATUS,Z ;ok?! goto ajt_status ;ajusta lp ;*************************************************************** ; recebe caracteres para ajuste e outros rec_ajuste: ;recebe 4 caracteres btfss FLG_RX,1 ;testa se variável 1 ja recebeu goto ins_var1 ;insere na variável 1 btfss FLG_RX,2 ;testa se variável 2 ja recebeu goto ins_var2 ;insere na variável 2 btfss FLG_RX,3 ;testa se variável 3 ja recebeu goto ins_var3 ;insere na variável 3 btfss FLG_RX,4 ;testa se variável 4 ja recebeu goto ins_var4 ;insere na variável 4 return ;todas cheias, retorna ;*************************************************************** ; grava variáveis auxiliares com caracteres recebidos ins_var1: movf AUX,W ;carrega caracter recebido movwf VAR1 ;salva em variável 1 bsf FLG_RX,1 ;seta flag para avisar recebimento return ;volta ins_var2: movf AUX,W ;carrega caracter recebido movwf VAR2 ;salva em variável 2 bsf FLG_RX,2 ;seta flag para avisar recebimento return ;volta ins_var3: movf AUX,W ;carrega caracter recebido movwf VAR3 ;salva em variável 3 bsf FLG_RX,3 ;seta flag para avisar recebimento return ;volta ins_var4: movf AUX,W ;carrega caracter recebido movwf VAR4 ;salva em variável 4 bsf FLG_RX,4 ;seta flag para avisar recebimento return ;volta ;*************************************************************** ; trata variáveis recebidas para ser utilizada pela rotina ; acerta_srv - variáveis são inseridas nas variáveis P1,P2,P3 e P4 ajt_servo: ;em VAR1 número do servo movlw 0x30 ;carrega W com 30 hexa subwf VAR1,F ;subtrai para acertar de ASCII->valor movlw 0x30 ;carrega W com 30 hexa subwf VAR2,F ;subtrai para acertar de ASCII->valor movlw 0x30 ;carrega W com 30 hexa subwf VAR3,F ;subtrai para acertar de ASCII->valor movlw 0x30 ;carrega W com 30 hexa subwf VAR4,F ;subtrai para acertar de ASCII->valor movf VAR2,W ;em VAR2 centena do valor passado movwf VAR_AUX ;salva resultado em variável auxiliar ajtsrv1: movlw 0x63 ;carrega W com 99 (63 hexa) movwf T5 ;carrega T1 ajts_1: movf VAR_AUX,W ;em W, valor de VAR_AUX addwf VAR2,F ;soma ao conteúdo de VAR2 decfsz T5,F ;faz 100 vezes (0-99). VAR2=VAR2x100 goto ajts_1 movf VAR3,W ;em VAR3, dezena do valor movwf VAR_AUX ;salava resultado ajtsrv2: movlw 0x09 ;carrega W com 9 movwf T5 ;carrega T1 ajts_2: movf VAR_AUX,W ;em W, valor de VAR_AUX addwf VAR3,F ;soma ao conteúdo de VAR2 decfsz T5,F ;faz 10 vezes (0-9). VAR2=VAR2x10 goto ajts_2 movf VAR2,W ;prepara para somar addwf VAR3,W ;soma centena e dezena addwf VAR4,W ;soma com unidade movwf VAR_AUX ;salva resultado na variável auxiliar movf VAR1,W ;prepara para testar qual servo deve ser alterado xorlw 0x01 ;compara com primeiro btfss STATUS,Z ;é primeiro goto prxajts1 ;não. testa outro movf VAR_AUX,W ;sim, valor para primeiro servo movwf P1 ;carrega na variável o valor do movimento desejado goto fim_ajtsrv ;finaliza ajuste servo prxajts1: movf VAR1,W ;prepara para testar qual servo deve ser alterado xorlw 0x02 ;compara com primeiro btfss STATUS,Z ;é primeiro goto prxajts2 ;não. testa outro movf VAR_AUX,W ;sim, valor para primeiro servo movwf P2 ;carrega na variável o valor do movimento desejado goto fim_ajtsrv ;finaliza ajuste servo prxajts2: movf VAR1,W ;prepara para testar qual servo deve ser alterado xorlw 0x03 ;compara com primeiro btfss STATUS,Z ;é primeiro goto prxajts3 ;não. testa outro movf VAR_AUX,W ;sim, valor para primeiro servo movwf P3 ;carrega na variável o valor do movimento desejado goto fim_ajtsrv ;finaliza ajuste servo prxajts3: movf VAR1,W ;prepara para testar qual servo deve ser alterado xorlw 0x04 ;compara com primeiro btfss STATUS,Z ;é primeiro goto fim_ajtsrv ;não. Então valor é invalido! movf VAR_AUX,W ;sim, valor para primeiro servo movwf P4 ;carrega na variável o valor do movimento desejado fim_ajtsrv: goto fim_ajustes ;vai para o final dos ajustes ;*************************************************************** ; trata variáveis recebidas para ser utilizada pela rotina ; acerta_mtr - variáveis são inseridas na variável LIG_DES ajt_motor: movlw 0x30 ;carrega W com 30 hexa subwf VAR1,F ;subtrai para acertar de ASCII->valor movlw 0x30 ;carrega W com 30 hexa subwf VAR2,F ;subtrai para acertar de ASCII->valor movlw 0x30 ;carrega W com 30 hexa subwf VAR3,F ;subtrai para acertar de ASCII->valor movlw 0x30 ;carrega W com 30 hexa subwf VAR4,F ;subtrai para acertar de ASCII->valor bcf STATUS,C ;limpa carry bit rlf VAR1,F ;gira 3 vezes a esquerda para posicionar bit rlf VAR1,F ;de interesse rlf VAR1,F bcf STATUS,C ;limpa carry bit rlf VAR2,F ;gira 3 vezes a esquerda para posicionar bit rlf VAR2,F ;de interesse bcf STATUS,C ;limpa carry bit rlf VAR3,F ;gira uma vez a esquerda para posicionar bit clrf LD_MT_AUX ;limpa variável auxiliar movf LIG_DES,W ;carrega variável em W movwf LD_MT_AUX ;salva variável clrf LIG_DES ;limpa variável movf VAR1,W ;carrega W com variável 1 iorwf LIG_DES,F ;OR entre W e LIG_DES movf VAR2,W ;carrega W com variável 1 iorwf LIG_DES,F ;OR entre W e LIG_DES movf VAR3,W ;carrega W com variável 1 iorwf LIG_DES,F ;OR entre W e LIG_DES movf VAR4,W ;carrega W com variável 1 iorwf LIG_DES,F ;OR entre W e LIG_DES ;movf LIG_DES,W ;carrega variável em W ;andlw 0x0F ;limpa bits MSB ;movwf LIG_DES ;salva movf LIG_DES,W ;carrega W com variável dos motores xorlw b'00001001' ;testa com variável permitida - sentido 1 btfss STATUS,Z ;variável valida? goto next_m1 ;não, testa outra goto fajt_motor ;sim next_m1: movf LIG_DES,W ;não. Continua teste xorlw b'00000110' ;testa com variável permitida - sentido 2 btfss STATUS,Z ;variável valida? goto next_m2 ;não, testa outra goto fajt_motor ;sim next_m2: movf LIG_DES,W ;não. Continua teste xorlw b'00000000' ;testa com variável permitida - motor parado btfss STATUS,Z ;variável valida? goto next_m3 ;não, então usa valor anterior goto fajt_motor ;sim next_m3: movf LD_MT_AUX,W ;não. Pega valor anterior movwf LIG_DES ;e mantem ponte como estava fajt_motor: movf LIG_DES,W ;prepara para salvar movwf LD_MT_AUX ;salva call acerta_mtr ;acerta posição da ponte goto fim_ajustes ;finaliza ajustes limpando variáveis ;*************************************************************** ; trata variáveis recebidas para ligar/desligar saída extra ajt_rele: movlw 0x30 ;carrega W com 30 hexa subwf VAR4,F ;subtrai para acertar de ASCII->valor btfss VAR4,0 ;testa para saber se liga relé goto desl_rele ;não. bsf ACES2,RELE ;sim, liga rele goto fajtbeep ;vai para fim desl_rele: bcf ACES2,RELE ;desliga rele fajtrele: goto fim_ajustes ;finaliza ajustes limpando variáveis ;*************************************************************** ; trata variáveis recebidas para ligar/desligar beep ajt_beep: movlw 0x30 ;carrega W com 30 hexa subwf VAR4,F ;subtrai para acertar de ASCII->valor btfss VAR4,0 ;testa para saber se liga beep goto desl_beep ;não. bsf ACESS,BEEP ;sim, liga beep goto fajtbeep ;vai para fim desl_beep: bcf ACESS,BEEP ;desliga beep fajtbeep: goto fim_ajustes ;finaliza ajustes limpando variáveis ;*************************************************************** ; trata variáveis recebidas para enviar status ajt_status: call testa_bprs ;testa estado dos bumpers call tx_bumper ;envia dados (estado dos bumpers) goto fim_ajustes ;finaliza ajustes limpando variáveis ;*************************************************************** ; trata variáveis recebidas para ligar/desligar lâmpada ajt_lp: movlw 0x30 ;carrega W com 30 hexa subwf VAR4,F ;subtrai para acertar de ASCII->valor btfss VAR4,0 ;testa para saber se liga lâmpada goto desl_lp ;não. bsf ACESS,LP ;sim, liga lâmpada goto fajtlp ;vai para fim desl_lp: bcf ACESS,LP ;desliga beep fajtlp: nop ;não faz nada, o final está abaixo! ;*************************************************************** ; fim de todos os ajustes. Limpa flags de recepção! fim_ajustes: clrf FLG_RX ;limpa flags de recepção return ; ;*************************************************************** ; subrotina de interrupçoes ; salve o contexto geral se necessario - registros W, STATUS, etc ; trata apenas a int da USART ;*************************************************************** IntVector: ;prepara para salvar contexto movwf W2 ;salva W movf STATUS,W ;carrega W com registro de Status movwf STATUS2 ;salva STATUS movf PCLATH,W ;carrega W com PCLATH movwf PCLATH2 ;salva PCLATH btfss PIR1,RCIF ;USART gerou int? goto OutraInt ;nao, entao verifique outra int movlw 0x06 ;mascara para bits andwf RCSTA,W ;checa erros btfss STATUS,Z ;encontrado erro??? goto RcvError ;sim, trata movf RCREG,W ;Sem erros. Pega dado recebido movwf AUX ;guarda caracter recebido ;call enviaeco ;e envia mensagem e caracter de eco - comentar após final dos testes call trata ;trata dado recebido, de acordo com protocolo goto IntEnd ;fim da int. Restaure o contexto se necessario RcvError: bcf RCSTA,CREN ;limpa status de recebimento bsf RCSTA,CREN goto IntEnd ;fim da int. Restaure o contexto se necessario OutraInt: goto $ ;não existe outra int. Apenas retorna IntEnd: movf PCLATH2,W ;lê PCLATH2 movwf PCLATH ;restaura PCLATH com PCLATH2 movf STATUS2,W ;lê STATUS2 movwf STATUS ;restaura STATUS com STATUS2 movf W2,W ;lê W2 e restaura W com W2 retfie ;retorna da INT ;prepara para restaurar contexto anterior ; ;********************************************************* ; rotina para testar caracter enviado ;********************************************************* TestTx: bank1 Tst: btfss TXSTA,TRMT ;testa se buffer vazio goto Tst ;não, aguarda bank0 return ;buffer vazio, pronto para próximo TX ; ;*************************************************************** ; subrotina para enviar eco via RS232 enviaeco: movf AUX,W ;envia caracter recebido (eco) movwf TXREG ;envia caracter call TestTx return ; ;********************************************************* ; rotinas de temporização - espera ocupada ; rotinas desenvolvidas para uso com cristal de 4MHz ; ou oscilador RC interno a 4MHz ;********************************************************* ;********************************************************* ; delay de W x total de ciclos da subrotina micro segundos ; espera ocupada subrotina para uso com servos ; ; somatória dos ciclos de entrada = ; 2 chamada call ; 11 ciclos até 1 decremento com desvio goto ; 10 cilos x (W-1) ; 2 ciclos quando W = 0 ; 2 ciclos de retorno ; ; Exemplo com valor desejado de 2,5 ms para servo ; valor em W = 250 - somatória dos ciclos de entrada = ; 2 chamada call ; 11 ciclos até 1 decremento com desvio goto ; 10 cilos x 249 ; 2 ciclos quando W = 0 ; 2 ciclos de retorno ; total = 2 + 11 + 2490 + 2 + 2 = 2507 x 1us = 2,5ms _tsrv: movwf T1 ;1 ciclo _tsrv1 nop ;1 ciclo nop ;1 ciclo nop ;1 ciclo nop ;1 ciclo nop ;1 ciclo nop ;1 ciclo nop ;1 ciclo decfsz T1,F ;1 ciclo se T2>0 e 2 ciclos se T2=0 goto _tsrv1 ;2 ciclos return ;2 ciclos ;********************************************************* ; delay_srv - delay de 10 mili segundos (0.01 segundos) ; atraso aproximado delay_srv: movlw 0x18 ;carrega W com 24 movwf T1 ;carrega T1 com W movlw 0x00 ;carrega T4 com 0 movwf T4 goto car_1 ;********************************************************* ; delay de aproximadamente 1 segundo delay: movlw 0x08 ;carrega W com 6 movwf T3 ;carrega T3 com 6 movlw 0x01 ;carrega T4 com 1 movwf T4 car: movlw 0xff ;carrega W com 255 movwf T1 ;carrega T1 com W btfsc T4,0 ;testa bit 0 de T4 decfsz T3,F ;decrementa T3 goto car_1 return car_1: movlw 0xAA ;carrega W com 170 movwf T2 ;carrega T2 com 170 dec_1: decfsz T2,1 ;decrementa T2 goto dec_1 ;255 x T1 vezes decfsz T1,1 ;decrementa T1 goto car_1 ;volta a carregar T2 btfsc T4,0 ;testa bit 0 de T4 goto car ;retorna 0 em W return ;**************************************************************** ; fim do programa ;**************************************************************** end