PIC的一个读写I2C程序

pic的一个读写i2c程序
title two wire/i2c bus interface with pic16c5x
;
list p=16c54
;
;************************************************************
;** two wire/i2c bus read/write sample routines of microchip's
;** 24cxx / 85cxx serial cmos eeprom interfacing to a
;** pic16c54 8-bit cmos single chip microcomputer
;** revsied version 2.0 (4/2/92).
;**
;** part use = pic16c54-xt/jw
;** note: 1) all timings are based on a reference crystal frequency of 2mhz
;** which is equivalent to an instruction cycle time of 2 usec.
;** 2) address and literal values are read in octal unless otherwise
;** specified.
;********************************************************
;
;-----------------------------------------------------------------------------
; files assignment
;-----------------------------------------------------------------------------
;
pc equ 2 ; program counter
stat equ 3 ; pic status byte
fsr equ 4 ; file select register
ra equ 5 ; port a use to select device address
rb equ 6 ; rb7 = sda, rb6 = scl
;
status equ 08 ; status register
flag equ 09 ; common flag bits register
eeprom equ 0a ; bit buffer
ercode equ 0b ; error code (to indicate bus status)
addr equ 10 ; address register
datai equ 11 ; stored data input register
datao equ 12 ; stored data output register
slave equ 13 ; device address (1010xxx0)
txbuf equ 14 ; tx buffer
rxbuf equ 15 ; rx buffer
count equ 16 ; bit counter
;
timer0 equ 18 ; delay timer0
timer1 equ 19 ; delay timer1
;
;
;-----------------------------------------------------------------------------
; bit assignments
;-----------------------------------------------------------------------------
;
; status bits
;
z equ 2
c equ 0
;
; flag bits
;
error equ 0 ; error flag
;
; eeprom bits
;
di equ 7 ; eeprom input
do equ 6 ; eeprom output
;
; i2c device bits
;
sda equ 7 ; rb7, data in/out
scl equ 6 ; rb6, serial clock
;
;end files/bits equate
page
;
;-----------------------------------------------------------------------------
; two wire/i2c - cpu communication error status table and subroutine
;-----------------------------------------------------------------------------
; input : w-reg = error code
; output : ercode = error code
; flag(error) = 1
;
; code error status mode
; ------- ------------------------------------------------------
; 1 : scl locked low by device (bus is still busy)
; 2 : sda locked low by device (bus is still busy)
; 3 : no acknowledge from device (no handshake)
; 4 : sda bus not released for master to generate stop bit
;-----------------------------------------------------------------------------
;
;subroutine to identify the status of the serial clock (scl) and serial data
;(sda) condition according to the error status table. codes generated are
;useful for bus/device diagnosis.
;
err
btfss flag,error ; remain as first error encountered
movwf ercode ; save error code
bsf flag,error ; set error flag
retlw 0
;
;-----------------------------------------------------------------------------
; start bus communication routine
;-----------------------------------------------------------------------------
; input : none
; output : initialize bus communication
;-----------------------------------------------------------------------------
;
;generate start bit (scl is high while sda goes from high to low transition)
;and check status of the serial clock.
bstart
movlw b'00111111' ; put scl, sda line in output state
tris rb
;**************************************************************
bsf rb,sda ;make sure sda is high
;*******************************************************
bsf rb,scl ; set clock high
movlw 1 ; ready error status code 1
btfss rb,scl ; locked?
call err ; scl locked low by device
bcf rb,sda ; sda goes low during scl high
nop ; timing adjustment
nop
nop
bcf rb,scl ; start clock train
retlw 0
;
;end sub
page
;
;-----------------------------------------------------------------------------
; stop bus communication routine
;-----------------------------------------------------------------------------
; input : none
; output : bus communication, stop condition
;-----------------------------------------------------------------------------
;
;generate stop bit (sda goes from low to high during scl high state)
;and check bus conditions.
;
bstop
;*********************************************************
movlw b'00111111' ; put scl, sda line in output state
tris rb
;**************************************************************
bcf rb,sda ; return sda to low
bsf rb,scl ; set scl high
nop
nop
nop
movlw 1 ; ready error code 1
btfss rb,scl ; high?
call err ; no, scl locked low by device
bsf rb,sda ; sda goes from low to high during scl high
movlw 4 ; ready error code 4
btfss rb,sda ; high?
call err ; no, sda bus not release for stop
retlw 0
;
;end sub
;
;-----------------------------------------------------------------------------
; serial data send from pic to serial eeprom, bit-by-bit subroutine
;-----------------------------------------------------------------------------
; input : none
; output : to (di) of serial eeprom device
;-----------------------------------------------------------------------------
;
bitin
movlw b'10111111' ; force sda line as input
tris rb
bsf rb,sda ; set sda for input
bcf eeprom,di
bsf rb,scl ; clock high
movlw 1
btfsc rb,scl ; skip if scl is high
goto bit1
btfss flag,error ; remain as first error encountered
movwf ercode ; save error code
bsf flag,error ; set error flag
bit1
btfsc rb,sda ; read sda pin
bsf eeprom,di ; di = 1
nop ; delay
bcf rb,scl ; return scl to low
retlw 0
;
;end sub
page
;
;-----------------------------------------------------------------------------
; serial data receive from serial eeprom to pic, bit-by-bit subroutine
;-----------------------------------------------------------------------------
; input : eeprom file
; output : from (do) of serial eeprom device to pic
;-----------------------------------------------------------------------------
;
bitout
movlw b'00111111' ; set sda, scl as outputs
tris rb
btfss eeprom,do
goto bit0
bsf rb,sda ; output bit 0
movlw 2
btfsc rb,sda ; check for error code 2
goto clk1
btfss flag,error ; remain as first error encountered
movwf ercode ; save error code
bsf flag,error ; set error flag
goto clk1 ; sda locked low by device
;
bit0
bcf rb,sda ; output bit 0
nop ; delay
nop
nop
clk1
bsf rb,scl
movlw 1 ; error code 1
btfsc rb,scl ; scl locked low?
goto bit2 ; no.
btfss flag,error ; yes.
movwf ercode ; save error code
bsf flag,error ; set error flag
bit2
nop
nop
bcf rb,scl ; return scl to low
retlw 0
;
;end sub
page
;
;
;-----------------------------------------------------------------------------
; receive data subroutine
;-----------------------------------------------------------------------------
; input : none
; output : rxbuf = receive 8-bit data
;-----------------------------------------------------------------------------
;
rx
movlw .8 ; 8 bits of data
movwf count
clrf rxbuf
;
rxlp
rlf rxbuf ; shift data to buffer
skpc
bcf rxbuf,0 ; carry ---> f(0)
skpnc
bsf rxbuf,0
call bitin
btfsc eeprom,di
bsf rxbuf,0 ; input bit =1
decfsz count ; 8 bits?
goto rxlp
bsf eeprom,do ; set acknowledge bit = 1
call bitout ; to stop further input
retlw 0
;
;end sub
;
;-----------------------------------------------------------------------------
; transmit data subroutine
;-----------------------------------------------------------------------------
; input : txbuf
; output : data x'mitted to eeprom device
;-----------------------------------------------------------------------------
;
tx
movlw .8
movwf count
;
txlp
bcf eeprom,do ; shift data bit out.
btfsc txbuf,7 ; if shifted bit = 0, data bit = 0
bsf eeprom,do ; otherwise data bit = 1
call bitout ; serial data out
rlf txbuf ; rotate txbuf left
skpc ; f(6) ---> f(7)
bcf txbuf,0 ; f(7) ---> carry
skpnc ; carry ---> f(0)
bsf txbuf,0
decfsz count ; 8 bits done?
goto txlp ; no.
call bitin ; read acknowledge bit
movlw 3
btfsc eeprom,di ; check for acknowledgement
call err ; no acknowledge from device
retlw 0
;
;end sub
page
;
;-----------------------------------------------------------------------------
; byte-write, write one byte to eeprom device
;-----------------------------------------------------------------------------
; input : datao= data to be written
; addr = destination address
; slave = device address (1010xxx0)
; output : data written to eeprom device
;-----------------------------------------------------------------------------
;
org 080 ; the location for byte-write routine can be
; ; assigned anywhere between (377-777) octal.
wrbyte
movf slave,w ; get slave address
movwf txbuf ; to tx buffer
call bstart ; generate start bit
call tx ; output slave address
movf addr,w ; get word address
movwf txbuf ; into buffer
call tx ; output word address
movf datao,w ; move data
movwf txbuf ; into buffer
call tx ; output data and detect acknowledgement
call bstop ; generate stop bit
goto wrt_end
;
;
;
;-----------------------------------------------------------------------------
; byte-read, read one byte from serial eeprom device
;-----------------------------------------------------------------------------
; input : addr = source address
; slave = device address (1010xxx0)
; output : datai = data read from serial eeprom
;-----------------------------------------------------------------------------
;
org 0c0 ; the location for byte-read routine can be
; ; assigned anywhere between (377-777) octal.
rdbyte
movf slave,w ; move slave address
movwf txbuf ; into buffer (r/w = 0)
call bstart ; generate start bit
call tx ; output slave address. check ack.
movf addr,w ; get word address
movwf txbuf
call tx ; output word address. check ack.
call bstart ; start read (if only one device is
movf slave,w ; connected to the i2c bus)
movwf txbuf
bsf txbuf,0 ; specify read mode (r/w = 1)
call tx ; output slave address
call rx ; read in data and acknowledge
call bstop ; generate stop bit
movf rxbuf,w ; save data from buffer
movwf datai ; to datai file.
goto rd_end
;
;test program to read and write ramdom
start
movlw 0ae ;set a2=a1=a0=1
movwf slave ; /
movlw 2 ;set r/w loc. = 2
movwf addr ; /
movlw 55 ;write 55 to seeprom
movwf datao ; /
goto wrbyte ;write a byte
wrt_end
call delay ;wait for write
;operation (internal)
goto rdbyte ;read back data
rd_end
movlw 55 ;test if read
xorwf datai,w ;correct?
btfss stat,z ;yes then skip
wrong
goto wrong
correct
goto correct
;
;at 2.0mhz, delay = approx. 3ms.
delay
clrf 1f ;clear last location
dly1
nop
nop
nop
decfsz 1f ;reduce count
goto dly1 ;loop
retlw 0
;
org 0x1ff
goto start
;
end

12V~24V车载电源的设计与制作
新晋网红追觅3D立体避障扫拖机器人L10 Pro有哪些亮点
小米集团公布2018全年财报,董明珠“10亿赌局”的钱没找雷军要
LED投光灯和LED泛光灯存在的区别是什么
网友吐槽AirPods Max耳机出现水汽
PIC的一个读写I2C程序
凌华科技推出全新EtherCAT模块 为工业自动化提供完整的EtherCAT解决方案
怎样用一根线控制两个接触器
综合能源服务生态空间复杂度越高,数据智能发挥的作用越大
微软称“64位Windows很安全 几乎不中毒”
E拆解:简单拆解小米手环4,小爱同学藏哪呢?
贸泽电子联手安森美半导体推出全新资源网站,探索高功率电源转换策略与解决方案
如何移植OpenHarmony轻量系统
C语言总结_函数知识
应用NIST CSF网络的5个详细步骤
华为荣耀magic评测:与华为mate 9的评测对比
电脑主板的跳线连接方法
“中国制造”让韩国产生了紧张感
传IBM拟出售部分业务以专注云计算业务
芒果TV与洲明科技达成合作 共研、共享虚拟拍摄创新成果