Página 1 de 1

DPTR extrapolando?

MensagemEnviado: 09 Nov 2017 17:06
por Fabaum
Boa tarde!

Fiz um programa um pouco complexo que carrega informações num LCD 2x16 ao apertar das teclas.
O programa está todo em assembly.
Para cada nova informação, o algoritmo busca as referência numa tabela de dados.
Porém percebi que, num certo ponto, o display simplesmente fica doido!
Fiz muitos teste sem sucesso. Eliminei ao máximo as informações desnecessárias no programa, que agora conta simplesmente com as rotinas de inicialização do LCD e escrita nas duas linhas, mais nada! O defeito, entretanto, persiste...
Assim, comecei a desconfiar de duas coisas:
1) Problemas com o meu compilador (8051IDE);
2) Limitações na utilização do DPTR inerentes ao AT89S8252, impedindo a busca de dados após a posição de memória de programa 2000h.
Anexo a seguir o programa.
Na sub-rotina "TelaUm", a linha "mov DPTR,#teste3" está descomentada, ou seja, sem o ponto-e-vírgula, de modo que será executada pelo programa e gerará o defeito. Com a colocação do ponto-e-vírgula nela, o compilador irá ignorá-la na geração do .HEX. Se descomentarem a linha teste1 ou teste2, verão que o programa irá funcionar sem problemas...
Alguém saberia informar o motivo do mau-funcionamento?
OBS.: não consegui anexar o esquema do circuito aqui...

Segue o programa:

asm code
;TESTE DE MENUS LCD
tempo equ 60535 ;5.000us = 5ms (65535 - 60535 = 5000 pulsos)
tempo2 equ 15535 ;50.000us = 50ms (65535 - 15535 = 50000 pulsos)

LCDRot equ 1300h
MenuInicial equ 14E4h
MenuDetalhado equ 1FD4h

;PINOS DA PORTA P3 PARA CONTROLE DO LCD. PORTA DE ACIONAMENTO DO BARRAMENTO DO LCD: P0

LCD equ P0
EN equ P3.7
RS equ P3.6
RW equ P3.5

org 0030h

inicio: mov tmod,#1h ;habilita Timer0 em Modo 1 (contador 16 bits)
mov SP,#60h ;Stack Pointer inicializa na área de bytes endereçáveis (30h a 7Fh) acima dos outros bytes já utilizados

;*********************************************************************************************************
;INICIALIZAÇÃO DO DISPLAY

lcall inic_display ;inicializa display
lcall TelaUm

TelaUm: mov a,#80h ;posiciona o cursor: 80h=1ª linha (1ª coluna).
lcall wrcomando ;escreve a instrução
mov DPTR, #MenuInicial
lcall writestring ;escreve mensagem

mov a,#0C0h ;posiciona o cursor: C0h=2ª linha (1ª coluna).
lcall wrcomando ;escreve a instrução
; mov DPTR,#teste1 ;esta linha fica OK quando descomentada
; mov DPTR,#teste2 ;esta linha fica OK quando descomentada
mov DPTR,#teste3 ;o problema ocorre quando esta linha é descomentada (quando está sem o ponto-e-vírgula)
lcall writestring ;escreve mensagem

Loop: sjmp $ ;loop infinito

;*********************************************************************************************************
;Sub-rotinas LCD

inic_display:
lcall t15ms
lcall t15ms
mov a, #38h ;00111000b. Function set (8-bit interface, 2 linhas,matriz de 5*7)
lcall wrcomando
mov a, #38h ;idem
lcall wrcomando
mov a, #06h ;00000110b. Deslocar cursor à DIREITA à entrada de novo caractere
lcall wrcomando
mov a, #0ch ;00001100b. Liga o display, cursor desabilitado.
lcall wrcomando
mov a, #01h ;00000001b. Limpa display
lcall wrcomando
lcall t5ms ;chama atraso 5ms
ret

wrcomando: clr RW
clr RS
mov LCD,a
setb EN
clr EN
lcall t5ms
ret

wrdados: clr RW
setb RS
mov LCD,a
setb EN
clr EN
lcall t5ms
ret

writestring:
mov a, #0 ;utilização das STRINGs como segue abaixo:
movc a, @a+DPTR ;"varre" (incrementa)o DPTR até que encontre a letra "$" e aí pára de ler.
cjne a, #'$', write_next
sjmp finis_string
write_next:
lcall wrdados
inc DPTR
sjmp writestring
finis_string:
ret

;*********************************************************************************************************
;TEMPORIZADORES

t5ms: mov TL0, #low(tempo) ;carrega em TL0 a parte baixa do valor de 5ms
mov TH0, #high(tempo) ;carrega em TH0 a parte alta do valor de 5ms
setb tr0
jnb tf0, $
clr tr0
clr tf0
ret

