日本高清不卡中文字幕-一起草草视频在线观看-亚洲精品一区二区三区色-国产亚洲精品免费视频

你好!歡迎來(lái)到深圳市穎特新科技有限公司!
語(yǔ)言
當(dāng)前位置:首頁(yè) >> 技術(shù)中心 >> 單片機(jī)入門(mén) >> 單片機(jī)學(xué)習(xí)中的常見(jiàn)問(wèn)題

單片機(jī)學(xué)習(xí)中的常見(jiàn)問(wèn)題

關(guān)鍵字:單片機(jī) 常見(jiàn)問(wèn)題 作者:admin 來(lái)源:不詳 發(fā)布時(shí)間:2018-05-18  瀏覽:7

在單片機(jī)學(xué)習(xí)中,我們常常遇到這樣那樣的零星問(wèn)題,這里我將我遇到的問(wèn)題總結(jié)如下,都是個(gè)人見(jiàn)解,如果不對(duì),萬(wàn)望指出。(持續(xù)更新中)

問(wèn)題0001:51單片機(jī)下載失敗常見(jiàn)原因

1.查看單片機(jī)是否插反了;

2.下載軟件選擇正確的單片機(jī)型號(hào)(注意STC89C52和STC89C52RC是不同的) ;

3.檢測(cè)是否連接了晶振 ,時(shí)候有晶振接觸不良的現(xiàn)象 ;

4.查看電腦com是否有多個(gè),是否選錯(cuò)了com口 (是否安裝了相應(yīng)的驅(qū)動(dòng));

5.單片機(jī)開(kāi)發(fā)板是否重新上電了(下載單片機(jī)程序需要冷啟動(dòng)過(guò)程) ;

6.注意是否有短路(比如開(kāi)發(fā)板下面最好鋪一張紙,不要被短路) ;

7.下載軟件用的什么版本,舊版本可能需要設(shè)置最低、最高波特率,并且還會(huì)出現(xiàn)很多奇怪的現(xiàn)象,比如第一次燒寫(xiě)用一個(gè)波特率,第二次就不行了,但是有時(shí)候卻一直可以(個(gè)人經(jīng)驗(yàn))。新版本不用設(shè)置,并且不用等待軟件提醒上電才可以上電,點(diǎn)擊下載后,直接重新上電即可,建議盡量使用新版 ;

8.如果使用的是CH340/CH341或者PL2302,檢測(cè)RXD/TXD是否連接反了。(注意PL2302,驅(qū)動(dòng),新版的驅(qū)動(dòng)只支持正版芯片,這個(gè)一定要注意,很多人會(huì)沿用老版本驅(qū)動(dòng),不建議用PL2302)

9.換一個(gè)單片機(jī)試試看,驗(yàn)證單片機(jī)是否已損壞。

10.一部分人修改上一次工程代碼,然后直接編譯,下載無(wú)效果。可能是新的代碼編譯有錯(cuò)(編譯有三個(gè)按鈕,請(qǐng)注意區(qū)別差異),導(dǎo)致目標(biāo)文件未生成,hex文件未更新,所以下載的還是上一次的程序。這里要注意。

11.STC-ISP軟件選擇hex文件后,要勾“每次下載前都重新裝置文件”,這樣有三大好處:(1)免去每次編譯都重新手動(dòng)裝在hex文件(2)避免因忘記手動(dòng)重新裝載hex文件,而導(dǎo)致下載的hex文件還是上一次的hex文件,代碼下載后現(xiàn)象和上一次一樣,誤以為還是程序問(wèn)題(3)方便快速調(diào)試代碼。

12.連接線可以出現(xiàn)問(wèn)題,比如接觸不良,線頭脫斷等。

13.芯片“鎖死”。STC-ISP軟件設(shè)置問(wèn)題,上一次下載程序的時(shí)候,在STC-ISP可能勾選了“下次冷啟動(dòng)時(shí),P1.0 / P1.1為0/0才可以下載程序” , 這種情況,試著將此兩個(gè)IO拉低,下載程序試試看。

(其他原因后續(xù)更新中-------2016年2月2日最后更新此問(wèn)題)

問(wèn)題0002:學(xué)習(xí)單片機(jī)我們都需要什么軟件

最近看到群里面有很多人為了學(xué)習(xí)單片機(jī),下載了STC-ISP,然后又下載了串口軟件、單片機(jī)小精靈、定時(shí)器計(jì)算神器之類的,可謂五花八門(mén),但是實(shí)際我們并不需要那么多的軟件。

大家注意到STC-ISP軟件已經(jīng)附帶了很多功能了,學(xué)會(huì)使用這些功能可以讓我們事半功倍。另外,STC手冊(cè)上有C語(yǔ)言和匯編語(yǔ)言程序,值得參考。下面在分析幾款常用軟件給大家:

keil4 : 點(diǎn)擊打開(kāi)鏈接 (附帶我下載的兩個(gè)仿真插件,可以做很多仿真)

STC-ISP 下載方式:進(jìn)入www.stcmcu.comwww.stcmcu.com 然后CTRL+F搜索STC-ISP即可。

BCompare : 點(diǎn)擊打開(kāi)鏈接 (快速比較文件差異,便于對(duì)比程序)

Proteus7.5 仿真:點(diǎn)擊打開(kāi)鏈接 (文件中包含我錄制的破解過(guò)程,目前我的系統(tǒng)為W8.1暫時(shí)未發(fā)現(xiàn)使用問(wèn)題)

Multisim 仿真 :點(diǎn)擊打開(kāi)鏈接

Source Insight : 點(diǎn)擊打開(kāi)鏈接(適合編寫(xiě)代碼,非常方便)

SecureCRT7 :點(diǎn)擊打開(kāi)鏈接 (免破解)

Altium Designer6.9 : 點(diǎn)擊打開(kāi)鏈接

Altium Designer14.2.3 : 點(diǎn)擊打開(kāi)鏈接

屏幕錄制專家: 點(diǎn)擊打開(kāi)鏈接 (有時(shí)候交流溝通,錄制視頻更加簡(jiǎn)單直接)

另外,單片機(jī)采用C語(yǔ)言編程的學(xué)生,有兩本書(shū)必須要度:

華為技術(shù)有限公司c語(yǔ)言編程規(guī)范.pdf :點(diǎn)擊打開(kāi)鏈接

高質(zhì)量C編程指南—林銳.pdf : 點(diǎn)擊打開(kāi)鏈接

問(wèn)題0003:51類單片機(jī)需要冷啟動(dòng),但是一定要手動(dòng)重啟開(kāi)關(guān)一次嗎

51類單片機(jī)下載程序時(shí)必須冷啟動(dòng),這是大家都知道的。昨天,一個(gè)學(xué)生告訴我他是用的普中科技開(kāi)發(fā)板,他用普中科技的下載軟件去下載程序,發(fā)現(xiàn)不是很好用。我告訴他STC-ISP下載軟件非常好用,他說(shuō)STC-ISP軟件必須經(jīng)過(guò)手動(dòng)重啟開(kāi)關(guān)完成下載,而普中科技的開(kāi)發(fā)板,可以完成全自動(dòng)下載,只需點(diǎn)擊“下載”按鈕即可,無(wú)需手動(dòng)重啟開(kāi)關(guān),并且普中科技技術(shù)支持告訴他,只能使用他們的軟件才能夠完成全自動(dòng)下載(我對(duì)此只能呵呵)。本人也是采用普中科技開(kāi)發(fā)板,普中科技的自動(dòng)下載功能確實(shí)存在,但是我使用過(guò)發(fā)現(xiàn)并不是很好用,而且需要結(jié)合它的開(kāi)發(fā)板硬件才行。這里介紹一下我使用過(guò)的兩種“全自動(dòng)”下載(可能方法還有很多,需要廣大網(wǎng)友的補(bǔ)充)

(1)硬件法:利用STC自動(dòng)下載器,點(diǎn)擊下載后,模塊會(huì)自動(dòng)重新上電,完成下載任務(wù),需要淘寶購(gòu)買(mǎi),約9~13元。

(2)軟件法:利用串口結(jié)合IAP功能,點(diǎn)擊下載,模塊自動(dòng)完成下載,無(wú)需手動(dòng)重啟。(版本古老的芯片無(wú)此功能)此方法可參考我的筆記:stc單片機(jī)“全自動(dòng)下載”(程序版) http://blog.csdn.NET/yagnruinihao/article/details/21739665

問(wèn)題0004:變量的定義與程序的執(zhí)行

為了簡(jiǎn)化問(wèn)題,這里把程序簡(jiǎn)化為2行(先不要看變量i是否有意義)

 

在C語(yǔ)言方面,這是可以的(盡管這樣不是很規(guī)范),但是在keil4中,卻出現(xiàn)了問(wèn)題,網(wǎng)上百度,說(shuō)可能是有中文字符,但是我將程序刪除后,編譯沒(méi)有錯(cuò)誤,切換輸入法,再次輸入圖片2的內(nèi)容,出錯(cuò),將int i=0 ; 剪切到第一行,錯(cuò)誤消失。還有一個(gè)可能是軟件出錯(cuò)(經(jīng)過(guò)測(cè)試,排除可能性)。

所以,在單片機(jī)編程中,最好將變量的定義放在執(zhí)行語(yǔ)句的前面。

問(wèn)題0005:程序中的“死循環(huán)等待”正確嗎?

在單片機(jī)程序中,有時(shí)候會(huì)需要“死循環(huán)等待”,也就是等到某一條件我們才需要執(zhí)行下面的操作。這里以溫度傳感器DS18B20為例,主機(jī)首先需要發(fā)送一個(gè)存在檢測(cè)脈沖,如果DS18B20存在,則它會(huì)以60us至240us的電平來(lái)回應(yīng)主機(jī),這里就會(huì)需要一個(gè)“死循環(huán)等待”,我們必須等到DS18B20“回應(yīng)完成”,這時(shí)候主機(jī)才能繼續(xù)發(fā)送指令到DS18B20中去,這時(shí)候很多人會(huì)采用這樣的方式:(首先假設(shè)sbit ds18b20_io_bit = P3^7 ;)

則,while( !ds18b20_io_bit) ;

這樣的代碼其實(shí)是有問(wèn)題的,在未連接DS18B20或者接觸不良時(shí),DS18B20并不能回應(yīng)主機(jī),這樣的代碼就會(huì)有問(wèn)題,尤其在大工程中,所以,為了安全,我通常的做法是:

第一步:

