:最小系統能夠運行起來的必要條件。
1.電源 2.晶振3.復位電路
二:對單片機任意IO口的隨意操作
1.輸出控制電平高低2.輸出檢測電平高低。
三:單片機特殊功能應用
1: 定時器:重點掌握最常用的方式2
2: 中斷:外部中斷、定時器中斷、串口中斷
3: 串口通信:單片機之間、單片機與計算機間
(在此不詳細介紹單片機C語言)
一:最小系統運行條件
1.電源 2.晶振3.復位電路 詳細資料參見導論中的最小系統電路圖
二:普通I/O口的操作
1:輸出高低電平 output
操作:用程序給輸出寄存器P0/P1/P2/P3賦值,1/0實現高低電平的控制
應用:這種高低可實現一些對外部設備的控制,比如led,lcd····,也可加上電流驅動或繼電器或可控硅等器件實現對大型用電器的控制
實例:I/O操作最簡單的實例就是流水燈,流水燈程序參見:http://blog.csdn.net/metalseed/article/details/8196727
2:檢測電平高低 input
操作:先給寄存器P1/P2/P3賦值0xff,然后用 if 語句來進行判斷
應用:可用來讀取外部外部信息實現模擬通信,獲得傳感器數據,按鍵采集等
實例:矩陣鍵盤的掃描代碼:http://blog.csdn.net/metalseed/article/details/8296590
數碼管顯示:http://blog.csdn.net/metalseed/article/details/8537554
PS: P0為三態(tài)(高電平,低電平,高阻態(tài)) P1,P2,P3為準雙向IO口(內部有上拉電阻,做輸入用時,先寫1)
三:單片機特殊功能應用
這是進階的核心內容,單片機的特殊功能全部集中在P3口,這些引腳具有多功能,可通過寄存器配置(關于寄存器,日后補上詳細描述,寄存器理解屬于高階思想,在此先講操作)來確定啟用第幾功能。
首先附上P3第二功能定義
P3第二功能定義:
P3.0:RXD串行口輸入
P3.1:TXD串行口輸出
P3.2:INT0外部中斷0輸入
P3.3:INT1外部中斷1輸入
P3.4:T0定時器0外部輸入
P3.5:T1定時器1外部輸入
P3.6:WR外部寫控制
P3.7:RD外部讀控制
1: 中斷
中斷的概念:
中斷其實很容易理解,這樣來說吧,比如說你在做A事,但是突然間來了你想起來了更重要的B事,所以你馬上去做B事了,做完之后再回來繼續(xù)做A事,這個就是中斷!在程序里面也是一樣的!中斷系統里面有五個中斷,外部中斷0和1,定時器/計數器中斷0/1,串行口中斷!
舉個例子你可能會容易懂點,定時中斷:比如你定時1ms,主程序在運行,每當1ms時間到后,就跑到定時中斷子程序 里面執(zhí)行,執(zhí)行完后再回到主程序。。。中斷程序是1ms進去一次
后面中斷講解太過系統,不易理解,日后補上簡潔易懂的,請親見諒.....。。
中斷data請移步至:http://wenku.baidu.com/view/4f3738f64693daef5ef73da6.html
中斷實例:
超聲波外部中斷 + 串口通信 將測出的距離通過串口發(fā)送
http://blog.csdn.net/metalseed/article/details/8764348
2: 定時器
定時器簡介
定時器及計數器的應用,比 I / O 功能稍微高級點,可實現更為復雜的功能。
顧名思義,定時器可實現延時操作,計數器則可實現計數功能(這兩者都靠中斷實現)。
兩者實質上都是加一計數器(16位),由高8位和低8位兩個寄存器組成,當所有位為1即定時器溢出時,便觸發(fā)中斷。
PS:51內部有兩個定時器:定時器0,定時器1,定時模式加1的周期為一個機器周期 12M晶振的機器周期為1us
應用定時器,需要操作響應的寄存器。
主要涉及三個: 1:中斷允許寄存器IE (可位尋址,所以能直接操作EA,ET0, ET1,)
2:TMOD 是定時/計數的工作方式寄存器,確定工作方式和功能
3:TCON是控制寄存器,控制T0,T1的啟動和停止及設置溢出標志。
操作方法:
step 1: 配置IE寄存器,讓定時器使能(使能即能被應用,可假象為函數的聲明)。
step 2: 配置TMOD寄存器,來確定定時器的工作方式,同時配置TH,TL寄存器來對定時器裝入初值
step 3: 配置TCON寄存器,啟動或停止定時器(因為定時器一旦啟用,就不停加1,直到TH,TL所有位為1時溢出,跳入中斷函數,所以在啟用前,要寫好中斷函數,中斷函數寫法demo里有說明)
這里所說的配置,即給寄存器賦值,例如: TMOD=0X0f;
總而言之:要使用定時器或者計數器需要依次給如下寄存器賦值: IE,TOMD,TH,TL, TCON,具體要賦什么值,參加下面的寄存器位含義說明;
寄存器說明及定時器工作方式:
點擊打開特殊功能寄存器詳細說明
代碼示例:
1:最直白的定時器工作方式1演示,每隔50MS P0取反
[java] view plain copy print?
#include
void main()
{
EA=ET0=1; /*step 1 : 中斷允許*/
TMOD=0x01; /*step 2 : 模式配置*/
TH0=(65536 - 50000) / 256; /*裝初值*/
TL0=(65536 - 50000) % 256; /*裝初值*/
TR0=1; /*step 3 : 啟動*/
while(1)
{
/*Hello World*/
}
}
/*timer0為函數名,隨意寫,后面的interrupt X,X是相應中斷的編號,5個中斷源各有固定編號*/
/*using x 表示占用ram中的X寄存器(0-3),C語言中IDE自動分配不用寫 */
void timer0() interrupt 1 using 1
{
/*重裝初值*/
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
/*operation*/
P0=~P0;
}
2:高級模板
待補~
3: 串口通信
接口:RS232C
RS-422A用于全雙工,而RS-485則用于半雙工(比232距離遠)
需配置的寄存器 : SCON PCON IE
SCON是一個特殊功能寄存器,用以設定串行口的工作方式、接收/發(fā)送控制以及設置狀態(tài)標志:
SM0和SM1為工作方式選擇位,可選擇四種工作方式
SM2,多機通信控制位,主要用于方式2和方式3。當接收機的SM2=1時可以利用收到的RB8來控制是否激活RI(RB8=0時不激活RI,收到的信息丟棄;RB8=1時收到的數據進入SBUF,并激活RI,進而在中斷服務中將數據從SBUF讀走)。當SM2=0時,不論收到的RB8為0和1,均可以使收到的數據進入SBUF,并激活RI(即此時RB8不具有控制RI激活的功能)。通過控制SM2,可以實現多機通信。
在方式0時,SM2必須是0。在方式1時,若SM2=1,則只有接收到有效停止位時,RI才置1。
REN,允許串行接收位。由軟件置REN=1,則啟動串行口接收數據;若軟件置REN=0,則禁止接收。
TB8,在方式2或方式3中,是發(fā)送數據的第九位,可以用軟件規(guī)定其作用。可以用作數據的奇偶校驗位,或在多機通信中,作為地址幀/數據幀的標志位。
在方式0和方式1中,該位未用。
RB8,在方式2或方式3中,是接收到數據的第九位,作為奇偶校驗位或地址幀/數據幀的標志位。在方式1時,若SM2=0,則RB8是接收到的停止位。
TI,發(fā)送中斷標志位。在方式0時,當串行發(fā)送第8位數據結束時,或在其它方式,串行發(fā)送停止位的開始時,由內部硬件使TI置1,向CPU發(fā)中斷申請。在中斷服務程序中,必須用軟件將其清0,取消此中斷申請。
RI,接收中斷標志位。在方式0時,當串行接收第8位數據結束時,或在其它方式,串行接收停止位的中間時,由內部硬件使RI置1,向CPU發(fā)中斷申請。也必須在中斷服務程序中,用軟件將其清0,取消此中斷申請。
PCON中只有一位SMOD與串行口工作有關:
SMOD(PCON.7) 波特率倍增位。在串行口方式1、方式2、方式3時,波特率與SMOD有關,當SMOD=1時,波特率提高一倍。復位時,SMOD=0。
波特率的計算
方式0的波特率=fosc/12
方式2的波特率=(2SMOD/64)·fosc
方式1的波特率=(2SMOD/32)·(T1溢出率)
方式3的波特率=(2SMOD/32)·(T1溢出率)
當T1作為波特率發(fā)生器時,最典型的用法是使T1工作在自動再裝入的8位定時器方式(即方式2,且TCON的TR1=1,以啟動定時器)。這時溢出率取決于TH1中的計數值。
T1溢出率=fosc /{12×[256-(TH1)]}
操作步驟:
1:確定串口工作方式 (配置SCON 可位尋址)
2:根據1確定的方式,看是否需要手動設置波特率 (TMODE,TH TL)
3:設置波特率后啟動(REN, TR)
4:如果使用中斷,開中斷并寫函數(EA=ES=1, void ser() interrupt 4 )
串口通信模板:
http://blog.csdn.net/metalseed/article/details/8579997
點對點通信:
多機通信:
1、硬件連接
單片機構成的多機系統常采用總線型主從式結構。所謂主從式,即在數個單片機中,有一個是主機,其余的是從機,從機要服從主機的調度、支配。80C51單片機的串行口方式2和方式3適于這種主從式的通信結構。當然采用不同的通信標準時,還需進行相應的電平轉換,有時還要對信號進行光電隔離。在實際的多機應用系統中,常采用RS-485串行標準總線進行數據傳輸。
2、通信協議
所有從機的SM2位置1,處于接收地址幀狀態(tài)。
主機發(fā)送一地址幀,其中8位是地址,第9位為地址/數據的區(qū)分標志,該位置1表示該幀為地址幀。
所有從機收到地址幀后,都將接收的地址與本機的地址比較。對于地址相符的從機,使自己的SM2位置0(以接收主機隨后發(fā)來的數據幀),并把本站地址發(fā)回主機作為應答;對于地址不符的從機,仍保持SM2=1,對主機隨后發(fā)來的數據幀不予理睬。
從機發(fā)送數據結束后,要發(fā)送一幀校驗和,并置第9位(TB8)為1,作為從機數據傳送結束的標志。
主機接收數據時先判斷數據接收標志(RB8),若RB8=1,表示數據傳送結束,并比較此幀校驗和,若正確則回送正確信號00H,此信號命令該從機復位(即重新等待地址幀);若校驗和出錯,則發(fā)送0FFH,命令該從機重發(fā)數據。若接收幀的RB8=0,則存數據到緩沖區(qū),并準備接收下幀信息。
主機收到從機應答地址后,確認地址是否相符,如果地址不符,發(fā)復位信號(數據幀中TB8=1);如果地址相符,則清TB8,開始發(fā)送數據。
從機收到復位命令后回到監(jiān)聽地址狀態(tài)(SM2=1)。否則開始接收數據和命令。
3、應用程序
主機發(fā)送的地址聯絡信號為:00H,01H,02H ,… …(即從機設備地址),地址FFH為命令各從機復位,即恢復SM2=1。
主機命令編碼為:01H,主機命令從機接收數據;02H,主機命令從機發(fā)送數據。其它都按02H對待。
RRDY=1:表示從機準備好接收。
TRDY=1:表示從機準備好發(fā)送。
ERR=1: 表示從機接收的命令是非法的。
程序分為主機程序和從機程序。約定一次傳遞數據為16個字節(jié),以01H地址的從機為例。
寄存器數據手冊:
單片機細節(jié):
定義的變量存儲在RAM中,對寄存器賦值時,單片機內部通過數據交換實現。
復位時 P0,P1,P2,P3寄存器全為0xff,其他各位0x00;
break 語句“跳出”循環(huán)。
continue 語句“跳過”循環(huán)中的一個迭代。
在本教程稍早的章節(jié)中,您已見到了 break 語句。它被用于“跳出” switch 語句。
break 語句也可用于跳出循環(huán)。
break 語句會中斷循環(huán),并繼續(xù)執(zhí)行循環(huán)之后的代碼(如果有):
for (i=0; i < 10; i++) {
if (i===3) { break; }
text +="數字是 " + i + "<br>";
}
親自試一試
continue 語句中斷(循環(huán)中)的一個迭代,如果發(fā)生指定的條件。然后繼續(xù)循環(huán)中的下一個迭代。
本例跳過值 3 :
for (i=0; i < 10; i++) {
if (i===3) { continue; }
text +="數字是 " + i + "<br>";
}
親自試一試
如需標記 JavaScript 語句,請將標簽名和冒號置于語句之前:
label:
statements
break 和 continue 語句是僅有的可“跳出”代碼塊的 JavaScript 語句。
break labelname;
continue labelname;
continue 語句(不論有無標簽引用)只能用于跳過一個迭代。
break 語句,如果沒有標簽引用,只能用于跳出一個循環(huán)或一個 switch。
如果有標簽引用,則 break 語句可用于跳出任意代碼塊:
var cars=["BMW", "Volvo", "Saab", "Ford"];
list: {
text +=cars[0] + "<br>";
text +=cars[1] + "<br>";
text +=cars[2] + "<br>";
break list;
text +=cars[3] + "<br>";
text +=cars[4] + "<br>";
text +=cars[5] + "<br>";
}
親自試一試
代碼塊指的是 { 與 } 直接的代碼片段。
近作者看了一些關于JavaScript反調試的帖子,今天給大家整理一下希望有幫助哦~~~
前言
對于JavaScript來說,你只需要花一點時間進行調試和分析,你就能夠了解到JavaScript代碼段的功能邏輯。而我們所要討論的內容,可以給那些想要分析你JavaScript代碼的人增加一定的難度。不過我們的技術跟代碼混淆無關,我們主要針對的是如何給代碼主動調試增加困難。
本文所要介紹的技術方法大致如下:
1. 檢測未知的執(zhí)行環(huán)境(我們的代碼只想在瀏覽器中被執(zhí)行); 2. 檢測調試工具(例如DevTools); 3. 代碼完整性控制; 4. 流完整性控制; 5. 反模擬; 就是如果我們監(jiān)控到到了“非正常”的情況,程序的運行流程將會改變,并跳轉到偽造的代碼塊,并“隱藏”真正的功能代碼。
一、對函數的重新定義
這是一種最基本也是最常用的代碼反調試技能了。在JavaScript中,咱們能夠對用于搜集信息的函數進行重新定義。例如,函數console.log()能夠用來搜集函數和變量等信息,并將其顯現在操控臺中。例如我們把這個函數重新定義一下,就能夠修改函數的行為,并隱去特定信息或顯現假的信息。
可以在控制臺直接運行這個函數來看一下結果:
#測試代碼塊console.log("HelloWorld");var fake=function() {};window['console']['log']=fake;console.log("Youcan't see me!");
運行后結果:
VM48:1 Hello World
如上測試代碼,第二個信息console.log()信息并輸出,因為我們把console.log()函數給重新定義了,即“禁用”了它原有的功能。但是我們也可以讓它顯示偽造后的信息,例如:
console.log("Normalfunction");//First we save a reference to the original console.log functionvaroriginal=window['console']['log'];//Next we create our fake function//Basicly we check the argument and if match we call original function with otherparam.// If there is no match pass the argument to the original functionvar fake=function(argument) { if (argument==="Ka0labs") { original("Spoofed!"); } else { original(argument); } }// We redefine now console.log as our fake functionwindow['console']['log']=fake;//Then we call console.log with any argumentconsole.log("Thisis unaltered");//Now we should see other text in console different to "Ka0labs"console.log("Ka0labs");//Aaaand everything still OK console.log("Byebye!");
輸出結果:
Normal functionVM117:11 This is unalteredVM117:9 Spoofed!VM117:11 Bye bye!
實際上,為了操控代碼的運行方式,咱們還能用更好的方法來修正函數的功用。例如,根據上述代碼來構建一個代碼段,對eval函數重新定義。就能夠把JavaScript代碼傳遞給eval函數,接下來代碼將會被計算并運行。假如咱們重新定義了這個函數,咱們就能夠運行不同的代碼了:
//Just a normal evaleval("console.log('1337')");//Now we repat the process...var original=eval;var fake=function(argument) { // If the code to be evaluated contains1337...if (argument.indexOf("1337") !==-1) { // ... we just execute a different code original("for (i=0; i < 10;i++) { console.log(i);}"); } else { original(argument); } }eval=fake;eval("console.log('Weshould see this...')");//Now we should see the execution of a for loop instead of what is expectedeval("console.log('Too1337 for you!')");
輸出運行結果:
1337VM146:1We should see this…VM147:10VM147:11VM147:12VM147:13VM147:14VM147:15VM147:16VM147:17VM147:18VM147:19
這樣的方法雖然非常巧妙,但這也只是一種非常基礎并且常見的方法,也容易被檢測到。
二、斷點
我們在了解代碼的功能的時候,一般通過JavaScript調試工具(例如DevTools)通過設置斷點的方式來中斷或阻止腳本代碼的執(zhí)行,而斷點也是代碼調試中最基本的了。
如果你研究過調試器或者x86架構,你可能會比較熟悉0xCC指令。在JavaScript中,我們有一個名叫debugger的類似指令。當我們在代碼中聲明了debugger函數后,腳本代碼將會在debugger指令這里停止運行。比如說:
console.log("Seeme!");debugger;console.log("Seeme!");
許多商業(yè)產品會在代碼中設置一個無限循環(huán)的debugger指令,不過某些瀏覽器會屏蔽這種代碼,而有些則不會。這種辦法的首要意圖就是讓那些想要調試你代碼的人感到厭煩,由于無限循環(huán)意味著代碼會不斷地彈出窗口來問詢你是否要繼續(xù)運轉腳本代碼:
setTimeout(function(){while (true) {eval("debugger")
更多精彩內容可以關注“IT實戰(zhàn)聯盟”,也可以留言和作者互動或者加入我們實戰(zhàn)交流群哦~~~
*請認真填寫需求信息,我們會在24小時內與您取得聯系。