-
Posts
4.059 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Fabricantes
Livros
Cursos
Análises
Fórum
posts postados por Mulder_Fox
-
-
Não sei te informar, pois sempre configurei os bits no código.
-
Este texto foi copiado do "datasheet" do PIC16F628A:
"The user will note that address 2007h is beyond the
user program memory space. In fact, it belongs to thespecial configuration memory space (2000h-3FFFh),which can be accessed only during programming. See“PIC16F627A/628A/648A EEPROM MemoryProgramming Specification” (DS41196) for additionalinformation." -
Obrigado, mister nintendo.
A nossa recompensa vem de elogios como o seu, que nos anima a continuar a empreitada.
Comecei a escrever a parte 9, mas tenho tido pouco tempo livre, por isso deve demorar um pouco.
-
Sim, Lipextreme. Esses endereços da memória de programa não são usados quando fazemos o desvio no endereço 0000 para depois do fim da rotina de interrupção que começa no endereço 0004.
No MPlab, no menu "View", em "Disassembly listing" podemos ver o que será gravado em cada endereço da memória de programa:
Na imagem anterior, eu desenhei retângulos vermelhos ao redor dos endereços 0000 e 0004 da memória de programa. Repare que não será gravado nada nos endereços 0001, 0002 e 0003.
Comecei a escrever a parte 9 do tutorial.
Nela, vou mostrar como produzir três sinais PWM por software cujos ciclos ativos mudam regularmente, porém são diferentes entre si. Esses sinais PWM são usados para acionar um LED RGB. Como a cor aparente do LED é resultante da soma das três cores dele que são: vermelho, verde e azul, ela muda a cada intervalo de tempo, gerando um efeito visual muito interessante e que pode ser usado em decoração.
Edit:
vtrx, quando comecei a escrever esta resposta, você ainda não havia postado.
Sempre pensei que no PIC16F628A, a instrução GOTO ocupasse apenas um endereço de memória e que o destino do desvio constasse na própria instrução.
Repare na imagem a seguir que os dois últimos caracteres da instrução correspondem ao endereço de destino e que a instrução GOTO que será gravada no endereço 0009 só ocupa aquele endereço pois, no próximo 000A será gravada outra instrução:
-
Bom dia, ricardospimentel.
O que eu entendo sobre o funcionamento do PIC16F628A é o seguinte:
Há a chamada Memória de Programa, onde são gravadas as instruções que compõe o programa. Essa memória começa no endereço 0000 e vai até o endereço 07FF, totalizando 2048 endereços.
Há o chamado Contador de Programa onde está escrito qual endereço da memória de programa será acessado para que seja executada a instrução ali contida. Após a execução de uma instrução, o Contador de Programa é incrementado automaticamente.
Após um reset, inclusive o power-on reset que ocorre quando o microcontrolador recebe alimentação, o valor do Contador de Programa é igual a 0000 e, portanto, a instrução a ser executada é a gravada no endereço 0000 da Memória de Programa. Após isso, o contador de programa é incrementado e, então, será executada a instrução contida no endereço 0001 da Memória de Programa, depois o contido no endereço 0002 e assim por diante.
As interrupções são provocadas pelos periféricos do microcontrolador, que são circuitos "independentes". Elas fazem com que o microcontrolador execute a instrução gravada no endereço 0004 da Memória de Programa, pois, escrevem esse valor no Contador de Programa (ao mesmo tempo que salvam o endereço da Memória de Programa da instrução que seria executada antes da interrupção para que ela possa ser executada após a saída da rotina de interrupção).
Então, se o nosso programa não fará uso de nenhuma interrupção, podemos gravá-lo a partir do endereço 0000, passando pelo 0004 sem problemas.
Se vamos usar alguma interrupção, devemos gravar a rotina de interrupção a partir do endereço 0004, já que esse é o endereço que será acessado na interrupção. O limite para o tamanho da rotina de interrupção é o tamanho da Memória de Programa.
Como as instruções do programa que referem-se à rotina de interrupção devem ser escritas a partir do endereço 0004 da Memória de Programa, o restante do programa é gravado depois do fim da rotina de interrupção, já que não caberia nos quatro endereços que existem antes (0000, 0001, 0002 e 0003). No endereço 0000 da Memória de Programa é gravada uma instrução GOTO que desvia o microcontrolador para depois do fim da rotina de interrupção.
O microcontrolador executa apenas uma instrução por vez. Ele não roda dois códigos ao mesmo tempo e não há diferença entre a execução de instruções no programa "principal" ou na rotina de interrupção. É só uma questão do local da Memória de Programa onde as instruções estão gravadas.
Você pode simular a execução do programa com o MPlab dentro da rotina de interrupção, colocando um breakpoint onde ela começa.
Os Timers não rodam código, eles são circuitos digitais (contadores) que funcionam independentemente da CPU do microcontrolador. Eles podem ser sincronizados com o mesmo sinal de clock da CPU ou com um externo.
Posso estar enganado sobre o que escrevi, mas é assim que creio que a "coisa" toda funciona.
Segue o link para o manual de referência da família 16 da Microchip:
- 1
-
ricardospimentel, fico feliz por você estar gostando do tutorial.
Quando decidi escrever o tutorial, fiz questão de procurar descrever o uso do simulador do MPlab, justamente porque o considero uma ótima ferramenta.
- 1
-
Olá, ricardospimentel. O prazer é meu.
O que ocorre é que o incremento somente irá ocorrer quando terminar o "debounce" do botão 1.
Para o "debounce" são usadas as variáveis DB1_BTA e DB1_BTB. A primeira inicia com o valor 255 e é decrementada toda vez que a subrotina "TRATA_BOTAO_1" for executada, estando o botão 1 pressionado. Quando ela chega a 0, é reiniciada com o valor 255 e a variável DB1_BTB é decrementada. Essa última é inciada com o valor 20. Quando DB1_BTB houver chegado a 0, o debounce acabou e, então o incremento ocorre.
Dessa forma, rotina "TRATA_BOTAO_1" deve ser executada 5.100 vezes (255 x 20) para que ocorra o incremento.
O mesmo vale para o botão 2 que faz o decremento. Para o botão 2 são usadas as variáveis DB2_BTA e DB2_BTB.
Você pode colocar "breakpoints" para acompanhar passo a passo usando o botão "Run".
Coloque um "breakpoint" na seguinte linha para acompanhar a partir do fim do "debounce":
INCF UNIDADE,F ;INCREMENTA UNIDADE
Edit:
Opa! Estava escrevendo ao mesmo tempo que você!
Vejo que você já entendeu. De fato, cada vez que você clica no botão "Step Into" o simulador executa uma instrução.
- 1
-
Que bom que você entendeu. Se tiver outra dúvida, estamos aí para tentar esclarecer.
- 1
-
Lipextreme, você não está incomodando, pelo contrário.
Sua dúvida me mostrou que não expliquei bem as operações com os registradores.
No sistema decimal, cada dezena vale dez unidades e, por isso, quando vamos fazer, por exemplo, a operação 23 - 18, nós decrementamos a dezena do número 23 e somamos dez à sua unidade transformando-a em 13. Daí fazemos 13 - 8, o que resulta em 5. Depois subtraímos as dezenas (1 -1) resultando em 0. O resultado da subtração é portanto 5.
No sistema decimal cada algarismo varia de 0 a 9.
Repare que se decrementarmos o algarismo 3 oito vezes vamos chegar ao seguinte:
3 - 1 = 2
2 - 1 = 1
1 - 1 = 0
0 - 1 = 9
9 - 1 = 8
8 - 1 = 7
7 - 1 = 6
6 - 1 = 5
No caso dos registradores do programa, cada "unidade" do REG2B vale 256 "unidades" do REG1B.
Então se o REG1A for maior do que o REG1B, nós deveríamos decrementar REG2B e somar 256 ao REG1B para fazer a subtração.
Mas, nós não precisamos somar 256 ao REG1B, pois, no microcontrolador, a subtração ocorre pelo método do complemento de 2.
O resultado obtido é o mesmo que se o REG1B fosse decrementado um número de vezes igual ao valor do REG1A, como no exemplo que dei para o sistema decimal.
Vamos supor que o valor de REG1B fosse 128 e o de REG1A, 230.
Quando fazemos REG1B = REG1B - REG1A, através da instrução SUBWF, é como se o REG1B fosse decrementado 230 vezes. Após 128 vezes o seu valor seria igual a 0. Na 129ª vez, o seu valor seria igual a 255. Apos 230 vezes, o seu valor seria de 154.
Mas, repare que 154 é igual a (128 + 256) - 230
Só lembrando que o microcontrolador não decrementa o REG1B 230 vezes. Ele calcula o complemento de 2 do REG1A e depois soma (isso mesmo: soma) ao REG1B para efetuar a operação de subtração.
É por isso que não precisamos somar 256 ao REG1B antes. Foi isso que faltou explicar no tutorial e que gerou a sua dúvida. Espero que tenha sido claro.
- 1
-
Qualquer outra dúvida fique à vontade, Lipextreme.
Tive que interromper o tutorial por falta de tempo.
Pretendo continuá-lo tão logo seja possível.
-
Olá, Lipextreme.
Desculpe-me pela demora para responder. Estive muito ocupado nos últimos dias.
Obrigado pelos elogios.
Você deve salvar os registradores W e STATUS qualquer que seja a fonte de interrupção.
A razão de salvar os valores desses registradores é que eles são alterados dentro da rotina de interrupção.
O que muda quando se usa a interrupção do Timer1 é que deve-se testar se o bit TMR1IF está setado para confirmar que a interrupção foi gerada pelo Timer1 e depois zerá-lo.
- 1
-
Bom dia, vou fazer o circuito que você desenhou para 4 jogadores...
mas como não entendo muito, um colega de uma eletrônica sugeriu fazer uma placa, ele faz ela se eu mandar o desenho com o circuito porque com os fios vai dar um nó na cabeça de tanto fio...
eu vou usar esse sistema para as aulas do PROERD, ja que eu sou instrutor.
Obrigado
Recomendo testar o circuito numa protoboard antes de montá-lo, já que não foi testado antes.
Quando desenhei esse circuito desenvolvi também uma placa. Vou procurar aqui nos meus backups.
- 1
-
alderi17, entre montar com CIs e com microcontrolador, o melhor é com microcontrolador.
Com CI e para 6 jogadores, basta ampliar o circuito.
Não sou profissional.
-
Sim, essa fonte serve. Sua potência é mais do que suficiente. A rede aí é de 220 V?
-
Está correto. A fonte deve custar menos de R$10,00. O recipiente e a mangueira também são baratos.
-
Perfeito!
Com esses sensores, basta fazer os furos no reservatório nas alturas adequadas. Creio que vale a pena o investimento, pois terá um dispositivo confiável.
- 1
-
Funcionaria com qualquer chave que, quando pressionada, feche os seus contatos. Poderia ser simplesmente dois fios que se encostem. Não sei como são esses sensores da tampa das impressoras.
-
O mais difícil é construir as boias. Pensei em bolas de isopor coladas umas às outras dentro de um tubo. No final do tubo elas empurrariam a alavanca da chave. Quanto menos bolas maior a altura que a água atingiria. Um tubo para cada chave.
- 1
-
Editei o post anterior enquanto você postava. Leia, pois, adicionei um circuito para o controle da bomba através das duas chaves. A chave é conhecida por Micro Switch.
Creio que 10 cm são suficientes para você usar uma bomba submersa que tem uma altura de cerca de 5 cm.
Não conheço bomba pequena e barata que trabalhe sem estar submersa.
- 1
-
Dá para fazer com menos de R$100,00.
Uma pequena bomba submersa custa cerca de R$20,00:
Esse tipo de bomba não pode trabalhar a seco, e portanto teria que ser ligada quando o nível de água estivesse alto e desligada quando estivesse baixo, mas, ainda cobrindo a bomba.
Para ligar e desligar a bomba, poderiam ser construídas duas pequenas boias artesanais, que acionariam chaves desse tipo: http://www.soldafria.com.br/chave-micro-switch-kw11-3z-5-3t-56mm-p-1574.html
O circuito para controlar a bomba com as duas chaves usaria uma fonte de 12v e dois relés de 12V automotivos:
http://produto.mercadolivre.com.br/MLB-485758737-rele-auxiliar-5-pinos-_JM
A chave S1 é acionada quando o nível da água estiver, digamos, 2 cm acima da bomba. A chave S2 é acionada quando o nível da água estiver próximo de transbordar.
Quando S2 é acionada, os dois relés são armados. Quando o relé 1 é armado, os contatos 30 e 87 são fechados. Esses contatos estão ligados em paralelo com a chave S2, e, portanto, mesmo que S2 deixe de estar acionada, os relés continuam armados até que S1 deixe de estar acionada.
- 2
-
MulderFox provavelmente vai achar o tópico que ele solucionou
Acho que você se refere a este tópico, não é vtrx?:
http://forum.clubedohardware.com.br/precisao-timer0-ni/1134219
-
Segue exemplo de programa:
;VERSÃO 1.0
;DESENVOLVIDO POR: MULDER_FOX
;DATA DE CONCLUSÃO: 08/06/2013
#INCLUDE <P16F628A.INC> ;ARQUIVO padrão MICROCHIP PARA O PIC16F628A
;BITS DE CONFIGURAÇÃO
__CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _CP_OFF & DATA_CP_OFF
;PAGINACAO DE MEMORIA
#DEFINE BANCO_0 BCF STATUS,RP0 ;SETA BANCO 0 DE MEMORIA
#DEFINE BANCO_1 BSF STATUS,RP0 ;SETA BANCO 1 DE MEMORIA
;VARIÁVEIS
CBLOCK 0X20 ;ENDERECO INICIAL DA MEMORIA DO USUARIO
DB1_BTA ;PRIMEIRO REGISTRADOR DO DE-BOUNCING DO BOTÃO
DB1_BTB ;SEGUNDO REGISTRADOR DO DE-BOUNCING DO BOTÃO
FLAGS ;REGISTRADOR DE FLAGS
ENDC ;FIM DO BLOCO DE MEMORIA
;CONSTANTES
INI_DB1_BTA EQU .255 ;VALOR QUE DB1_BTA INICIA
INI_DB1_BTB EQU .20 ;VALOR QUE DB1_BTB INICIA
;SAÍDAS
#DEFINE LED_1 PORTB,0 ;SE = 1, O LED 1 ESTÁ ACESO
#DEFINE LED_2 PORTB,1 ;SE = 1, O LED 2 ESTÁ ACESO
;ENTRADA
#DEFINE BOTAO PORTB,2 ;BOTAO LIGADO EM RB2
;FLAGS
#DEFINE SOLTAR_BOTAO FLAGS,0 ;SE = 1 AGUARDA SOLTAR O BOTÃO
#DEFINE LED_1_OU_2 FLAGS,1 ;SE = 0, ACENDER O LED 1, SE = 1, ACENDER O LED 2
;VETOR DE RESET
ORG 0X00 ;ENDERECO INICIAL DE PROCESSAMENTO
GOTO INICIO ;DESVIA PARA INICIO
;ROTINA DE INTERRUPÇÃO
ORG 0X04
RETFIE
;configuração DOS REGISTRADORES DE USO ESPECÍFICO
INICIO
BANCO_1 ;SELECIONA BANCO 1 DE MEMORIA
MOVLW B'11111100'
MOVWF TRISB ;CONFIGURA O PINO RB0 E RB1 COMO SAIDAS E DEMAIS COMO ENTRADAS
BANCO_0 ;SELECIONA BANCO 0 DE MEMORIA
;INICIALIZACAO DAS VARIAVEIS
MOVLW INI_DB1_BTA ;W = INI_DB1_BTA
MOVWF DB1_BTA ;INICIALIZA DB1_BTA
MOVLW INI_DB1_BTB ;W = INI_DB1_BTB
MOVWF DB1_BTB ;INICIALIZA DB1_BTB
BCF LED_1 ;APAGA LED 1
BCF LED_2 ;APAGA LED 2
PRINCIPAL
CLRWDT ;LIMPA O WDT
BTFSS SOLTAR_BOTAO ;AGUARDA SOLTAR O BOTAO?
GOTO TESTA_BOTAO ;NAO, DESVIA
BTFSS BOTAO ;SIM, O BOTÃO ESTÁ SOLTO?
GOTO PRINCIPAL ;NAO
BCF SOLTAR_BOTAO ;SIM, APAGA FLAG
TESTA_BOTAO
BTFSC BOTAO ;O BOTÃO ESTÁ PRESSIONADO?
GOTO REINC_CONT_DEB ;NÃO, DESVIA
DECFSZ DB1_BTA,F ;SIM, DECREMENTA DB1_BTA. DB1_BTA = 0?
GOTO PRINCIPAL ;NAO
MOVLW INI_DB1_BTA ;SIM, W = INI_DB1_BTA
MOVWF DB1_BTA ;INICIALIZA DB1_BTA
DECFSZ DB1_BTB,F ;DECREMENTA DB1_BTB. DB1_BTB = 0?
GOTO PRINCIPAL ;NAO
MOVLW INI_DB1_BTB ;SIM, W = INI_DB1_BTB
MOVWF DB1_BTB ;INICIALIZA DB1_BTB
BSF SOLTAR_BOTAO ;SETA FLAG PARA AGUARDAR SOLTAR O BOTÃO
BTFSS LED_1 ;O LED 1 ESTÁ ACESO?
GOTO TESTA_LED_2 ;NAO
BCF LED_1 ;SIM, APAGA O LED 1
BSF LED_1_OU_2 ;SETA O FLAG
GOTO PRINCIPAL
TESTA_LED_2
BTFSS LED_2 ;O LED 2 ESTÁ ACESO?
GOTO ACENDER_LED_1_OU_LED_2 ;NAO
BCF LED_2 ;SIM, APAGA LED 2
BCF LED_1_OU_2 ;APAGA O FLAG
GOTO PRINCIPAL
ACENDER_LED_1_OU_LED_2
BTFSC LED_1_OU_2 ;ACENDER O LED_1?
GOTO ACENDE_LED_2 ;NÃO
BSF LED_1 ;SIM, ACENDE LED_1
GOTO PRINCIPAL
ACENDE_LED_2
BSF LED_2 ;ACENDE O LED 2
GOTO PRINCIPAL
REINC_CONT_DEB
MOVLW INI_DB1_BTA ;W = INI_DB1_BTA
MOVWF DB1_BTA ;INICIALIZA DB1_BTA
MOVLW INI_DB1_BTB ;W = INI_DB1_BTB
MOVWF DB1_BTB ;INICIALIZA DB1_BTB
GOTO PRINCIPAL
END ;FIM DO PROGRAMA;PROGRAMA: UM BOTAO COMANDA DOIS LEDS
Circuito:
- 2
-
Como o amigo vtrx disse dá para fazer de várias formas, por exemplo usando bits de um registrador geral como flags.
- 1
-
Fiz o download do MPLAB X, versão 1.80. Como sou amador, e uso o simulador apenas para programas simples, não sei se vou perceber alguma melhora ou piora.
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
Temporizador de 20min com alarme.
em Eletrônica
Postado
Já conseguiu o circuito?