基于pic單片機(jī)的模擬I2C通信
Delay47uSec:
movlw ((_47uS_Delay-5)/3 + 1) ; move delay into W
DlyK
movwf DelayCount ; move what is in W to DelayCount
decfsz DelayCount, F ; Decrement DelayCount
goto $-1 ; Loop until 0
return ; return
Delay40uSec:
movlw ((_40uS_Delay-8)/3 + 1) ; move delay into W
goto DlyK ; goto DlyK loop
以下為測(cè)試程序(pic16f84)
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Copyright (C) 1997 by Innovatus
; All Rights Reserved.
; This code may be distributed and used freely provided that this
; copyright notice stays intact and that any modifications are noted.
; For more information about Innovatus: http://www.innovatu.com
s;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; File Name: testI2C.asm
; Author: Alan G. Smith
; Purpose: This is testing out the I2C code.
;
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LIST P=16f84, F=INHX8M, C=100, N=59
#include p16f84.inc
XTAL_FREQ equ 10000000 ; the crystal frequency we are using
ClkOut equ XTAL_FREQ / 4 ; the number of cycles per second
_40uS_Delay set (ClkOut/250000)
_47uS_Delay set (ClkOut/212766)
_50uS_Delay set (ClkOut/200000)
#define SclPin PORTA, 0 ; Pin for SCL (I2C)
#define SdaPin PORTA, 1 ; Pin for SDA (I2C)
#define _SCL TRISA, 0 ; How do we toggle SCL
#define _SDA TRISA, 1 ; How do we toggle SDA
#define MSB 7
#define LSB 0
#define TRUE 1
#define FALSE 0
InitTrisA equ 0x07 ; The Initial state to TRIS port A.
#define Bus_Busy BusStatus,0
#define Abort BusStatus,1
#define Txmt_Progress BusStatus,2
#define Rcv_Progress BusStatus,3
#define Txmt_Success BusStatus,4
#define Rcv_Success BusStatus,5
#define Fatal_Error BusStatus,6
#define ACK_Error BusStatus,7
#define Slave_RW BusControl,0
#define Last_Byte_Rcv BusControl,1
#define SlaveActive BusControl,2
CBLOCK 0x0C ; I2C Ram needed
BusStatus ; The I2C Status register
BusControl ; The I2C Control register
I2CBitCount ; Number of bits left to send (or receive)
I2CData ; Data (note: This is DESTROYED when sending)
SlaveAddr ; Slave Address
ENDC
CBLOCK
DelayCount ; used to figure out precise time delays
ENDC
org 0 ; Reset Vector
goto start ; Goto Start
start
bcf INTCON, GIE ; Turn off interrupts in this critical part of code!
bcf STATUS, RP0 ; Select Page 0 of registers
movlw 0x0C ; Make sure there are 0‘s on SCL and SDA
movwf PORTA ; We write 1‘s to TX since 0 is a start bit
bsf STATUS, RP0 ; Select Page 1 of registers
movlw InitTrisA ; Load W with the value for TRIS A
movwf TRISA ; movw the value from W into TRIS A
;*************** DEBUG CODE (let us use LEDs) *******************
clrf TRISB
;****************************************************************
clrf BusStatus ; Let‘s clear out busStatus before we start
clrf BusControl ; Let‘s clear out busControl before we start
;*************** TEST CODE *******************
clrf PORTB
main
movlw 0xB0 ; address of EEPROM
movwf SlaveAddr ; move into SlaveAddress register
call IsSlaveActive ; Check and see if the slave is active
movlw 0xFF ; move FF into w (turn all LED‘s on)
btfss SlaveActive ; If the slave is active, leave it
movlw 0xAA ; We didn‘t find it, turn off half.
bcf STATUS, RP0 ; Select page 0 of registers
movwf PORTB ; move W to PortB
done ; Game over man!
goto done ; endless loop
IsSlaveActive
bcf Slave_RW ; set for write operation
call TxmtStartBit ; Transmit Start Bit
call TxmtSlaveAddr ; Transmit Slave Address
bcf SlaveActive ; Assume not present
btfss ACK_Error ; skip if NACK, device is not present or not responding
bsf SlaveActive ; ACK received, device present listening
call TxmtStopBit
return
#include i2c_low.asm
評(píng)論