You are on page 1of 9

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

; Filename:
I2C.asm
*
; Date:
November 6, 2012
*
; File Version:
1.0
*
;
*
; Author:
Nolan Manteufel
*
;
*
; Company:
University of Texas at San Antonio
*
; URL:
www.utsa.edu/engineering
*
;
*
;******************************************************************************
list
#include

p=16f1823
; list directive to define processor
<p16f1823.inc> ; processor specific variable definitions

;-----------------------------------------------------------------------------; CONFIGURATION WORD SETUP


;-----------------------------------------------------------------------------__CONFIG
_CONFIG1, _CP_OFF & _WDTE_ON & _FOSC_INTOSC &
_PWRTE_OFF & _MCLRE_ON & _CLKOUTEN_OFF
__CONFIG
_CONFIG2, _LVP_OFF & _BORV_HI & _STVREN_ON & _WRT_OFF
;-----------------------------------------------------------------------------; RAM
;-----------------------------------------------------------------------------CBLOCK 0x20
; Location of RAM
POT
; Used for Potentiometer
POT_VALUE
;
POT_LOCATION
;
x
; Used for pointless math
i2c_address
; Used for I2C
i2c_address_buffer
;
i2c_status
;
i2c_status_buffer
;
i2c_data_out
;
i2c_data_out_buffer
;
i2c_data_in
;
i2c_data_in_buffer
;
ENDC
;
;-----------------------------------------------------------------------------; DEFINITIONS
;-----------------------------------------------------------------------------DIR
EQU
0x03
; 1 = getting brighter, 0 = getting dimmer.

LED
EQU
;---------------------------------------setup_i2c
EQU
ready_i2c
EQU
;---------------------------------------start_i2c
EQU
stop_i2c
EQU
;---------------------------------------address_put_i2c
EQU
;---------------------------------------data_put_i2c
EQU
done_i2c
EQU

0x05

; LED location on PORTC

0x00
0x01

; I2C Status Values


;

0x02
0x04

;
;

0x05

0x0e
0x10

;
;

;-----------------------------------------------------------------------------; RESET VECTOR


;-----------------------------------------------------------------------------ORG 0x0000
; Reset vector
nop
;
goto START
;
;-----------------------------------------------------------------------------; INTERRUPT SERVICE ROUTINE
;-----------------------------------------------------------------------------ORG
0x0004
;
nop
;
banksel
INTCON
;
btfsc
INTCON, TMR0IF
; checks for TIMR0 IF
goto
timer0_isr
;
banksel
PIR1
;
btfsc
PIR1, SSP1IF
; checks for I2C IF
goto
run_I2C
;
banksel
INTCON
;
movlw
b'01100000'
;
movwf
INTCON
;
retfie
;
;------------------------------------------------------------------------------; TIMER0 Interrupt Service Routine
;------------------------------------------------------------------------------timer0_isr
;
banksel
i2c_status
;
movfw
i2c_status
;
sublw
ready_i2c
;
btfss
STATUS, Z
;

retfie
POT_VALUE
banksel
POT_VALUE
btfsc
goto
goto
brighter
banksel
incf
movfw
xorlw
btfsc
goto
movfw
movwf
movfw
movwf
movlw
movwf
call
banksel
movlw
movwf
retfie
dimm_down
banksel
bcf
retfie
dimmer
banksel
decf
movfw
xorlw
btfsc
goto
movfw
movwf
movfw
movwf
movlw
movwf
call
banksel

; clear == I2C busy, don't modify the


POT

; set == I2C ready, modify and send

POT, DIR
brighter
dimmer

;
; set == going up
; clear == going down
;
;
;
;
;
;
; set == maximum limit
; clear == still going up
;
;
;
;
;
;
;
;
;
;
;
;
; change direction
;
;
;
;
;
;
;
; set == minumum limit
; clear == still going down
;
;
;
;
;
;
;

