TSmooth
Newbie level 4
- Joined
- Nov 24, 2014
- Messages
- 5
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Activity points
- 63
Hello I have been trying to get a I2C compass module to talk to a PIC16F877A. I can repeatedly send the slave address with the R/W bit low and the address I want to read from and receive acknowledgement every time (I have a bus pirate logic analyser which I am able to view the signal on). However, as soon as I ask the slave to transmit (R/W bit high) I see nothing on the logic analyser. Was wondering if anyone can see anything obvious I have missed? Thanks
Code dot - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 configp clrf PORTB clrf PORTA ;reset input and outputs bank1 ;select bank1 movlw b'00000110' ;configure all pins movwf ADCON1 ; as DIGITAL movlw b'000000' ;porta is 6 bits wide movwf TRISA ;porta RA5 to RA0 input movlw b'00000000' ;a 0 in ctrl register make the I/O pin an output movwf TRISB movlw b'00000000' movwf TRISD ;portb is all output movlw b'11111111' movwf TRISC movlw b'00000111' ;divide clock frquency by 256 movwf OPTION_REG ;timer PRESCALAR bank0 ;select bank0 movlw b'00000000' ;w = 00h movwf INTCON ;clear interrupts retlw 0 ;return from subroutine ;;------------Delay delayp movlw time movwf count1 ; save time factor in gpr loop3 clrf rtcc loop1 btfsc rtcc,0 ; use bit 1 under simulation goto loop2 ; if rtcc timer delay done goto loop2 clrwdt goto loop1 ; keep checking rtcc bit for a 1 loop2 decfsz count1,1 ; has time factor reached 0? goto loop3 ; repeat rtcc timer delay retlw 0 ; delay done ;---------i2c subroutines---------------------------------- i2c_config banksel SSPADD ; select SFR bank movlw b'00110001' ; 20mhz clock, 100khz = 49 movwf SSPADD ; initialize I2C baud rate bcf SSPSTAT,6 ; select I2C input levels bsf SSPSTAT,7 ; disable slew rate bcf STATUS,RP0 ; select SFR bank movlw b'00101000' ; movwf SSPCON ; Master mode, SSP enable return i2c_send banksel SSPBUF ;select SSPBUF bank movwf SSPBUF ;copy the content from W register to SSPBUF banksel PIR1 ;select PIR1 bank sndwait btfss PIR1,SSPIF ;check whether transmission is complete? goto sndwait ;wait until it completes. bcf PIR1,SSPIF ;clear SSPIF bit banksel SSPCON2 ;select SSPCON2 bank for checking acknowledgement from slave. nop btfsc SSPCON2,ACKSTAT;check for acknldge, If ACKSTAT=0,acknowledged. goto not_ack ;if not acknowledge send error signal banksel PIR1 bcf PIR1,SSPIF ;Clear SSPIF bit bank0 return i2c_receive banksel SSPCON2 bsf SSPCON2,RCEN ; Enable Receive Mode (I2C) bsf SSPCON2,ACKDT ; ACK DATA to send is 1, which is NACK. call i2c_wait banksel SSPBUF movf SSPBUF, w banksel SSPCON2 bsf SSPCON2,ACKEN ; Send ACK DATA now. ait btfss PIR1,SSPIF ;check whether transmission is complete? goto ait ;wait until it completes. return startb banksel SSPCON2 ;Select SSPCON2 Bank bsf SSPCON2,SEN ;Initiaite Start Sequence call i2c_wait ;Call i2c_wait return rstartb banksel SSPCON2 ;Select SSPCON2 Bank bsf SSPCON2,RSEN ;Initiaite Restart Sequence call i2c_wait ;Call i2c_wait return stopb banksel SSPCON2 ;Select SSPCON2 Bank bsf SSPCON2,PEN ;Initiaite Stop Sequence call i2c_wait ;Call i2c_wait return i2c_wait banksel PIR1 iiwait btfss PIR1,SSPIF ;Operation Completed succesfully? goto iiwait ;No, Keep Checking bcf PIR1,SSPIF ;Clear SSPIF bit return not_ack banksel PORTB addlw d'1' addwf PORTB, 1 banksel PIR1 ;select PIR1 bank bcf PIR1,SSPIF bcf PIR1, BCLIF return ;;; -----main program------------------------------------------ start call configp call delayp call i2c_config call delayp call delayp repeat call startb movlw b'11000000' call i2c_send movlw b'00000001' call i2c_send call stopb call delayp call startb movlw b'11000001' call i2c_send call i2c_receive call stopb goto repeat end
Last edited by a moderator: