娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2024年09月20日(星期五)

正在發(fā)生

2019年09月20日 | 關(guān)于單片機上for循環(huán)中運用ACC的隱蔽錯誤

發(fā)布者:Jinyu521 來源: eefocus關(guān)鍵字:單片機  for循環(huán)  ACC  隱蔽錯誤 手機看文章 掃描二維碼
隨時隨地手機看文章

最近寫了幾個程序,一個是用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;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,修改如下:


//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了。

關(guān)鍵字:單片機  for循環(huán)  ACC  隱蔽錯誤 引用地址:關(guān)于單片機上for循環(huán)中運用ACC的隱蔽錯誤

上一篇:Keil(C51)介紹、下載、安裝與注冊
下一篇:51單片機學(xué)習(xí)筆記(五)

推薦閱讀

usb自動更新程序IAP(in application programming)DFU(develepment firemeware upgrate).整個芯片有512k的片內(nèi)flash,用戶程序下載在里面運行,flash的地址是0x8000000,大小為0x80000,usb自動更新程序首先下載0x8000000——0x80002FFF,總大小為12K,用戶程序下載到0x80003000,大小為0x7D000(500K),usb自動更新代碼為如下,如果按鍵按下,就進入D...
在第二十一屆中國國際工業(yè)博覽會(以下簡稱“工博會”)上,江蘇哈工智能機器人股份有限公司(以下簡稱:哈工智能,股票代碼:000584.SZ)為助力國產(chǎn)工業(yè)機器人行業(yè)發(fā)展帶來了新路徑。?9月17日,哈工智能旗下海寧哈工現(xiàn)代機器人有限公司(下稱“哈工現(xiàn)代”)攜四款酷炫機器人機型亮相工博會。哈工現(xiàn)代總經(jīng)理辛志表示,從工業(yè)機器人產(chǎn)業(yè)鏈來看,機器人本體...
據(jù)外媒報道,高通5nm旗艦處理器驍龍875將首次采用Cortex X1超大核心。消息稱高通驍龍875采用“1+3+4”八核心設(shè)計,其中“1”為超大核心Cortex X1。以往高通驍龍旗艦處理器也采用過“1+3+4”這種“超大核+大核+能效核心”這樣的三叢集八核心架構(gòu),但是超大核和大核之間的差別主要在于CPU頻率。高通驍龍875芯片結(jié)構(gòu)(圖源來自網(wǎng)絡(luò))高通驍龍芯片一直是眾多...
近日,信維通信在接受機構(gòu)調(diào)研時表示,過去,公司無線充電業(yè)務(wù)收入大部分來自于手機接收端;當(dāng)前,公司無線充電業(yè)務(wù)從手機接收端逐步拓展至手機發(fā)射端、耳機、手表、平板等各類終端應(yīng)用,非手機接收端逐步成為公司無線充電業(yè)務(wù)增長動力。目前,信維通信無線充電在各大客戶的供應(yīng)商地位穩(wěn)固,在鞏固現(xiàn)在手機接收端項目供應(yīng)份額的同時,不斷拓展了發(fā)射端、無...

史海拾趣

問答坊 | AI 解惑

使用SignalTap II邏輯分析儀調(diào)試FPGA.pdf

使用SignalTap II邏輯分析儀調(diào)試FPGA.pdf…

查看全部問答∨

*****ARM程序在RAM中執(zhí)行跳轉(zhuǎn)出錯,懇請指教*****

各位前輩,小弟在用友善的supervivi下程序到SDRAM中執(zhí)行的時候,發(fā)現(xiàn)如下問題: 我寫了一個測試程序:         B         SYSINIT         B         Handler ...…

查看全部問答∨

非一體機屏蔽GPS后外放沒聲音?

我的目的是把屏蔽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。…

查看全部問答∨

非常不錯的亞穩(wěn)態(tài)分析

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ī)范,也基本上是按華為的那一套去做。在工作這幾個月中,給我感觸最深的是 ...…

查看全部問答∨

OTL功放電路

  首先,我是 學(xué)生黨。   以下是我在實訓(xùn)中設(shè)計的一個  OTL音頻功放電路 請問一下,為什么我按照下面的電路圖接好實驗板后,要么就是沒有輸出信號,要么就是得到一些奇怪的信號(見第二張圖)?   思考了很久,試了多次 ...…

查看全部問答∨

程序移植

本人正在學(xué)習(xí)UCOS II下的LM3S6911程序移植,哪位大蝦能提供LM3S6911的UCOS的移植說明,謝謝!…

查看全部問答∨
小廣播
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機文章

 
EEWorld訂閱號

 
EEWorld服務(wù)號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務(wù)審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 波密县| 桦川县| 同仁县| 四子王旗| 白水县| 和田市| 泰安市| 邯郸县| 延寿县| 罗江县| 大兴区| 辛集市| 兴隆县| 海宁市| 鄂温| 昭通市| 吉安县| 聂荣县| 临武县| 玉门市| 建平县| 浏阳市| 华亭县| 偏关县| 鄱阳县| 惠东县| 琼结县| 虞城县| 精河县| 视频| 阿拉善右旗| 汾阳市| 靖宇县| 如皋市| 孙吴县| 唐山市| 司法| 平谷区| 临潭县| 定日县| 水富县|