.
;********************************************************************************
;* Configurações para os CIs ligados no barramento do TWI isto é, I2C, *
;* que são os PCF8574P (expansão), o 24C16 (memória) e PCF8583 (RTR). *
;* O CI PCF8574 tem dois endereços em função do seu tipo que pode ser P (40/41) *
;* ou A (70/71), sendo uma para o barramento do LCD, um para o teclado, um para *
;* os LEDs e um para dados em geral. *
;* *
;* Nomenclatura:
;* r_ rotina *
;* i_ de acesso interno *
;* e_ de acesso externo *
;* f_ fixo *
;* v_ variável *
;* mscr_ máscara *
;* mcr_ macro *
;********************************************************************************
;
;
;*************** Inserir no arquivo de seleção (selecao.inc). *******************
;
;
;********************************************************************************
;* .EQU f_ativar = 1 ; *
;* .MESSAGE "<<< o PCF8574 no simular é do tipo A (0x70) e no chip é do tipo P (0x40) >>>"
;*
;* .EQU __CI_8574__ = f_ativar ; comentar desabilita o CI 8574-x.
;* .EQU __CI_tipo_P__ = f_ativado ; comentar habilita o CI 8574-x como tipo P.
;* .EQU __twi_barramento_LCD__ = f_ativar ; comentar desabilita o barramento LCD via CI 8574-x.
;* .EQU __twi_barramento_LEDs__ = f_ativar ; comentar desabilita o barramento LEDs via CI 8574-x.
;* .EQU __twi_barramento_DADOs__ = f_ativar ; comentar desabilita o barramento DADOs via CI 8574-x.
;* .EQU __klavaro_8574__ = f_ativar ; comentar desabilita o barramento KLAVARO via CI 8574-x.
;* *
;* Obsrvação: deve ser comentado a variável __TIPO_P__ para usar no simulador. *
;********************************************************************************
;
;
;************* Inserir no arquivo de definições (definicao.inc). ****************
;
;
;********************************************************************************
;* .IFDEF __TIPO_P__ ; *
;* .MESSAGE "Definido o CI PCF8574 como tipo P" ; 0x70 não funciona no simulador*
;* *
;* .EQU f_dds_E = 0x40 ; 0100 0 0 0 r/-w rs -w/r en luz lcd - klvr beep
;* .EQU f_dds_L = 0x41 ; 0100 0 0 0 r/-w
;* .EQU f_vsr_E = 0x42 ; 0100 0 0 1 r/-w
;* .EQU f_vsr_L = 0x43 ; 0100 0 0 1 r/-w
;* .EQU f_lds_E = 0x44 ; 0100 0 1 0 r/-w
;* .EQU f_lds_L = 0x45 ; 0100 0 1 0 r/-w
;* .EQU f_klvr_E = 0x4E ; 0100 1 1 1 r/-w
;* .EQU f_klvr_L = 0x4F ; 0100 1 1 1 r/-w
;*
;* .ELSE
;* .MESSAGE "Definido os endereços do CI PCF8574 como tipo A." ; *
;* .EQU f_dds_E = 0x70 ; 0111 0 0 0 r/-w
;* .EQU f_dds_L = 0x71 ; 0111 0 0 0 r/-w
;* .EQU f_vsr_E = 0x72 ; 0111 0 0 1 r/-w
;* .EQU f_vsr_L = 0x73 ; 0111 0 0 1 r/-w
;* .EQU f_lds_E = 0x74 ; 0111 0 1 0 r/-w
;* .EQU f_lds_L = 0x75 ; 0111 0 1 0 r/-w
;* .EQU f_klvr_E = 0x7E ; 0111 1 1 1 r/-w
;* .EQU f_klvr_L = 0x7F ; 0111 1 1 1 r/-w
;* *
;* .ENDIF
;*;------------------------------------------------------------------------------
;* .IFDEF __CI_8574__
;* .MESSAGE "Ativando as máscaras do CI PCF8574."
;* *
;* .EQU f_mscr_s = 0x08
;* .EQU f_mscr_ack = 0x18
;* .EQU f_mscr_dado = 0x28
;* .EQU f_mscr_limpa = 0xF8
;* .EQU f_mscr_nack = 0xC0
;*
;* .EQU f_mscr_a1 = 0x40
;* .EQU f_mscr_a2 = 0x50
;* .EQU f_mscr_leNA = 0x58
;* *
;* ;.EQU mscr_38 = 0x38 ; para 8 bits
;* ;.EQU mscr_50 = 0x50 ; para 16 bits
;* .EQU f_mscr_sr = 0x10
;* *
;* .EQU f_desligados = 0
;* .EQU f_ligados = 0xFF
;* *
;* .ELSE
;* .MESSAGE "Sem o CI PCF8574."
;* .ENDIF
;******************************************************************************
;
;
;
;************* Inserir no arquivo de variáveis (variavel.inc). ****************
;
;******************************************************************************
;* .IFDEF __CI_8574__
;* .MESSAGE "Alocando as variáveis para o CI 8574-x."
;* *
;* v_8574_endci
;* v_8574_dado
;* *
;* e_er_hw: .BYTE 1 ; klv, vsr, lds, rtr, leit, escr, dds e ---
;* .EQU i_Eklv_tst = 7
;* .EQU i_Eklv_def = 0b10000000 ; 1=erro no teclado
;* .EQU i_Evsr_tst = 6
;* .EQU i_Evsr_def = 0b01000000 ; 1=erro no visor
;* .EQU i_Elds_tst = 5
;* .EQU i_Elds_def = 0b00100000 ; 1=erro do leds
;* .EQU i_Ertr_tst = 4
;* .EQU i_Ertr_def = 0b00010000 ; 1=erro no rtr
;* .EQU i_Edds_tst = 3
;* .EQU i_Edds_def = 0b00001000 ; 1=erro do dds
;* .EQU i_Ele_tst = 2
;* .EQU i_Ele_def = 0b00000100 ; 1=erro de leitura
;* .EQU i_Ees_tst = 1
;* .EQU i_Ees_def = 0b00000010 ; 1=erro de escrita
;* .EQU i_E_tst = 0
;* .EQU i_E_def = 0b00000001 ; 1=erro de
;* *
;* .ELSE
;* .MESSAGE "Sem o CI 8574-x."
;* .ENDIF
;******************************************************************************
;
;
;
;************* Chamadas do TWI. ****************
;
;******************************************************************************
;* ri_twi_verifica
;* re_lcd_rtrd
;* ri_nops
;*
;* re_brrmt_lds_E
;* re_brrmt_klvr_E
;* re_brrmt_dds_E
;* re_brrmt_vsr_E
;*
;* ri_pcf8574_ESC
;* ri_pcf8574_LE
;*
;******************************************************************************
;
;
;
;******************************************************************************
;* Macros de esperas de desocupado.
;******************************************************************************
.IFDEF __CI_8574__
.MESSAGE "Instalando as macros de 1 a 7 para o CI 8574-x."
.MESSAGE "ri_pcf8574_ESC: mcr_twi_ESP_1, mcr_twi_ESP_2 e mcr_twi_ESP_3."
.macro mcr_twi_ESP_1
m_twi_ESPERA1: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA1
.endmacro
;------------------------------------------------------------------------------
.macro mcr_twi_ESP_2
m_twi_ESPERA2: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA2
.endmacro
;------------------------------------------------------------------------------
.macro mcr_twi_ESP_3
m_twi_ESPERA3: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA3
.endmacro
;------------------------------------------------------------------------------
.macro mcr_twi_ESP_4 ; não usado
m_twi_ESPERA4: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA4
.endmacro
;------------------------------------------------------------------------------
.MESSAGE "ri_pcf8574_LE: mcr_twi_ESP_5, mcr_twi_ESP_6 e mcr_twi_ESP_7."
.macro mcr_twi_ESP_5
m_twi_ESPERA5: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA5
.endmacro
;------------------------------------------------------------------------------
.macro mcr_twi_ESP_6
m_twi_ESPERA6: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA6
.endmacro
;------------------------------------------------------------------------------
.macro mcr_twi_ESP_7
m_twi_ESPERA7: nop
in r16,TWCR
sbrs r16,TWINT
rjmp m_twi_ESPERA7
.endmacro
.ELSE
.MESSAGE "Sem as macros de 1 a 7 para o CI 8574-x.""
.ENDIF
;******************************************************************************
;
;
;
;******************************************************************************
.IFDEF __CI_8574__
.MESSAGE "Instalado as macros ini, nack e ack para o CI 8574-x."
.macro mcr_twi_Tini
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_s
brne twi_iniero
.endmacro
.macro mcr_twi_Tack
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_ack
brne twi_ackero
.endmacro
.macro mcr_twi_Tackdad
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_dado
brne twi_ackdero
.endmacro
.macro mcr_twi_Tnack ; não usado
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_nack
brne twi_ackero
.endmacro
.ELSE
.MESSAGE "Sem as macros ini, nack e ack para o CI 8574-x."
.ENDIF
;******************************************************************************
;
;
;
;******************************************************************************
.IFDEF __CI_8574__
.MESSAGE "Instalado as macros Tx para o CI 8574-x."
.macro mcr_twi74_Ts
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_s
brne twi74_s_ero
.endmacro
.macro mcr_twi74_Ta1
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_a1;ck
brne twi74_a1_ero
.endmacro
.macro mcr_twi74_Tna
in r16,TWSR
andi r16,f_mscr_limpa
cpi r16,f_mscr_leNA
brne twi74_na_ero
.endmacro
.ELSE
.MESSAGE "Sem as macros Tx para o CI 8574-x."
.ENDIF
;******************************************************************************
;
;
;
;******************************************************************************
.macro mcr_twi_INICIA
ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWSTA) ;Envia INÍCIO
out TWCR,r16
.endmacro
;******************************************************************************
.macro mcr_twi_CMD
ldi r16,(1<<TWINT)|(1<<TWEN) ; limpa int e habilita
out TWCR,r16
.endmacro
;******************************************************************************
.macro mcr_twi_PARA
ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWSTO) ;Envia PÁRADA
out TWCR,r16
.endmacro
;******************************************************************************
.macro mcr_twi_ACK
ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWEA)
out TWCR,r16
.endmacro
;******************************************************************************
.macro mcr_twi_NACK
ldi r16,(1<<TWINT)|(1<<TWEN)|(0<<TWEA)
out TWCR,r16
.endmacro
;******************************************************************************
.macro mcr_twi_ackcmd
ldi r16,(1<<TWINT)|(1<<TWEN)|(1<<TWEA)
out TWCR,r16
.endmacro
.macro mcr_twi_nackcmd
ldi r16,(1<<TWINT)|(1<<TWEN)|(0<<TWEA)
out TWCR,r16
.endmacro
;******************************************************************************
;
;
;
;******************************************************************************
;* Desenvolvidos para verificação se o barramento 2F esta em uso. *
;* 1 = esta em uso
;* 0 = esta livre
;******************************************************************************
.macro mcr_twi_cntrl
lds r16,e_SITUACAO ; em uso ?
sbrc r16,i_brrm_tst ; se não: executa
ret ; se sim: sai
;
sbr r16,i_brrm_def ; indica em uso
sts e_SITUACAO,r16 ; salva
.endmacro
.macro mcr_twi_limpa
lds r16,e_SITUACAO
cbr r16,i_brrm_def ; habilita para uso, indica que esta livre para uso.
sts e_SITUACAO,r16 ; salva
.endmacro
;******************************************************************************
;
;
;
;******************************************************************************
;* espera 20 vezes o twi responder, para não travar durante a operação.
;* uso: rcall ri_twi_verifica
;* brts erro
;* brtc correto
;******************************************************************************
ri_twi_verifica: push r17
push r16
ldi r17,20
;
twi_vrfc2: nop
dec r17
cpi r17,0
breq twi_vrfc1 ; termina com erro
;
in r16,TWCR
sbrs r16,TWINT
rjmp twi_vrfc2
clt ; correto: t=0
twi_vrfcf: pop r16
pop r17
ret
;
twi_vrfc1: set ; erro: t=1
rjmp twi_vrfcf
;******************************************************************************
;
;
;
;******************************************************************************
;* Configura o CI e define as saídas dos CIs.
;******************************************************************************
re_twi_cnfg: ldi r16,32;f_twi_tempo ; velocidade > 100KHz
out TWBR,r16
ldi r16,0;(1<<TWPS1)|(1<<TWPS0) ; divisor=64=máximo
out TWSR,r16
; mcr_twi_PARA
call re_twi_5ms; re_lcd_rtrd
;
.IFDEF __twi_barramento_LCD__
ldi r16,f_desligados
rcall re_brrmt_vsr_E
; call re_twi_5ms; re_lcd_rtrd
.ENDIF
;
.IFDEF __twi_barramento_LEDs__
ldi r16,f_desligados
rcall re_brrmt_lds_E
; call re_twi_5ms; re_lcd_rtrd
.ENDIF
;
.IFDEF __klavaro_8574__
ldi r16,f_ligados
rcall re_brrmt_klvr_E
; call re_twi_5ms; re_lcd_rtrd
.ENDIF
;
.IFDEF __twi_barramento_DADOs__
ldi r16,f_desligados
rcall re_brrmt_dds_E
; call re_twi_5ms; re_lcd_rtrd
;
.ENDIF
ret
;******************************************************************************
;
;
;
;******************************************************************************
; Entrada: r17 = dado
; Rotinas externas
; Definição do nome da rotina: re_twi_expX_E
; ^^ ^ ^ ^ ^
; || | | | |
; || | | | +- escrita
; || | | +--- número do dispositivo
; || | +------ espansão
; || +---------- dispositivo dois fios
; |+------------ externa
; +------------- rotina
;
; em função da númeração de X é mudado o X de: f_endX8574_E que define o
; enderço do dispositivo na variável v_8574_endci.
;******************************************************************************
; prepara a transmissão
; entrada: r16 o dado a ser escrito
; destroe: r16
; uso: ldi r16,dado
; rcal re_brrmt_klvr_E
; mov r18,r16 ; contador
; mov r16,r17 ; klavo
; ...
;******************************************************************************
.IFDEF __klavaro_8574__
.MESSAGE "Ativando o barramento do teclado via PCF 8574-x."
re_brrmt_klvr_E: sts v_8574_dado,r16
ldi r16,f_klvr_E
sts v_8574_endci,r16
rcall ri_pcf8574_ESC
brts brrt_klv_err
; call re_rtdsw_1ms ; re_lcd_rtrd
ret
;
re_brrmt_klvr_L: ldi r16,f_klvr_L
sts v_8574_endci,r16
rcall ri_pcf8574_LE ; r17 = klavo
brts brrt_klv_err
; call re_rtdsw_1ms ; re_lcd_rtrd
ret
brrt_klv_err: lds r16,e_er_hw
sbr r16,i_Eklv_def
sts e_er_hw,r16
ret
.ELSE
.MESSAGE "Sem o barramento do teclado via PCF 8574-x"
.ENDIF
;******************************************************************************
; prepara a transmissão
; entrada: r16 o dado a ser escrito
; destroe: r16
; uso: ldi r16,xx
; rcall re_brrmt_vsr_E
; ...
;******************************************************************************
.IFDEF __twi_barramento_LCD__
.MESSAGE "Ativando o barramento do LCD via PCF 8574-x."
re_brrmt_vsr_E: sts v_8574_dado,r16
ldi r16,f_vsr_E
sts v_8574_endci,r16
rcall ri_pcf8574_ESC
brts brrt_vsr_err
; call re_rtdsw_1ms
ret
;
brrt_vsr_err: lds r16,e_er_hw
sbr r16,i_Evsr_def
sts e_er_hw,r16
ret
.ELSE
.MESSAGE "Sem o barramento do LCD via PCF 8574-x"
.ENDIF
;******************************************************************************
; prepara a transmissão
; entrada: r16 o dado a ser escrito
; destroe: r16
; uso: ldi r16,xx
; rcalL re_brrmt_lds_E
; ...
; uso: lds r16,e_leds
; ori r16,0b00110000 / andi r16,0b11001111
; rcall re_brrmt_lds_E
;
;******************************************************************************
.IFDEF __twi_barramento_LEDs__
.MESSAGE "Ativando o barramento dos LEDs via PCF 8574-x."
re_brrmt_lds_E: sts e_leds,r16
com r16 ; inverte os bits porque os leds acendem em 0 e penso em 1
sts v_8574_dado,r16
ldi r16,f_lds_E
sts v_8574_endci,r16
rcall ri_pcf8574_ESC
brts brrt_lds_err
; call re_lcd_rtrd
ret
;
brrt_lds_err: lds r16,e_er_hw
sbr r16,i_Elds_def
sts e_er_hw,r16
; rcall re_ruido
ret
.ELSE
.MESSAGE "Sem o barramento dos LEDs via PCF 8574-x"
.ENDIF
;******************************************************************************
;
;
;
;******************************************************************************
; entrada: r16 o dado a ser escrito
; destroe: r16
; uso: ldi r16,xx
; lds r16,e_dds
;
; rcalL re_brrmt_dds_E
; ...
; DO = RS
; D1 = EN
; D2 = LUZ
;******************************************************************************
.IFDEF __twi_barramento_DADOs__
.MESSAGE "Ativando o barramento de dados via PCF 8574-x."
re_brrmt_dds_E: sts e_dds,r16 ; rs, -w/r, en, luz ,- ,- ,- ,beep
sts v_8574_dado,r16
ldi r16,f_dds_E
sts v_8574_endci,r16
rcall ri_pcf8574_ESC
brts brrt_dds_err
; call re_lcd_rtrd
ret
;
brrt_dds_err: lds r16,e_er_hw
sbr r16,i_Edds_def
sts e_er_hw,r16
ret
.ELSE
.MESSAGE "Sem o barramento dos dados via PCF 8574-x"
.ENDIF
;******************************************************************************
;
;
;
;******************************************************************************
.IFDEF __CI_8574__
.MESSAGE "Código para o CI 8574-x."
;******************************************************************************
; descrição: escreve um byte do barramento twi
; término: 04/01/2008
; entrada: v_8574_endci e v_8574_dado
; saída: -
; destroe: r16
; rotina interna
;* macros: mcr_twi_ESP_1, mcr_twi_ESP_2 e mcr_twi_ESP_3.
;
;PCF8574_ESCR: i2c_INICIA
; i2c_ESPERA
;
; lds r16,v_8574_end ; endereço do CI
; out TWDR,r16
; i2c_ESCREVE
; i2c_ESPERA
;
; lds r16,v_8574_dado ; dado
; out TWDR,r16
; i2c_ESCREVE
; i2c_ESPERA
;
; i2c_PARA
; ; i2c_ESPERA
; clt ; t = 0 sem erros
; ret
;******************************************************************************
ri_pcf8574_ESC: ; mcr_twi_cntrl ; indicador de atividade
mcr_twi_INICIA
mcr_twi_ESP_1
mcr_twi_Tini
;
lds r16,v_8574_endci ; endereço do CI + escrita
out TWDR,r16
mcr_twi_CMD
mcr_twi_ESP_2
mcr_twi_Tack
; ;
lds r16,v_8574_dado ; dado
out TWDR,r16
mcr_twi_CMD
mcr_twi_ESP_3
mcr_twi_Tackdad
;
mcr_twi_PARA
; rcall ri_nops
; sem o retardo aqui, não funciona (2ms)
call re_twi_5ms; re_lcd_rtrd ;re_twi_2ms ;re_rtdsw_1ms (com não funciona)
mcr_twi_limpa ; limpa o indicador de atividade
clt ; t = 0 sem erros
ret
;------------------------------------------------------------------------------
ri_nops: ldi r16,22 ; 22 é o mínimo
ri_nops1: nop
wdr
dec r16
cpi r16,0
brne ri_nops1
ret
;------------------------------------------------------------------------------
twi_iniero:
twi_ackero:
twi_ackdero: mcr_twi_PARA
pcf8574e_erro: lds r16,e_er_hw
sbr r16,i_Ees_def
sts e_er_hw,r16
set ; t = 1 com erros
ret
;******************************************************************************
;
;
;
;******************************************************************************
; descrição: lê um byte do barramento twi
; retorna: r17 = dado lido
; entrada: v_8574_endci
; saída: r17
;
;* macros: mcr_twi_ESP_5, mcr_twi_ESP_6 e mcr_twi_ESP_7.
;
; rotina interna
; S endCI+w *A *dado -A P
; * = escravo
; comandos: início, espera, verif 08,
; carrega porta, escrita, espera, verif 40,
; leitura, espera,
; lê porta, ack, espera, verif 38,
; párada
;******************************************************************************
ri_pcf8574_LE: ; mcr_twi_cntrl
mcr_twi_INICIA
mcr_twi_ESP_5
mcr_twi74_Ts
;
lds r16,v_8574_endci ; endereço do CI + leitura
out TWDR,r16
mcr_twi_CMD
mcr_twi_ESP_6
mcr_twi74_Ta1
;
mcr_twi_nackcmd ; sem não lê dado
mcr_twi_ESP_7
mcr_twi74_Tna ; confere: dado tem que ser recibido e ack transmitido = 0x50
;
in r17,TWDR
;
lds r16,v_8574_cnt ; porque repete a leitura das klavoj
inc r16 ; interrupção na borda de subida e na borda de descida
sts v_8574_cnt,r16
cpi r16,1
brne ri_pcf8574_Laa
sts v_8574_var,r17
;
ri_pcf8574_Laa: mcr_twi_PARA
mcr_twi_limpa
clt
ret
;------------------------------------------------------------------------------
twi74_s_ero:
twi74_a1_ero:
twi74_a2_ero:
twi74_na_ero: ; mcr_twi_NACK ; senão duplica cadeia mesma linha
mcr_twi_PARA
lds r16,e_er_hw
sbr r16,i_Ele_def
sts e_er_hw,r16
set
ret
;------------------------------------------------------------------------------
.ELSE
.MESSAGE "Sem código para CI 8574-X."
.ENDIF
;******************************************************************************
.
Nenhum comentário:
Postar um comentário