please dont rip this site

PIC Microcontoller DRAM Memory Method

COMMON.H

#define PORTBIT(port, bit) ((unsigned)&(port)*8+(bit)) #define TESTBIT(var, bit) ((var) & (1 <<(bit))) #define SETBIT(var, bit) ((var) |= (1 << (bit))) #define CLRBIT(var, bit) ((var) &= ~(1 << (bit))) DRAM.C
#include <pic.h>
#include <common.h>

// dram.c -- adapted from dram.src in parallax assembly by Craig Lee

// Upon power up or reset, this program starts sampling pin ra.0 and 
// recording its state in sequential addresses of a 1Mb dynamic RAM. 
// When the DRAM is full, the program plays back the recorded bits
// in a continuous loop. 


//Sin   =     ra.0    ; Signal generator input
//RAS   =     ra.1    ; DRAM row-address strobe
//WR    =     ra.2    ; DRAM write line (0 = write)
//Dout  =     ra.3    ; DRAM data line
//CAS   =     rc.3    ; DRAM column-address strobe
//adrb_lo       =     rb      ; Low bits of address bus
//adrb_hi       =     rc      ; High bits of address bus
//Din   =     rc.2    ; DRAM Q line
//Sout  =     rc.5    ; Signal out to speaker

#define Sin             RA0   // Signal generator input
#define RAS             RA1     // DRAM row-address strobe
#define WR              RA2   // DRAM write line (0 = write)
#define Dout            RA3   // DRAM data line
#define CAS             RC3   // DRAM column-address strobe
#define adrb_lo PORTB // Low bits of address bus
#define adrb_hi PORTC // High bits of address bus
#define Din                     RC2   // DRAM Q line
#define Sout            RC5   // Signal out to speaker


#define BYTE unsigned char
#define WORD unsigned int

//; Put variable storage above special-purpose registers. 
//      org     8

//r_ctr ds      1       ; Refresh counter
//row_lo        ds      1       ; Eight LSBs of row address
//row_hi        ds      1       ; Two MSBs of row address
//col_lo        ds      1       ; Eight LSBs of column address
//col_hi        ds      1       ; Two MSBs of column address
//flags ds      1       ; Holder for bit variable flag
//flag  =     flags.0 ; Overflow flag for 20-bit address

BYTE r_ctr;             // Refresh counter
BYTE row_lo;    // Eight LSBs of row address
BYTE row_hi;    // Two MSBs of row address
BYTE col_lo;    // Eight LSBs of column address
BYTE col_hi;    // Two MSBs of column address
bit flag;               // Overflow flag for 20-bit address

//; Remember to change device info when programming part. 
//      device  pic16c55,xt_osc,wdt_off,protect_off
//      reset   start

//; Set starting point in program ROM to zero
//      org     0



//start setb    RAS     ; Disable RAS and CAS before
//      setb    CAS     ; setting ports to output.
//      mov     !ra,#1  ; Make ra.0 (Sin) an input.
//      mov     !rb,#0  ; Make rb (low addresses) output. 
//      mov     !rc,#00000100b  ; Make rc.2 (Din) an input. 
//      clr     flags   ; Clear the variables. 
//      clr     row_lo
//      clr     row_hi
//      clr     col_lo
//      clr     col_hi
//      call    refresh ; Initialize DRAM. 

void init(void);
void record(void);
void play(void);
void refresh(void);
void write(void);
void read(void);
void inc_xy(void);


void
init(void)
{
        RAS = 1;                      // Disable RAS and CAS before
   CAS = 1;                           // setting ports to output.

        TRISA = 0xFF;                 // set RA0 as input
        TRISB = 0x00;         // set address bus LSB as output
        TRISC = 0x04;         // set Din as input

        flag  = 0;                    // clear flag

        row_lo = 0;                   // clear temp row address
        row_hi = 0;                   //
        col_lo = 0;                   // clear temp column address
        col_hi = 0;                   //
}


void
main(void)
{
        init();

        record();

        while(1)
        {
                play();
        }
}


//:record       call    refresh ; Refresh the DRAM. 
//      call    write   ; Write Sin bit to DRAM. 
//      call    inc_xy  ; Increment row and col addresses.
//      jnb     flag,:record    ; Repeat until address overflows. 

void
record(void)
{
        while(!flag)
        {
                refresh();
                write();
                inc_xy();
        }
}

//:play call    refresh ; Refresh the DRAM. 
//      call    read    ; Retrieve bit and write to Sout)
//      call    inc_xy  ; Increment row and col addresses.
//      goto    :play   ; Loop until reset. 

void
play(void)
{
        refresh();
        read();
        inc_xy();
}

//write mov     adrb_lo,row_lo  ; Put LSBs of row addr onto bus (rb). 
//      AND     adrb_hi,#11111100b      ; Clear bits adrb_hi.0 and .1.
//      OR      adrb_hi,row_hi  ; Put MSBs of row addr onto bus (rc). 
//      clrb    RAS     ; Strobe in the row address. 
//      movb    Dout,Sin        ; Supply the input bit to the DRAM,
//      movb    Sout,Sin        ; and echo it to the speaker. 
//      mov     adrb_lo,col_lo  ; Put LSBs of col addr onto bus (rb). 
//      AND     adrb_hi,#11111100b      ; Clear bits adrb_hi.0 and .1.
//      OR      adrb_hi,col_hi  ; Put MSBs of col addr onto bus (rc). 
//      clrb    WR      ; Set up to write. 
//      clrb    CAS     ; Strobe in the column address.
//      setb    WR      ; Conclude the transaction by 
//      setb    RAS     ; restoring WR, RAS, and CAS high
//      setb    CAS     ; (inactive). 
//      ret

void
write(void)
{
        adrb_lo = row_lo;                             // put lsb of row address and
        adrb_hi = row_hi | 0xFC;      // the 2 msb bits to the bus
        RAS = 0;                                                      // strobe the row address

        Dout = Sin;                                           // put the current bit to the dram
        Sout = Sin;                                           // and echo it

        adrb_lo = col_lo;                             // put lsb of column address and
        adrb_hi = col_hi | 0xFC;      // the 2 msb bits to the bus

        WR = 0;                                                       // set to write

        CAS = 0;                                                      // strobe in the column address

        WR = 1;                                                       // restore to complete write
        RAS = 1;
        CAS = 1;
}


//read  mov     adrb_lo,row_lo  ; Put LSBs of row addr onto bus (rb). 
//      AND     adrb_hi,#11111100b      ; Clear bits adrb_hi.0 and .1.
//      OR      adrb_hi,row_hi  ; Put MSBs of row addr onto bus (rc). 
//      clrb    RAS     ; Strobe in the row address. 
//      mov     adrb_lo,col_lo  ; Put LSBs of col addr onto bus (rb). 
//      AND     adrb_hi,#11111100b      ; Clear bits adrb_hi.0 and .1.
//      OR      adrb_hi,col_hi  ; Put MSBs of col addr onto bus (rc). 
//      clrb    CAS     ; Strobe in the column address.
//      movb    Sout,Din        ; Copy the DRAM data to the speaker. 
//      setb    RAS     ; Conclude the transaction by restoring 
//      setb    CAS     ; RAS and CAS high (inactive). 
//      ret

void
read(void)
{
        adrb_lo = row_lo;                             // put lsb of row address and
        adrb_hi = row_hi | 0xFC;      // the 2 msb bits to the bus
        RAS = 0;                                                      // strobe the row address

        adrb_lo = col_lo;                             // put lsb of column address and
        adrb_hi = col_hi | 0xFC;      // the 2 msb bits to the bus
        CAS = 0;                                                      // strobe in the column address

        Din = Sout;                                           // put the current bit to the dram
        Sout = Sin;                                           // and echo it

        RAS = 1;                                                      // restore to complete read
        CAS = 1;
}


// This routine implements a CAS-before-RAS refresh. The DRAM has an onboard
// counter to keep track of row addresses, so the status of the external 
// address bus doesn't matter. The DRAM requires 512 row addresses be refreshed
// each 8 ms, so this routine must be called once every 125 microseconds. 
// Changing the initial value moved into r_ctr will alter the refresh schedule. 
// For example, to refresh the entire DRAM, move #0 into r_ctr (256 loops) and 
// call the routine twice in a row (512). 

//refresh       mov     r_ctr,#8
//:loop clrb    CAS     ; Activate column strobe. 
//      clrb    RAS     ; Activate row strobe. 
//      setb    CAS     ; Deactivate column strobe. 
//      setb    RAS     ; Deactivate row strobe. 
//      djnz    r_ctr,:loop     ; Repeat. 
//      ret

void
refresh(void)
{
        char i;

        i = 8;

        while(i)
        {
                CAS = 0;              // toggle em!
                RAS = 0;
                CAS = 1;
                RAS = 1;

                i--;
        }
}

// This routine increments a 20-bit number representing the 1,048,576 addresses
// of the DRAM. For convenience, the number is broken into two 10-bit numbers, 
// which are each stored in a pair of byte variables. Note that wherever the 
// routine relies on the carry bit to indicate a byte overflow, it uses 
// the syntax "add variable,#1" not "inc variable." Inc does not set or clear 
// the carry flag. 

//inc_xy        add     row_lo,#1       ; Add 1 to eight LSBs of row addr. 
//      sc              ; If carry, add 1 to MSB, else return. 
//      ret     	
//      inc     row_hi  ; Increment MSBs of row address. 
//      sb      row_hi.2        ; If we've overflowed 10 bits, clear 
//      ret             ; row_ hi and add 1 to column 
//      clr     row_hi  ; address, else return. 
//      add     col_lo,#1
//      sc              ; If carry, add 1 to MSB, else return. 
//      ret
//      inc     col_hi  ; Increment MSBs of col address. 
//      sb      col_hi.2        ; If we've overflowed 10 bits, clear 
//      ret             ; col_ hi and set the flag to signal
//      clr     col_hi  ; main program that we've reached the 
//      setb    flag    ; end of available memory, then return. 
//      ret

void
inc_xy(void)
{
        row_lo++;               //increment lsb of address

        if(CARRY)               //if carry, add one to msb
        {
                row_hi++;
        }

        if(TESTBIT(row_hi,2))   //overflowed the 10 bit address?
        {
                row_hi = 0;   //clear
                col_lo++;       //next column

                if(CARRY)
                {
                        col_hi++;
                }

                if(TESTBIT(col_hi,2))
                {
                        col_hi = 0;
                        flag = 1;
                }
        }
}


file: /Techref/microchip/dram_c.htm, 10KB, , updated: 2005/2/11 12:00, local time: 2024/11/26 18:06,
TOP NEW HELP FIND: 
3.148.108.192:LOG IN

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://techref.massmind.org/Techref/microchip/dram_c.htm"> PIC Microcontoller DRAM&nbsp;Memory Method</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 

Welcome to massmind.org!

 

Welcome to techref.massmind.org!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .