Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2021
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.37 KB | None | 0 0
  1. #include p16f886.inc
  2. processor p16f886 ;not really critical, can set in configure
  3.  
  4. RESET CODE 0x0000
  5. goto START
  6.  
  7. UDATA; gpr0
  8. var1 RES 1
  9. var2 RES 2
  10. i2c_address RES 1
  11. i2c_write_data RES 1
  12. i2c_add_search_delay RES 1
  13.  
  14.  
  15. CODE
  16. START:
  17. CALL SETUP_I2C
  18. NOP
  19. CALL FIND_I2C_ADDRESS
  20. NOP
  21. CALL LCD_I2C_INF_LOOP
  22. NOP
  23. GOTO $
  24.  
  25. SETUP_I2C:
  26. ;Set SDA (RC4) and SCL (RC3) pins as input
  27. BANKSEL TRISC
  28. BSF TRISC, RC3
  29. BSF TRISC, RC4
  30.  
  31. ;Enable I2C (bit5), use I2C Master mode (bits 3:0)
  32. ;clock set in this mode FOSC / (4 * (SSPADD+1))
  33. BANKSEL SSPCON
  34. MOVLW 0x28
  35. MOVWF SSPCON
  36. BANKSEL SSPCON2
  37. CLRF SSPCON2 ;SSPCON2 controls the actual operation. Init to 0
  38. ; SSPADD = (_XTAL_FREQ/(4*feq_K))-1;
  39. BANKSEL SSPADD
  40. MOVLW 0x18 ;decimal 24 gives 80Khz clock
  41. MOVWF SSPADD
  42. BANKSEL SSPSTAT
  43. CLRF SSPSTAT ;Clear out any status bits
  44.  
  45. RETURN
  46.  
  47. ;wait for I2C to stop being busy
  48. WAIT_I2C:
  49. ;check bit2 of SSPSTAT (in master mode 0 indicates completion)
  50. BANKSEL SSPSTAT
  51. BTFSC SSPSTAT,2
  52. GOTO $-1
  53.  
  54. ;check the individual operations completion
  55. ;acken, rcen, pen, rsen, sen pg. 180
  56. test_sspcon2:
  57. BANKSEL SSPCON2
  58. MOVLW 0x1F
  59. ANDWF SSPCON2, 0
  60. BANKSEL STATUS
  61. BTFSS STATUS,Z ;repeat if status is not 0
  62. GOTO test_sspcon2
  63.  
  64. RETURN
  65.  
  66. START_I2C:
  67. ;function puts out the start condition after ensuring not busy
  68. CALL WAIT_I2C
  69. BANKSEL SSPCON2
  70. BSF SSPCON2, SEN
  71. RETURN
  72. STOP_I2C:
  73. ;function puts out the stop condition after ensuring not busy
  74. CALL WAIT_I2C
  75. BANKSEL SSPCON2
  76. BSF SSPCON2, PEN
  77. RETURN
  78.  
  79. WRITE_I2C:
  80. ;function writes out to I2C, this is used for both add and data
  81. ;the data should be place ind i2c_write_data
  82. CALL WAIT_I2C
  83. BANKSEL i2c_write_data
  84. MOVF i2c_write_data,0
  85. BANKSEL SSPBUF
  86. MOVWF SSPBUF ;place the address or data in SSPBUF for
  87. ;transmission
  88. RETURN
  89.  
  90. FIND_I2C_ADDRESS:
  91. ;This function repeatedly checks the I2C lines for presense of
  92. ;the pcf8574 chip and stores the address in i2c_address
  93. ;A retun or 1 indicates success
  94. ;address is 7 bits + LSB r/w`
  95.  
  96.  
  97. MOVLW 0x00 ;init W to 0
  98. BANKSEL i2c_address
  99. MOVWF i2c_address
  100.  
  101. addr_search_again:
  102. CALL START_I2C ;assert start
  103. BANKSEL i2c_address
  104. MOVF i2c_address,0
  105. BANKSEL i2c_write_data
  106. MOVWF i2c_write_data ; pass the argument (data to transmit)
  107. ;MOVWF i2c_address ;save the data (actually address)
  108. CALL WRITE_I2C ;write it out on the bus
  109.  
  110. BANKSEL SSPSTAT ;wait for transmission to complete
  111. BTFSC SSPSTAT,2
  112. GOTO $-1
  113.  
  114. MOVLW 0xFF
  115. BANKSEL i2c_add_search_delay
  116. MOVWF i2c_add_search_delay
  117. MOVLW i2c_add_search_delay
  118. DECFSZ i2c_add_search_delay,1;decrement W, update W, skip if zero
  119. ;here 0, or 1 both mean the same
  120. GOTO $-1
  121.  
  122. BANKSEL SSPCON2
  123. BTFSS SSPCON2, ACKSTAT ;bit ->0 means ack received
  124. GOTO addr_search_break
  125. ;MOVF i2c_address,0 ;restore the address, increment
  126. ;INCFSZ W,0 ;on a rollover FF-> 0 break out
  127. BANKSEL i2c_address
  128. INCFSZ i2c_address,1 ;increment add, resotre to w, skip on rollover
  129. GOTO addr_search_again
  130.  
  131. addr_search_break:
  132. BANKSEL i2c_address
  133. MOVF i2c_address, 0
  134. BANKSEL STATUS
  135. BTFSC STATUS, Z ;skip if zero flag not set, else return 0
  136. RETLW 0x00 ;0 indicates no response on all address.
  137. RETLW 0x01
  138.  
  139. LCD_I2C_INF_LOOP:
  140. ;just an infinite loop writing via I2C to the LCD
  141. ;this is just used to manually program it during ICD
  142. ;For the i2c lcd backpack, this is the pin mapping (D0-3 are tied high for 4bit md)
  143. ;Bit 7 6 5 4 3 2 1 0
  144. ;conn D7 D6 D5 D4 LED e rw rs
  145.  
  146. ;To use the 1602 in 4 bit mode follow these rules:
  147.  
  148. ;1. Start with the 4 bit config write. The lower nibble is tied low/high. so
  149. ;the first one would effectivley be an 8 bit write to set 4 bit mode
  150. ;i.e. 88,8c,88 (e -> 0,1,0 with constant data). When it switches modes, it auto
  151. ;goes into 2 rows mode dunno why
  152.  
  153. ;2. Now it's in 4 bit mode, send nibbles msb first, strobing e every time
  154. ;e.g to set the row count to two, 5x7 char 28,2c,28,88,8c,88
  155.  
  156. ;3. clear the display and we can start using it for displaying letter.
  157. ;CALL START_I2C
  158. CALL I2C_START
  159. BANKSEL i2c_address
  160. MOVF i2c_address, 0
  161. MOVWF i2c_write_data
  162. CALL WRITE_I2C ;write address
  163. NOP
  164. CALL WAIT_I2C
  165. ;directly modify i2c_write_data address
  166. NOP
  167. CALL WRITE_I2C
  168. NOP
  169. CALL STOP_I2C
  170. NOP
  171. GOTO LCD_I2C_INF_LOOP
  172. RETURN
  173.  
  174.  
  175. END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement