10.6.11

Micro tutorial - Programação em BASIC usando o MikroBasic

Olá a todos.
Vamos começar do começo. Estou fazendo um trabalho para o professor da disciplina "Microcontroladores" e o mesmo exige quer que o trabalho seja escrito nessa linguagem. Ok, eu já programo alguma coisa em C, e a lógica pra mim não é problema, apenas a sintaxe. Não vou mentir que não estou apanhando um pouco, pois é um tanto difícil entender como o BASIC consegue saber o que é o quê, sem ser case sensitive ou sem delimitar os finais das linhas. Vícios do C...
Estou criando esse mini tutorial sobre BASIC com o intuito de ajudar algumas pessoas do meu grupo, e também da minha sala, já que o professor não foi muito feliz em explicar a matéria para a turma.

Vamos lá.

Não vou começar explicando sobre a interface do MikroBasic e nem sobre como criar um projeto, já que existe bastante material na internet. Massssss esse material é, ao mesmo tempo, extenso e superficial. O que pretendo fazer é falar um pouquinho daquilo que eles não falam direito.

Criando o primeiro projeto.

Bom, após a criação do projeto em branco, que aqui chamei de "primeiro", vou criar um programa que irá acender, um a um, todos os leds ligados ao PORTD da minha placa de desenvolvimento.
Ao pressionar a tecla ligada ao Portb.0, ele irá percorrer os leds para a direita, e, ao pressionar a tecla no Portb.2 para a esquerda.

