;**************************************************************************** ;TITLE: Program to store and recover one data word from EEPROM, depending on ; choice of user. ; ;Format of instruction : c aaaa dddd ; where, c is choice : read EEPROM (R) or write EEPROM (W) ; aaaa is EEPROM address ; dddd is data word to be stored (if choice is W) ; ;Crystal frequency : 3.58 MHz. ;Baud rate : 2400 ; ;FUNCTIONS ;********* ;receive : receive 4 digits from comp & pack ;transmit : transmit the 4 packed digits to comp ;hextoasc : converts hex to ascii ;asctohex : converts ascii digit to hex ;rxcomp : receive ascii digit from comp ;txcomp : transmit ascii digit to comp ;epwrite : write a data byte to EEPROM (whole routine) ;ack : get acknowledge from EEPROM ;rxep : receive a byte from EEPROM ;txep : transmit a byte to EEPROM ;epread : receive a data byte from EEPROM, in random read (whole routine) ;**************************************************************************** .include "2313def.inc" .def rtemp = r16 .def treg = r17 ;data (in ASCII) to be transmitted to computer .def rreg = r18 ;data (in ASCII) received from computer .def cnt = r19 ;counter 0 .def cnt1 = r20 ;counter 1 .def datmsb = r21 ;msb of packed data .def datlsb = r22 ;lsb of packed data .def datbyt = r23 ;data received from or transmitted to EEPROM .def choice = r24 .def rtemp1 = r25 .def epaddr1 = r27 ;registers to store higher and lower .def epaddr2 = r26 ; addresses of the EEPROM .cseg .org 0 rjmp RESET RESET: ldi rtemp, $a0 ; initialize stack out SPL, rtemp ldi rtemp,$5A ; Setting baud rate to 2400 at crystal out UBRR,rtemp ; frequency of 3.58 MHz rcall rxcomp ; get choice -- whether to read from or write mov choice,rreg ; to EEPROM cpi choice,$52 ; if choice = R breq nxt2 ; then jump to nxt2 cpi choice,$57 ; else if choice = W breq nxt2 ; then jump to nxt2 rjmp nxt1 ; else jump to nxt1 nxt2: rcall rxcomp ; wait for key press cpi rreg,$20 ; & check if it is space brne nxt2 ldi rtemp1,0 rcall receive ; get memory address from user & mov MSB into mov epaddr1,datmsb ; epaddr1 and LSB into epaddr2 mov epaddr2,datlsb bck: rcall rxcomp ; wait for key press cpi rreg,$20 ; & check if it is space brne bck cpi choice,$52 ; if choice is to read from EEPROM brne nxt rcall epread ; then read a byte from EEPROM rcall transmit ; and transmit it computer. mov rtemp,epaddr2 ; increment lower address & inc epaddr2 ; compensate for roll over rol rtemp ; Note : page size in the EEPROM is brcc nxt3 ; 128 bytes. So separate roll over scheme ori epaddr2,$80 ; reqd. for transition, from 7F to 00 and rjmp nxt4 ; from FF to 80, in the lower address. Hence nxt3: andi epaddr2,$7F ; the check for 8th bit in lower address. nxt4: rcall epread ; read a byte from EEPROM rcall transmit ; and transmit it to computer. rjmp nxt1 nxt: ldi rtemp1,0 ; if choice is to write to EEPROM rcall receive ; then read a byte from computer rcall epwrite ; and store it in EEPROM nxt1: ldi treg,$0a ; leave a line after a command rcall txcomp rjmp RESET ; loop again ;***************************************************************************** ;'receive' ;Aim ; Function to receive 16 bits (4 digits) from comp, using the serial ; port. ;Registers used ; cnt number the loop is to be run. For one run, two digits are ; taken, converted to hex and packed. ; rtemp1 value given to cnt ; rreg register in which packed received hex data present ; datmsb registers in which data bytes are stored and returned to ; datlsb calling function (MSB & LSB) ;Functions called ; rxcomp ; asctohex ;***************************************************************************** receive: mov cnt,rtemp1 rebck: rcall rxcomp ; get one digit from comp rcall asctohex ; convert received data to hex swap rreg ; swap nibbles cpi cnt,0 ; check where to move data (msb(0) or lsb(1)) brne renxt mov datmsb,rreg ; copy rreg to msb rjmp renxt2 renxt: mov datlsb,rreg ; copy rreg to lsb renxt2: rcall rxcomp ; get next digit from comp rcall asctohex cpi cnt,0 ; check if part of lsb or msb brne renxt1 add datmsb,rreg rjmp renxt3 renxt1: add datlsb,rreg renxt3: inc cnt cpi cnt,$01 ; check if 4 digits got breq rebck ret ; go to main if all data received ;**************************************************************************** ;'transmit' ;Aim ; Function to transmit 8 bits (2 digits) to comp, using the serial ; port. ;Registers used ; datbyt contains data received from calling function ; treg contains packed hex data to be transmitted ;Functions called ; txcomp ; hextoasc ;**************************************************************************** transmit: mov treg,datbyt swap treg ; swap nibbles rcall hextoasc ; convert one digit to ASCII rcall txcomp ; and transmit mov treg,datbyt rcall hextoasc ; convert next digit to ASCII rcall txcomp ; and transmit ret ; return if complete data transmitted ;***************************************************************************** ;'hextoasc' ;Aim ; Convert hex to ASCII. Hex value is passed from & ASCII value is passed ; back to calling function in register treg. ;Registers used ; rtemp temporary register ; treg register containing data ;Functions called ; none ;***************************************************************************** hextoasc: andi treg,$0f cpi treg,$0a brsh henxt1 ldi rtemp,$30 rjmp henxt2 henxt1: ldi rtemp,$37 henxt2: add treg,rtemp ret ;***************************************************************************** ;'asctohex' ;Aim ; Convert ASCII to hex. ASCII value to be converted is passed from & hex ; value is passed back to calling function in register rreg. ;Registers used ; rreg register containing data ;Functions called ; none ;***************************************************************************** asctohex: cpi rreg,$40 brsh asnxt subi rreg,$30 rjmp asnxt1 asnxt: subi rreg,$37 asnxt1: ret ;***************************************************************************** ;'rxcomp' ;Aim ; Function to receive data (1 digit) from computer. Value received is ; passed to calling function through register rreg. ;Registers used ; rtemp temporary register ; rreg register containing data received ;Functions called ; none ;***************************************************************************** rxcomp: ldi rtemp, $10 ; enable receiver out UCR,rtemp rxpoll: sbis USR,7 ; poll to check if char received rjmp rxpoll in rreg,UDR ; put received data in rreg ret ;***************************************************************************** ;'txcomp' ;Aim ; Function to transmit data (1 digit) to computer. The value to be ; transmitted is passed from calling function into register treg. ;Registers used ; rtemp temporary register ; treg register containing data to be transmitted ;Functions called ; none ;***************************************************************************** txcomp: ldi rtemp, $08 ; Enable transmitter out UCR,rtemp out UDR,treg txpoll: sbis USR,5 ; Poll to check end of transmission rjmp txpoll ret ;****************************************************************************** ;'epwrite' ;Aim ; Complete function to write a byte into eprom ;Registers used ; datbyt register in which data to be transmitted is stored ; rtemp temporary register ; epaddr1,epaddr2 address registers (msb,lsb) ; datlsb value passed from main ;Functions called ; ack ; txep ;***************************************************************************** epwrite: ldi rtemp, 0b11111111 ; configure B as output port out DDRB,rtemp sbi PORTB,PINB4 ; start bit: set SDA sbi PORTB,PINB5 ; set SCL cbi PORTB,PINB4 ; clear SDA ldi datbyt,0b10100000 ; load device address of EEPROM rcall txep rcall ack mov datbyt,epaddr1 ; load memory location 1 rcall txep rcall ack mov datbyt,epaddr2 ; load memory location 2 rcall txep rcall ack mov datbyt,datmsb ; write first byte to EEPROM rcall txep rcall ack mov datbyt,datlsb ; write second byte to EEPROM rcall txep rcall ack cbi PORTB,PINB4 ; stop bit:clear SDA sbi PORTB,PINB5 ; set SCL sbi PORTB,PINB4 ; set SDA ret ;**************************************************************************** ;'txep' ;Aim ; Function to write a byte to EEPROM. Value to be written is passed from ; calling function in register datbyt ;Registers used ; cnt to store no of bits ; datbyt to store the data ;Functions called ; none ;***************************************************************************** txep: ldi cnt, $08 ; load counter txbck: rol datbyt ; rotate data left through carry cbi PORTB,PINB5 ; clear SCL brcc txnxt ; if carry set sbi PORTB,PINB4 ; set SDA rjmp txnxt1 ; else txnxt: cbi PORTB,PINB4 ; clear SDA txnxt1: sbi PORTB,PINB5 ; set SCL dec cnt ; decrement counter brne txbck ; if counter not zero, go back nop cbi PORTB,PINB5 ; clear SCL ret ;**************************************************************************** ;'ack' ;Aim ; To get the acknowledge signal from the EEPROM ;Registers used ; none ;Functions used ; none ;**************************************************************************** ack: sbi PORTB,PINB5 ; set SCL ldi rtemp,0b11101111 ; configure pinb4 as input out DDRB,rtemp acbck: sbic PINB,PINB4 ; goto calling function if SDA clear rjmp acbck ; else go back to ack cbi PORTB,PINB5 ; clear SCL ldi rtemp,0b11111111 ; configure portb as output out DDRB,rtemp ret ;****************************************************************************** ;'rxep' ;Aim ; Function to read a byte from EEPROM. Value read is returned in ; register datbyt ;Registers used ; cnt to store no of bits ; datbyt to store the data read ;Functions called ; none ;***************************************************************************** rxep: ldi rtemp, 0b11101111 ; configure PB4 as input out DDRB,rtemp sbi PORTB,PINB4 ldi cnt,$08 ; load counter ldi datbyt, 0 rxbck: sbi PORTB,PINB5 ; set SCL sbic PINB,PINB4 ; if SDA set then sec ; set carry sbis PINB,PINB4 ; else clc ; clear carry rol datbyt ; rotate data received from EEPROM left cbi PORTB,PINB5 ; clear SCL dec cnt ; decrement counter brne rxbck ; if counter equals zero, goto main ret ; else jump back ;****************************************************************************** ;'epread' ;Aim ; Complete function to read a byte from EEPROM. ;Registers used ; datbyt register in which data read is stored ; rtemp temporary register ; epaddr1,epaddr2 address registers (msb,lsb) ;Functions called ; ack ; txep ; rxep ;***************************************************************************** epread: ldi rtemp, 0b11111111 ; configure B as output port out DDRB,rtemp sbi PORTB,PINB4 ; start bit: set SDA sbi PORTB,PINB5 ; set SCL cbi PORTB,PINB4 ; clear SDA ldi datbyt,0b10100000 ; load device address rcall txep rcall ack mov datbyt,epaddr1 ; load memory location 1 rcall txep rcall ack mov datbyt,epaddr2 ; load memory location 2 rcall txep rcall ack sbi PORTB,PINB4 ; start bit: set SDA sbi PORTB,PINB5 ; set SCL cbi PORTB,PINB4 ; clear SDA ldi datbyt,0b10100001 ; load device address rcall txep rcall ack rcall rxep ; read data from EEPROM sbi PORTB,PINB5 ; give clock pulse: set SCL nop cbi PORTB,PINB5 ; clear SCL ldi rtemp, 0b11111111 ; configure B as output port out DDRB,rtemp cbi PORTB,PINB4 ; stop bit: clear SDA sbi PORTB,PINB5 ; set SCL sbi PORTB,PINB4 ; set SDA ret ;******************************************************************************