Ir ao conteúdo

[Resolvido]Contador de 0 a 9 com PIC16F877A


Gabriel-Kun

Posts recomendados

Postado

Boa Noite!

Tenho que fazer um contador com PIC para um trabalho na escola, mas como estou começando com PIC agora, estou com dúvidas quanto ao programa.

O programa tem que ser linguagem Assembly.

Descrição do Programa: Iniciar o display mostrando o número 0, a cada vez um botão S4 for pressionado, incrementar o valor mostrado no display, zerando novamente após o número 9, quando pressionar o botão S3 decrementar o valor no display. Se possível usando o display da esquerda.

Será que muito difícil fazer?

Agradeço desde já!!!!

Circuito PIC16F877A

CircuitoPIC16F877A.gif

Postado

Mas o problema é que o professor não explicou como fazer as rotinas para fazer soma e conversão binario e decimal. Nos aprendemos algumas intrusões(movlw, movwf, bsf, bcf, goto, btfsc, btfss, clrw, clrf, movf, rrf, rlf), ai eu acho que fica meio difícil fazer este tipo de programa, os outros que ele passou(mais simples), eu já fiz, só falta este.

Postado

Gabriel, o problema é que só existem essas ações pra se fazer... você não vai fazer conversão de binário para decimal, você vai fazer a conversão de um código binário relativo a um número (exemplo 0111 = 7) e vai transforma-lo em bits que irão ligar determinados pinos do display de 7 segmentos... além de fazer o chaveamento dos displays... para ser sincero um colega de classe meu apresentou mês passado EXATAMENTE ESSE projeto num trabalho para SD, porém o dele contava até 9999 e reiniciava.

Infelizmente, como o Mulder falou... você vai ter que se virar rapaz, é um projeto de simples "inc w" "movwf portX"...

Postado

Opa...

Depois de mexer aqui no meu programa consegui fazer ele iniciar com zero somar e subtrair, mas consegui só em binário, agora como faço para associar este número binário a um digito no display? Uma outra dúvida como faço para por um limite na contagem?

Fiz até uma tabela com a combinação de bits para mostrar o número no display.

Postado

Grabriel-Kun se quiser posso tentar ajudá-lo.

Não vou entrar em detalhes específicos deste modelo de PIC, apenas quanto as rotinas de programação, pois, o modelo de PIC que estou familiarizado é o 16F628A.

As rotinas de verificação dos botões deveriam incluir debounce, para evitar disparos aleatórios.

No seu programa, você incrementa e decrementa o PORTD, mas, você deveria usar um outro registrador como contador, que depois seria lido e convertido para 7 segmentos, com o auxílio de uma tabela, seria copiado para o PORTD.

Não é necessário escrever no PORTB depois de incrementar o contador.

Não entendi a finalidade dos regs TEMP1 TEMP2 E TEMP3 e também não entendi o programa a partir do Espera.

Postado

tem que fazer mais que isso Gabriel... olha, pra ser sincero eu vou te dar o programa, eu estive dando uma olhada e ele é ABSURDAMENTE complicado para quem ta começando...

Não sei se tem a necessidade do delay ja que é display de sete segmentos e ele não tem delay como o LCD.

Assim que meu amigo entrar no msn eu posto o programa pra você

Postado

; Controle de fluxo

; O projeto exemplo tem como principal função, criar um contador

; formado por um botão (push button com resistor de pull up) no

; pino porta.4 e a cada pulso recebido por este, o microcontrolador

; será responsável por indicar por meio de 4 displays 7 segmentos o

; número de vezes em que o botão foi pressionado. Ao mesmo tempo,

; para que o microcontrolador possa indicar o número de vezes que

; o botão for presionado nos 4 displays, ele controlará tanto a informação

; que sairá do portb (controle a, b, c, d, e, f,g) quanto qual display que será

; acionado (controle feito por transistores).

;Botão de controle – Conectado ao porta.4

#include<p16f877a.inc>

;define as variáveis e outros registros necessários para o programa

indo equ 00h ;registro de indireccion

pc equ 02h ;contador de programa

status equ 03h ;registro de estado

fsr equ 04h ;registro de selecão

porta equ 05h ;port a

portb equ 06h ;port b

rota equ 0fh ;variable para desplazamiento de display

trisa equ 85h ;configuracion puerto a

trisb equ 86h ;configuracion puerto b

dig1 equ 10h ;acumulador miles

dig2 equ 11h ;acumulador centenas

dig3 equ 12h ;acumulador decenas

dig4 equ 13h ;acumulador unidades

loops equ 1dh ;variavel usadas em delays

loops2 equ 1eh ;variavel usadas em delays

z que 02h ;flag de zero

ram equ 05h ;bit de selecão da pagina de memória

c equ 00h ;flag de acarreo

w equ 00h ;bit de destino do registro work

reset:

org 00

goto inicio

org 05h

retardo: ;subrutina de delay

movwf loops ;la variable de trabajo contiene la cant.

top2:

movlw d'110' ;tempo em ms de delay

movwf loops2

top:

nop

nop

nop

nop

nop

nop

decfsz loops2 ;controla do termino de 1ms

goto top

decfsz loops ;controla se terminou o delay completo

goto top2

retlw 0

s1000: ;rotina de incremento de uinidade de milhar

clrf dig2 ;zera as centenas

incf dig1 ;incrementa a unidade de milhar

movf dig1, w ;carrega no registro work com o valor das unidades de milhar

xorlw 0ah ;se o registro work=10, então agora work=0

btfsc status, z ;se for igual a 0, então aciona o flag z

clrf dig1 ;reinicia o valor da unidade de milhar

return

s100: ;rotina de incremento das centenas.

clrf dig3 ;zera as dezenas.

incf dig2 ;incrementa o contador das centenas.

movf dig2, w ;carrega o valor das centenas no registro work.

xorlw 0ah ;se o registro work=10, então agora work=0.

btfsc status, z ;se for igual a 0, então aciona o flag z

call s1000 ;incrementa a unidade de milhar.

return

s10: ;rotina de incremento das dezenas

clrf dig4 ;zera as unidades

incf dig3 ;incrementa o contador das dezenas

movf dig3, w ;carrega o registro work com o valor das dezenas

xorlw 0ah ;se o registro work=10, então agora work=0

btfsc status, z ;se for igual a 0, então aciona o flag z

call s100 ;incrementa as centenas

return

subir: ;rotina de incremento das unidades

incf dig4 ;incrementa as unidades

movf dig4, w ;carrega no registro work o valor das unidades

xorlw 0ah ;se o registro work=10, então agora work=0

btfsc status, z ;se for igual a 0, então aciona o flag z

call s10 ;incrementa as dezenas

movlw d'250' ;gera um delay de 100ms

call retardo

return

tabla: ;gera os dígitos correspondendes a cada display

addwf pc ;adiciona ao contador de programa (pc) o valor do registro work

retlw b'00111111' ;gera no display o digito 0

retlw b'00011000' ;gera no display o digito 1

retlw b'01110110' ;gera no display o digito 2

retlw b'01111100' ;gera no display o digito 3

retlw b'01011001' ;gera no display o digito 4

retlw b'01101101' ;gera no display o digito 5

retlw b'01101111' ;gera no display o digito 6

retlw b'00111000' ;gera no display o digito 7

retlw b'01111111' ;gera no display o digito 8

retlw b'01111101' ;gera no display o digito 9

inicio: ;programa principal

bsf status, ram ;seleciona o BANK1

movlw b'00010000' ;configura o port a

movwf trisa ;porta.4 como entrada e os demais como saída

movlw 00h ;configura o portb

movwf trisb ;todas como saida

bcf status, ram ;seleciona o BANK0

nop

call retardo

nop

clrf dig1 ;inicializa os acumuladores

clrf dig2

clrf dig3

clrf dig4

movlw 00 ;envia o valor 0 na base dos transistores

movwf porta ;apaga todos os displays

empe:

btfss porta, 4 ;verifica se o botão foi pressionado

call subir ;se sim, chama a rotina de incremento de um número

movlw 08h ;se não, inicia em 1 o registro para a rotação de valores nos displays

movwf rota

movlw dig1 ;o registro selector (fsr) é responsável

movwf fsr ;por apontar o primeiro valor a se mostrar no display

disp:

movlw 00h ;zera as saídas que vão para os displays

movwf portb ;para apagalos

movf rota, w ;passa a rotacão do display ao registro work

movwf porta ;e controla os transistores dos displays