Vamos ao código:
Lembrando que tudo o que estiver após aspas simples ( ' ) na linha é um comentário.

Na primeira linha temos:
program primeiro
Estamos dizendo qual é o nome do programa que estamos criando.

Depois, temos a seção de declarações:

' Declarations section 
symbol Testabit_left = PORTB.2   'Cria um Symbol para o PORTB.0
symbol Testabit_right = PORTB.0  'Cria um Symbol para o PORTB.2
dim i as integer                 'variavel para a contagem


Aqui eu estou dizendo que Testabit_left e Testabit_right são símbolos ou alias para as portas 0 e 2 no PORTB e uma varíável numérica inteira chamada "i", que irei usar como auxiliar no meu contador

Vou criar, então a minha procedure para fazer o meu deslocamento de bits:

'****************************************************************
'Procedure para deslocar os bits do PORTD para a direita
'
Sub Procedure LACO_direita
    for i=1 to 8             'são 8 leds
        PORTD = PORTD >> 1   'Shift para a direita
        delay_ms(50)
    next i
    PORTD.0 = 1               'Como ele andou os bits e ficou zerado...
End Sub
'****************************************************************

Chamei minha procedure de LACO_direita, nesta subrotina, estou inicializando meu contador com 1 e dizendo para ele contar até 8 (mais 7 vezes) em um laço contado (for). Ao entrar no laço, irei deslocar o meu bit para a direita, usando o shift register, um operador que desloca os bits setados na variável, ou, nesse caso, no port, para a direita o número de vezes especificado, nesse caso, uma vez. note que, nessa operação, os bits que estiverem setados mais à direita serão perdidos e os bits à esquerda estarão com o valor 0, como se eu estivesse realmente deslocando-os ao longo do port.
Um intervalo de 50ms é chamado com o comando Delay_ms.
next i irá incementar a variável i em um e irá voltar ao início do laço.
Depois disso tem uma gambiarra, como, no deslocamento, eu zerei todos os bits, eu preciso resetar o primeiro. com isso, basta deixá-lo ligado.

A subrotina LACO_esquerda é exatamente igual, mas o operador usado é o << que executa um shift register para a esquerda.

Depois disso eu chamo a minha rotina main, a rotina principal e a primeira que será executada.


main:
'   Main program


    TRISD = 0 'Setando todo o portD como saída
    TRISB = 255 'Setando o portB como entrada
   
    PORTD = 000001 'Primeiro pino do Portd está setado com nível lógico 1
                '(Led aceso)


    Laco_principal:              'Laço Principal
      If Testabit_right = 0 then 'Se portb.2 pressionado, então...
         LACO_direita            'Chama laco direita
         delay_ms(100)           'Delay de 100ms
      end if                     'Fim se
     
      If Testabit_left = 0 then   'Se portb.0 pressionado, então...
         LACO_esquerda            'Chama laco esqueda
         delay_ms(100)            'Delay de 100ms
      end if                      'Fim se


    GOTO Laco_principal           'Volta ao laço principal (loop infinito)
   
end. 'Fim

Nas primeiras linhas eu tenho os comandos TRISD e TRISB. O comando TRIS é usado para configurar um port como entrada ou como saída. Quando eu seto, ou seja, atribuo 1, um pino de um port, eu estou dizendo que esse pino é uma entrada e quando eu atribuo 0 à ele, ele é será uma saída. Ou seja, 1=Input=Entrada e 0=Output=Saída.

Logo depois eu dou o comando PORTD = 000001, o comando PORTX é usado para atribuir um valor à um port específico do meu microcontrolador.
Perceba que o comando TRIS APENAS DETERMINA O COMPORTAMENTO DO PINO, enquanto o PORTX ATRIBUI ESTADOS AO PINO OU PINOS.
O comando "=" é usado para atribuição.
"%" significa que o valor que eu estou entrando é um valor binário. Então eu estou desligando dos bits 8 a 2 no meu PORTD e ligando apenas o primeiro pino. Note aqui que a leitura é feita do bit menos significativo para o mais significativo. Assim, apenas o primeiro led (ligado ao portd.0) ficará aceso.

Laco_principal: é um label, ou seja, um rótulo que eu uso quando quiser mandar o programa para aquela linha. No caso usando o comando GOTO.

"If Testabit_right = 0 then" Significa SE o terceiro pino do portb (portb.2) estiver com o valor 0, ou seja, com 0V, eu executarei o que estiver entre o IF e o END IF. 
Aqui vai um pormenor. Na minha placa (e em muitas aplicações) as teclas estão ligadas em pull-up, então, quando eu pressionar o botão, ele irá para 0V(nível lógico 0), senão estará com +Vcc (nível lógico 1).
No IF, o teste lógico será verdadeiro quando a tecla for pressionada.

Dentro do laço IF, existem dois comando, um é a chamada para a procedure criada lá em cima, e, logo após, um comando delay (já explicado, também).

Depois é realizado outro teste com o portb.0.

Após, eu tenho o coando GOTO Laco_principal, nessa linha ele salta de volta para a linha imediatamente após o label Laco_principal:. Está criado um loop infinito.

A ultima linha finaliza todo o programa em Basic, um end.
Vou deixar o código fonte copiável e colável lá embaixo...

É isso aí, até a próxima.


program primeiro


'=================================================================
' Descrição:
' Primeiro programa do mini tutorial sobre BASIC.
' Esse programa fará uma varredura nos leds ligados ao PORTD
' Quando se pressionar uma tecla ligada ao PortB.0 ou ao PortB.2
' Então ele passará a fazer a varredura no sentido inverso.
'
' Por:   Fábio Luiz dos Santos
' Data:  04/06/2011 - 16:31
'
' Configuração:
' Microcontrolador: PIC16F877A
' Cristal: 8MHz
' SW: MikroBasic PRO for PIC v 3.8
'Última alteração: 05/06/2011 - 12:51
'==========================================================


' Declarations section 
symbol Testabit_left = PORTB.2   'Cria um Symbol para o PORTB.0
symbol Testabit_right = PORTB.0  'Cria um Symbol para o PORTB.2
dim i as integer                 'variavel para a contagem


'**********************************************************
'Procedure para deslocar os bits do PORTD para a direita
'
Sub Procedure LACO_direita
    for i=1 to 8             'são 8 leds
        PORTD = PORTD >> 1   'Shift para a direita
        delay_ms(50)
    next i
    PORTD.0 = 1               'Como ele andou os bits e ficou zerado...
End Sub
'**********************************************************


'**********************************************************
'Procedure para deslocar os bits do PORTD para a esquerda
'
Sub Procedure LACO_esquerda
    for i=1 to 8            'Para 8 leds
        PORTD = PORTD << 1  'Shift para a esquerda
        delay_ms(50)
    next i
    PORTD.7 = 1             'E garante o ultimo led aceso
End Sub
'**********************************************************
main:
'   Main program 




    TRISD = 0 'Setando todo o portD como saída
    TRISB = 255 'Setando o portB como entrada
    
    PORTD = 000001 'Primeiro pino do Portd está setado com nível lógico 1
                '(Led aceso)


    Laco_principal:              'Laço Principal
      If Testabit_right = 0 then 'Se portb.2 pressionado, então...
         LACO_direita            'Chama laco direita
         delay_ms(100)           'Delay de 100ms
      end if                     'Fim se
      
      If Testabit_left = 0 then   'Se portb.0 pressionado, então...
         LACO_esquerda            'Chama laco esquerda
         delay_ms(100)            'Delay de 100ms
      end if                      'Fim se


    GOTO Laco_principal           'Volta ao laço principal (loop infinito)
    
end. 'Fim