0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

干貨 | 關(guān)于單片機上for循環(huán)中運用ACC的隱蔽錯誤

2oON_changxuemc ? 來源:YXQ ? 2019-06-20 10:47 ? 次閱讀

先上代碼:第一個為錯誤代碼,第二個為正確代碼。這是用來向ds1302芯片寫入命令或數(shù)據(jù)的函數(shù)。實現(xiàn)把8位的數(shù)據(jù)dat一位一位地寫入ds1302的io口。其中ACC0為ACC的第0位。

認(rèn)真對比這兩個代碼,可能會覺得沒區(qū)別,而且這兩個代碼都可以通過編譯(加上reg52.h和一些宏定義)。我也是一直認(rèn)為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++)的運算中可能有累加器ACC參與了,導(dǎo)致修改了ACC的值,使寫入的命令出現(xiàn)錯誤。但為什么for(i=8;i>0;i--)就沒有ACC的參與呢?一個大大的問號?;谖艺{(diào)試了一個星期的程序,皆因為這一個神奇的錯誤,我實在不甘心,決定研究到底。于是,分別查看了這三個程序代碼keil4 編譯后得到的 匯編代碼。(學(xué)過匯編就是爽啊,哈)

對比后,可以發(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;i0;i--)類的指令多了 CLR A 和 INC R7 兩條指令,CJNE 指令又比較DJNZ指令多了一個字節(jié)的程序代碼存儲空間,在頻率為12M的51單片機上體現(xiàn)為執(zhí)行同樣功能的程序,要多用2us,代碼空間花多一字節(jié)。所以前者是毫無優(yōu)勢的,以后應(yīng)養(yǎng)成用

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,修改如下:

想到了這個方法后,覺得自己好白癡,以后都不用ACC了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6030

    文章

    44500

    瀏覽量

    632246
  • ACC
    ACC
    +關(guān)注

    關(guān)注

    1

    文章

    56

    瀏覽量

    22718

原文標(biāo)題:關(guān)于單片機上for循環(huán)中運用ACC的隱蔽錯誤

文章出處:【微信號:changxuemcu,微信公眾號:暢學(xué)單片機】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    請問TPA3112D1的datasheet上的control system要連在單片機上嗎?

    請問TPA3112D1的datasheet上的control system 要連在單片機上嗎?AVCC是連在單片機上的某個引腳嗎?PVCC是連接電源嗎?附件是datasheet上給的參考電路圖。
    發(fā)表于 10-31 08:32

    西門子博途中循環(huán)中斷功能的編程示例

    在以下示例中,將讀取循環(huán)中斷 OB (OB31) 的相位和循環(huán)時間,并設(shè)置一個新的循環(huán)時間。
    的頭像 發(fā)表于 10-28 10:11 ?352次閱讀
    西門子博途中<b class='flag-5'>循環(huán)中</b>斷功能的編程示例

    單片機燒錄程序的線比單片機上的少還能燒錄嗎

    單片機燒錄原理 單片機燒錄是指將編寫好的程序代碼通過一定的方式傳輸?shù)?b class='flag-5'>單片機的存儲器中,使其能夠按照程序的指令運行。這個過程通常需要使用燒錄器或者編程器等設(shè)備,通過一定的接口與單片機進行
    的頭像 發(fā)表于 09-02 09:54 ?376次閱讀

    單片機上位機軟件用什么開發(fā)

    在開發(fā)單片機上位機軟件時,選擇合適的開發(fā)工具和編程語言至關(guān)重要。本文將詳細(xì)介紹單片機上位機軟件開發(fā)的各個方面,包括開發(fā)環(huán)境、編程語言、界面設(shè)計、通信協(xié)議、調(diào)試與測試等。 1. 開發(fā)環(huán)境選擇 開發(fā)單片機上
    的頭像 發(fā)表于 06-07 09:17 ?1141次閱讀

    使用STM32F401的單片機移植了ucosii操作系統(tǒng)后,在循環(huán)中調(diào)用sprintf函數(shù)時莫名卡死的原因?

    使用STM32F401的單片機移植了ucosii操作系統(tǒng)后。在編寫任務(wù)函數(shù)時,在循環(huán)中調(diào)用sprintf函數(shù)時莫名卡死的原因?
    發(fā)表于 04-02 06:12

    使用 MISRA C++:2023? 避免基于范圍的 for 循環(huán)中錯誤

    在前兩篇博客中,我們?向您介紹了新的 MISRA C++ 標(biāo)準(zhǔn)?和?C++ 的歷史?。在這篇博客中,我們將仔細(xì)研究以 C++ 中?for?循環(huán)為中心的特定規(guī)則。
    的頭像 發(fā)表于 03-28 13:53 ?717次閱讀
    使用 MISRA C++:2023? 避免基于范圍的 for <b class='flag-5'>循環(huán)中</b>的<b class='flag-5'>錯誤</b>

    單片機中for語句的運用

    單片機中的for語句是一種常見的循環(huán)控制結(jié)構(gòu),用于重復(fù)執(zhí)行一段代碼塊,可以簡化程序的編寫和減少代碼量。本文將詳細(xì)介紹單片機中for語句的運用。 一、for語句的基本結(jié)構(gòu)和功能 for語
    的頭像 發(fā)表于 01-05 14:02 ?2102次閱讀

    如何在循環(huán)中斷中創(chuàng)建工藝對象PID控制器?

    以下步驟將介紹如何在循環(huán)中斷 OB“PID [OB200]”中調(diào)用工藝對象“PID_Compact” 。
    的頭像 發(fā)表于 12-29 18:10 ?1689次閱讀
    如何在<b class='flag-5'>循環(huán)中</b>斷中創(chuàng)建工藝對象PID控制器?

    51單片機for循環(huán)結(jié)束之后還在運行

    當(dāng)我們設(shè)計并編寫嵌入式系統(tǒng)時,使用51單片機編寫程序時,常常會用到循環(huán)結(jié)構(gòu)來重復(fù)執(zhí)行一段代碼。然而,有時我們可能會遇到51單片機循環(huán)結(jié)束之后還在運行的問題,這可能會導(dǎo)致系統(tǒng)的功能異常
    的頭像 發(fā)表于 12-26 14:06 ?989次閱讀

    AvR單片機for循環(huán)需要幾個指令周期

    在AvR單片機中,for循環(huán)語句的執(zhí)行需要多個指令周期。指令周期是一個基本的處理器時鐘周期,用于執(zhí)行一條指令的所有操作。 首先,我們需要了解AvR單片機的架構(gòu),它使用了在指令級別上進行并行處理
    的頭像 發(fā)表于 12-26 14:03 ?1043次閱讀

    關(guān)于AD5940移植到其他單片機上的問題求解

    你好,我想問一下關(guān)于AD5940移植到其他單片機上的問題,我有以下問題。 1、我在調(diào)試過程中,單片機可以正常發(fā)送數(shù)據(jù),但無法讀回AD5940芯片的數(shù)據(jù),為什么會出現(xiàn)這種情況?AD5940
    發(fā)表于 12-01 06:05

    for循環(huán)中i++與++i的區(qū)別

    的含義。i++被稱為后綴遞增運算符,它的作用是先使用變量i的值,然后再將i的值加一。而++i被稱為前綴遞增運算符,它的作用是先將i的值加一,然后再使用i的值。盡管這兩個運算符都會增加變量的值,但它們在使用變量值的時機上稍有不同。 在循環(huán)中,i++和++
    的頭像 發(fā)表于 11-26 09:20 ?9239次閱讀

    python循環(huán)里的輸出結(jié)果匯總

    循環(huán)是計算機編程中常用的一種控制結(jié)構(gòu),用于重復(fù)執(zhí)行一段代碼。Python提供了多種類型的循環(huán)結(jié)構(gòu),包括for循環(huán)和while循環(huán)。在這篇文章中,我們將詳細(xì)介紹Python
    的頭像 發(fā)表于 11-22 09:59 ?1567次閱讀

    python怎么把for循環(huán)的值拿出來

    Python中可以使用for循環(huán)來遍歷一個序列或者迭代器中的元素。當(dāng)我們希望將for循環(huán)中的值取出來并進行其他操作時,我們可以使用一些方法和技巧來實現(xiàn)。 一、使用列表解析 列表解析是一種創(chuàng)建新列表
    的頭像 發(fā)表于 11-22 09:54 ?3225次閱讀

    單片機上電后沒有運轉(zhuǎn),首先要檢查什么?

    單片機上電后沒有運轉(zhuǎn),首先要檢查什么? 當(dāng)單片機上電后沒有運轉(zhuǎn)時,我們需要進行一系列的檢查,以確定導(dǎo)致問題的根源。 導(dǎo)語: 在現(xiàn)代科技領(lǐng)域中,單片機扮演著重要的角色,它廣泛應(yīng)用于各種電子設(shè)備中。然而
    的頭像 發(fā)表于 11-17 14:16 ?3655次閱讀