|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測(cè)控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動(dòng)編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
求助:?jiǎn)纹瑱C(jī)模擬IIC讀寫AT24c02出錯(cuò) |
| 作者:judylea 欄目:單片機(jī) |
各位高手,我最近在用51單片機(jī)讀寫EEPROM時(shí)出現(xiàn)一個(gè)很奇怪的現(xiàn)象:比如說我要寫16個(gè)byte的東西進(jìn)去,可經(jīng)常寫不進(jìn)去或只能寫進(jìn)部分,其他的要么是0,要么是FF。 單片機(jī):AT89C51 晶振: 6MHZ 電路: 24C02的SCL和SDA分別接有10K上拉電阻,其他腳接低電平。 (之所以用匯編寫是因?yàn)槲也粫?huì)用Keil C) 下面是我的程序,請(qǐng)各位指點(diǎn)。其實(shí)這些子程序以前是用過的,讀寫都沒有問題。只是現(xiàn)在其他項(xiàng)目要用,挪過去時(shí)發(fā)生的問題。 MAIN: MOV R6,#0 MOV R0,#reg0 MOV R3,#16 LCALL SEEPROM_savedata AJMP $ (我將reg0~reg16的內(nèi)容設(shè)為0~16,結(jié)果讀出來(lái)的0000H~0016H的數(shù)據(jù)為9、A、B、C、D、E、F,后面就全為0了) ;===================================================================== SEEPROM_savedata: LCALL IIC_write_head SEEPROM_savenext: MOV A,@R0 LCALL IIC_write_byte INC R0 DJNZ R3,SEEPROM_savenext LCALL IIC_stop RET ;=====================================================================; input: R6 --- seeprom start address ; OUTPUT: NONE ; used: A ;===================================================================== IIC_Write_head: SCL_HIGH ; SDA_HIGH ; SCL - SDA - CALL DelayXus SDA_LOW ; SCL -- SDA -_ start bit CALL DelayXus SCL_LOW ; SCL --1 SDA -__ MOV A,#IICWRITECOM ; send write command ACALL IIC_write_byte SCL_LOW ; SCL...__--| MOV A,R6 ; send write addr. ACALL IIC_write_byte RET ;=====================================================================; input: A ; OUTPUT: NONE ; used: R7 ;===================================================================== ; SCL ...--| IIC_write_byte: MOV R7,#8 CLR C IIC_write_bits: CALL DelayXus ; SCL ...--_ RLC A ; SDA ...x JC IIC_write_high SDA_LOW AJMP IIC_write_bits_end IIC_write_high: SDA_HIGH IIC_write_bits_end: ACALL DelayXus ; SCL ...--__ SDA ...x SCL_HIGH ; SCL ...--__-- SDA ..... CALL DelayXus CALL DelayXus SCL_LOW ; SCL ...--__--1 SDA ...... DJNZ R7, IIC_write_bits ; acknowledge ACALL DelayXus ; SCL ...__ ACALL DelayXus SCL_HIGH ; SCL ...__-- ACALL DelayXus ACALL DelayXus SCL_LOW ; SCL ...__-- RET ;=====================================================================; input: NONE ; OUTPUT: A ;=====================================================================IIC_read_head: SCL_HIGH ; SDA_HIGH ; SCL - SDA - CALL DelayXus SDA_LOW ; SCL -- SDA -_ start bit CALL DelayXus SCL_LOW ; SCL --1 SDA -__ MOV A,#IICREADCOM ; send read command ACALL IIC_write |
| 2樓: | >>參與討論 |
| 作者: fsjt 于 2006/4/6 0:14:00 發(fā)布:
可能是時(shí)鐘頻率的問題 我原來(lái)用X25045的時(shí)候,就是由于時(shí)鐘的問題讀寫出錯(cuò),后來(lái)我連續(xù)單步運(yùn)行可以,然后我把時(shí)鐘調(diào)到4M就沒問題了.為了分?jǐn)?shù),來(lái)灌水了,不過還是希望能幫上點(diǎn)什么 |
|
| 3樓: | >>參與討論 |
| 作者: diannaoza 于 2006/4/6 4:07:00 發(fā)布:
我寫的很準(zhǔn)時(shí)序,估計(jì)是你寫的時(shí)序不準(zhǔn)。 看看能不能幫上你忙,在這BBS上發(fā)過,現(xiàn)在貼過來(lái) 匯編]I2C讀寫程序,可工作于24MHZ-6MHZ. ;;;;匯編i2c讀時(shí)序圖;;;12MHZ;數(shù)為a0,00,a1,57;;;; ;;;;此程序可以在d:0x40h中(可以看到剛從,30H中數(shù)為57H;;;; ;;;;寫入24C02的00h中并從24C02中的00H中讀出到40h) ;;;; ;;;;可工作于6Mhz-24Mhz;;;; scl bit p1.7 sda bit p1.6 org 0000h ajmp main org 30h main: setb 20h mov sp,#5fh mov r1,#40h;;;;;讀到40h中;;;; mov r0,#30h mov 30h,#57h;;;;想寫的數(shù);;;; mov r3,#00h;;;;24C02地址;;;; re1: acall write1;;;;;;; acall read1 inc 30h ajmp re1 write1: acall stara0 mov a,r3;;;address acall iw mov a,@r0;;;;soure data acall iw acall stop ret read1: acall stara0 mov a,r3;;;address acall iw acall stara1 acall ir acall stop ret stara0:;;;;;start iw setb sda;;;;star: setb scl clr sda nop nop nop ;;;;scl for h 5us clr scl clr scl mov a,#0a0h ;;1 iw:mov r7,#08h;;1 a0w8:clr scl rlc a;;1 mov sda,c;;;;1 nop nop setb scl nop djnz r7,a0w8;;;;時(shí)鐘低為7us clr scl setb sda;;;;確認(rèn)24C02是否拉低電平。若不拉低則 nop;;;;ack: nop nop setb scl mov c,sda;;;;在這就可以知道出錯(cuò);;;; mov 10h,c nop clr scl ret stara1:;;;;;start_iw_a1 setb sda;;;;star: setb scl clr sda nop nop nop ;;;;scl for h 5us clr scl clr scl mov a,#0a1h ;;1 iwa1:mov r7,#08h;;1 iw8a1:clr scl rlc a;;1 mov sda,c;;;1 nop nop setb scl nop djnz r7,iw8a1;;;時(shí)鐘低為5us clr scl setb sda nop ;;; si2cack: nop;;;;;;;保持與寫的時(shí)鐘一至為5us nop setb scl mov c,sda mov 20h,c nop clr scl ret ir: mov r7,#08h;;;;;;單字節(jié)讀 rw8:nop nop setb scl mov c,sda rlc a nop clr scl djnz r7,rw8 setb sda mov @r1,a i2cnmack: setb scl nop nop nop clr scl clr sda nop ret mack:;;;;連續(xù)讀的主應(yīng)答;;;要不然24C02不知道你什么時(shí)候讀下一個(gè)? clr sda nop nop setb scl nop nop nop clr scl setb sda | |
| 4樓: | >>參與討論 |
| 作者: 110xia 于 2006/4/6 9:13:00 發(fā)布:
看一下我寫的程序 到"軟件交流"欄下"51讀寫24C04程序欣賞面" M=11.0595 |
|
| 5樓: | >>參與討論 |
| 作者: kimfufree 于 2006/4/6 11:03:00 發(fā)布:
我遇到過同樣的問題。 從你描述的情況看,應(yīng)該是時(shí)序不匹配引起的。24C02有提到PAGE Write功能。只能一下子寫7個(gè)。再想寫的話就會(huì)后面的值會(huì)覆蓋前面的值。不過有補(bǔ)救方法就是寫完7個(gè)后再?gòu)腟tart信號(hào)接著寫。我不太熟匯編,我用C寫的,測(cè)試過了。延時(shí)可根據(jù)實(shí)際加長(zhǎng)或減短。 void Eeprom_Write(BYTE subaddress,BYTE *databuffer,BYTE datalen) { BYTE datanum,temp2; BYTE pagei; temp2=datalen; for( pagei=0;pagei<=(datalen/8);pagei++) { if(temp2>8) { datanum=8; temp2-=8; } else datanum=temp2; if (pagei == 0) { I2C_Start(); I2C_WriteByte(EEPROMWRITEADDRESS); I2C_Ack(); I2C_WriteByte(subaddress); I2C_Ack(); for(;datanum!=0;datanum--) { I2C_WriteByte(*databuffer); I2C_Ack(); databuffer++; } I2C_Stop(); Delay_X_us(300); } else { I2C_Start(); I2C_WriteByte(EEPROMWRITEADDRESS); I2C_Ack(); I2C_WriteByte(subaddress+pagei*8); I2C_Ack(); for(;datanum!=0;datanum--) { I2C_WriteByte(*databuffer); I2C_Ack(); databuffer++; } I2C_Stop(); Delay_X_us(300); } } } |
|
| 6樓: | >>參與討論 |
| 作者: hunao 于 2006/4/7 6:30:00 發(fā)布:
還是沒看好好看資料。。! 24C01A、24C02A連續(xù)寫的時(shí)候是頁(yè)寫模式以,8字節(jié)為一頁(yè),頁(yè)邊界是8的倍數(shù),有一個(gè)8字節(jié)的頁(yè)緩沖區(qū)。連續(xù)寫的時(shí)候,先寫到了頁(yè)緩沖中,如果地址超過頁(yè)邊界會(huì)發(fā)生頁(yè)回卷,比如從地址7開始連續(xù)寫了兩個(gè)字節(jié),第二個(gè)字節(jié)實(shí)際上寫到了地址0,所以,當(dāng)寫到頁(yè)邊界的時(shí)候要暫停一下,等數(shù)據(jù)實(shí)際寫入以后才能繼續(xù)寫下一批,最多不超過8個(gè)字節(jié)。 從你讀出的數(shù)據(jù)看,你的讀寫時(shí)序沒有錯(cuò),是發(fā)生了回卷,后8個(gè)把前8個(gè)給覆蓋了。 |
|
| 7樓: | >>參與討論 |
| 作者: fly1978 于 2006/4/7 10:15:00 發(fā)布:
ZLGMCU上有IC2的數(shù)據(jù)包,拿來(lái)就可以用。 ZLGMCU上有IC2的程序包,拿來(lái)就可以用。 用后可不要感謝一下ZLG 同時(shí)不要忘記好好讀讀它的免費(fèi)程序包。 |
|
|
|
| 免費(fèi)注冊(cè)為維庫(kù)電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào) |