POT_VALUE
POT_VALUE, F
POT_VALUE
0xd0
STATUS, Z
dimm_down
POT_LOCATION
i2c_address
POT_VALUE
i2c_data_out
start_i2c
i2c_status
run_I2C
INTCON
b'01100000'
INTCON

POT
POT, DIR

POT_VALUE
POT_VALUE, F
POT_VALUE
0xb0
STATUS, Z
brighten_up
POT_LOCATION
i2c_address
POT_VALUE
i2c_data_out
start_i2c
i2c_status
run_I2C
INTCON

movlw
movwf
retfie
brighten_up
banksel
bsf
retfie

b'01100000'
INTCON

POT
POT, DIR

;
;
;
;
;
; change direction
;

;-----------------------------------------------------------------------------; MAIN PROGRAM


;-----------------------------------------------------------------------------START
;
movlw
0xb0
;
banksel
POT_VALUE
;
movwf POT_VALUE
;
movlw
b'01011110'
; MCP4018 address
movwf
POT_LOCATION
;
bsf
POT, DIR
;
;------------------------------------------------------------------------------; Configuring PORTC for LED, see page 129 of PIC16F1823 datasheet
;------------------------------------------------------------------------------config_PORTC
banksel
PORTC
bcf
PORTC, LED
banksel
LATC
bcf
LATC, LED
banksel
ANSELC
clrf
ANSELC
banksel
TRISC
bcf
TRISC, LED
;-----------------------------------------------------------------------------; Initialize RAM used for I2C.
;-----------------------------------------------------------------------------banksel
i2c_status
;
clrf
i2c_address
;
clrf
i2c_address_buffer
;
clrf
i2c_status
;
clrf
i2c_status_buffer
;
clrf
i2c_data_out
;
clrf
i2c_data_out_buffer
;
clrf
i2c_data_in
;
clrf
i2c_data_in_buffer
;

call

run_I2C

; Initializes the I2C Module

;------------------------------------------------------------------------------; Configuring Timer0 and Interrupts, see page 177 of PIC16F1823 datasheet
;------------------------------------------------------------------------------banksel
TMR0
;
clrf
TMR0
;
banksel
OPTION_REG
;
movlw
b'00000011'
; Number to configure TIMER0.
movwf
OPTION_REG
;
banksel
INTCON
;
movlw
b'11100000'
;
movwf
INTCON
;
;------------------------------------------------------------------------------; Pointless math
;------------------------------------------------------------------------------math
;
incf
x,F
;
movlw 0x04
;
movfw i2c_status
;
addwf x,F
;
decf x,F
;
goto math
;
;------------------------------------------------------------------------------; I2C
;------------------------------------------------------------------------------run_I2C
; Only PUBLIC I2C function
clrwdt
;
movlw
setup_i2c
;
banksel
i2c_status
;
xorwf
i2c_status
;
banksel
STATUS
;
btfsc
STATUS, Z
;
goto
setup_I2C
;
banksel
movfw
sublw
btfsc
return

i2c_status
i2c_status
ready_i2c
STATUS, Z

;
;
;
;

movfw

i2c_status

sublw
btfsc
goto

start_i2c
STATUS, Z
start_I2C

;
;
;

movfw
sublw
btfsc
goto

i2c_status
stop_i2c
STATUS, Z
stop_I2C

;
;
;
;

movfw
sublw
btfsc
goto

i2c_status
address_put_i2c
STATUS, Z
addressPut_I2C

;
;
;
;

movfw
sublw
btfsc
goto

i2c_status
data_put_i2c
STATUS, Z
dataPut_I2C

;
;
;
;

movfw
sublw
btfsc
goto
goto

i2c_status
done_i2c
STATUS, Z
done_I2C
setup_I2C

;
;
;
;
;

