注:本文是作者以前發表在其個人博客,現在發布到電子發燒友專欄
本例是用針對標準I2C接口EEPROM存儲器24C02進行讀寫操作,只要對例程做適當修改,就可以用到大部分控制I2C接口設備的場合。
應廣單片機軟件I2C接口例程(MASTER模式)
本例僅供參考,歡迎指正程序中的問題
//-----------------------------------------
.chip p201cs14a
//{{PADAUK_CODE_OPTION
.Code_OptionBootupSlow// 1024 ILRC
.Code_OptionLVD2.79V// Maximum performance = 4 MIPS
.Code_OptionSecurityEnable// Security 3/4 words Enable
//}}PADAUK_CODE_OPTION
//定義I2C接口
I2C_SDAequpa.7
I2C_SCLequpa.6
I2C_SDA_DIRequpac.7
I2C_SCL_DIRequpac.6
I2C_LONG_DLYequ50
I2C_SHORT_DLYequ20
I2C_SDA_HIGHequset1I2C_SDA
I2C_SDA_LOWequset0I2C_SDA
I2C_SCL_HIGHequset1I2C_SCL
I2C_SCL_LOWequset0I2C_SCL
I2C_SDA_OUTPUTequset1I2C_SDA_DIR
I2C_SDA_INPUTequset0I2C_SDA_DIR
I2C_SCL_OUTPUTequset1I2C_SCL_DIR
I2C_SCL_INPUTequset0I2C_SCL_DIR
//定義I2C變量
bytei2c_rw_addr//讀寫地址
bytei2c_rw_byte//讀寫數據
bytei2c_rw_cmd//讀寫的器件地址
bytei2c_rw_temp//讀寫過程中間變量
bytei2c_rw_cnt//讀寫過程中間變量
//
byteXms
bytems_cnt
//
bytetest_addr
bytetest_data
.romadr0x000
gotomain0
gotomain1
.romadr0x010
isr_entry:
pushaf
intrq = 0
popaf
reti
//----------------------------
//產生START信號
//----------------------------
i2c_start:
I2C_SDA_OUTPUT
I2C_SCL_OUTPUT
I2C_SDA_HIGH
delayI2C_LONG_DLY
I2C_SCL_HIGH
delayI2C_LONG_DLY
I2C_SDA_LOW
delayI2C_LONG_DLY
I2C_SCL_LOW
delayI2C_LONG_DLY
ret
//----------------------------
//產生STOP信號
//----------------------------
i2c_stop:
I2C_SCL_LOW
delayI2C_LONG_DLY
I2C_SDA_LOW
delayI2C_LONG_DLY
I2C_SCL_HIGH
delayI2C_LONG_DLY
I2C_SDA_HIGH
delayI2C_LONG_DLY
//
I2C_SCL_INPUT
I2C_SDA_INPUT
ret
//----------------------------
//檢查SALVE ACK信號
//----------------------------
i2c_slave_ack:
//don't check ACK
I2C_SDA_INPUT
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
I2C_SDA_OUTPUT
I2C_SDA_LOW
delayI2C_SHORT_DLY
ret
//----------------------------
//輸出MASTER ACK信號
//----------------------------
i2c_master_ack:
I2C_SDA_OUTPUT
I2C_SDA_LOW
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
ret
//----------------------------
//輸出MASTER NACK信號
//----------------------------
i2c_master_nack:
I2C_SDA_OUTPUT
I2C_SDA_HIGH
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
ret
//------------------------------
//寫一個字節
//Input: i2c_rw_temp
//Used: i2c_rw_cnt
//------------------------------
i2c_write_8bit:
i2c_rw_cnt = 8
i2c_write_8bit_loop:
slci2c_rw_temp
swapcI2C_SDA
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY
dzsni2c_rw_cnt
gotoi2c_write_8bit_loop
ret
//------------------------------
//讀一個字節
//Used: i2c_rw_cnt
//Output: i2c_rw_temp
//------------------------------
i2c_read_8bit:
i2c_rw_temp = 0
i2c_rw_cnt = 8
delayI2C_SHORT_DLY
i2c_read_8bit_loop:
I2C_SCL_HIGH
delayI2C_SHORT_DLY
swapcI2C_SDA
slci2c_rw_temp
I2C_SCL_LOW
delayI2C_SHORT_DLY
dzsni2c_rw_cnt
gotoi2c_read_8bit_loop
ret
//------------------------------
//Input: i2c_rw_addr
// i2c_rw_cmd
//Used: i2c_rw_cnt
// i2c_rw_temp
//Output: i2c_rw_byte
//------------------------------
i2c_read_byte:
//start
calli2c_start
//write device address(write)
i2c_rw_temp = i2c_rw_cmd
calli2c_write_8bit
//slave ack
calli2c_slave_ack
//write register address
i2c_rw_temp = i2c_rw_addr
calli2c_write_8bit
//slave ack
//don't check ACK
calli2c_slave_ack
//start repeat
calli2c_start
//write device address(read)
i2c_rw_temp = i2c_rw_cmd
i2c_rw_temp.0 = 1
calli2c_write_8bit
//slave ack
//don't check ACK
I2C_SDA_INPUT
delayI2C_SHORT_DLY
I2C_SCL_HIGH
delayI2C_SHORT_DLY
I2C_SCL_LOW
delayI2C_SHORT_DLY//這里為特殊情況I2C_SDA不用轉為輸出
//read data
i2c_rw_temp = 0
calli2c_read_8bit
i2c_rw_byte = i2c_rw_temp//store data
//master nack
calli2c_master_nack
//stop
calli2c_stop
//retune
delayI2C_LONG_DLY
wdreset
ret
//------------------------------
//Input: i2c_rw_addr
// i2c_rw_byte
// i2c_rw_cmd
//Used: i2c_rw_cnt
// i2c_rw_temp
//------------------------------
i2c_write_byte:
//start
calli2c_start
//write device address
i2c_rw_temp = i2c_rw_cmd
calli2c_write_8bit
//slave ack
//don't check ACK
calli2c_slave_ack
//write register address
i2c_rw_temp = i2c_rw_addr
calli2c_write_8bit
//slave ack
//don't check ACK
calli2c_slave_ack
//write data
i2c_rw_temp = i2c_rw_byte
calli2c_write_8bit
//slave ack
//don't check ACK
calli2c_slave_ack
//stop
calli2c_stop
//retune
delayI2C_LONG_DLY
wdreset
ret
EEPROM_RW_CMDequ0xA0
//------------------------------
//函數名: eeprom_read_byte
//Input: i2c_rw_addr
//Used: i2c_rw_cnt
// i2c_rw_temp
//Output: i2c_rw_byte
//------------------------------
eeprom_read_byte:
i2c_rw_cmd = EEPROM_RW_CMD
gotoi2c_read_byte//注意這里用的是跳轉
//------------------------------
//函數名: eeprom_write_byte
//Input: i2c_rw_addr
// i2c_rw_byte
//Used: i2c_rw_cnt
// i2c_rw_temp
//注意: 調用完后需要等待一段時間以保證寫操作完成
//------------------------------
eeprom_write_byte:
i2c_rw_cmd = EEPROM_RW_CMD
gotoi2c_write_byte//注意這里用的是跳轉
//----------------------------------------
//input: ms
//該函數以4M頻率為基準時鐘實現延時
//----------------------------------------
delayXms:
while(Xms)
{
wdreset
ms_cnt = 20
while(ms_cnt)
{
delay195
ms_cnt--
}
Xms--
}
ret
main0:
.ADJUST_OTP_IHRCR8MIPS// IHRC/2 = 8MIPS, WatchDog Disable, RAM 0,1 temporary be used
sp = 0x30
disgint
inten = 0
pa = 0b0000_0000
paph = 0b1101_0000
pac = 0b0000_0001
pb = 0b0000_0000
pbph = 0b0000_0000
pbc = 0b1111_1111
I2C_SDA_INPUT
I2C_SCL_INPUT
delay200
mova,0b100_11_111
movt16m,a
clkmd.1 = 1//enable watch dog
wdreset
Xms = 100
calldelayXms
test_data = 0
test_addr = 0
main0_loop:
wdreset
//寫E2EPROM
i2c_rw_addr = test_addr
i2c_rw_byte = test_data
calleeprom_write_byte
//調用EEPROM寫操作函數后要等待一段時間,以保證數據寫操作完成
Xms = 20
calldelayXms
//讀E2EPROM
i2c_rw_addr = test_addr
calleeprom_read_byte
if(i2c_rw_byte != test_data)
{
//讀回的數據比較出錯,判斷為讀寫E2PROM出錯
nop
}
test_addr ++
test_data --
gotomain0_loop
//----------------FPPA1-------------------
main1:
sp = 52
main1_loop:
gotomain1_loop
本例代碼是從實際程序中移植而來,已編譯,未做最終調試
-
單機片
+關注
關注
0文章
51瀏覽量
11801
發布評論請先 登錄
相關推薦
I2C總線與Arduino的接口示例
I2C總線與單片機的連接
I2C總線應用實例分析
UC-001:MicroConverter I2C兼容接口
![UC-001:MicroConverter <b class='flag-5'>I2C</b>兼容<b class='flag-5'>接口</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
用tvl320aic32完成通話的功能,單片機i2s接口發送的數據aic32接收不到怎么解決?
51單片機STC8H8K64U通過RA8889/RA8876如何控制彩屏 I2C源碼下載
![51<b class='flag-5'>單片機</b>STC8H8K64U通過RA8889/RA8876如何控制彩屏 <b class='flag-5'>I2C</b>源碼下載](https://file1.elecfans.com/web2/M00/F5/17/wKgZomZ-al2AHDocABQ4vQBctks963.jpg)
CYUSB3014通過I2C EEPROM啟動時,收到了I2C EEPROM編程失敗的錯誤信息怎么解決?
如何通過cyusb3014的i2c操作界面操作ads1119的i2c接口?
利用軟件模擬i2c讀寫EEPROM,超過256個字節就讀寫不了了的原因?如何處理?
STM32F103利用軟件模擬I2C讀寫EEPROM,超過385個字節就讀寫不了的原因?
stm32f4軟件模擬I2C讀寫EEPROM無器件響應是什么原因造成的?
i2c接口由哪幾根線組成 i2c接口可以接哪些器件
![<b class='flag-5'>i2c</b><b class='flag-5'>接口</b>由哪幾根線組成 <b class='flag-5'>i2c</b><b class='flag-5'>接口</b>可以接哪些器件](https://file1.elecfans.com/web2/M00/C2/B4/wKgZomXm3k6AZmDMAAA1TY4XfOI571.png)
什么是I2C接口?什么是I3C接口?I2C與I3C的區別
![什么是<b class='flag-5'>I2C</b><b class='flag-5'>接口</b>?什么是<b class='flag-5'>I3C</b><b class='flag-5'>接口</b>?<b class='flag-5'>I2C</b>與<b class='flag-5'>I3C</b>的區別](https://file1.elecfans.com/web2/M00/BC/CA/wKgZomWmIsKARiRgAAC_1I6QLUY175.jpg)
評論