LED RGB com PWM no PIC - Parte 2

Destinado á  discussões de temas livres etc...
Você precisa estar Logado para acessar os demais Fóruns, SEJA BEM VINDO - ao mundo da Tecnologia.
Responder
Avatar do usuário
Marcio_Ortolan
Comunidade Técnica VIP
Comunidade Técnica VIP
Mensagens: 102
Registrado em: Qua Out 29, 2008 9:23 am
Localização: Arujá - SP
Contato:

LED RGB com PWM no PIC - Parte 2

Mensagem por Marcio_Ortolan » Qui Out 08, 2009 11:25 am

Em seguida, temos as definições de constantes, variáveis locais, flags de software, entradas e saídas, assim como a definição e configuração dos PORTs de I/O.

Nos próximos blocos entramos na rotina principal do programa. Nela, configuraremos as funções dos periféricos do PIC16F628A. Vale salientar que os pontos principais sao as configurações dos timers 1 e 2, assim como a configuração das interrupções. Estas configurações serao abordadas mais adiante.

Repare que a execução das configurações iniciais e dos periféricos só é executada uma aºnica vez, durante a inicialização do PIC. Após a limpeza dos PORTs, entramos em um loop infinito, onde o microcontrolador executará as funções principais de nosso programa.

Neste loop infinito (iniciado na instrução while(true), as funções executadas envolvem:

• Limpar o contador do Watch Dog Timer
• Testar o contador de período para o LED vermelho e compará-lo ao valor especificado para o Duty Cicle do mesmo. Se este valor for igual ou maior ao especificado, entao o pino que controla este LED recebe o valor lógico “0”, ou seja apaga o LED (atingiu o ponto B na figura 5).
• Testar, analogamente ao executado para o LED vermelho, os LEDs verde e azul (seguindo esta ordem).
• Testar se alguma das seis chaves está pressionada. O fluxo de teste destas chaves pode ser visto na figura 7, que será detalhado mais a  frente.

Após estes passos, o programa retorna para o passo 1 acima descrito, reiniciando o ciclo.

O próximo fluxo que iremos analisar é o fluxo dos botaµes, que pode ser visualizado na figura 7.

Imagem

Este fluxo pode parecer complicado a  primeira vista, mas a sua implementação é muito simples. Basicamente as suas funções sao:

• Verificar se o botao está pressionado;
• Verificar se o botao já estava pressionado no ciclo anterior;
• Se o botao já estava pressionado, decrementar o contador para o filtro de debouncing;
• Se o contador do filtro estiver zerado, marcará um flag indicando que o botao já estava pressionado;
• No caso de ser um botao de incremento do Duty Cicle de um LED específico, a variável responsável (pwm_red, pwm_green ou pwm_blue) será incrementada em uma unidade, respeitando-se o valor máximo definido pela constante MAX. No nosso caso, esta constante foi definida com o valor “10” (LED com intensidade de carga máxima – Duty Cicle de 100%);
• Caso seja um botao de decremento do Duty Cicle, as variáveis pwm_red, pwm_green ou pwm_blue serao decrementadas em uma unidade, respeitando-se o valor mínimo definido pela constante MIN. No nosso exemplo, esta constante foi definida com o valor “0” (LED apagado – Duty Cicle de 0%);
• Após este passo, o programa segue seu fluxo normal.

Na definição do programa, temos também que definir as ações que as interrupções para o TIMER1 e para o TIMER2 irao executar. O fluxo de execução do TIMER1 pode ser visto na figura 8. Esta interrupção é bem simples. Aliás fica aqui uma “dica”: Os códigos para as interrupções devem ser bem enxutos para evitar que uma interrupção ocorra enquanto estivermos dentro de outra interrupção. Se isto não for bem controlado, o seu programa poderá apresentar resultados imprevisíveis.

Imagem

Basicamente, como podemos ver na figura 8, esta interrupção apenas incrementa uma unidade no contador do período de cada Duty Cicle. Estas variáveis foram definidas como contador_red, contador_green e contador_blue. Após este incremento, ele carrega o TIMER1 com o valor de 63535. Com isto, o TIMER1 irá “estourar” a cada exato 1 ms.

Mais adiante estudaremos mais sobre o TIMER1.

O aºltimo fluxo que analisaremos é o da interrupção do TIMER2, ilustrado na figura 9. Este é um pouco mais complexo que o da interrupção do TIMER1, mas também é muito simples de ser implementado.

Imagem

Esta interrupção é responsável por gerar a frequaªncia do PWM para os LEDs, e as funções que esta executa nada mais é que verificar se o PWM ajustado para a cada LED é diferente de zero. Se esta condição for verdadeira, ele irá colocar a saída em nível lógico “1”, e representa o ponto A que vimos na figura 5.

É igualmente importante que esta interrupção zere os contadores de todos os períodos para os LEDs, para garantir que as características do ciclo que estiver sendo executado sao as mesmas do mesmo do ciclo anterior.

Esta interrupção inclusive carrega o TIMER1 com o valor 63535 para que o TIMER1 também comece a marcar o período de 1 ms necessário para incrementar os contadores dos LEDs.

Feito isso, verificamos que com, estas configurações de TIMER1 e TIMER2 podemos ter os valores 0 ms, 1 ms, 2 ms, 3 ms, 4 ms, 5 ms, 6 ms, 7 ms, 8 ms, 9 ms e 10 ms para o PWM, representando Duty Cicles de 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% e 100%, respectivamente.

O TIMER1

O TIMER1 é um módulo de 16 bits, composto por dois registradores de 8 bits cada (TMR1H e TMR1L). Além da função de leitura destes registradores, até podemos alterar os seus valores (possuem função de escrita). Isto será muito aºtil quando quisermos iniciar este timer com um valor pré-definido e nos permitirá configurar o timer para que a interrupção ocorra em intervalos pré-determinados por nós.

Ele é utilizado como base para o módulo “Capture e Compare” e pode operar em traªs modos distintos.

O primeiro modo é o de Temporizador Síncrono (Synchronous Timer). Neste modo, o TIMER1 é incrementado em cada ciclo de instrução (ciclo de máquina) que é dado pela fórmula fosc / 4, onde fosc é a frequaªncia do oscilador (interno ou externo) do PIC16F628A.

O segundo modo de operação deste Timer é o de Contador Síncrono (Synchronous Counter). Neste modo, o TIMER1 será incrementado a cada borda de subida do sinal aplicado ao pino T1CKI. Com esta configuração, durante o modo SLEEP, este Timer não será incrementado, mesmo se o sinal externo estiver presente.

O terceiro modo é o Contador Assíncrono (Asynchronous Counter). Neste modo, semelhante ao que acontece no contador Síncrono, o TIMER1 será incrementado a cada borda de subida do sinal aplicado ao pino T1CKI. A diferença entre os dois contadores está no fato de que, neste modo, o TIMER1 continua a ser incrementado independentemente do clock interno do PIC ou se ele estiver durante uma operação de SLEEP. Devido a estas características, durante o SLEEP, uma interrupção pode ser gerada “acordando” o microcontrolador para reiniciar as suas funções. Outra característica deste modo, é que, uma vez que ele não está sincronizado com o clock interno do PIC, ele pode ser usado como base para implementar um Real Time Clock (RTC). Operando como Contador Assíncrono, o TIMER1 não pode ser usado como base de tempo para as operações de Capture e Compare.

Para configurarmos o TIMER1, utilizando o compilador da CCS, precisamos declarar a função setup_timer_1(modo), onde modo pode ser:

• T1_DISABLED – Desabilita o TIMER1;
• T1_INTERNAL – Modo Temporizador Síncrono;
• TI_EXTERNAL – Modo Contador Assíncrono;
• T1_EXTERNAL_SYNC – Modo Contador Síncrono.

O modo que iremos utilizar em nosso projeto é o Temporizador Síncrono. Portanto, a sintaxe para configurar o TIMER1 é setup_timer_1(T1_INTERNAL).

Outra característica do TIMER1 é o prescale, que nada mais é que um divisor de frequaªncia para o timer. Podemos aplicar um prescale no TIMER1 de valor 1, 2, 4 ou 8. Isso significa que podemos dividir o tempo de incremento do TIMER1 por 1, 2, 4 ou 8. Para configurar o prescale do TIMER1, também utilizaremos a sintaxe é setup_timer_1(modo). Neste caso, modo pode ser:

• T1_DIV_BY_1 – Prescale de 1 (sem prescale);
• T1_DIV_BY_2 – Prescale de 2 (divide a frequaªncia do TIMER1 por 2);
• T1_DIV_BY_4 – Prescale de 4 (divide a frequaªncia do TIMER1 por 4);
• T1_DIV_BY_8 – Prescale de 8 (divide a frequaªncia do TIMER1 por 8).

Em nosso código, não utilizaremos o prescale, ou seja, o modo será T1_DIV_BY_1.

Entao, o código para as configurações do TIMER1, em nosso código, deverá ser:

• setup_timer_1(T1_INTERNAL);
• setup_timer_1(T1_DIV_BY_1);
• Podemos ainda definir de outra forma, um pouco mais resumida, utilizando o caractere “|” (conhecido como “pipe”) para separar os argumentos. O nosso código ficará entao da seguinte forma:
• setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
• Com esta configuração, e utilizando um oscilador de 8 MHz, o TIMER1 será incrementado a cada 0,5 μs e gerará uma interrupção a cada 32.767,5 μs, ou seja, teremos cerca de 32,77 ms entre duas interrupções do TIMER1.
• Se atribuirmos o valor inicial para o TIMER1 de 63535, a interrupção acontecerá exatamente em 1 ms.


O TIMER2

O TIMER2 é um timer de 8 bits que conta com um prescaler, um postscaler e um registrador de período (conhecido como PR2).

O prescaler é um divisor de frequaªncia que vai dividir a frequaªncia do clock interno (fosc / 4) por 1, 4 ou 16.

O postscaler é um contador para as interrupções. Ele conta quanto ciclos completos (de 0 a 255) precisam ser realizados para que uma interrupção seja gerada. Ele pode assumir os valores de 1 a 16.

O registrador de período PR2 é utilizado para iniciar um valor pré determinado para o TIMER2, permitindo uma maior flexibilidade e controle do tempo em que a interrupção deve acontecer.

A fonte de clock para este timer é o clock do microcontrolador, ou seja, é fosc / 4. Devido a isto, o TIMER2 é suspenso durante uma operação de SLEEP, voltando a operar assim que o controlador “acorda”.

É o TIMER2 que é utilizado como base para a frequaªncia do PWM para os microcontroladores que possuem esta função diretamente no hardware.

O PIC16F628A já possui um pino específico para o PWM (por hardware), mas como precisamos controlar traªs pinos, e a idéia de nosso projeto é fazer o PWM por software, não vamos utilizar o hardware interno do PIC16F628A.

Apenas para fins didáticos, vamos utilizar o TIMER2 também como base da frequaªncia de nosso PWM.

Para configurarmos o TIMER2 usando o compilador C da CCS, precisamos empregar o seguinte comando setup_timer_2(modo, período, postscale).

Para o comando acima, o parâmetro modo: pode ser:

• T2 _DISABLED – Desabilita o TIMER2;
• T2_DIV_BY_1 – TIMER2 ativado, com prescale de 1;
• T2_DIV_BY_4 – TIMER2 ativado, com prescale de 4;
• T2_DIV_BY_16 – TIMER2 ativado, com prescale de 16.

Podemos utilizar para o parâmetro período qualquer valor inteiro entre 0 e 255, o que vai determinar quando que o valor do clock será resetado (reinicializado).

Para o parâmetro postscale, podemos utilizar um naºmero, também inteiro, entre 1 e 16 que irá determinar quantos resets serao necessários para gerar uma interrupção

Como a nossa idéia é gerar uma interrupção a cada 10 ms para gerar uma frequaªncia de PWM de 100 Hz, vamos configurar o TIMER2 de acordo com a função abaixo:

setup_timer_2(T2_DIV_BY_16,78,16);

Seguindo estas configurações (prescale de 16, PR2 de 78 e postscale de 16) e utilizando o ressonador de 8 MHz, teremos que o ciclo de máquina (fosc/4) será de 0,5 μs, o TIMER2 será atualizado (incrementado) a cada 8 μs, o overflow ocorrerá a cada 632 μs e a interrupção acontecerá a cada 10 ms (aproximadamente).


Compilando o programa

Para compilar o programa, podemos utilizar o compilador CCS diretamente através da interface IDE, ou pelo próprio MPLAB (se possuir o plug-in de conexao, disponível no site da CCS). Veja mais informações no site da própria CCS, no link: http://www.ccsinfo.com , seção de Support/Downloads.

Após a compilação, basta gravar o arquivo HEX gerado no PIC16F628A, utilizando um bom programador para este microcontrolador.

Este é um programa muito leve, que ocupa apenas 15% do microcontrolador.

Teste e uso

O teste para este circuito é muito simples. Em primeiro lugar, verifique se todos os componentes, principalmente aqueles que possuem polaridade, estao soldados corretamente.

Observe também se o microcontrolador está inserido no soquete corretamente, pois a inversao dele pode provocar a sua queima, inutilizando-o permanentemente.

Outro ponto importante é verificar se não há curto-circuito entre as soldas ou mesmo se há alguma solda “fria” que pode provocar o mau funcionamento do circuito.

Feito isso, é só plugar uma fonte de alimentação, com tensao entre 7 V e 15 V, prestando atenção que o polo positivo é o pino central, pois se o circuito for ligado a uma fonte com os terminais invertidos, o regulador de tensao irá se queimar.

Basta agora pressionar os botaµes para aumentar ou diminuir a intensidade do vermelho, verde e/ou azul do LED, verificando a cor resultante.
Conclusao

Este circuito é muito simples, mas é muito interessante, pois a partir dele o leitor poderá realizar outros testes, como as alterações na frequaªncia do PWM, no passo para o Duty Cicle, no ressonador utilizado para permitir alterações no código (lembrando que o PIC16F628A suporta osciladores de até 20 MHz), criação de uma rotina automática para alternação das cores etc.

Ele pode ser utilizado como base para iluminação indireta em ambientes, “tuning” em carros e motos, “case mod” para o seu computador, alimentação de motores DC, base de estudo para o PWM, alimentação de circuitos “Peltier” entre diversas outras. Enfim, saiba que a sua mente e criatividade sao os limites!

Boa montagem e boa diversao!

Imagem

*Originalmente publicado na revista Saber Eletra´nica Nº440

Se leu e não entedeu nada, explico que o autor tentou explicar como montar o programa para que seja feito a combinação entre as cores do leds, mas se preoculpou tanto em explicar os detalhes das interrupções que ficou meio confuso.

E no fim muitos iram procurar pelo exemplo para tentar entender e se encontrar no que foi dito, mas não encontrara mastigadinho com em outros projetos, assim se seu curso de microcontrolador, foi bem palestrado, saberá como escrever as funções e insterrupções que direcionam o PWM para as I/Os comuns, senão vai ficar um pouco por fora e não vai conseguir fazer o proposto.

Abraço.

Avatar do usuário
Marcio_Ortolan
Comunidade Técnica VIP
Comunidade Técnica VIP
Mensagens: 102
Registrado em: Qua Out 29, 2008 9:23 am
Localização: Arujá - SP
Contato:

Re: LED RGB com PWM no PIC - Parte 2

Mensagem por Marcio_Ortolan » Qui Out 08, 2009 2:01 pm

Simples chaveamento de I/Os em loop.

http://www.4shared.com/file/138531445/c ... clip0.html

Imagem

Código em ASM do vídeo.

; ADDRESS OPCODE ASM
; ----------------------------------------------
$0000 $2804 GOTO _main
$0004 $ _main:
;RGB_led.c,1 :: void main(){
;RGB_led.c,3 :: trisb.f0 = 0; // rb0 como saida
$0004 $1303 BCF STATUS, RP1
$0005 $1683 BSF STATUS, RP0
$0006 $1006 BCF TRISB, 0
;RGB_led.c,4 :: trisb.f1 = 0; // rb1 como saida
$0007 $1086 BCF TRISB, 1
;RGB_led.c,5 :: trisb.f2 = 0; // rb2 como saida
$0008 $1106 BCF TRISB, 2
;RGB_led.c,7 :: portb.f0 = 0; // todas as saidas iniciam desligadas
$0009 $1283 BCF STATUS, RP0
$000A $1006 BCF PORTB, 0
;RGB_led.c,8 :: portb.f1 = 0; // todas as saidas iniciam desligadas
$000B $1086 BCF PORTB, 1
;RGB_led.c,9 :: portb.f2 = 0; // todas as saidas iniciam desligadas
$000C $1106 BCF PORTB, 2
;RGB_led.c,11 :: while(1){
$000D $ L_main_0:
;RGB_led.c,13 :: portb = 0b00000100; // led vermelho ligado
$000D $3004 MOVLW 4
$000E $0086 MOVWF PORTB
;RGB_led.c,14 :: delay_ms(300);// aguarda 200 milisegundos
$000F $3002 MOVLW 2
$0010 $00FC MOVWF STACK_12
$0011 $30FF MOVLW 255
$0012 $00FB MOVWF STACK_11
$0013 $30FF MOVLW 255
$0014 $00FA MOVWF STACK_10
$0015 $0BFC DECFSZ STACK_12, F
$0016 $2818 GOTO $+2
$0017 $281F GOTO $+8
$0018 $0BFB DECFSZ STACK_11, F
$0019 $281B GOTO $+2
$001A $281E GOTO $+4
$001B $0BFA DECFSZ STACK_10, F
$001C $281B GOTO $-1
$001D $2818 GOTO $-5
$001E $2815 GOTO $-9
$001F $3087 MOVLW 135
$0020 $00FB MOVWF STACK_11
$0021 $30FF MOVLW 255
$0022 $00FA MOVWF STACK_10
$0023 $0BFB DECFSZ STACK_11, F
$0024 $2826 GOTO $+2
$0025 $2829 GOTO $+4
$0026 $0BFA DECFSZ STACK_10, F
$0027 $2826 GOTO $-1
$0028 $2823 GOTO $-5
$0029 $3093 MOVLW 147
$002A $00FA MOVWF STACK_10
$002B $0BFA DECFSZ STACK_10, F
$002C $282B GOTO $-1
$002D $0000 NOP
;RGB_led.c,15 :: portb = 0b00000000; // led vermelho desligado
$002E $0186 CLRF PORTB, 1
;RGB_led.c,16 :: delay_ms(300);// aguarda 100 milisegundos
$002F $3002 MOVLW 2
$0030 $00FC MOVWF STACK_12
$0031 $30FF MOVLW 255
$0032 $00FB MOVWF STACK_11
$0033 $30FF MOVLW 255
$0034 $00FA MOVWF STACK_10
$0035 $0BFC DECFSZ STACK_12, F
$0036 $2838 GOTO $+2
$0037 $283F GOTO $+8
$0038 $0BFB DECFSZ STACK_11, F
$0039 $283B GOTO $+2
$003A $283E GOTO $+4
$003B $0BFA DECFSZ STACK_10, F
$003C $283B GOTO $-1
$003D $2838 GOTO $-5
$003E $2835 GOTO $-9
$003F $3087 MOVLW 135
$0040 $00FB MOVWF STACK_11
$0041 $30FF MOVLW 255
$0042 $00FA MOVWF STACK_10
$0043 $0BFB DECFSZ STACK_11, F
$0044 $2846 GOTO $+2
$0045 $2849 GOTO $+4
$0046 $0BFA DECFSZ STACK_10, F
$0047 $2846 GOTO $-1
$0048 $2843 GOTO $-5
$0049 $3093 MOVLW 147
$004A $00FA MOVWF STACK_10
$004B $0BFA DECFSZ STACK_10, F
$004C $284B GOTO $-1
$004D $0000 NOP
;RGB_led.c,17 :: portb = 0b00000010; // led verde ligado
$004E $3002 MOVLW 2
$004F $0086 MOVWF PORTB
;RGB_led.c,18 :: delay_ms(300);// aguarda 100 milisegundos
$0050 $3002 MOVLW 2
$0051 $00FC MOVWF STACK_12
$0052 $30FF MOVLW 255
$0053 $00FB MOVWF STACK_11
$0054 $30FF MOVLW 255
$0055 $00FA MOVWF STACK_10
$0056 $0BFC DECFSZ STACK_12, F
$0057 $2859 GOTO $+2
$0058 $2860 GOTO $+8
$0059 $0BFB DECFSZ STACK_11, F
$005A $285C GOTO $+2
$005B $285F GOTO $+4
$005C $0BFA DECFSZ STACK_10, F
$005D $285C GOTO $-1
$005E $2859 GOTO $-5
$005F $2856 GOTO $-9
$0060 $3087 MOVLW 135
$0061 $00FB MOVWF STACK_11
$0062 $30FF MOVLW 255
$0063 $00FA MOVWF STACK_10
$0064 $0BFB DECFSZ STACK_11, F
$0065 $2867 GOTO $+2
$0066 $286A GOTO $+4
$0067 $0BFA DECFSZ STACK_10, F
$0068 $2867 GOTO $-1
$0069 $2864 GOTO $-5
$006A $3093 MOVLW 147
$006B $00FA MOVWF STACK_10
$006C $0BFA DECFSZ STACK_10, F
$006D $286C GOTO $-1
$006E $0000 NOP
;RGB_led.c,19 :: portb = 0b00000000; // led verde desligado
$006F $0186 CLRF PORTB, 1
;RGB_led.c,20 :: delay_ms(300);// aguarda 100 milisegundos
$0070 $3002 MOVLW 2
$0071 $00FC MOVWF STACK_12
$0072 $30FF MOVLW 255
$0073 $00FB MOVWF STACK_11
$0074 $30FF MOVLW 255
$0075 $00FA MOVWF STACK_10
$0076 $0BFC DECFSZ STACK_12, F
$0077 $2879 GOTO $+2
$0078 $2880 GOTO $+8
$0079 $0BFB DECFSZ STACK_11, F
$007A $287C GOTO $+2
$007B $287F GOTO $+4
$007C $0BFA DECFSZ STACK_10, F
$007D $287C GOTO $-1
$007E $2879 GOTO $-5
$007F $2876 GOTO $-9
$0080 $3087 MOVLW 135
$0081 $00FB MOVWF STACK_11
$0082 $30FF MOVLW 255
$0083 $00FA MOVWF STACK_10
$0084 $0BFB DECFSZ STACK_11, F
$0085 $2887 GOTO $+2
$0086 $288A GOTO $+4
$0087 $0BFA DECFSZ STACK_10, F
$0088 $2887 GOTO $-1
$0089 $2884 GOTO $-5
$008A $3093 MOVLW 147
$008B $00FA MOVWF STACK_10
$008C $0BFA DECFSZ STACK_10, F
$008D $288C GOTO $-1
$008E $0000 NOP
;RGB_led.c,21 :: portb = 0b00000001; // led azul ligado
$008F $3001 MOVLW 1
$0090 $0086 MOVWF PORTB
;RGB_led.c,22 :: delay_ms(300);// aguarda 500 milisegundos
$0091 $3002 MOVLW 2
$0092 $00FC MOVWF STACK_12
$0093 $30FF MOVLW 255
$0094 $00FB MOVWF STACK_11
$0095 $30FF MOVLW 255
$0096 $00FA MOVWF STACK_10
$0097 $0BFC DECFSZ STACK_12, F
$0098 $289A GOTO $+2
$0099 $28A1 GOTO $+8
$009A $0BFB DECFSZ STACK_11, F
$009B $289D GOTO $+2
$009C $28A0 GOTO $+4
$009D $0BFA DECFSZ STACK_10, F
$009E $289D GOTO $-1
$009F $289A GOTO $-5
$00A0 $2897 GOTO $-9
$00A1 $3087 MOVLW 135
$00A2 $00FB MOVWF STACK_11
$00A3 $30FF MOVLW 255
$00A4 $00FA MOVWF STACK_10
$00A5 $0BFB DECFSZ STACK_11, F
$00A6 $28A8 GOTO $+2
$00A7 $28AB GOTO $+4
$00A8 $0BFA DECFSZ STACK_10, F
$00A9 $28A8 GOTO $-1
$00AA $28A5 GOTO $-5
$00AB $3093 MOVLW 147
$00AC $00FA MOVWF STACK_10
$00AD $0BFA DECFSZ STACK_10, F
$00AE $28AD GOTO $-1
$00AF $0000 NOP
;RGB_led.c,23 :: portb = 0b00000000; // led azul desligado
$00B0 $0186 CLRF PORTB, 1
;RGB_led.c,24 :: delay_ms(300);// aguarda 500 milisegundos
$00B1 $3002 MOVLW 2
$00B2 $00FC MOVWF STACK_12
$00B3 $30FF MOVLW 255
$00B4 $00FB MOVWF STACK_11
$00B5 $30FF MOVLW 255
$00B6 $00FA MOVWF STACK_10
$00B7 $0BFC DECFSZ STACK_12, F
$00B8 $28BA GOTO $+2
$00B9 $28C1 GOTO $+8
$00BA $0BFB DECFSZ STACK_11, F
$00BB $28BD GOTO $+2
$00BC $28C0 GOTO $+4
$00BD $0BFA DECFSZ STACK_10, F
$00BE $28BD GOTO $-1
$00BF $28BA GOTO $-5
$00C0 $28B7 GOTO $-9
$00C1 $3087 MOVLW 135
$00C2 $00FB MOVWF STACK_11
$00C3 $30FF MOVLW 255
$00C4 $00FA MOVWF STACK_10
$00C5 $0BFB DECFSZ STACK_11, F
$00C6 $28C8 GOTO $+2
$00C7 $28CB GOTO $+4
$00C8 $0BFA DECFSZ STACK_10, F
$00C9 $28C8 GOTO $-1
$00CA $28C5 GOTO $-5
$00CB $3093 MOVLW 147
$00CC $00FA MOVWF STACK_10
$00CD $0BFA DECFSZ STACK_10, F
$00CE $28CD GOTO $-1
$00CF $0000 NOP
;RGB_led.c,26 :: portb = 0b00000101; // vermelho e azul
$00D0 $3005 MOVLW 5
$00D1 $0086 MOVWF PORTB
;RGB_led.c,27 :: delay_ms(500);
$00D2 $3003 MOVLW 3
$00D3 $00FC MOVWF STACK_12
$00D4 $30FF MOVLW 255
$00D5 $00FB MOVWF STACK_11
$00D6 $30FF MOVLW 255
$00D7 $00FA MOVWF STACK_10
$00D8 $0BFC DECFSZ STACK_12, F
$00D9 $28DB GOTO $+2
$00DA $28E2 GOTO $+8
$00DB $0BFB DECFSZ STACK_11, F
$00DC $28DE GOTO $+2
$00DD $28E1 GOTO $+4
$00DE $0BFA DECFSZ STACK_10, F
$00DF $28DE GOTO $-1
$00E0 $28DB GOTO $-5
$00E1 $28D8 GOTO $-9
$00E2 $308C MOVLW 140
$00E3 $00FB MOVWF STACK_11
$00E4 $30FF MOVLW 255
$00E5 $00FA MOVWF STACK_10
$00E6 $0BFB DECFSZ STACK_11, F
$00E7 $28E9 GOTO $+2
$00E8 $28EC GOTO $+4
$00E9 $0BFA DECFSZ STACK_10, F
$00EA $28E9 GOTO $-1
$00EB $28E6 GOTO $-5
$00EC $30A1 MOVLW 161
$00ED $00FA MOVWF STACK_10
$00EE $0BFA DECFSZ STACK_10, F
$00EF $28EE GOTO $-1
$00F0 $0000 NOP
;RGB_led.c,28 :: portb = 0b00000000; // led azul desligado
$00F1 $0186 CLRF PORTB, 1
;RGB_led.c,29 :: delay_ms(100);// aguarda 500 milisegundos
$00F2 $3082 MOVLW 130
$00F3 $00FB MOVWF STACK_11
$00F4 $30FF MOVLW 255
$00F5 $00FA MOVWF STACK_10
$00F6 $0BFB DECFSZ STACK_11, F
$00F7 $28F9 GOTO $+2
$00F8 $28FC GOTO $+4
$00F9 $0BFA DECFSZ STACK_10, F
$00FA $28F9 GOTO $-1
$00FB $28F6 GOTO $-5
$00FC $3087 MOVLW 135
$00FD $00FA MOVWF STACK_10
$00FE $0BFA DECFSZ STACK_10, F
$00FF $28FE GOTO $-1
$0100 $0000 NOP
;RGB_led.c,30 :: portb = 0b00000110; // vermelho e verde
$0101 $3006 MOVLW 6
$0102 $0086 MOVWF PORTB
;RGB_led.c,31 :: delay_ms(500);
$0103 $3003 MOVLW 3
$0104 $00FC MOVWF STACK_12
$0105 $30FF MOVLW 255
$0106 $00FB MOVWF STACK_11
$0107 $30FF MOVLW 255
$0108 $00FA MOVWF STACK_10
$0109 $0BFC DECFSZ STACK_12, F
$010A $290C GOTO $+2
$010B $2913 GOTO $+8
$010C $0BFB DECFSZ STACK_11, F
$010D $290F GOTO $+2
$010E $2912 GOTO $+4
$010F $0BFA DECFSZ STACK_10, F
$0110 $290F GOTO $-1
$0111 $290C GOTO $-5
$0112 $2909 GOTO $-9
$0113 $308C MOVLW 140
$0114 $00FB MOVWF STACK_11
$0115 $30FF MOVLW 255
$0116 $00FA MOVWF STACK_10
$0117 $0BFB DECFSZ STACK_11, F
$0118 $291A GOTO $+2
$0119 $291D GOTO $+4
$011A $0BFA DECFSZ STACK_10, F
$011B $291A GOTO $-1
$011C $2917 GOTO $-5
$011D $30A1 MOVLW 161
$011E $00FA MOVWF STACK_10
$011F $0BFA DECFSZ STACK_10, F
$0120 $291F GOTO $-1
$0121 $0000 NOP
;RGB_led.c,32 :: portb = 0b00000000; // led azul desligado
$0122 $0186 CLRF PORTB, 1
;RGB_led.c,33 :: delay_ms(100);// aguarda 500 milisegundos
$0123 $3082 MOVLW 130
$0124 $00FB MOVWF STACK_11
$0125 $30FF MOVLW 255
$0126 $00FA MOVWF STACK_10
$0127 $0BFB DECFSZ STACK_11, F
$0128 $292A GOTO $+2
$0129 $292D GOTO $+4
$012A $0BFA DECFSZ STACK_10, F
$012B $292A GOTO $-1
$012C $2927 GOTO $-5
$012D $3087 MOVLW 135
$012E $00FA MOVWF STACK_10
$012F $0BFA DECFSZ STACK_10, F
$0130 $292F GOTO $-1
$0131 $0000 NOP
;RGB_led.c,34 :: portb = 0b00000011; // azul e verde
$0132 $3003 MOVLW 3
$0133 $0086 MOVWF PORTB
;RGB_led.c,35 :: delay_ms(500);
$0134 $3003 MOVLW 3
$0135 $00FC MOVWF STACK_12
$0136 $30FF MOVLW 255
$0137 $00FB MOVWF STACK_11
$0138 $30FF MOVLW 255
$0139 $00FA MOVWF STACK_10
$013A $0BFC DECFSZ STACK_12, F
$013B $293D GOTO $+2
$013C $2944 GOTO $+8
$013D $0BFB DECFSZ STACK_11, F
$013E $2940 GOTO $+2
$013F $2943 GOTO $+4
$0140 $0BFA DECFSZ STACK_10, F
$0141 $2940 GOTO $-1
$0142 $293D GOTO $-5
$0143 $293A GOTO $-9
$0144 $308C MOVLW 140
$0145 $00FB MOVWF STACK_11
$0146 $30FF MOVLW 255
$0147 $00FA MOVWF STACK_10
$0148 $0BFB DECFSZ STACK_11, F
$0149 $294B GOTO $+2
$014A $294E GOTO $+4
$014B $0BFA DECFSZ STACK_10, F
$014C $294B GOTO $-1
$014D $2948 GOTO $-5
$014E $30A1 MOVLW 161
$014F $00FA MOVWF STACK_10
$0150 $0BFA DECFSZ STACK_10, F
$0151 $2950 GOTO $-1
$0152 $0000 NOP
;RGB_led.c,36 :: portb = 0b00000000; // led azul desligado
$0153 $0186 CLRF PORTB, 1
;RGB_led.c,37 :: delay_ms(100);// aguarda 500 milisegundos
$0154 $3082 MOVLW 130
$0155 $00FB MOVWF STACK_11
$0156 $30FF MOVLW 255
$0157 $00FA MOVWF STACK_10
$0158 $0BFB DECFSZ STACK_11, F
$0159 $295B GOTO $+2
$015A $295E GOTO $+4
$015B $0BFA DECFSZ STACK_10, F
$015C $295B GOTO $-1
$015D $2958 GOTO $-5
$015E $3087 MOVLW 135
$015F $00FA MOVWF STACK_10
$0160 $0BFA DECFSZ STACK_10, F
$0161 $2960 GOTO $-1
$0162 $0000 NOP
;RGB_led.c,38 :: portb = 0b00000111; // azul e verde
$0163 $3007 MOVLW 7
$0164 $0086 MOVWF PORTB
;RGB_led.c,39 :: delay_ms(500);
$0165 $3003 MOVLW 3
$0166 $00FC MOVWF STACK_12
$0167 $30FF MOVLW 255
$0168 $00FB MOVWF STACK_11
$0169 $30FF MOVLW 255
$016A $00FA MOVWF STACK_10
$016B $0BFC DECFSZ STACK_12, F
$016C $296E GOTO $+2
$016D $2975 GOTO $+8
$016E $0BFB DECFSZ STACK_11, F
$016F $2971 GOTO $+2
$0170 $2974 GOTO $+4
$0171 $0BFA DECFSZ STACK_10, F
$0172 $2971 GOTO $-1
$0173 $296E GOTO $-5
$0174 $296B GOTO $-9
$0175 $308C MOVLW 140
$0176 $00FB MOVWF STACK_11
$0177 $30FF MOVLW 255
$0178 $00FA MOVWF STACK_10
$0179 $0BFB DECFSZ STACK_11, F
$017A $297C GOTO $+2
$017B $297F GOTO $+4
$017C $0BFA DECFSZ STACK_10, F
$017D $297C GOTO $-1
$017E $2979 GOTO $-5
$017F $30A1 MOVLW 161
$0180 $00FA MOVWF STACK_10
$0181 $0BFA DECFSZ STACK_10, F
$0182 $2981 GOTO $-1
$0183 $0000 NOP
;RGB_led.c,40 :: portb = 0b00000000; // led azul desligado
$0184 $0186 CLRF PORTB, 1
;RGB_led.c,41 :: delay_ms(100);// aguarda 500 milisegundos
$0185 $3082 MOVLW 130
$0186 $00FB MOVWF STACK_11
$0187 $30FF MOVLW 255
$0188 $00FA MOVWF STACK_10
$0189 $0BFB DECFSZ STACK_11, F
$018A $298C GOTO $+2
$018B $298F GOTO $+4
$018C $0BFA DECFSZ STACK_10, F
$018D $298C GOTO $-1
$018E $2989 GOTO $-5
$018F $3087 MOVLW 135
$0190 $00FA MOVWF STACK_10
$0191 $0BFA DECFSZ STACK_10, F
$0192 $2991 GOTO $-1
$0193 $0000 NOP
;RGB_led.c,42 :: }
$0194 $280D GOTO L_main_0
;RGB_led.c,43 :: }
$0195 $2995 GOTO $

Responder