while( (!ds18b20_io_bit) ;

P1=0x01 ; //led

如果,P1口的led有變化,則表示我們“程序在邏輯上和時(shí)序上沒(méi)有問(wèn)題”

第二步:

將上面的代碼修改為:

unsigned long i=0

while( ( (!ds18b20_io_bit) && (i++)) ;

然后打印 i ,

因?yàn)閕一般都很小,所以這時(shí)候我一般將unsigned long 修改為unsigned char 類型,然后最后修改為這樣

while( (!ds18b20_io_bit)&& (i++ <250)) ;

注意這里的250不是隨意寫(xiě)的,是經(jīng)過(guò)測(cè)試的,經(jīng)過(guò)測(cè)試,我讀出的i值遠(yuǎn)小于250,我才這樣做的,如果在其他類似的地方,打印出來(lái)i是其他較大的值,那就重新定義i的類型為unsigned int 或者unsigned long ,根據(jù)具體情況而定。

上面的修改似乎意義不大,但是在大工程中,這樣不會(huì)因?yàn)镈S18B20的“不存在”而導(dǎo)致整個(gè)程序“死循環(huán)等待”。

問(wèn)題0006:指針能否指向特殊功能寄存器

特殊功能寄存器的尋址方式只有直接尋址和位尋址。沒(méi)有間接尋址方式。而指針卻是間接尋址方式,不能通過(guò)指向特殊功能寄存器的指針來(lái)操作特殊功能寄存器。

例:利用指向0x90的指針來(lái)操作P1口的LCD燈(高電平時(shí)LCD點(diǎn)亮)(P1口的地址是0x90,但是屬于特殊功能寄存器區(qū))

#include

#include "./stc/stc12c5a60s2.h"

void main(void)

{

unsigned char *p=0x90;

while(1)

{

*p=0x55;/*從這里看,似乎應(yīng)該是LCD每隔一個(gè)被點(diǎn)亮,但是事實(shí)卻并非這樣*/

}

}

問(wèn)題0007:“判忙” 函數(shù)重要嗎

在某些芯片操作時(shí),會(huì)有一些引腳或者寄存器或地址的數(shù)據(jù)被用來(lái)表明當(dāng)前芯片處于的狀態(tài)為忙碌狀態(tài)或者空閑狀態(tài),如果忙碌,單片機(jī)需要用輪詢的方式等待直到芯片空閑下來(lái)才繼續(xù)發(fā)送指令或數(shù)據(jù)。這里以1602液晶屏為例:

一個(gè)朋友用ST89C52操作1602液晶屏,操作成功,后來(lái)?yè)Q了芯片STC12C5A60S2,同樣的程序,顯示出來(lái)的卻是“亂碼”,后來(lái)經(jīng)過(guò)測(cè)試,程序部門(mén)似乎沒(méi)有問(wèn)題,于是,我在LCD1602的“寫(xiě)命令”函數(shù)和“寫(xiě)數(shù)據(jù)”函數(shù)中

加入了延時(shí)(只是為了快速測(cè)試),下載后,兩個(gè)芯片都運(yùn)行正常。其實(shí)對(duì)于LCD1602,一般都不需要“判忙”,它運(yùn)行時(shí)比較快的,但是如果將一個(gè)沒(méi)有“判忙”的1602液晶屏模塊封裝起來(lái),在調(diào)試一個(gè)大工程時(shí),這時(shí)候

因?yàn)閾Q了芯片,導(dǎo)致整體效果錯(cuò)誤,這就是增加了調(diào)試難度。比如在利用LCD1602學(xué)習(xí)使用時(shí)鐘芯片DS1302時(shí),如果顯示亂碼,這時(shí)候,因?yàn)槟愕腖CD1602是實(shí)驗(yàn)的基礎(chǔ)環(huán)節(jié),肯定是你之前就已經(jīng)封裝好了的,這時(shí)候

你肯定會(huì)懷疑DS1302環(huán)節(jié)操作出錯(cuò)了,這就增加了調(diào)試的難度和時(shí)間。所以,“判忙”函數(shù)必不可少。這里,又有一個(gè)技巧,就是防止程序“卡死”,含義與本文中的問(wèn)題0002類似。

起初LCD1602的核心操作為:

[cpp] view plain copy

do{

;

}while( (lcd1602ReadStatus()) & 0x80));

后來(lái)我變?yōu)?/p>

[cpp] view plain copy

unsigned long i=0 ;

do{

i++;

}while( (lcd1602ReadStatus()) & 0x80);

UartSendValue("i = " ,i) ;/*利用串口打印出i的值*/

打印出i的值為 “1”(基于芯片STC12C5A60S1,11.0592MHZ,其他型號(hào)的單品機(jī)可能打印出來(lái)的效果不同,甚至同樣的型號(hào)單片機(jī)、同樣的晶振、同樣型號(hào)的1602 操作打印出來(lái)的值也是不一樣的),又變化為:

[cpp] view plain copy

unsigned char i=0 ;/*同時(shí),需要注意這里,修改了類型*/

do{

i++;

}while( ((lcd1602ReadStatus()) & 0x80) && (i<10)); /*經(jīng)過(guò)驗(yàn)證,10已經(jīng)可以滿足足夠的時(shí)間了*/

這樣做才是安全的。(尤其在大系統(tǒng)中,不會(huì)因?yàn)?602的”不存在“導(dǎo)致整個(gè)系統(tǒng)的運(yùn)行失敗,經(jīng)典案例如下)

(在2015年2月7日,我?guī)椭粋(gè)大四學(xué)生調(diào)試畢設(shè)時(shí),也發(fā)現(xiàn)了同樣的問(wèn)題,此同學(xué)在1602液晶屏的寫(xiě)命令、寫(xiě)數(shù)據(jù)函數(shù)里面加入了判忙函數(shù),判忙核心代碼如下:

[cpp] view plain copy

do{

;

}while( (lcd1602ReadStatus()) & 0x80));

,最后因在系統(tǒng)設(shè)計(jì)時(shí),暫時(shí)用了1602顯示,后來(lái)為了做上位機(jī),就用了串口通信代替1602, 拔掉了1602液晶屏,但是沒(méi)有屏蔽掉主函數(shù)中關(guān)于1602的操作,導(dǎo)致了程序卡死在判忙函數(shù)中,因?yàn)槿绻麤](méi)有硬件連接,通過(guò)數(shù)據(jù)口讀取到的1602狀態(tài)數(shù)據(jù)是0xff,然后0xff&0x80,這樣得到的結(jié)果永遠(yuǎn)是1(除非再次插上液晶屏或者手動(dòng)將數(shù)據(jù)最高bit對(duì)應(yīng)的IO口拉低),導(dǎo)致程序卡死在這里,而且這些功能都是封裝好的,所以就更加加大了難度,導(dǎo)致一周沒(méi)有調(diào)試出來(lái),后來(lái),我給他指出兩種方法(1)在主函數(shù)中屏蔽所有關(guān)于1602液晶屏的函數(shù),實(shí)驗(yàn)后,系統(tǒng)運(yùn)行正常(2)修改判忙函數(shù),因?yàn)橐粍谟酪,試?yàn)后,運(yùn)行正常,即使主函數(shù)中沒(méi)有屏蔽1602相關(guān)函數(shù),1602硬件暫時(shí)取下,也是可以成功運(yùn)行的)

另外,還有很多同學(xué)運(yùn)用了延時(shí)的方法去操作,似乎大部分人都得到了滿意的結(jié)果,那么,這里有出現(xiàn)了兩個(gè)問(wèn)題:(1)延時(shí)的結(jié)果有三種:延時(shí)太小、延時(shí)正好、延時(shí)太大,對(duì)于大家來(lái)說(shuō),延時(shí)正好、延時(shí)太大都是可以完成系統(tǒng)的設(shè)計(jì)的,但是,你又如何保證你的延時(shí)不會(huì)小呢?大部分人想,這非常簡(jiǎn)單,把延時(shí)設(shè)計(jì)的非常大就好了,那么,就引出了問(wèn)題(2)延時(shí)太大,不利于系統(tǒng)整體設(shè)計(jì),導(dǎo)致了效率太低 。 何去何從,大家可以想一想。

問(wèn)題0008:調(diào)試程序之“窮途末路”

有時(shí)候,在調(diào)試程序時(shí),明明都是嚴(yán)格按照datasheet的說(shuō)明和時(shí)序圖編寫(xiě)的代碼,就是沒(méi)有效果,然后借鑒別人的代碼,代碼相同,但還是沒(méi)有效果 。 這時(shí)候,先要懷疑硬件,如果硬件沒(méi)有問(wèn)題,有可能還會(huì)有一個(gè)原因,那就是單片機(jī)的問(wèn)題(或者是keil軟件的問(wèn)題,這個(gè)不得而知了)。我之前遇到過(guò)編寫(xiě)一個(gè)代碼,沒(méi)有效果,最后把全部代碼屏蔽掉,只在main函數(shù)中,點(diǎn)亮了LED,但還是失敗了,后來(lái),復(fù)制代碼,重新新建工程,粘貼代碼,就好了。(這里不是噴STC,其實(shí)STC在國(guó)內(nèi)做的較好,但是總會(huì)有一些奇葩的時(shí)候),這里分享一下,僅個(gè)人經(jīng)歷。

問(wèn)題0009:如何一步步測(cè)試編寫(xiě)代碼

單片機(jī)程序測(cè)試調(diào)試似乎對(duì)于剛?cè)腴T(mén)的同學(xué)有一定難度,但是入門(mén)之后我們快速調(diào)試程序呢?很多人寫(xiě)代碼一氣呵成,然后在main函數(shù)中調(diào)用10幾個(gè)子函數(shù),然后直接通過(guò)液晶屏或者其他的手段觀察效果是正確,這樣的方法對(duì)嗎 ?以下是常用方法:

1.借助于網(wǎng)上的視頻講解或源代碼,(對(duì)于32位的MCU尚可理解,但是51、PIC.MSP430單片機(jī)使用者如果入門(mén)后還是同樣的方法,你就OUT了),但只適用于部分網(wǎng)上資料較多的芯片。

2.借助"邏輯分析儀"儀器去分析(這種神器我也是通過(guò)網(wǎng)上資料介紹,有所了解,但是并沒(méi)有使用過(guò),不過(guò)好像非常好用的),通過(guò)邏輯分析儀可以分析我們的時(shí)序是否存在問(wèn)題,但是個(gè)人感覺(jué)比較適用于菜鳥(niǎo)和破解單片機(jī)程序的高手,對(duì)于大多數(shù)用戶,沒(méi)有必須花錢(qián)購(gòu)買(mǎi)

3.利用程序本身去驗(yàn)證程序,編寫(xiě)一個(gè)函數(shù),測(cè)試一個(gè)函數(shù),操作簡(jiǎn)單,屢試不爽,這里以大家熟知的51類單片機(jī)STC12C5A60S2和數(shù)字溫度傳感器DS18B20為例(單總線協(xié)議通信)。

下圖為DS18B20的“復(fù)位”時(shí)序,因?yàn)槊看尾僮鞫夹枰狹CU發(fā)送一個(gè)復(fù)位信號(hào),所以,“復(fù)位”函數(shù)相當(dāng)重要。

我們知道,當(dāng)DS18B20存在時(shí),紅色部分的時(shí)間內(nèi),總線將會(huì)被DS15B20拉低,呈現(xiàn)低電平 ; 如果DS15B20不存在,則在單片機(jī)使用總線(藍(lán)色)后,紅色部分仍然是高電平。

假設(shè)我們有以下定義:

[cpp] view plain copy

typedef unsigned char UB8 ;

typedef unsigned short int UW16 ;

typedef unsigned long UL32 ;

typedef char SB8;

typedef short int SW16 ;

typedef long SL32 ;

#define HIGH_LEVEL 1

#define LOW_LEVEL 0

sbit ds18b20_io_bit = P1^7 ;/*根據(jù)硬件選擇*/

#define DS18B20_EXISTENCE 0 /*存在DS18B20*/

#define DS18B20_NOT_EXISTENCE -1/*不存在DS18B20*/

然后編寫(xiě)“復(fù)位函數(shù)”

[cpp] view plain copy

/******************************************************

Function :ds18b20Init

Input :N/A

Output :N/A

Return :DS18B20_EXISTENCE或者DS18B20_NOT_EXISTENCE

Description :N/A

Note :經(jīng)過(guò)測(cè)試在11.0592MHZ和12.00MHZ條件下都可以

檢測(cè)到ds18b20的存在。

******************************************************/

SB8 ds18b20Init(void)

{

SB8 existenceFlag ;

UB8 i=0 ;

ds18b20_io_bit = HIGH_LEVEL ;

_nop_() ;

_nop_() ;

/*master transmit the reset pulse */

ds18b20_io_bit = LOW_LEVEL ;

delay720usForDs18b20();

/*rising edge*/

ds18b20_io_bit = HIGH_LEVEL ;

/*ds18b20 wait 15us to 60us then transmit a presence pulse by

pulling the 1-wire low for 60us to 240 us */

delay15usForDs18b20();

delay15usForDs18b20();

delay15usForDs18b20();

delay15usForDs18b20();

if( ! ds18b20_io_bit)

{/*ds18b20 eixstence*/

existenceFlag = DS18B20_EXISTENCE;

}

else

{/*no ds18b20*/

existenceFlag = DS18B20_NOT_EXISTENCE;

}

while((!ds18b20_io_bit) && (i<250))

{

i++;/*wait*//*暫時(shí),具體見(jiàn)調(diào)試*/

/*經(jīng)過(guò)測(cè)試,這里的250對(duì)于11.0592MHZ和12MHZ都遠(yuǎn)遠(yuǎn)足夠了*/

}

return existenceFlag ;

}

然后,我們驗(yàn)證此函數(shù)是否可以成功完成“復(fù)位功能”:(時(shí)序不再詳細(xì)分析)

[cpp] view plain copy

#include

#include "ds18b20.h"

void main(void)

{

SB8 flag = -3 ;

P1=0x00;//連接leds,高電平點(diǎn)亮

flag = ds18b20Init();

if( flag == DS18B20_EXISTENCE) //檢測(cè)結(jié)果:存在,0

{

P1 = 0x01 ;

}

else if(flag == DS18B20_NOT_EXISTENCE)//檢測(cè)結(jié)果:不存在,-1

{

P1=0x02;

}

else

{

P1 = 0x04 ;

}

while(1) ;

}

這樣,我們通過(guò)LED就可以驗(yàn)證函數(shù)了:

(1)正常連接DS18B20,結(jié)果如果是P1的第一個(gè)燈亮了(P1=0x01),則表示單片機(jī)可以檢測(cè)到DS18B20的存在,說(shuō)明函數(shù)可能對(duì)了(可以檢測(cè)到DS18B20的存在);

(2)拔掉DS18B20,結(jié)果如果是P1的第二個(gè)燈亮了(P1=0x02),則表示單片機(jī)未檢測(cè)到DS18B20的存在,說(shuō)明函數(shù)完全正確。(可以同時(shí)檢測(cè)到DS18B20的存在和不存在)

注意:只有當(dāng)(1)(2)都正確后,才表示此“復(fù)位”函數(shù)編寫(xiě)正確了。然后繼續(xù)進(jìn)行下面的函數(shù)編寫(xiě)。

同樣的,對(duì)于很多芯片,我們使用51單片機(jī)驅(qū)動(dòng)時(shí),都會(huì)涉及到“讀操作”和“寫(xiě)操作”,在編寫(xiě)讀寫(xiě)函數(shù)時(shí),通常嚴(yán)格按照時(shí)序編寫(xiě)“寫(xiě)”函數(shù)和“讀”函數(shù),然后向芯片的內(nèi)部RAM寫(xiě)入一個(gè)數(shù)據(jù)(這個(gè)數(shù)據(jù)最好不是0xff,因?yàn)楫?dāng)芯片未連接時(shí),單片機(jī)讀出的數(shù)據(jù)就是0xff,這時(shí)候如果我們寫(xiě)0xff,然后讀取,因?yàn)榻Y(jié)果肯定是0xff,所以并不能證明我們的讀寫(xiě)函數(shù)書(shū)寫(xiě)正確),然后讀出該地址的數(shù)據(jù),驗(yàn)證數(shù)據(jù)是否相同,如果相同,表明讀寫(xiě)操作正確,但是這里同時(shí)需要注意一個(gè)問(wèn)題:讀/寫(xiě)操作周期為多少?即需要隔多長(zhǎng)時(shí)間MCU才可以繼續(xù)讀/寫(xiě)此芯片,因?yàn)閷?duì)于芯片,我們讀寫(xiě)一次后,可能需要過(guò)一段時(shí)間才可以繼續(xù)讀寫(xiě),如果沒(méi)有注意這個(gè)問(wèn)題,就可能導(dǎo)致:編寫(xiě)的代碼好像沒(méi)錯(cuò),但是在后期我們連續(xù)對(duì)芯片進(jìn)行讀/寫(xiě)操作時(shí),沒(méi)有注意這個(gè)延時(shí)等待啊,就會(huì)出現(xiàn)很奇怪的問(wèn)題(通常這種錯(cuò)誤導(dǎo)致的結(jié)果是隨機(jī)的),這時(shí)候反過(guò)來(lái)調(diào)試過(guò)程可能就繁瑣了,如果連續(xù)操作間隔較長(zhǎng),安全的做法是:在每一次讀/寫(xiě)操作后,都加一個(gè)延時(shí),這樣就保證肯定OK了。

問(wèn)題0010:藍(lán)牙串口模塊使用的正確步驟

很多人現(xiàn)在都開(kāi)始使用藍(lán)口模塊,利用手機(jī)藍(lán)牙或者PC藍(lán)牙進(jìn)行控制單片機(jī)系統(tǒng)。但是很多人一上來(lái)就直接把藍(lán)牙模塊和單片機(jī)相連接,然后編寫(xiě)程序,效果實(shí)現(xiàn)不了,就不知該如何了。藍(lán)牙模塊很多都是結(jié)合了串口通信的,通常拿到模塊,需要經(jīng)過(guò)一下步驟(自己總結(jié),可做參考):

(1)首先,需要藍(lán)牙模塊和PC的硬件連接,這里有兩種方法:

把你的開(kāi)發(fā)板的單片機(jī)取下來(lái),然后從開(kāi)發(fā)板引出電源線VCC和GND,還有P30、P31接口,連接藍(lán)牙模塊的四個(gè)端口(注意RXD和TXD不要反接了)

如果你有USB-TTL模塊,可以直接連接藍(lán)牙模塊,無(wú)需單片機(jī)開(kāi)發(fā)板轉(zhuǎn)接過(guò)去。

(2)通過(guò)PC的串口軟件(比如STC-ISP軟件自帶的串口),設(shè)置好軟件的波特率和通信數(shù)據(jù)格式,通過(guò)串口軟件發(fā)送AT命令(通常購(gòu)買(mǎi)時(shí)賣(mài)家提供了),看是否有返回?cái)?shù)據(jù),如果沒(méi)有返回,有可能是P30、P31接口需要換過(guò)來(lái),如果發(fā)送命令,有返回信息且不是亂碼,表示藍(lán)牙模塊和PC可以串口通信了。

(3)手機(jī)下載軟件“藍(lán)牙串口”,通過(guò)此軟件連接藍(lán)牙模塊(藍(lán)牙的名稱和配對(duì)密碼可通過(guò) AT命令設(shè)置),然后給藍(lán)牙模塊供電,PC打開(kāi)串口軟件,手機(jī)發(fā)送任意字符到藍(lán)牙模塊,會(huì)發(fā)現(xiàn)PC串口軟件接收到了信息,這表示藍(lán)牙可以正常工作。

(4)編寫(xiě)單片機(jī)程序,此時(shí)需要分為兩步:

先不連接藍(lán)牙模塊,編寫(xiě)程序,單片機(jī)接收到串口數(shù)據(jù),做出相應(yīng)動(dòng)作,寫(xiě)好后下載,然后打開(kāi)PC的串口軟件,發(fā)送命令,檢驗(yàn)現(xiàn)象是否正確,如果正確,開(kāi)始第二步

把藍(lán)牙模塊連接到單片機(jī),手機(jī)藍(lán)牙連接模塊,手機(jī)發(fā)送命令,此時(shí)只要步驟現(xiàn)象經(jīng)過(guò)反復(fù)驗(yàn)證沒(méi)有問(wèn)題,第二步肯定沒(méi)問(wèn)題。(如果第二步不對(duì),那就返回去做第一步)

(5)其他。如果需要用PC的藍(lán)牙進(jìn)行控制,還需要購(gòu)買(mǎi)藍(lán)牙適配器,也就是模塊發(fā)送信息到電腦時(shí),需要一個(gè)接收器。如果不是很必要,就用手機(jī)藍(lán)牙軟件就好了,省錢(qián)省事。

問(wèn)題0011:不知道遙控器的編碼協(xié)議,如何解碼

不同的遙控器,其協(xié)議也不同.

要看你的目的是什么 , 分兩種情況:

(1)你只是想單純的解碼出來(lái)而已 :可以查看一下你用的遙控器類型,然后百度一下試試看 , 然后結(jié)合示波器觀看。

(2)你想解碼出來(lái)后,用到其他設(shè)計(jì)上去 :這里有兩種方法

較為嚴(yán)格 : 就是參考(1)的思路去實(shí)驗(yàn),但是花時(shí)太多。

<2>不是很?chē)?yán)格,但是很實(shí)用 : 先在網(wǎng)上看一個(gè)紅外遙控器的協(xié)議,然后根據(jù)它的協(xié)議去解碼,然后,查看解碼的是否正確(通過(guò)原碼和反碼初步驗(yàn)證) , 然后把按下每一個(gè)按鍵,去記錄下他的編碼,然后下一設(shè)計(jì)要用到它的時(shí)候,你就把上次記錄的編碼,做一個(gè)數(shù)組,然后自己去定義每一個(gè)編碼對(duì)應(yīng)的功能即可。(因?yàn)閷?shí)際上很多類型的編碼,無(wú)非是引導(dǎo)碼的時(shí)間不同,當(dāng)然我們可以不關(guān)心引導(dǎo)碼 ,還有就是0和1的定義不同,再或者就是先傳輸?shù)氖歉呶贿是低位 , 就是以上三點(diǎn)不同---->個(gè)人理解,可能有所偏差,但是對(duì)于我們,我們可以不關(guān)心解碼得到的是對(duì)的,還是不對(duì)的--->這里的“不對(duì)”是指是否和其真實(shí)的編碼相同,而不是解碼失敗。我們只需要關(guān)注,接收到的信息是否和數(shù)組里面的一樣,如果一樣,就完成某種功能。 當(dāng)然,這里有更加簡(jiǎn)單的方法,就是無(wú)需每次記錄,用一個(gè)薄碼開(kāi)關(guān),去選擇學(xué)習(xí)模式和工作模式,這時(shí)候定義一個(gè)數(shù)組,然后先進(jìn)入學(xué)習(xí)模式下,將接收到的信息放在數(shù)組中,然后進(jìn)入工作模式,工作模式下只是對(duì)比此次接受的編碼和數(shù)組當(dāng)中的編碼,如果相同,則完成一定的任務(wù)就可以了)

問(wèn)題0012:Proteus仿真的那點(diǎn)事

越來(lái)越多的人,問(wèn)我以下問(wèn)題

(1)為什么我的程序在Proteus中可以運(yùn)行,但在實(shí)物上卻運(yùn)行失敗。

(2)為什么我的程序在實(shí)物上可以運(yùn)行,但是Proteus中卻運(yùn)行失敗。

現(xiàn)在在這里做統(tǒng)一解答 : (1)Proteus仿真和實(shí)物有差異,在Proteus中成功的代碼不一定可以用于實(shí)物,反過(guò)來(lái),實(shí)物上已經(jīng)成功的代碼也不一定可以用于Proteus。如果出現(xiàn)了一方成功,一方失敗,那么很大的就是延時(shí)。(當(dāng)然不排除其他可能性,但這個(gè)延時(shí)問(wèn)題可能最大)

(2)如果軟件仿真和硬件實(shí)驗(yàn),只有一方可以成功,而另一方失敗。 那么表明你的邏輯上沒(méi)有錯(cuò)誤。參照第一條,稍做修改即可 。

問(wèn)題0013:程序的嚴(yán)格性

程序的嚴(yán)格性似乎總是被很多人遺忘,在編寫(xiě)程序時(shí),一定要把隱患消滅掉,否則后患無(wú)窮。這里以1602液晶屏為例,希望可以作為一個(gè)切入點(diǎn),但是要通過(guò)問(wèn)題表象,看到問(wèn)題本質(zhì),而不僅僅局限于1602液晶屏,思想更加重要。大家都知道1602液晶屏的數(shù)據(jù)口是8位數(shù)據(jù)口,但是實(shí)際上還有一種模式,就是4位數(shù)據(jù)口,實(shí)質(zhì)上很簡(jiǎn)單,就是利用4位數(shù)據(jù)口傳送數(shù)據(jù),傳送兩次而已,其他無(wú)差別,但這不是這里討論的關(guān)鍵。下面看一下網(wǎng)友的代碼(只放關(guān)鍵部分):

[cpp] view plain copy

#define DataPort P0

void LCD_Write_Data(unsigned char Data)

{

//while(LCD_Check_Busy()); //忙則等待

DelayMs(5);

RS_SET;

RW_CLR;

EN_SET;

DataPort= Data;

_nop_();

EN_CLR;

EN_SET;

DataPort= Data<<4;

_nop_();

EN_CLR;

}

其中,我們之關(guān)心兩句話,就是DataPort= Data; 和DataPort= Data<<4; 這兩句話什么意思呢 ? 就是通過(guò)P0端口的高4個(gè)Bit,把數(shù)據(jù)傳送兩次,使用的是P04,P05,P06,P07。這里的實(shí)驗(yàn)網(wǎng)友成功了,他認(rèn)為這個(gè)代碼沒(méi)有問(wèn)題,但是這里的隱患確實(shí)非常明顯的,如果不該掉,可能導(dǎo)致這樣的情況發(fā)生:在1602的液晶屏4位數(shù)據(jù)口模式的獨(dú)立實(shí)驗(yàn)中成功了,但是在一個(gè)復(fù)雜的系統(tǒng)設(shè)計(jì)中,卻出現(xiàn)了很多意料之外的情況。實(shí)際上,問(wèn)題較為突出,比如第一句DataPort= Data ; 從上面我們看出,對(duì)于1602而言,他只關(guān)心和他的4位數(shù)據(jù)口連接的 P04,P05,P06,P07的狀態(tài),但是上面的復(fù)制,卻影響到了P00,P01,P02,P03,這里明顯不行的,比如P00,P01,P02,P03連接了LED或者其他設(shè)備,這時(shí)候會(huì)影響到他們的運(yùn)行。所以我的建議是,修改為:

[cpp] view plain copy

第一次傳送:

DataPort &= 0x0f ; /*P0高4位清零,準(zhǔn)備傳送數(shù)據(jù)*/

DataPort |= (temp & 0xf0) ;/*P0傳送數(shù)據(jù)temp的高4位,P0的低4位不受影響*/

第二次傳送:

DataPort &= 0x0f ; /*P0高4位清零,準(zhǔn)備傳送數(shù)據(jù)*/

DataPort |= ((temp & 0x0f)<<4) ;/*P0傳送數(shù)據(jù)temp的低4位,P0的低4位不受影響*/

這里,希望新手可以通過(guò)這表象,看到問(wèn)題的本質(zhì),將隱患扼殺在搖籃,否則簡(jiǎn)單的1602的4位數(shù)據(jù)口模式,會(huì)成為你調(diào)試復(fù)雜系統(tǒng)調(diào)試的噩夢(mèng)。

問(wèn)題0014:液晶如何顯示小數(shù)并且小數(shù)自動(dòng)四舍五入

液晶顯示數(shù)據(jù)的小小技巧:(主要針對(duì)液晶顯示浮點(diǎn)型數(shù)據(jù))

我們?cè)谑褂靡壕恋臅r(shí)候,無(wú)論是1602/12864、NOKIA、J2004A還是其他的,常常遇到需要顯示一個(gè)變量(尤其是小數(shù)),那么顯示變量又有一些小小的技巧,這里把我的一些使用方法,給新手介紹一下,歡迎新人學(xué)習(xí),更加歡迎高手拍磚(但不能總是拍,得讓我知道為什么被拍)

(1)首先,我們需要先做一些預(yù)備知識(shí):如何進(jìn)行四舍五入:

[cpp] view plain copy

float temp = 2.376 ;

我們需要保留兩位小數(shù),也就是2.38(四舍五入后的結(jié)果)

在程序中,我們只需要一句話:temp = (unsigned int)((temp*100)+0.5) / 100 ;就完成了這個(gè)功能,得到的結(jié)果就是2.38(不信可以試試看額)

(2)液晶如何顯示小數(shù)

使用以下代碼:

[cpp] view plain copy

#include

#include

#include "lcd1602.h"

void main(void)

{

float a = 182.376 ;

lcd1602Init();

lcd1602WriteCommand(0X0C);

/*顯示原來(lái)的數(shù)字,非重點(diǎn)*/

lcd1602AddressWriteByte(LCD1602_ROW0,0,((unsigned long)a)%1000/100+'0') ;

lcd1602AddressWriteByte(LCD1602_ROW0,1,((unsigned long)a)%100/10+'0') ;

lcd1602AddressWriteByte(LCD1602_ROW0,2,((unsigned long)a)%10+'0') ;

lcd1602AddressWriteByte(LCD1602_ROW0,3,'.') ;

lcd1602AddressWriteByte(LCD1602_ROW0,4,(unsigned long)(a*10)%10+'0') ;

lcd1602AddressWriteByte(LCD1602_ROW0,5,(unsigned long )(a*100)%10+'0') ;

lcd1602AddressWriteByte(LCD1602_ROW0,6,(unsigned long )(a*1000)%10+'0') ;

lcd1602AddressWriteByte(LCD1602_ROW0,8,0x7e) ;

/*重點(diǎn)部分*/

/*顯示,百位這里我一直最高是百位,所以沒(méi)有判斷更加位,實(shí)際操作時(shí),應(yīng)該添加其他機(jī)制,使其更加智能*/

lcd1602AddressWriteByte(LCD1602_ROW0,10,((unsigned long)a)%1000/100+'0') ;

/*顯示十位*/

lcd1602AddressWriteByte(LCD1602_ROW0,11,((unsigned long)a)%100/10+'0') ;

/*顯示各位*/

lcd1602AddressWriteByte(LCD1602_ROW0,12,((unsigned long)a)%10+'0') ;

/*顯示小數(shù)點(diǎn)*/

lcd1602AddressWriteByte(LCD1602_ROW0,13,'.') ;

/*顯示小數(shù)點(diǎn)后第一位*/

lcd1602AddressWriteByte(LCD1602_ROW0,14,(unsigned long)(a*10)%10+'0') ;

/*顯示小數(shù)點(diǎn)后第二位,此時(shí)需要四舍五入計(jì)算*/

lcd1602AddressWriteByte(LCD1602_ROW0,15,(unsigned long )(a*100+0.5)%10+'0') ;

lcd1602AddressWriteString(LCD1602_ROW1,0,"QQ:279729201") ;

while(1);

}

下載程序后效果如下圖所示:

如果此時(shí)修改數(shù)據(jù)temp為182.372,則顯示為下圖:

發(fā)現(xiàn)液晶不僅顯示了數(shù)據(jù),而且有了四舍五入的心結(jié)果。實(shí)際上,這里為了實(shí)驗(yàn)效果,部分代碼并沒(méi)有做很好的處理,主要是為了凸顯出重點(diǎn),網(wǎng)友們可以在我的基礎(chǔ)上不斷修改,希望大家可以通過(guò)點(diǎn),看到面,不要局限于這一個(gè)方式。

編輯:admin  最后修改時(shí)間:2018-05-18

聯(lián)系方式

0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬(wàn)眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08

Copyright © 2014-2023 穎特新科技有限公司 All Rights Reserved.  粵ICP備14043402號(hào)-4

上思县| 夏邑县| 黄大仙区| 乌苏市| 淄博市| 唐海县| 荆州市| 保山市| 申扎县| 轮台县| 乐都县| 肃北| 新河县| 哈尔滨市| 泸溪县| 龙海市| 揭阳市| 宁海县| 巴林右旗| 逊克县| 泽州县| 色达县| 林口县| 九江县| 黄龙县| 石台县| 大荔县| 高淳县| 湖口县| 北流市| 定州市| 德兴市| 海南省| 彭山县| 江孜县| 北安市| 大宁县| 桐城市| 含山县| 大石桥市| 西峡县|