t15ms: mov TL0, #low(tempo2) ;carrega em TL0 a parte baixa do valor de 15ms
mov TH0, #high(tempo2) ;carrega em TH0 a parte alta do valor de 15ms
setb tr0
jnb tf0, $
clr tr0
clr tf0
ret

;*********************************************************************************************************
org MenuInicial
db 'Menu Inicial $'

org MenuDetalhado
teste1: db 'LARANJA $'
teste2: db 'LIMAO $'
teste3: db 'ABACAXI $'
end

Re: DPTR extrapolando?

MensagemEnviado: 09 Nov 2017 21:13
por KrafT
Aloca "MenuDetalhado" (0x1FD4) mais para baixo, pois a soma dos teu textos deve estar passando da Flash Code memory para a EEPROM Data memory. As três frases somam 60 (0x3c) bytes, logo 0x1FD4+0x3C=0x2010, sendo que:

The Code and Data memory arrays are mapped via separate address spaces in the
serial programming mode. In the parallel programming mode, the two arrays occupy
one contiguous address space: 0000H to 1FFFH for the Code array and 2000H to
27FFH for the Data array
http://www.atmel.com/Images/DOC1018.PDF

Logo "MenuDetalhado" deveria no máximo estar alocado em 0x1FC3.
Mas para dar uma folga, testa com 0x1F00.
Considere programar em C.


Isso tudo supondo que vc não está usando EEPROM externa.

Re: DPTR extrapolando?

MensagemEnviado: 09 Nov 2017 23:36
por Fabaum
Kraft, muito obrigado pelos esclarecimentos. Vou estudar com calma as questões que levantou.
De fato, não utilizo nada nesta placa a não ser o microcontrolador, 4 teclas e o LCD.
Com respeito ao C, de fato gosto demais, porém como apenas recentemente voltei a programar depois de muitos anos, achei mais fácil, ou melhor, mais rápido de relembrar o assembly do que reaprender o C, ainda que o assembly seja mais trabalhoso de programar. De qualquer forma, minha próxima meta assim que este projeto estiver concluído ou pelo menos mais maduro é me dedicar ao C.
Qual programador vc utiliza?
O Keil na versão gratuita só programa até 2K, a versão paga deve estar alguns milhares de dólares...

Re: DPTR extrapolando?

MensagemEnviado: 10 Nov 2017 06:12
por KrafT
Eu não uso o AT89S8252, mas se você quiser programar em C e não se adaptar ao SDCC (http://sdcc.sourceforge.net/), você pode usar o Simplicity Studio ( https://www.silabs.com/products/develop ... ity-studio ) e ignorar que o target não é Silabs, que vai comppilar na boa (https://jaycarlson.net/2017/06/27/blink ... ntel-8051/).

Mas parabéns por estudar a "base das coisas" e não cair no co(modismo) do Arduíno e assemelhados.

Por outro lado, sugiro usar um MCU com debug incircuit, vc vai ganhar muito tempo. Quando possível, estude Linux embarcado, que é um mercado muito carente e promissor.

E por último tem um erro na minha resposta anterior, pois a Flash Code memory não é de fato contígua à EEPROM Data memory, mas isso não invalida a resposta nem a solução proposta.

Re: DPTR extrapolando?

MensagemEnviado: 10 Nov 2017 14:48
por Fabaum
KrafT, obrigado novamente. Excelente o artigo de Jay Carlson.
Já baixei o Simplicity e instalei. Vou estudar as restrições de licença gratuita.
Obrigado!

Re: DPTR extrapolando?

MensagemEnviado: 10 Nov 2017 14:50
por Fabaum
A propósito: acho que vou ter que usar uma EEPROM no projeto, já que estou com esta limitação de memória...
Paginação de LCD, na quantidade de telas que preciso fazer, demanda muita memória, o 8K do AT89S8252 não são suficientes, acredito que nem os 12K do AT89S8253 sejam...

Re: DPTR extrapolando?

MensagemEnviado: 10 Nov 2017 16:50
por KrafT
Mas me diga, resolveu trocar
Código: Selecionar todos
MenuDetalhado   equ 1FD4h
por
Código: Selecionar todos
MenuDetalhado   equ 1F00h
?

Re: DPTR extrapolando?

MensagemEnviado: 11 Nov 2017 17:20
por Fabaum
Sim KrafT, fiz isso.
Na verdade, seguindo a lógica do que me disse, verifiquei no editor da gravadora (VP-596) o arquivo .HEX problemático gerado, e vi onde minha lista de menus terminava. Então modifiquei o programa, iniciando o "org" das telas do LCD antes, de modo que o último caracter da última frase para LCD caísse exatamente na posição 1FFFh (8kB da memória flash). Então, ainda tenho algum espaço entre o código que programei até agora e o início de paginação do LCD para incluir alguma coisa mais...