movf indo, w ;lê o a informação do registro apontado pelo fsr

call tabla ;genera o digito de 7 segmentos

movwf portb ;envia o digito ao portb

movlw 03h ;cria um delay de 3ms para vis=ualização do dígito

call retardo

btfsc rota, 0 ;verifica se toda a rotação para mostrar os dígitos foram feitas

goto empe ;se sim, volta ao começo da sub-rotina empe para verificar o botão de entrada

bcf status, c ;se não zera o carry para não afetar o processo de rotação

rrf rota ;direciona a rotação para a direita

incf fsr ;incrementa e seleciona o próximo display

goto disp ;volta ao começo da sub-rotina disp

end

falei que era chato o programa....

Postado

Opa valeu mesmo... o programa de pois do Espera é uma rotina de tempo, ele vai decrementando uma variavel(que no caso é h'30') até ela zerar, depois volta de onde eu a chamei, eu coloquei essa rotina para ter um pequeno intervalo de tempo no toque do botão, é que sem esta rotina, eu apertava o botão uma vez e ele contava varias vezes.

Postado

O programa esta dando erro ao compilar, eu só mudei as portas...onde era PORTA, eu coloquei PORTB, e onde era PORTB eu coloquei PORTD, é que os botões do meu circuito estão no PORTB e os displays no PORTD.

Postado

O programa a seguir, é de um contador crescente/decrescente de 0 a 9, desenvolvido para o PIC16F628A.

É para você tirar algumas idéias e adaptar para o seu exercício.

;*************************************************************************

; PROGRAMA – CONTADOR CRESCENTE/DECRESCENTE DE 0 A 9

;*************************************************************************

; ARQUIVOS DE DEFINICOES

;*************************************************************************

#INCLUDE <P16F628A.INC> ;ARQUIVO padrão MICROCHIP PARA O PIC16F628A

;*************************************************************************

; BITS DE configuração

;*************************************************************************

__CONFIG _BOREN_ON&_CP_OFF&_PWRTE_ON&_WDT_OFF&_LVP_OFF&_DATA_CP_OFF&_MCLRE_ON&_XT_OSC

;*********************************************************

; PAGINACAO DA MEMORIA

;*********************************************************

;COMANDOS PARA ALTERACAO DE PAGINA DE MEMORIA

BANK0 MACRO ;MACRO PARA SELECIONAR BANCO 0

BCF STATUS,RP0

BCF STATUS,RP1

ENDM ;FIM DA MACRO BANK0

BANK1 MACRO ;MACRO PARA SELECIONAR BANCO 1

BSF STATUS,RP0

BCF STATUS,RP1

ENDM ;FIM DA MACRO BANK1

BANK2 MACRO ;MACRO PARA SELECIONAR BANCO 2

BCF STATUS,RP0

BSF STATUS,RP1

ENDM ;FIM DA MACRO BANK2

BANK3 MACRO ;MACRO PARA SELECIONAR BANCO 3

BSF STATUS,RP0

BSF STATUS,RP1

ENDM ;FIM DA MACRO BANK3

;********************************************************* VARIAVEIS

;*********************************************************ENDERECOS DAS VARIAVEIS UTILIZADAS PELO SISTEMA

CBLOCK 0x20 ;ENDERECO INICIAL DA MEMORIA DO USUARIO

DEBOUNCE ;0x20, USADO NO DEBOUNCE

COUNT ;0x21, USADO NO DEBOUNCE

CONTADOR ;0x22, ARMAZENA A CONTAGEM

ENDC ;FIM DO BLOCO DE MEMORIA

;*********************************************************; CONSTANTES

;*********************************************************;CONSTANTES UTILIZADAS PELO SISTEMA

DEB EQU .200 ;INICIALIZACAO DO REG DEBOUNCE

DEB_CONT EQU .50 ;INICIALIZACAO DO REG COUNT

MINIMO EQU .0 ;VALOR MINIMO DA CONTAGEM

MAXIMO EQU .9 ;VALOR MAXIMO DA CONTAGEM

;*********************************************************

; ENTRADAS

;*********************************************************

;PINOS QUE SERAO UTILIZADOS COMO ENTRADA

#DEFINE BOTAO1 PORTA,1 ;0 --> PRESSIONADO ;1 --> LIBERADO

