16F628A a paměť 24C16A - kde dělám chybu?

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Jirka
Příspěvky: 2034
Registrován: 01 črc 2005, 00:00
Bydliště: zbídačený kraj
Kontaktovat uživatele:

16F628A a paměť 24C16A - kde dělám chybu?

#1 Příspěvek od Jirka »

Zdravím,
snažím se připojit paměť Atmel 24C16A k PIC 16F628A, abych do ní mohl ukládat nápisy na displej. Nefunguje mi ale I2C komunikace. Rutinu pro I2C jsem použil od tmm http://www.ebastlirna.cz/modules.php?na ... 686#222686 , ale něco dělám špatně.

Můžete se někdo na to kouknout a vysvětlit mi, kde dělám chybu.

PIC16F628, vnitřní osc 4,00MHz, 24C16A na RA1-0, pull-up odpory 10k na SDA a SCL. Snažím se pro začátek jen zapisovat a číst první byte v paměti.

Kód: Vybrat vše

; PIC16F628, vnitřní osc 4,00MHz, 24C16A na RA1-0, pull-up odpory 10k na SDA a SCL
;
;**************************************************************************
;*                                  PIC16F628                             *
;*                             --------\/--------                         *
;*                            -|RA2          RA1|-  SCL                   *
;*                            -|RA3          RA0|-  SDA                   *
;*                            -|RA4ck       osc1|-                        *
;*                            -|MCLR        osc2|-                        *
;*                        0V  -|Vss          Vdd|-  +5V                   *
;*                    LCD RS  -|RB0/INT  PGD/RB7|-  LCD data bit 7        *
;*                            -|RB1      PGC/RB6|-  LCD data bit 6        *
;*                            -|RB2          RB5|-  LCD data bit 5        *
;*                    LCD E   -|RB3          RB4|-  LCD data bit 4        *
;*                             ------------------                         *
;*                                                                        *
;**************************************************************************

   list   p=16f628A, R=DEC
   include   "p16f628A.inc"

   org   0x2007      ; adresa konfigurace PIC16F627 a 628
   dw _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT

;- Proměnné ----------------------------------------------------
;
RAM      equ   20h
TMP0      equ   RAM+4   ; cekaci smycka
TMP1      equ   RAM+5   ; cekaci smycka
TMP2      equ   RAM+6   ; cekaci smycka
TMP3      equ   RAM+7   ; cekaci smycka
ADRESA      equ   RAM+8   ; inicializace cestiny, adresa pro misto znaku
ZNAK      equ   RAM+9   ; zobrazeni znaku na LCD

EVAL      equ   70h
EADR      equ   71h   ; Adresa v EEPROM při čtení
EBYTE      equ   72h
rot      equ   73h   ; rotace bytu
EE_ADR      equ   7Eh   ; !!! 70h - 7Fh pro vsechny banky !!!

#define   E   PORTB,3      ; E  - LCD displej
#define   RS   PORTB,0      ; RS - LCD displej
#define   SDA   PORTA,0      ; I2C data
#define   SCL   PORTA,1      ; I2C Hodiny
#define SDADIR   TRISA,0
#define SCLDIR   TRISA,1

;
;************************ Nastavení dat v EEPROM **************************
;
   org   0x2100      ; tabulka v pameti EEPROM (128 bytu)

/// tady  mám české znaky pro LCD

;
;---------------------------------------------------------------
;
   org   0x0000      ; zacatek programu
   goto   INIT      ; skok na počáteční inicalizaci
;
;- Nastavení V/V -----------------------------------------------
;
INIT   movlw   b'00000111'   ; digitalni vstupy na PORTu A (PIC16F627 a 628)
   movwf   CMCON
   bsf   STATUS,RP0   ; přesun do banky 1
   movlw   b'00000011'   ; RA7-2 výstupy RA1-0 vstup
   movwf   TRISA
   movlw   b'00000000'   ; RB7-0 výstupy
   movwf   TRISB
   bcf   STATUS,RP0   ; přesun zpět do banky 0
   movlw   b'00000011'
   movwf   PORTA
   movlw   b'00000000'
   movwf   PORTB

   call   INI_LCD      ; inicializace LCD
   call   CESTINA

   clrf   EVAL
;
;- Vlastní program ---------------------------------------------