setup_I2C
;------------------------------------------------------------------------------; Configuring I2C, see page 277 of PIC16F1823 datasheet
;------------------------------------------------------------------------------banksel
SSP1CON1
; Mode: Master I2C
movlw
b'00101000'
;
movwf SSP1CON1
;
banksel
SSP1ADD
; Baud Rate == 400KHz @ 16MHz
movlw
b'00001001'
;
movwf SSP1ADD
;
banksel
SSP1STAT
; Slew Rate == enabled
movlw
b'00000000'
;
movwf SSP1STAT
;
banksel
TRISC
; Pins == inputs
bsf
TRISC, SCL
;
bsf
TRISC, SDA
;
banksel
PIR1
; Interrupts
bcf
PIR1, SSP1IF
;
banksel
INTCON
;

bsf
banksel
bsf
banksel
bcf
movlw
banksel
movwf
return
start_I2C
banksel
bsf
movlw
banksel
movwf
return

INTCON, PEIE
PIE1
PIE1, SSP1IE
PIE2
PIE2, BCL1IE
ready_i2c
i2c_status
i2c_status

SSP1CON2
SSP1CON2, SEN
address_put_i2c
i2c_status
i2c_status

addressPut_I2C
banksel
PIR1
bcf
PIR1, SSP1IF
banksel
i2c_address
movfw
i2c_address
banksel
SSP1BUF
movwf SSP1BUF
movlw
data_put_i2c
banksel
i2c_status
movwf
i2c_status
retfie

;
;
; SSP Event IF == enable
;
; SSP Collision IF == disable
;
;
; Set i2c_status = ready_i2c
;
;
;
; Sends start signal,
; Sets status to "address_put_i2c",
;
;
; Returns to wait for interrupt.
;
;
; Clears interrupt flag.
;
; MCP4018 address == b'01011110'
;
; Sends the address,
;
;
; Sets the status to "data_put_i2c",
; Returns from Interrupt.

dataPut_I2C
;
banksel
PIR1
;
bcf
PIR1, SSP1IF
; Clears interrupt flag.
banksel
SSP1CON2
;
btfsc
SSP1CON2, ACKSTAT
;
goto
test_NACK
; set = NACK
banksel
i2c_data_out
; clear = ACK, chip ready
movfw
i2c_data_out
;
banksel
SSP1BUF
;
movwf SSP1BUF
; Sends the data, Sets status to "stop_i2c",
movlw
stop_i2c
;
banksel
i2c_status
;
movwf
i2c_status
;
banksel
PORTC
;

bcf
retfie
stop_I2C
banksel
bcf
banksel
btfsc
goto
bsf
movlw
banksel
movwf
retfie
test_NACK
banksel
bsf
goto
done_I2C
banksel
bcf
movlw
banksel
movwf
movfw
btfsc
retfie
movwf
clrf
movfw
movwf
clrf
movfw
movfw
clrf
movfw
movwf
mode.
clrf
call
retfie

PORTC, LED

; Sets status to "stop_i2c".


; Returns from interrupt.

PIR1
PIR1, SSP1IF
;
SSP1CON2
SSP1CON2, ACKSTAT
test_NACK
SSP1CON2, PEN
done_i2c
i2c_status
i2c_status

i2c_status
i2c_status_buffer
i2c_address_buffer
i2c_address
i2c_address_buffer
i2c_data_out_buffer
i2c_data_out
i2c_data_out_buffer
i2c_data_in_buffer
i2c_data_in
i2c_data_in_buffer
run_I2C

;
;
; set = NACK
; clear = ACK, data sent
;
;
; Sets status to "done_i2c".
; Returns from interrupt.
;
;
;
;

PORTC
PORTC, LED
done_I2C

PIR1
PIR1, SSP1IF
ready_i2c
i2c_status
i2c_status
i2c_status_buffer
STATUS, Z

;
;

;
;
;
;
;
; Sets status to "ready_i2c".
; Checks i2c_status_buffer,
;
; clear = buffer empty.
; set = buffer full.
;
;
;
;
;
;
;
; In/Out data registers is pointless for I2C.
; In/Out distinction may be helpful for SPI
;
;
;

END

You might also like