#DEFINE BOTAO2 PORTA,2 ;0 --> PRESSIONADO ;1 --> LIBERADO

;*********************************************************

; SAIDAS

;*********************************************************

;O PROTB ESTA LIGADO NUM DISPLAY DE SETE SEGMENTOS, SENDO CADA SEGMENTO

;ATIVADO(ACESO) QUANDO NO RESPECTIVO PINO FOR COLOCADO NIVEL LOGICO 1.

; A

;RB0 - SEGMENTO A **********

;RB1 - SEGMENTO B F* *B

;RB2 - SEGMENTO C * G *

;RB3 - SEGMENTO D **********

;RB4 - SEGMENTO E E* *C

;RB5 - SEGMENTO F * D *

;RB6 - SEGMENTO G ********** *P

;RB7 - PONTO

;*********************************************************

; VETOR DE RESET

;*********************************************************

ORG 0x00 ;ENDERECO INICIAL DE PROCESSAMENTO

GOTO INICIO

;*********************************************************

; INTERRUPCAO

;*********************************************************

;AS INTERRUPCOES NAO SERAO UTILIZADAS

ORG 0x04 ;ENDERECO INICAL DA INTERRUPCAO

RETFIE ;RETORNA DA INTERRUPCAO

;*********************************************************

; INICIO

;*********************************************************INICIO

BANK1 ;ALTERA PARA BANCO 1

MOVLW B'00000110'

MOVWF TRISA

MOVLW B'00000000'

MOVWF TRISB ;DEFINE O PORTB COMO SAIDA

MOVLW B'10000000' ;PULL_UPS DESABILIADOS <7>

MOVWF OPTION_REG ;DEMAIS BITS IRRELEVANTES

MOVLW B'00000000'

MOVWF INTCON

BANK0 ;ALTERA PARA BANCO 0

MOVLW B'00000111' ;CONFIGURA RA3:RA0 COM I/O <2:0>

MOVWF CMCON

;*********************************************************

; INICIALIZACAO DAS VARIAVEIS

;*********************************************************

CLRF PORTA ;LIMPA PORTA

MOVLW B'00111111'

MOVWF PORTB ;INICIALIZA DISPLAY COM ZERO

CLRF CONTADOR ;INICIALIZA CONTADOR COM ZERO

;*********************************************************

MAIN

MOVLW DEB ;INICIALIZA DEBOUNCE COM 200

MOVWF DEBOUNCE

MOVLW DEB_CONT ;INICIALIZA COUNT COM 50

MOVWF COUNT

TESTA_BT1

BTFSC BOTAO1 ;BOTAO1 ESTA PRESSIONADO?

GOTO TESTA_BT2 ;NAO, DESVIA

GOTO FAZER_DEBOUNCE1 ;SIM, DESVIA

TESTA_BT2

BTFSC BOTAO2 ;BOTAO2 ESTA PRESSIONADO?

GOTO MAIN ;NAO, DESVIA

GOTO FAZER_DEBOUNCE2 ;SIM, DESVIA

FAZER_DEBOUNCE1

DECFSZ DEBOUNCE,F ;DECREMENTA DEBOUNCE, = 0?

GOTO TESTA_BT1 ;NAO, DESVIA

MOVLW DEB ;SIM, CONTINUA

MOVWF DEBOUNCE ;INICIALIZA DEBOUNCE COM 200

DECFSZ COUNT,F ;DECREMENTA COUNT, COUNT=0?

GOTO TESTA_BT1 ;NAO, DESVIA

GOTO TRATA_BT1 ;SIM, DESVIA

FAZER_DEBOUNCE2

DECFSZ DEBOUNCE,F ;DECREMENTA DEBOUNCE, = 0?

GOTO TESTA_BT2 ;NAO, DESVIA

MOVLW DEB ;SIM, CONTINUA

MOVWF DEBOUNCE ;INICIALIZA DEBOUNCE COM 200

DECFSZ COUNT,F ;DECREMENTA COUNT, COUNT=0?

GOTO TESTA_BT2 ;NAO, DESVIA

;SIM, CONTINUA

TRATA_BT2

MOVLW .0 ;W RECEBE 0

XORWF CONTADOR,W ;W = W xor CONTADOR

BTFSC STATUS,Z ;CONTADOR = 0?

GOTO SOLTAR_BOTAO ;SIM, AGUARDA SOLTAR BOTAO

DECF CONTADOR,F ;NAO, DECREMENTA CONTADOR

CALL CONV_DISP ;CHAMA SUB- ROTINA.

MOVWF PORTB ;ATUALIZA DISPLAY

GOTO SOLTAR_BOTAO ;DESVIA

TRATA_BT1

MOVLW .9 ;W RECEBE 9

XORWF CONTADOR,W ;W = W xor CONTADOR

BTFSC STATUS,Z ;CONTADOR = 9?

GOTO SOLTAR_BOTAO ;SIM, AGUARDA SOLTAR BOTAO

INCF CONTADOR,F ;NAO, INCREMENTA CONTADOR

CALL CONV_DISP ;CHAMA SUB- ROTINA. MOVWF PORTB ;ATUALIZA DISPLAY

SOLTAR_BOTAO

BTFSS BOTAO1 ;BOTAO1 ESTA SOLTO?

GOTO $-1 ;NAO, AGUARDA SOLTAR BOTAO1

BTFSS BOTAO2 ;BOTAO2 ESTA SOLTO?

GOTO $-1 ;NAO, AGUARDA SOLTAR BOTAO2

GOTO MAIN ;SIM, DESVIA

;*********************************************************

;ESTA SUB-ROTINA CONVERTE O VALOR ARMAZENADO NO REGISTRADOR CONTADOR PARA

;DISPLAY DE SETE SEGMENTOS, RETORNANDO O VALOR CONVERTIDO EM W.

CONV_DISP

MOVF CONTADOR,W ;W RECEBE CONTEUDO DE CONTADOR

ADDWF PCL,F ;PCL RECEBE (W + PCL)

;OS COMENTARIOS ABAIXO SE REFEREM AOS VALORES VISTOS NO DISPLAY

;.GFEDCBA ;POSICAO DOS SEGMENTOS DO DISPLAY LIGADO NO PORTB

RETLW B'00111111' ;0

RETLW B'00000110' ;1

RETLW B'01011011' ;2

RETLW B'01001111' ;3

RETLW B'01100110' ;4

RETLW B'01101101' ;5

RETLW B'01111101' ;6

RETLW B'00000111' ;7

RETLW B'01111111' ;8

RETLW B'01100111' ;9

;*********************************************************

END ;FIM DO PROGRAMA

;*********************************************************

Postado

Opa...Consegui fazer ele contar no display, mas agora o problema é por um limite na contagem, ele esta contando até 9 e continua.

Ele tem que contar até 9 voltar para zero e começar de novo, para decrementar a mesma coisa, tem que chegar a zero e voltar 3, 2, 1, 0, 9, 8..., só falta isso agora.

Postado
O programa esta dando erro ao compilar, eu só mudei as portas...onde era PORTA, eu coloquei PORTB, e onde era PORTB eu coloquei PORTD, é que os botões do meu circuito estão no PORTB e os displays no PORTD.

setou o trisb corretamente?

um provavel erro é se você se esqueceu de dar as necessárias "tabs"

Postado

coloca uma variável "MAX" assim

MAX = (número máximo)

cada vez que você somar um número no seu contador, ele vai subtrair 1 do MAX, então se max for = 0 você força o contador a ficar = 0 também, então faz um goto antes do max, ele é NOVAMENTE setado para o número máximo.

quando subtrair você faz parecido, se o contador for zero então ele seta o contador para o valor max e o "max" ele seta para o valor max também... e faça um goto- inicio depois

Postado

Consegui fazer isso aqui, mas não sei porque não consigo ver o Zero, parece que ele passa rápido demais.

Outra coisa, ele também não esta contando decrescente(0, 9, 8, 7, ...), quando ele chega no zero, para e não conta mais.

Quando eu faz a contagem crescente e decrescente algumas vezes, ele zera no meio da contagem.

Postado

Sugiro que você substitua o método de verificação de máximo e mínimo por outro que antes de incrementar verifique se o valor do contador é 9 e antes de decrementar verifique se é 0. É mais simples.

Da forma como está, quando MIN atinge 0, ele zera o contador, quando deveria voltar a 9.

Postado

É verdade eu fiz assim pelo método de decrementar uma variável e ele zera o contador.

Mas como faria para fazer a verificação do contador, qual instrução faz isso?

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!