📄 1820.asm
字号:
* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* TRIANGLE.ASM
* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* Purpose: Test of I2C bit-banging using the J1A
* Target: 705J1A
* Author: Brad Bierschenk, MMD Applications
* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* Tested using Maxim I2C DAC IC, MAX517
* Has a "2-wire interface" (another word for I2C)
*
* This code continuously sends 8-bit data to the
* Digital to Analog IC, incrementing from $00 to
* $FF, and back down again. This creates a
* triangular waveform at the output of the DAC chip.
*
* The SCL frequency is approximately 28 kHz. This is
* completely arbitrary.
* -------------------------------------------------------------
* Assembler Equates
* -------------------------------------------------------------
RAMSPACE EQU $C0 ;RAM start address
ROMSPACE EQU $300 ;EPROM start address
PORTA EQU $00 ;Port A
PORTB EQU $01 ;Port B
DDRA EQU $04 ;Data direction A
DDRB EQU $05 ;Data direction B
* -------------------------------------------------------------
* Emulated I2C lines on Port A pins
* Need a clock (SCL) and data (SDA)
* -------------------------------------------------------------
SCL EQU 0 ;Serial clock
SDA EQU 1 ;Serial data
DACADDR EQU $2C ;Slave address of DAC
* -------------------------------------------------------------
* RAM Variables
* -------------------------------------------------------------
ORG RAMSPACE
BitCounter RMB 1 ;Used to count bits in a Tx
Value RMB 1 ;Used to store data value
Direction RMB 1 ;Indicates increment or
;decrement
* -------------------------------------------------------------
* Start of program code
* -------------------------------------------------------------
ORG ROMSPACE ;Start of EPROM
Start: ;Initialize variables
CLR Value ;Clear all RAM variables
CLR BitCounter
CLR Direction ;Setup parallel ports
LDA #$03 ;PA0 and PA1 as outputs
STA PORTA ;driven high to start
STA DDRA
* -------------------------------------------------------------
* This main loop just ramps up and down the data
* value that is sent to the DAC chip.
* -------------------------------------------------------------
TxLoop:
LDA Direction ;Increment or decrement?
BEQ GoUp
GoDown:
LDA Value ;Decrement
BNE GD2 ;Change direction if needed
CLR Direction
BRA SendIt
GD2:
DEC Value ;Decrement the data value
BRA SendIt
GoUp:
LDA Value ;Increment
CMP #$FF ;Change direction if needed
BNE GU2
INC Direction ;Increment the data value
BRA SendIt
GU2:
INC Value
* -------------------------------------------------------------
* Send the I2C transmission, including START, address,
* data, and STOP
* -------------------------------------------------------------
SendIt: ;START condition
JSR I2CStartBit ;Give START condition
;ADDRESS byte, consists of 7-bit address + 0 as LSbit
LDA #DACADDR ;Slave device address
ASLA ;Need this to align address
JSR I2CTxByte ;Send the eight bits
;DATA bytes
LDA #$00 ;$00 is command byte for DAC
JSR I2CTxByte ;Send the 8 bits
LDA Value ;Value is value to set DAC
JSR I2CTxByte ;Send it
;STOP condition
JSR I2CStopBit ;Give STOP condition
JSR I2CBitDelay ;Wait a bit
BRA TxLoop ;Repeat
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; I2CTxByte
; Transmit the byte in Acc to the SDA pin
; (Acc will not be restored on return)
; Must be careful to change SDA values only while SCL is low,
; otherwise a STOP or START could be implied
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I2CTxByte: ;Initialize variable
LDX #$08
STX BitCounter
I2CNextBit:
ROLA ;Shift MSbit into Carry
BCC SendLow ;Send low bit or high bit
SendHigh:
BSET SDA,PORTA ;Set the data bit value
JSR I2CSetupDelay ;Give some time for data setup
BSET SCL,PORTA ;Clock it in
JSR I2CBitDelay ;Wait a bit
BRA I2CTxCont ;Continue
SendLow:
BCLR SDA,PORTA
JSR I2CSetupDelay
BSET SCL,PORTA
JSR I2CBitDelay
I2CTxCont:
BCLR SCL,PORTA ;Restore clock to low state
DEC BitCounter ;Decrement the bit counter
BEQ I2CAckPoll ;Last bit?
BRA I2CNextBit
I2CAckPoll:
BSET SDA,PORTA
BCLR SDA,DDRA ;Set SDA as input
JSR I2CSetupDelay
BSET SCL,PORTA ;Clock the line to get ACK
JSR I2CBitDelay
BRSET SDA,PORTA,I2CNoAck ;Look for ACK from slave
;device
BCLR SCL,PORTA ;Restore clock line
BSET SDA,DDRA ;SDA back as output
RTS
;No acknowledgment received from slave device
;Some error action can be performed here
;For now, just restore the bus
I2CNoAck:
BCLR SCL,PORTA
BSET SDA,DDRA
RTS
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; A START condition is defined as a falling edge
; on SDA while SCL is high
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-
I2CStartBit:
BCLR SDA,PORTA
JSR I2CBitDelay
BCLR SCL,PORTA
RTS
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; A STOP condition is defined as a rising edge
; on SDA while SCL is high
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I2CStopBit:
BCLR SDA,PORTA
BSET SCL,PORTA
BSET SDA,PORTA
JSR I2CBitDelay
RTS
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; Provide some data setup time to allow
; SDA to stabilize in slave device
; Completely arbitrary delay (10 cycles)
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I2CSetupDelay:
NOP
NOP
RTS
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; Bit delay to provide (approximately) the desired
; SCL frequency
; Again, this is arbitrary (16 cycles)
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I2CBitDelay:
NOP
NOP
NOP
NOP
NOP
RTS
* -------------------------------------------------------------
* Vector Definitions
* -------------------------------------------------------------
ORG $07FE ;Reset vector
FDB Start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -