?? i2c_eemem.s43
字號:
#include "msp430x11x1.h"; Standard Definitions File
;******************************************************************************
; MSP430x11x1 to 24LC04 EEPROM via I2C communications
; Program name -- I2C_EEmem.S43
;
; Description: This program demonstrates I2C communication with a 24LC04
; EEPROM. Random reads or writes to the 512 EEPROM bytes (000 - 1FF hex) is
; implemented.
; The program prompts for a read or write operation and address using a
; terminal interface program running on a personal computer. This program is
; written to communicate at 9600 baud using 8N1 protocol.
;
;
; /|\ /|\ /|\
; | 24LC04 10k 10k MSP430 PC
; | |-------| | | |----------| |-----------------
; ---|Vcc SDA|<-|---+>|P2.0 P2.2|<----|TXD (to MSP430)
; ---|Vss SCL|<-+-----|P2.1 P1.1|---->|RXD (from MSP430)
; \|/ ------- | | |
;
;
;-----------RAM memory used for variables---------------------------------------
RXTXData equ 200h ; Word for RX and TX UART Data
RXTXI2C equ 202h ; Byte for RX and TX I2C Data
DataConv equ 203h ; Byte for I2C -> ASCII conversion
ADDRI2C equ 204h ; Byte for EEPROM address
DATAI2C equ 205h ; Byte for EEPROM data
BITI2C equ 206h ; Byte for I2C bit counting
ScndBlck equ 207h ; Byte used as flag for addresses > 0FF hex, when
; added to control byte, addresses 2nd memory block
;-----------CPU registers used--------------------------------------------------
#define BitCnt R5
; Used to count UART bits. Register used
; due to use of indirect autoincrement mode
;;; R11
; String pointer. Register used due to use of
; indirect autoincrement mode
;-----------Definitions for I2C bus---------------------------------------------
SDA equ 001h ; P2.0 controls SDA line (pull-up used for logic 1)
SCL equ 002h ; P2.1 controls SCL line (pull-up used for logic 1)
Code equ 0A0h ; EE memory control code = 1010 = upper nibble
;-----------Definitions for 9600 Baud HW/SW UART, MCLK= 37.5x32768= 1228800-----
Bitime_5 equ 0064 ; 0.5 bit length - one half of time between bits
Bitime equ 0128 ; 104 us - timing between bits
Delta equ 150 ; Delta = (target DCO)/(32768/4), used for DCO cal'
RXD set 004h ; RXD on I/O pin P2.2
TXD set 002h ; TXD on I/O pin P1.1
LF equ 0ah ; ASCII Line Feed
CR equ 0dh ; ASCII Carriage Return
;*******************************************************************************
RSEG CSTACK ; System stack
DS 0
;-------------------------------------------------------------------------------
RSEG CODE ; Program code
RESET mov #SFE(CSTACK),SP ; Initialize stackpointer to top of RAM
call #Init_Sys ; Initialize system
mov #String0,R11 ; R11 pointer = to initial instruction
; string, only used once
call #TX_String ; Transmit string to PC
Mainloop mov #String1,R11 ; R11 Pointer = to user prompt
call #TX_String ; Transmit string to PC
call #RX ; Receive 'r' or 'w' (read or write)
cmp.b #'w',RXTXData ; w? (write), read is default
push SR ; Save test result for use below
mov #String2,R11 ; R11 Pointer = to string "000-1FF"
call #TX_String ; Transmit string to PC
call #Get3digits ; Get 3 byte address
mov.b RXTXData,ADDRI2C ; ADDRI2C=EEPROM address
pop SR ; SR from 'w' test above
jeq Write_ ; jump if = 'w'
Read_ mov #String5,R11 ; R11 Pointer = to "= "
call #TX_String ; Transmit string to PC
call #Read_I2C ; Read data from address
mov.b RXTXI2C,DataConv ; Move data for ASCII conversion
call #TX_Byte_ASCII ; Routine to convert and send data to PC
jmp Mainloop ; Loop again
Write_ mov #String4,R11 ; R11 pointer = to "w?"
call #TX_String ; Transmit string to PC
call #Get2digits ; Read 2 data digits from PC
mov.b RXTXData,DATAI2C ; Data from PC -> I2C for TX
call #Write_I2C ; Write data to EEPROM via I2C
jmp Mainloop ; Loop again
;-------------------------------------------------------------------------------
; Start of subroutines to communicate with EEPROM via I2C
;-------------------------------------------------------------------------------
Read_I2C; Routine to set up for and read one byte of EEPROM memory
; input = address (000-1ff) output = data (00-ff)
;-------------------------------------------------------------------------------
mov.b #Code,RXTXI2C ; Load device code for TX
add.b ScndBlck,RXTXI2C ; Set bit to indicate if addr > 0ff hex
call #I2C_Start ; Send start, control byte and ack
mov.b ADDRI2C,RXTXI2C ; Load address for TX
call #I2C_TX ; Send address and ack
mov.b #Code,RXTXI2C ; Load device code for TX
add.b ScndBlck,RXTXI2C ; Set bit to indicate if addr > 0ff hex
bis.b #01h,RXTXI2C ; Set bit to indicate a read operation
call #I2C_Start ; Send start, control byte and ack
call #I2C_Read ; Read 8 bits of data and send ack
call #I2C_Stop ; Send Stop
ret
;-------------------------------------------------------------------------------
I2C_Start; Set up start condition for I2C
;-------------------------------------------------------------------------------
bic.b #SCL+SDA,&P2DIR ; SCL and SDA set to inputs, signals
; go high due to pull-up resistors
bis.b #SDA,&P2DIR ; Set to output, data low so SDA = 0
bis.b #SCL,&P2DIR ; Set to output, data low so SCL = 0
;-------------------------------------------------------------------------------
I2C_TX; Transmit 8 bits of I2C data
;-------------------------------------------------------------------------------
mov.b #08,BITI2C ; Load I2C bit counter
I2C_Send rla.b RXTXI2C ; Move data bit -> carry
jc I2C_Send1 ; Jump if bit high
I2C_Send0 bis.b #SDA,&P2DIR ; Set to output, data low so SDA = 0
jmp I2C_Sx ; Jump over next instruction
I2C_Send1 bic.b #SDA,&P2DIR ; Set to input, SDA = 1 due to pull-up
I2C_Sx bic.b #SCL,&P2DIR ; Set to input, SDL = 1 due to pull-up
nop ; delay to meet I2C spec
nop ; " " "
bis.b #SCL,&P2DIR ; Set to output, data low so SCL = 0
dec.b BITI2C ; Decrement I2C bit counter
jnz I2C_Send ; Loop until 8 bits are sent
bic.b #SDA,&P2DIR ; Set to input, SDA = 1 due to pull-up
;-------------------------------------------------------------------------------
I2C_Ackn; Set up for I2C acknowledge but is not actually tested. It is assumed
; that the EEPROM does send it.
;-------------------------------------------------------------------------------
bic.b #SCL,&P2DIR ; Set to input, SDL = 1 due to pull-up
nop ; delay to meet I2C spec
nop ; " " "
bis.b #SCL,&P2DIR ; Set to output, data low so SCL = 0
ret ; Return from subroutine
;-------------------------------------------------------------------------------
I2C_Read; Read 8 bits of I2C data
;-------------------------------------------------------------------------------
mov.b #08,BITI2C ; Load I2C bit counter
I2C_RX bic.b #SCL,&P2DIR ; Set to input, SDL = 1 due to pull-up
bit.b #SDA,&P2IN ; Test SDA state, status -> carry bit
rlc.b RXTXI2C ; Carry shifted into LSBit
bis.b #SCL,&P2DIR ; Set to output, data low so SCL = 0
dec.b BITI2C ; Decrement I2C bit counter
jnz I2C_RX ; Loop until 8 bits are read
jmp I2C_Ackn ; Jump to send ack
;-------------------------------------------------------------------------------
I2C_Stop; Send I2C stop command
;-------------------------------------------------------------------------------
bis.b #SDA,&P2DIR ; Set to output, data low so SCA = 0
bic.b #SCL,&P2DIR ; Set to input, SDL = 1 due to pull-up
bic.b #SDA,&P2DIR ; Set to input, SDA = 1 due to pull-up
I2C_End ret
;-------------------------------------------------------------------------------
Write_I2C; Routine to set up for and write one byte of EEPROM memory
; inputs = address (000-1ff) & data (00-ff)
;-------------------------------------------------------------------------------
mov.b #Code,RXTXI2C ; Load device code for TX
add.b ScndBlck,RXTXI2C ; Sets bit to indicate if addr > 0ff hex
call #I2C_Start ; Send Start, control byte and ack
mov.b ADDRI2C,RXTXI2C ; Load address for TX
call #I2C_TX ; Send address and ack
mov.b DATAI2C,RXTXI2C ; Load data for TX
call #I2C_TX ; Send data and ack
call #I2C_Stop ; Send stop
ret
;-----------I2C Subroutines end-------------------------------------------------
;-------------------------------------------------------------------------------
; Sart of subroutines to communicate with PC via UART
;-------------------------------------------------------------------------------
RX; Routine to get 3 address or 2 data bytes from PC
;-------------------------------------------------------------------------------
call #RX_Ready ; Setup UART to receive
LOOP bit #CCIE,&CCTL0 ; All bits RXed?, = interrupt disabled
; in RX_Comp routine
jnz LOOP ; No, then loop
ret
Test_Blck clr.b ScndBlck ; Clear flag for 2nd memory block
cmp.b #30h,RXTXData ; First byte = 0? (30h = ASCII 0)
jeq Test_ret ; Yes, jump to return
mov.b #02h,ScndBlck ; No, set bit to indicate
; memory addresses > 0FF hex
Test_Num sub.b #30h,RXTXData ; Convert 0-9 to binary
cmp.b #0Ah,RXTXData ; Data = 10 or more?
jlo Test_end ; No, skip next instruction
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -