最近寫了幾個程序,一個是用51單片機讀取模數(shù)傳感器adc0832的電壓值,一個是讀取ds1302的時間值,結(jié)果都出現(xiàn)了讀數(shù)一直為0的情況。我調(diào)試了近一個星期,修改了一個我認為不可能會錯的句子,程序運行成功了,這才發(fā)現(xiàn)了一個極其隱蔽的錯誤。(我用的是xp系統(tǒng),用keil4軟件編譯)
先上代碼:第一個為錯誤代碼,第二個為正確代碼。這是用來向ds1302芯片寫入命令或數(shù)據(jù)的函數(shù)。實現(xiàn)把8位的數(shù)據(jù)dat一位一位地寫入ds1302的io口。其中ACC0為ACC的第0位。
//for(i=0;i<8;i++),ACC版
void ds1302_input(uchar dat)
{
uchar i; //uchar= unsigned char
ACC = dat; //ACC為51的累加器
for(i=0;i<8;i++)
{
DS1302_SCLK = 0; //ds1302的時鐘引腳
DS1302_IO = ACC0; //ds1302的io口
DS1302_SCLK = 1; //上升沿寫入數(shù)據(jù)
ACC >>= 1; //第一個不移動
}
}
//for(i=8;i>0;i--),ACC版
void ds1302_input(uchar dat)
{
uchar i;
ACC = dat;
for(i=8;i>0;i--)
{
DS1302_SCLK = 0;
DS1302_IO = ACC0;
DS1302_SCLK = 1; //上升沿寫入數(shù)據(jù)
ACC >>= 1; // 第一個不移動
}
}
認真對比這兩個代碼,可能會覺得沒區(qū)別,而且這兩個代碼都可以通過編譯(加上reg52.h和一些宏定義)。我也是一直認為for()這里邊沒有錯誤,結(jié)果。。。試著修改時鐘信號,增加延時之類的,調(diào)了好久還是錯,嚴(yán)重打擊我的自信心。這兩個代碼的區(qū)別就只有for(i=0;i<8;i++)和for(i=8;i>0;i--)了。學(xué)過c語言的人都知道,這兩個句子都是實現(xiàn)一個8次的循環(huán),功能一模一樣。怎么會因為這個句子的區(qū)別就導(dǎo)致單片機控制的錯誤呢?神奇!
接著我試著把錯誤程序中的ACC改為51芯片的寄存器B,燒錄進單片機,程序運行成功,跟“for(i=8;i>0;i--),ACC版”一樣,lcd在很囂張地顯示著正確的時間( for(i=0;i<8;i++),ACC版lcd的時間顯示為0)。附:
//for(i=0;i<8;i++),寄存器B版
void ds1302_input(uchar dat)
{
uchar i;
B = dat;
for(i=0;i<8;i++)
{
DS1302_SCLK = 0;
DS1302_IO = B0;
DS1302_SCLK = 1; //上升沿寫入數(shù)據(jù)
B >>= 1; //第一個不移動
}
}
這樣就知道原因了,使用for(i=0;i<8;i++)的運算中可能有累加器ACC參與了,導(dǎo)致修改了ACC的值,使寫入的命令出現(xiàn)錯誤。但為什么for(i=8;i>0;i--)就沒有ACC的參與呢?一個大大的問號。基于我調(diào)試了一個星期的程序,皆因為這一個神奇的錯誤,我實在不甘心,決定研究到底。于是,分別查看了這三個程序代碼用 keil4 編譯后得到的 匯編代碼。(學(xué)過匯編就是爽啊,哈)
;for(i=0;i>8;i++),ACC版 匯編中“;”后的這行句子是注釋
RSEG ?PR?_ds1302_input?DS1302
_ds1302_input:
USING 0
;---- Variable 'dat?141' assigned to Register 'R7' ----
MOV A,R7 ;實參值dat的數(shù)據(jù)存儲到r7寄存器,把r7的值賦給累加器ACC
CLR A ;把ACC清零(就是因為這句子導(dǎo)致程序有問題)
MOV R7,A ;把ACC的值賦給R7
?C0005:
CLR DS1302_SCLK ;時鐘線sclk清零
MOV C,ACC0 ;把ACC第0位賦值到進位寄存器C中
MOV DS1302_IO,C ;把c賦值給IO口,改變單片機的引腳值
SETB DS1302_SCLK ;時鐘線sclk置1
CLR C ;進位寄存器c清零
RRC A ;ACC右移一位
INC R7 ;寄存器R值加1
CJNE R7,#08H,?C0005 ;r7的值與8比較,不相等跳轉(zhuǎn)到?c005:循環(huán)
?C0008:
RET ;子函數(shù)返回
;for(i=8;i>0;i--)ACC版
RSEG ?PR?_ds1302_input?DS1302
_ds1302_input:
USING 0
;---- Variable 'dat?040' assigned to Register 'R7' ----
MOV A,R7 ;把實參值dat賦給寄存器ACC
;---- Variable 'i?041' assigned to Register 'R7' ----
MOV R7,#08H ;把8賦值給寄存器R7
?C0001:
CLR DS1302_SCLK ;此處跟i=0版的一樣
MOV C,ACC0
MOV DS1302_IO,C
SETB DS1302_SCLK
CLR C
RRC A
DJNZ R7,?C0001 ;r7的值減1,不是零跳轉(zhuǎn)到?c001,循環(huán)
?C0004:
RET
對比后,可以發(fā)現(xiàn),出錯的原因是for(i=0;i<8;i++)ACC版中,用ACC接收了實參(存儲的為要寫入的指令),然后在 for 循環(huán)前要給變量 “ i " 賦值時,要用到ACC清零,再把ACC中的零賦給 R7 ("i"的值存儲在R7)。這樣的話,原來存儲在ACC中的寫入指令就被清零,自然會導(dǎo)致控制出現(xiàn)錯誤,最終沒法讀取ds1302芯片的時間,故顯示為零。
而在for(i=8;i>0;i--)ACC版中,也用ACC接收了實參的值,但在 for 循環(huán)前,給變量“ i ” 賦值時,賦值為8,不需要用到ACC,所以ACC一直是存儲著實參中的指令,沒有被清零,所以能夠順利地向ds1302發(fā)送指令,從而能夠讀取到時間。
總結(jié):
因為用for(i=0;i for(i=n;i>0;i--)的習(xí)慣。 請不要反駁我用了這么長的時間去研究,只能使單片機執(zhí)行快2us,而說我鉆牛角尖,只是因為,這個錯誤導(dǎo)致我整個程序無法正常運行,這不是一件小事。 至于為什么要用到累加器ACC來接收實參,是因為后面的程序要把一個8位的實參一位一位地輸出到一個io口,自定義一個變量的話,按位尋址好像比較麻煩,要經(jīng)過一系列 位運算 ,或者用bit定義8個位(有好的方法請告訴我,哈),而且我寫不出來。而用ACC的話,可以很輕易地操作ACC的任意一位,如ACC0,ACC7。在網(wǎng)上查了一下,好像還有一種方法是定義 一種叫 位域 的東東,我看的c語言的書都沒介紹,所以還不是很了解。 /************************************************************/ 剛剛想了一下,不用ACC 的方法,作一個位運算dat &0x01,修改如下: //for(i=0;i<8;i++),ACC版 void ds1302_input(uchar dat) { uchar i; //uchar= unsigned char for(i=0;i<8;i++) { DS1302_SCLK = 0; //ds1302的時鐘引腳 DS1302_IO = dat & 0x01; //ds1302的io口 DS1302_SCLK = 1; //上升沿寫入數(shù)據(jù) dat >>= 1; //第一個不移動 } } 想到了這個方法后,覺得自己好白癡,以后都不用ACC了。
上一篇:Keil(C51)介紹、下載、安裝與注冊
下一篇:51單片機學(xué)習(xí)筆記(五)
推薦閱讀
史海拾趣
寶士曼第三代半導(dǎo)體研發(fā)生產(chǎn)項目位于蘇州東山大道旁,占地50畝,計劃建設(shè)生產(chǎn)、研發(fā)、辦公等樓宇。項目整體將分二期建成,總建筑面積約70000平方米。已經(jīng)封頂?shù)?號樓建筑面積超11600平方米,主要用于第三代半導(dǎo)體器件專用封裝設(shè)備的研發(fā)生產(chǎn)。在施工過程中,寶士曼對環(huán)保和施工細節(jié)提出了更高的要求,要求地面每5平方米的高度誤差要小于3毫米,并在施工中做到“工完場清”,最大程度減少對今后生產(chǎn)的影響。這種對細節(jié)的嚴(yán)格要求體現(xiàn)了寶士曼對產(chǎn)品質(zhì)量和環(huán)保責(zé)任的重視。
Boundary Devices公司成立于2003年,總部位于美國亞利桑那州。創(chuàng)立之初,公司便專注于嵌入式系統(tǒng)硬件的開發(fā)與生產(chǎn),憑借對技術(shù)的深刻理解和市場需求的敏銳洞察,Boundary Devices迅速在行業(yè)中嶄露頭角。其推出的Boundary Devices插座和適配器,因其兼容性強、性能穩(wěn)定而備受市場青睞。同時,公司與NXP/Freescale建立了緊密的合作關(guān)系,共同推進i.MX系列處理器的應(yīng)用與發(fā)展,為公司的后續(xù)發(fā)展奠定了堅實的基礎(chǔ)。
隨著公司業(yè)務(wù)的不斷拓展,科通技術(shù)開始與國際知名品牌展開合作。通過與Xilinx、Intel、SanDisk等全球領(lǐng)先的芯片原廠建立緊密的合作關(guān)系,科通技術(shù)獲得了這些品牌的產(chǎn)品線授權(quán),并為其在中國市場的拓展提供了有力的支持。這些合作不僅提升了科通技術(shù)的品牌影響力,也為其帶來了更多的市場機會。
在電子行業(yè)的浪潮中,創(chuàng)都(CAX)公司憑借其卓越的技術(shù)創(chuàng)新能力,逐漸嶄露頭角。公司創(chuàng)始人李先生是一位熱衷于新技術(shù)的電子工程師,他帶領(lǐng)著一支由業(yè)內(nèi)頂尖人才組成的研發(fā)團隊,不斷挑戰(zhàn)技術(shù)極限。在一次偶然的機會中,他們成功研發(fā)出了一款具有革命性意義的高效能芯片,這款芯片不僅性能卓越,而且成本大幅降低,迅速在市場中獲得了廣泛認可。隨著這款芯片的成功推出,創(chuàng)都公司的知名度迅速提升,訂單量激增,公司也借此機會逐步擴大了生產(chǎn)規(guī)模和市場占有率。
隨著技術(shù)的不斷進步和市場的變化,EETools意識到必須不斷創(chuàng)新才能保持競爭力。公司投入大量研發(fā)資源,對嵌入式開發(fā)工具進行技術(shù)升級和產(chǎn)品優(yōu)化。經(jīng)過數(shù)年的努力,EETools成功推出了一系列具有領(lǐng)先技術(shù)的嵌入式開發(fā)工具,如高性能的芯片編程器、智能調(diào)試器等。這些產(chǎn)品不僅提高了客戶的工作效率,還降低了成本,贏得了市場的廣泛認可。
隨著公司規(guī)模的擴大和市場的拓展,Amphenol公司開始實施全球擴張和多元化戰(zhàn)略。公司不僅在美國本土設(shè)立了多個生產(chǎn)基地,還在歐洲、亞洲等地建立了分公司和研發(fā)中心。此外,Amphenol公司還積極涉足電子連接器等其他領(lǐng)域,進一步豐富了公司的產(chǎn)品線。這些舉措不僅增強了公司的市場競爭力,也為公司的長期發(fā)展奠定了堅實的基礎(chǔ)。
*****ARM程序在RAM中執(zhí)行跳轉(zhuǎn)出錯,懇請指教***** 各位前輩,小弟在用友善的supervivi下程序到SDRAM中執(zhí)行的時候,發(fā)現(xiàn)如下問題: 我寫了一個測試程序: B SYSINIT B Handler ...… 查看全部問答∨ |
|
我的目的是把屏蔽GPS,當(dāng)做PDA來用。 最近到手一個GPS,開機后沒有能直接wince桌面的按鍵和設(shè)置。要解決的問題是進入電腦桌面。 1,在SD卡上CO入explorer.exe這個文件,把導(dǎo)航路徑設(shè)為\\sd\\explorer.exe. 這樣就可以進入wince桌面了。 2,運行 ...… 查看全部問答∨ |
Flash Programmer下提示arm2410開發(fā)板連不PC 電腦連不上開發(fā)板,F(xiàn)lash Programmer提示如下: Target Communications Error:PC to Target Cable disconneted 我是一個新手,自學(xué)嵌入式,放棄原來的java開發(fā),學(xué)了4個月的C和linux, 第一次用Realarm2410開發(fā)板, 系統(tǒng)windowsxpsp2克隆版 ...… 查看全部問答∨ |
TVS二極管特性及其在電路設(shè)計中的應(yīng)用 TVS二極管特性及其在電路設(shè)計中的應(yīng)用電路保護器件。需要TVS相關(guān)型號的資料可以找我,加我Q:281426466。… 查看全部問答∨ |
|
1,簡介這篇文章是我對電子設(shè)計中,亞穩(wěn)態(tài)問題的一種分析和總結(jié)。文章通過對數(shù)字電路中器件的工作機制的介紹,引出亞穩(wěn)態(tài)問題的發(fā)生機制。并通過對亞穩(wěn)態(tài)問題發(fā)生機制的探討,用以得到一種能夠清楚地,有的放矢地解決亞穩(wěn)態(tài)問題的能力。而這種能力 ...… 查看全部問答∨ |
[轉(zhuǎn)載]FPGA經(jīng)驗總結(jié) 看到這篇文章寫得比較好,就轉(zhuǎn)載過來了。 時序是設(shè)計出來的 我的boss有在華為及峻龍工作的背景,自然就給我們講了一些華為及altera做邏輯的一些東西,而我們的項目規(guī)范,也基本上是按華為的那一套去做。在工作這幾個月中,給我感觸最深的是 ...… 查看全部問答∨ |
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 嵌入式學(xué)習(xí)篇丨迅為4412開發(fā)板Android4.4系統(tǒng)編譯
- Linux系統(tǒng)編程篇丨迅為IMX6ULL-對應(yīng)視頻講解
- 嵌入式學(xué)習(xí)丨4412開發(fā)板-uboot源碼-匯編-源碼分析(一)嵌入式學(xué)習(xí)丨4412開發(fā)板-uboot源碼-匯
- 迅為IMX6ULL開發(fā)板-主頻和時鐘配置例程(二)
- 迅為IMX6ULL開發(fā)板-主頻和時鐘配置例程
- 迅為IMX6ULL開發(fā)板安裝VMware Tool工具
- i.MX6ULL終結(jié)者Debian文件系統(tǒng)的構(gòu)建i.MX6ULL 移植Debian文件系統(tǒng)
- 迅為i.MX6ULL開發(fā)板按鍵例程編譯及運行
- 迅為-i.MX6開發(fā)板手冊更新-非設(shè)備樹uboot-修改默認環(huán)境變量
- 北京、上海、深圳自動駕駛領(lǐng)跑全國!
- 基于智能網(wǎng)聯(lián)汽車質(zhì)量與安全要求的全融合研發(fā)體系研究
- 全球首個人形機器人半馬將舉行,機器人在北京街頭開啟首次路測
- 高標(biāo)準(zhǔn)提升智能網(wǎng)聯(lián)汽車安全 SGS為杰發(fā)科技頒發(fā)ISO/SAE 21434認證證書
- 元戎啟行聯(lián)合高通基于驍龍智駕平臺發(fā)布高階智駕解決方案
- 動力電池迎“新大考”① | 超快充爆發(fā)元年,安全標(biāo)準(zhǔn)何時升級
- 五菱發(fā)布神煉電池4.0,全球首款6C高錳電池M亮相
- 各車企智駕技術(shù)方案盤點
- 更強、更可靠的ESD方案
- 25億美元!英飛凌收購Marvell汽車以太網(wǎng)業(yè)務(wù)
- 比亞迪將全面搭載刀片電池,并準(zhǔn)備全行業(yè)外供
- SIA敦促美國政府采取行動,以加強美國的半導(dǎo)體供應(yīng)鏈
- IC Insights預(yù)計2021年半導(dǎo)體總出貨量將超過1萬1千億個
- HEV電池“狼煙四起”
- 一加在印度注冊O(shè)nePlus Pay商標(biāo) 引進數(shù)字支付服務(wù)
- CeMAT ASIA 2019展會預(yù)告|找仙知,打造你的專屬移動機器人
- 蘋果將推出5G芯片是怎么回事?
- 芯片卡脖子,中國智能機器人破局點在哪?
- 優(yōu)傲機器人蘇璧凱:為什么協(xié)作機器人會是未來?
- 中國工程院院士樊邦奎將出席2019中國(南京)國際無人機系統(tǒng)產(chǎn)業(yè)大會