HLAVNI   call   DISPLEJ1   ; zobrazení textu a znaku v registru EVAL - b'00000000'
   call   CEK2s
   call   @eeprom_read   ; na zkoušku přečtu hodnotu v prázDné EEPROM
   call   DISPLEJ1   ; zobrazení textu a znaku v registru EVAL (FF)
   call   CEK2s
   call   @eeprom_write   ; chci zapsat na 1. pozici - b'00100100' (na dipleji to je $)
   call   CEK100m
   call   @eeprom_read   ; chci přečíst 1. pozici v paměti - b'00100100' (na dipleji to je $)
   call   DISPLEJ1   ; zobrazení textu a znaku v registru EVAL
   call   CEK2s
   goto   HLAVNI      ; znovu, ikdyž bude v EVAL stále - b'00100100' (na dipleji to je $)

;**************************************************************************
; PODPROGRAM eeprom_read
; Přečte EEPROM na zadané adrese a hodnotu uloží do registru EVAL
;
; Vstupní registry:
;   EADR - adresa
;
; Výstupní registry:
;   EVAL - hodnota
;
; -------------------------------------------------------------
@eeprom_read 
        CALL    @i2c_start

        ; Device Address
        MOVLW   B'10100000'
        CALL    @i2c_write

        ; Word Address
        MOVLW   H'00'
        CALL    @i2c_write

        CALL    @i2c_start

        ; Device Address
        MOVLW   B'10100001'
        CALL    @i2c_write

        CALL    @i2c_read
        MOVF    EBYTE,W
        MOVWF   EVAL

        CALL    @i2c_stop

        RETURN

; -------------------------------------------------------------
; PODPROGRAM eeprom_write
; -------------------------------------------------------------
@eeprom_write
        CALL    @i2c_start

        ; Device Address
        MOVLW   B'10100000'
        CALL    @i2c_write

        ; Word Address
        MOVLW   H'00'
        CALL    @i2c_write

        ; Zápis dat do EEPROM
        MOVLW   b'00100100'
        CALL    @i2c_write

        CALL    @i2c_stop

        RETURN
; -------------------------------------------------------------
; I2C
; -------------------------------------------------------------
@i2c_read
        MOVLW   8
        MOVWF   rot             ; Počet rotací

        BSF     STATUS,RP0     
        BSF     SDADIR          ; SDA vstup
        BCF     STATUS,RP0
   
i2c_read_rot
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us

        BCF     STATUS,C        ; Vynulujeme C
        BTFSC   SDA             ; Otestujeme SDA
        BSF     STATUS,C        ; Pokud SDA == 1, nastavíme C

        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0

        RLF     EBYTE,1         ; Rotace EBYTE přes C doleva
        DECFSZ  rot,1
        GOTO    i2c_read_rot    ; Cyklus
       

        CALL    @delay_10us     ; Pauza cca 10us

        BCF     SDA             ; SDA = 0
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA výstup
        BCF     STATUS,RP0

        RETURN

@i2c_send_ack
        BCF     SDA             ; SDA = 0
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0

        RETURN

@i2c_write
        MOVWF   EBYTE           ; W do EBYTE
        MOVLW   8           
        MOVWF   rot             ; Počet rotací
i2c_write_rot
        RLF     EBYTE,1         ; Rotace EBYTE o 1 bit doleva přes C

        BTFSS   STATUS,C        ; Otestujeme C a nastavíme SDA
        GOTO    $+3
        BSF     SDA             ; SDA = 1
        GOTO    $+2
        BCF     SDA             ; SDA = 0

        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0;

        DECFSZ  rot,1           
        GOTO    i2c_write_rot   ; Cyklus
       
        CALL    @delay_10us     ; Pauza cca 10us
        CALL    @i2c_ack        ; ACK

        RETURN

@i2c_start
        BSF     SDA             ; SDA = 1
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA výstup
        BCF     STATUS,RP0
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SDA             ; SDA = 0
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SCL             ; SCL = 0
        RETURN

@i2c_stop
        CALL    @delay_10us     ; Pauza cca 10us
        BCF     SDA             ; SDA = 0
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SDA             ; SDA = 1
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA vstup
        BCF     STATUS,RP0
        RETURN

@i2c_ack
        BSF     STATUS,RP0     
        BSF     SDADIR          ; SDA vstup
        BCF     STATUS,RP0
        CALL    @delay_10us     ; Pauza cca 10us
        BSF     SCL             ; SCL = 1

        CALL    @delay_10us     ; Pauza cca 10us
        BTFSC   SDA
        GOTO    $-1
        CALL    @delay_10us     ; Pauza cca 10us

        BCF     SCL             ; SCL = 0
        CALL    @delay_10us     ; Pauza cca 10us

        BCF     SDA             
        BSF     STATUS,RP0
        BCF     SDADIR          ; SDA výstup
        BCF     STATUS,RP0
        RETURN

@delay_10us
        GOTO    $+1
        GOTO    $+1
        RETURN
;**************************************************************************
;**************************************************************************
; čtení z EEPROM v PIC

/// čtu české znaky

;**************************************************************************
; obsluha LCD

/// rutiny pro LCD

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

/// čekací smyčky

;**************************************************************************
   END         ;konec programu
*****
Uživatelský avatar
Atlan
Příspěvky: 4514
Registrován: 10 kvě 2004, 00:00
Bydliště: Košice

#2 Příspěvek od Atlan »

Hmm na zaciatok skus...citat namiesto zapisu :D
tj naprogrammuj niekde tu eeprom a skuz ju nacitat.

A skus upravit iniciaizaciu ako je napisane vo vlakne odkial si skopiroval zdrojak :)
Naposledy upravil(a) Atlan dne 04 kvě 2009, 16:25, celkem upraveno 2 x.
Jirka
Příspěvky: 2034
Registrován: 01 črc 2005, 00:00
Bydliště: zbídačený kraj
Kontaktovat uživatele:

#3 Příspěvek od Jirka »

Ale tady bych měl přečíst něco z pamětí a zobrazit na displeji, nebo ne?

Kód: Vybrat vše

HLAVNI   call   DISPLEJ1   ; zobrazení textu a znaku v registru EVAL - b'00000000'
   call   CEK2s
   call   @eeprom_read   ; na zkoušku přečtu hodnotu v prázDné EEPROM
   call   DISPLEJ1   ; zobrazení textu a znaku v registru EVAL (FF)
   call   CEK2s


- vypíšu nápis s nulovou hodnotou v EVAL
- počkám 2s, abych to viděl
- chci číst eeprom, ikdyž je prázdná, zak něco načíst musí
- chci to zobrazit to na 2 vteřiny, ale hodnota v EVAL se mi nezměnila!!
...
- pak se teprve začínám pouštět do zápisu a následného čtení mnou zapsané hodnoty
*****
Uživatelský avatar
Atlan
Příspěvky: 4514
Registrován: 10 kvě 2004, 00:00
Bydliště: Košice

#4 Příspěvek od Atlan »

nechapem ..ale v eprom je zapisana 0 teorwticky...a nacitas 0 pricom predtym bola nuula.v EVAL .aku zmenu chces vidiet ? :)


tak ze najprv skus EVAL at na nejake cislo napr 5 a po precitani eprom tam bude 0
Jirka
Příspěvky: 2034
Registrován: 01 črc 2005, 00:00
Bydliště: zbídačený kraj
Kontaktovat uživatele:

#5 Příspěvek od Jirka »

A sakra. Domníval jsem se, že v EEPROM bude FF

A inicializaci? Myslel jsi tohle?
Este takato vec.... najprv prednastav porty na log1 a az potom ich zadefinuj ako i/o....... tj najprv bsf portA,0 a az potom bsf alebo bcf TRISA,0.
Lebo pri zapniti pic su i/o v vysokej impedancii.... aby si nahodou nespustil starrt impulz ani nevieš ako ....Smile
*****
Uživatelský avatar
Atlan
Příspěvky: 4514
Registrován: 10 kvě 2004, 00:00
Bydliště: Košice

#6 Příspěvek od Atlan »

Ano pre istotu :D nič badaj neboj prides na to :)

Ale nejde mi to do hlavy, zdrojak je oskusany, nieje chyba v zapojeni ? :)

Adresy eproom a1, a2 ,a3 uzemnene ? :)
Stan3

#7 Příspěvek od Stan3 »

Zkus to (čtení)upravit:

exp equ xxh
.......................................
movlw 08h
movwf rot
movlw 01h
movwf exp
clrf ebyte
......................................
bsf STATUS,RP0
bsf SDADIR
bcf STATUS,RP0
.......................................
opak call delay10
bsf SCL
call delay10
btfss SDA
goto SDA_0
movf exp,w
addwf ebyte
SDA_0 bcf SCL
bcf STATUS,C
rlf exp,F
decfsz rot,F
goto opak
Jirka
Příspěvky: 2034
Registrován: 01 črc 2005, 00:00
Bydliště: zbídačený kraj
Kontaktovat uživatele:

#8 Příspěvek od Jirka »

Vyměnil jsem rutinu za jinou, 1 byte zapíšu i přečtu. Více jsem nezkoušel, nebyl čas, ale mělo by to jít.

datasheet 24C16A - The A0, A1 and A2 pins are no connects. Uzemněný je stejně mám včetně WP.
Ještě, až bude čas, zkusím tu úpravu od Stan3 a dám vědět.
*****
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“