新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > pic單片機(jī)的模擬I2C通信

pic單片機(jī)的模擬I2C通信

作者: 時(shí)間:2011-02-24 來源:網(wǎng)絡(luò) 收藏
*****************************************         pic的模擬I2C通信       *****************************************;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;                      Copyright (C) 1997 by Innovatus; 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.innovatus.com;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;    File Name: i2c_low.asm;       Author: Alan G. Smith;      Purpose: This code is borrowed from Microchip with all of the fancy;               stuff taken out.;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++InitI2CBusMaster;************************************************************TxmtStartBitbsf    Bus_Busy                       ; on a start condition bus is busybsf    STATUS, RP0                    ; Select page 1bsf    _SDA                           ; set SDA highbsf    _SCL                           ; clock is highcall   Delay40uSec                    ; This is necessary for setup timebcf    _SDA                           ; This gives a falling edge on SDA while clock is highcall   Delay47uSec                    ; Necessary for START HOLD timereturn;************************************************************TxmtStopBitbsf    STATUS, RP0                    ; Select page 1bcf    _SCL                           ; clock is lowbcf    _SDA                           ; set SDA lowbsf    _SCL                           ; clock is pulled upcall   Delay40uSec                    ; Setup time for STOP conditionbsf    _SDA                           ; rising edge on SDA while CLOCK is highcall   Delay47uSec                    ; makes sure a START isn't sent immediately after a STOPbcf    Bus_Busy                       ; The bus isn't busy anymorereturn;************************************************************AbortI2Ccall   TxmtStopBit                    ; Send a stop bitbsf    Abort                          ; set the abort bitreturn;************************************************************TxmtSlaveAddrmovf   SlaveAddr, w                   ; Move slave address to Wbcf    ACK_Error                      ; reset Acknowledge error bitmovwf  I2CData                        ; move W to I2C Databcf    I2CData, LSB                   ; Set for writebtfsc  Slave_RW                       ; If skip then write operationbsf    I2CData, LSB                   ; Clear for readcall   SendData                       ; send the addressbtfss  Txmt_Success                   ; skip if successfulgoto   AddrSendFail                   ; Oops, we failedretlw  TRUE                           ; return trueAddrSendFailbtfss  ACK_Error                      ; was there an error acknowledgingretlw  FALSE                          ; No, so return 0call   TxmtStopBit                    ; Address not acknowleged, so send STOP bitretlw  FALSE                          ; Unsuccessful, so return 0;************************************************************SendData; We might should make a copy of the data here, the example does but I don't see why!!!bsf    Txmt_Progress                  ; We are in the middle of transmittingbcf    Txmt_Success                   ; reset success bitmovlw  0x08movwf  I2CBitCount                    ; Set I2C Bit Count to 8bsf    STATUS, RP0                    ; Select page 1TxmtNextBit:bcf    _SCL                           ; Set clock Lowrlf    I2CData, F                     ; MSB First, Note that I2CData is Destroyedbcf    _SDA                           ; Set clock based on what the MSB isbtfsc  STATUS,C                       ; Was the MSB a 1bsf    _SDA                           ; Nope set it highcall   Delay47uSec                    ; guarantee min LOW TIME tLOW  Setup timebsf    _SCL                           ; set clock highcall   Delay40uSec                    ; guarantee min HIGH TIME tHIGHdecfsz I2CBitCount, F                 ; are we done yetgoto   TxmtNextBit                    ; nope, send the next bit;; Check For Acknowledge;bcf    _SCL                           ; reset clockbsf    _SDA                           ; Release SDA line for Slave to pull downcall   Delay47uSec                    ; guarantee min LOW TIME tLOW  Setup timebsf    _SCL                           ; clock for slave to ACKcall   Delay40uSec                    ; guarantee min HIGH TIME tHIGHbcf    STATUS, RP0                    ; Select PAGE 0 to test SDA pinbtfsc  SdaPin                         ; SDA should be pulled low by slave if OKgoto   TxmtErrorAck                   ; Uh oh, slave isn't behaving (or isn't there)bsf    STATUS, RP0                    ; Select PAGE 1bcf    _SCL                           ; reset clockbcf    Txmt_Progress                  ; reset progress bit in Bus Statusbsf    Txmt_Success                   ; Transmission successfulbcf    ACK_Error                      ; ACK OKreturnTxmtErrorAckbsf    STATUS,RP0                     ; select page 1bsf    _SDA                           ; tristate SDAbsf    _SCL                           ; tristate SCLbcf    Txmt_Progress                  ; reset progress bit in Bus Statusbcf    Txmt_Success                   ; Transmission NOT successfulbsf    ACK_Error                      ; No ACK From Slavereturn;************************************************************GetDatabsf    Rcv_Progress                   ; set Bus status for txmt progressbcf    Rcv_Success                    ; reset status bitmovlw  0x08movwf  I2CBitCountRcvNextBitbsf    STATUS, RP0                    ; page 1 for TRIS manipulationbcf    _SCL                           ; lower clockbcf    _SDA                           ; lower data linecall   Delay47uSec                    ; guarantee min LOW TIME tLOW  setup timebsf    _SCL                           ; clock high, data sent by slavecall   Delay40uSec                    ; guarantee min HIGH TIME tHIGHbcf    STATUS, RP0                    ; select page 0 to read Portsbcf    STATUS, C                      ; 0 out Statusbtfsc  SdaPin                         ; Check state of pinbsf    STATUS, C                      ; Pin was high, set statusrlf    I2CData, F                     ; left Shift data (MSB first)decfsz I2CBitCount, F                 ; Are we done yetgoto   RcvNextBit                     ; Nope, go get the next one;; Generate ACK bit if not last byte to be read,; if last byte Gennerate NACK ; do not send ACK on last byte, main routine will send a STOP bit;bsf    STATUS, RP0                    ; Page 1 for TRIS manipulationbcf    _SCL                           ; pull SCL lowbcf    _SDA                           ; ACK by pulling SDA lowbtfsc  Last_Byte_Rcv                  ; Is it the last byte to receivebsf    _SDA                           ; If so, send NACK by setting SDA highcall   Delay47uSec                    ; guarantee min LOW TIME tLOW  Setup timebsf    _SCL                           ; Raise Clock back upcall   Delay40uSec                    ; guarantee min HIGH TIME tHIGHRcvEnd:bcf    _SCL                           ; reset clockbcf    Rcv_Progress                   ; reset bit in Bus Statusbsf    Rcv_Success                    ; transmission successfulbcf    ACK_Error                      ; ACK OKreturnDelay47uSec:movlw ((_47uS_Delay-5)/3 + 1)         ; move delay into WDlyKmovwf DelayCount                      ; move what is in W to DelayCountdecfsz   DelayCount, F                ; Decrement DelayCountgoto  $-1                             ; Loop until 0return                                ; returnDelay40uSec:movlw ((_40uS_Delay-8)/3 + 1)         ; move delay into Wgoto  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.innovatus.com;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;    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 usingClkOut          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 0InitTrisA       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,2CBLOCK     0x0C                        ; I2C Ram neededBusStatus                            ; The I2C Status registerBusControl                           ; The I2C Control registerI2CBitCount                          ; Number of bits left to send (or receive)I2CData                              ; Data (note: This is DESTROYED when sending)SlaveAddr                            ; Slave AddressENDCCBLOCKDelayCount                           ; used to figure out precise time delaysENDCorg 0                                 ; Reset Vectorgoto   start                          ; Goto Startstartbcf    INTCON, GIE                    ; Turn off interrupts in this critical part of code!bcf    STATUS, RP0                    ; Select Page 0 of registersmovlw  0x0C                           ; Make sure there are 0's on SCL and SDAmovwf  PORTA                          ; We write 1's to TX since 0 is a start bitbsf    STATUS, RP0                    ; Select Page 1 of registersmovlw  InitTrisA                      ; Load W with the value for TRIS Amovwf  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 startclrf   BusControl                     ; Let's clear out busControl before we start;*************** TEST CODE *******************clrf   PORTBmainmovlw  0xB0                           ; address of EEPROMmovwf  SlaveAddr                      ; move into SlaveAddress registercall   IsSlaveActive                  ; Check and see if the slave is activemovlw  0xFF                           ; move FF into w (turn all LED's on)btfss  SlaveActive                    ; If the slave is active, leave itmovlw  0xAA                           ; We didn't find it, turn off half.bcf    STATUS, RP0                    ; Select page 0 of registersmovwf  PORTB                          ; move W to PortBdone                                     ; Game over man!goto   done                           ; endless loopIsSlaveActivebcf    Slave_RW                       ; set for write operationcall   TxmtStartBit                   ; Transmit Start Bitcall   TxmtSlaveAddr                  ; Transmit Slave Addressbcf    SlaveActive                    ; Assume not presentbtfss  ACK_Error                      ; skip if NACK, device is not present or not respondingbsf    SlaveActive                    ; ACK received, device present  listeningcall   TxmtStopBitreturn#include "i2c_low.asm"END


評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