數位邏輯與實習:實驗七 拴鎖器與正反器實驗
A. R-S Latch (拴鎖器)實驗
實驗目的:1.請使用程式來撰寫一個 RS 拴鎖器。
2.利用兩個輸入埠,兩個輸出埠,觀察在模擬版 LED 顯示的結果,將實驗之結果 填入真值表。
3.真值表上的 1 代表高準位(請接 VDD),0 代表低準位(請接 VSS)。
實作方法:1.將模擬板上之 VDD 與 VSS 分別以杜邦線接至麵包版的排針上。
2.將模擬上 J4 的 PA5、PA6 接至模擬板上 J5 的 L0、L1。
3.將模擬板上的 J3 的 PA0、PA1 分別依照真值表來測試輸出結果。
範例程式:
#include "ht48e50.h" //載入 ht48e50.h 的設定值 unsigned q,q_; //設定非負數之變數
void Delay(unsigned x1) //延遲副程式 {
unsigned x2,x3;
for(x2=0;x2<x1;x2++) for(x3=0;x3<250;x3++);
}
RS_flip_flop(unsigned s_,unsigned r_,unsigned qq, unsigned qq_) // RS 副程式模組 {
unsigned i;
for(i=0;i<3;i++) //此迴圈用來緩衝用
{
q=!(r_|qq_); //RS 基本邏輯閘運算 q_=!(s_|qq);
qq=q; //將 q 的值存至 qq qq_=q_; //將 q_的值存至 qq_
} }
void main() //主程式
{
班級:
姓名:
學號:
unsigned r=0,s=0,clk_0,r0=0,s0=1,q0=0,q0_=1; //宣告 7 個非負數之變數
_pac=0x0f; //設定 pa 低 4bits(pa0~pa3)為輸入;
//高 4bits(pa4~pa7)為輸出。
_pa=0xff; //設定 pa 初始值(LED 初始為暗)
q=q0; //將 q 值更新 q_=q0_; //將 q_值更新 while(1)
{
r=_pa0; //設 r 為輸入腳
s=_pa1; //設 s 為輸入腳
RS_flip_flop(s,r,q0,q0_); //將 s,r,q0,q0_值,存至 RS 副程式 _pa5=q; //將 q 值用 pa5 輸出
_pa6=q_; //將 q_值用 pa6 輸出
q0=q; //將 q0 值更新
q0_=q_; //將 q0_值更新 }
}
R-S 真值表與電路圖
Input Output
R S Q Q
B.
R−SLatch (拴鎖器)實驗
實驗目的:1.請使用程式來撰寫一個R−S 拴鎖器。
2.利用兩個輸入埠,兩個輸出埠,觀察在模擬版 LED 顯示的結果並填入真值表。
3.真值表上的 1 代表高準位(請接 VDD),0 代表低準位(請接 VSS)。
實作方法:1.將模擬板上之 VDD 與 VSS 分別以杜邦線接至麵包版的排針上。
2.將模擬上 J4 的 PA5、PA6 接至模擬板上 J5 的 L0、L1。
3.將模擬板上的 J3 的 PA0、PA1 分別依照真值表來測試輸出結果。
R−S 真值表與電路圖
Input Output
R S Q Q
C. J-K Flip-Flop (正反器)實驗
實驗目的:1.請使用程式來撰寫一個 JK 正反器。
2.利用兩個輸入埠,兩個輸出埠,觀察在模擬版 LED 顯示的結果並填入真值表。
3.真值表上的 1 代表高準位(請接 VDD),0 帶表低準位(請接 VSS)。
4.使用鍵盤來控制時脈,並且觀察結果。
實作方法:1.將模擬板上之 VDD 與 VSS 分別以杜邦線接至麵包版的排針上。
2.將模擬上 J4 的 PA5、PA6 接至模擬板上 J5 的 L0、L1。
3.將模擬板上 J3 的 PA0、PA1 分別依照真值表來測試輸出結果。
4.將模擬板上 J3 與 J4 的 PA2、PA4 接至 J8 的 KB0、KA0。
5.鍵盤觸發,按下去觸發為 0,常態為 1 範例程式:
#include "ht48e50.h" //載入 ht48e50.h 的設定值 unsigned q,q_; //宣告非負之兩個變數 void Delay(unsigned x1) //延遲副程式
{
unsigned x2,x3;
for(x2=0;x2<x1;x2++) for(x3=0;x3<250;x3++);
}
JK_flip_flop(unsigned j,unsigned k,unsigned qq, unsigned qq_) // JK 副程式模組 {
unsigned s_,r_,i; // 宣告非負之三個變數 s_=!(j&qq_); // RS 之邏輯運算
r_=!(k&qq); // RS 之邏輯運算 Q
R
S
for (i=0;i<2;i++) //緩衝 RS 邏輯運算 {
q=!(s_&qq_); // JK 邏輯運算 q_=!(r_&qq); // JK 邏輯運算
qq=q; //將 q 的值存至 qq
qq_=q_; //將 q_的值存至 qq_
} }
get_key() //鍵盤副程式
{
unsigned a; //宣告非負之變數
_pa4=0; //掃描鍵盤
Delay(1); //延遲副程式
a=_pa2; //將鍵盤掃描值讀回
return a; //回傳鍵盤掃描值
}
void main() {
unsigned j0=0,k0=0,clk_0,q0=0,q0_=1,c,qq_=0,qq=0; //宣告非負數變數 unsigned key_release=0; //宣告鍵盤放開旗標
unsigned key_debouncer=0; //宣告防彈跳旗標
_pac=0x0f; //設定 pa 低 4bit(pa0~pa3)為輸入;
//高 4bit(pa4~pa7)為輸出。
_pa=0xff; //設定 pa 初始值(LED 初始為暗)
q=q0; //將 q 值更新
q_=q0_; //將 q_值更新
while(1) //無窮迴圈
{
j0=_pa0; //將 j0 的值自 pa0 讀入 k0=_pa1; //將 k0 的值自 pa1 讀入 clk_0=get_key(); //擷取觸發訊號
if ((clk_0==0)&&(key_release==0)) //若為觸發且鍵盤剛按下 {
key_release=1; //鬆開旗標設為 1,表鍵盤按下未放開 JK_flip_flop(j0,k0,q0,q0_); //將值帶入 JK 模組運算
}
else if(key_debouncer==100) //防彈跳 {
if((clk_0==1)) //若已鬆開鍵盤按鍵
{
key_release=0; //放開旗標設定成 0 key_debouncer=0; //防彈跳旗標設定為 0
} }
else if((key_release==1)) //若鍵盤按鍵已按下
key_debouncer=key_debouncer+1; //防彈跳旗標累積計數 q0=q; //更新 q0
q0_=q_; //更新 q0_
_pa5=q0; //q0 的值由 pa5 輸出 _pa6=q0_; //q0_的值由 pa6 輸出 }
}
D.同步序向邏輯之計數器實驗:
實驗目的:1.請使用 JK 模組來設計一同步 3bits 計數器 2.使用鍵盤來控制時脈,並且觀察結果。
3.三個輸出腳接至 LED 燈,並且觀察變化值。
實作方法:1.將模擬上 J4 的 PA5、PA6、PA7 接至模擬板上 J5 的 L0、L1、L2。
2.將模擬板上 J3 與 J4 的 PA2、PA4 接至 J8 的 KB0、KA0。
3.鍵盤觸發,按下去觸發為 0,常態為 1。
※在規劃同步邏輯設計,必須從後面的正反器先作處理,更新其輸出,以免影響前級的結果。
範例程式:
#include "ht48e50.h" //載入 ht48e50.h 的設定值 unsigned q,q_; //宣告非負數支兩個變數 void Delay(unsigned x1) //延遲副程式
{
unsigned x2,x3;
for(x2=0;x2<x1;x2++) for(x3=0;x3<250;x3++);
}
JK_flip_flop(unsigned j,unsigned k,unsigned qq, unsigned qq_) // JK 副程式模組 {
unsigned s_,r_,i; //宣告非負數之三個變數 s_=!(j&qq_); //RS 邏輯運算
r_=!(k&qq);
for (i=0;i<2;i++) //緩衝迴圈 {
q=!(s_&qq_); //JK 邏輯運算 q_=!(r_&qq); //JK 邏輯運算
qq=q; //將 qq 值更新
qq_=q_; //將 qq_值更新 }
}
get_key() //鍵盤副程式
{
unsigned a; //宣告非負之變數
_pa4=0; //掃描鍵盤
Delay(1); //延遲副程式
a=_pa2; //將鍵盤掃描值讀回
return a; //回傳鍵盤掃描值
}
void main() {
unsigned clk_0,q0=0,q0_=1,q1=0,q1_=1,q2=0,q2_=1; //宣告非負之 7 個變數 unsigned key_release=0; //宣告鍵盤放開旗標
unsigned key_debouncer=0; //宣告防彈跳旗標
_pac=0x0f; //設定 pa 低 4bits(pa0~pa3)為輸入;
//高 4bits(pa4~pa7)為輸出。
_pa=0x00; //設定 pa 初始值
q=q0; //將 q 值更新
q_=q0_; //將 q_值更新
while(1) //無窮迴圈
{
clk_0=get_key(); //擷取觸發訊號
if ((clk_0==0)&&(key_release==0)) //若為觸發且鍵盤剛按下 {
key_release=1; //鬆開旗標設為 1,表鍵盤按下未放開 JK_flip_flop((q0&q1),(q0&q1),q2,q2_); //將值帶入 JK 模組(JK2)
q2=q; //更新 q2 q2_=q_; //更新 q2_
_pa7=q2; //q2 的值由 pa7 輸出 JK_flip_flop(q0,q0,q1,q1_); //將值帶入 JK 模組(JK1)
q1=q; //更新 q1 q1_=q_; //更新 q1_
_pa6=q1; //q1 的值由 pa6 輸出 JK_flip_flop(1,1,q0,q0_); //將值帶入 JK 模組(JK0)
q0=q; //更新 q0 q0_=q_; //更新 q0_
_pa5=q0; //q0 的值由 pa5 輸出 }
else if(key_debouncer==100) //防彈跳 {
if((clk_0==1)) //若已鬆開鍵盤按鍵 {
key_release=0; //放開旗標設定成 0 key_debouncer=0; //防彈跳旗標設定為 0
} }
else if((key_release==1)) //若鍵盤按鍵已按下
key_debouncer=key_debouncer+1; //防彈跳旗標累積計數 }
}
E.非同步序向邏輯之計數器實驗
實驗目的:1.請使用 JK 模組來設計一非同步 3bits 計數器 2.使用鍵盤來控制時脈,並且觀察結果。
3.輸出結果以七段顯示器顯示,並且觀察計數值是否正確。
實作方法:1.將模擬板上 J3 的 PB0~PB3 與 J4 的 PB4~PB6,依序接到 J6 的 SA~SF。
2.將模擬板上 J3 與 J4 的 PA2、PA4 接至 J8 的 KB0、KA0。
3.以鍵盤來觸發,按下去觸發為 0,常態為 1。
4.將模擬板上 J4 的 PC4 接至 J7 的 COM3。
※在規劃非同步邏輯設計,須從前面的正反器先作處理,更新其輸出,以判斷觸發後級動作。
範例程式:
#include "ht48e50.h" //載入 ht48e50.h 的設定值 unsigned q,q_; //宣告非負之變兩個變數
const unsigned led_code[9]= {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08};
//宣告 0~8 顯示非負數字元陣列 void Delay(unsigned x1) //延遲副程式
{
unsigned x2,x3;
for(x2=0;x2<x1;x2++) for(x3=0;x3<25;x3++);
}
JK_flip_flop(unsigned j,unsigned k,unsigned qq, unsigned qq_) //JK 副程式模組 {
unsigned s_,r_,i; //宣告非負數之三個變數 s_=!(j&qq_); //RS 邏輯運算
r_=!(k&qq); //RS 邏輯運算 for (i=0;i<2;i++) //緩衝
{
q=!(s_&qq_); //JK 邏輯運算 q_=!(r_&qq); //JK 邏輯運算
qq=q; //更新 qq
qq_=q_; //更新 qq_
} }
get_key() //鍵盤副程式
{
unsigned a; //宣告非負之變數
_pa4=0; //掃描鍵盤
Delay(1); //延遲副程式
a=_pa2; //將鍵盤掃描值讀回
return a; //回傳鍵盤掃描值
}
void main() {
unsigned tab[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xd8,0x80,0x98,0x7f};
//七段顯示器字元
unsigned clk_0,q0=0,q0_=1,q1=0,q1_=1,q2=0,q2_=1,cc=0; //宣告非負之變數 unsigned key_release=0; //宣告鍵盤放開旗標
unsigned key_debouncer=0; //宣告防彈跳旗標
_pac=0x0f; //設定 pa 低 4bits(pa0~pa3)為輸入;
//高 4bits(pa4~pa7)為輸出。
_pa=0x1f; //pa 初始值
_pcc=_pbc=0x00; //設定 pb 與 pc 埠皆為輸出 _pc=_pb=0xff; //pb 與 pc 埠初始值
q=q0; //更新 q 的值 q_=q0_; //更新 q_的值
while(1) //無窮迴圈
{
clk_0=get_key(); //擷取觸發訊號
if ((clk_0==0)&&(key_release==0)) //若為觸發且鍵盤剛按下 {
key_release=1; //鬆開旗標設為 1,表鍵盤按下未放開 JK_flip_flop(1,1,q0,q0_); //將值帶入 JK 模組(JK0)
q0=q; //更新 q0 q0_=q_; //更新 q0_
if(q0_==1) //非同步觸發(JK1) {
JK_flip_flop(1,1,q1,q1_); //將值帶入 JK 模組(JK1) q1=q; //更新 q1
q1_=q_; //更新 q1_
if(q1_!=0) //非同步觸發(JK2) {
JK_flip_flop(1,1,q2,q2_); //將值帶入 JK 模組(JK2) q2=q; //更新 q2
q2_=q_; //更新 q2_
} }
cc=q0+(q1*2)+(q2*4); //將 3bits 之 2 進制轉成 10 進制數字 }
else if(key_debouncer==100) //防彈跳 {
if((clk_0==1)) //若已鬆開鍵盤按鍵 {
key_release=0; //放開旗標設定成 0
key_debouncer=0; // 防彈跳旗標設定為 0 }
}
else if((key_release==1)) //若鍵盤按鍵已按下
key_debouncer=key_debouncer+1; //防彈跳旗標累積計數
_pc=0xef; //指定七段顯示器掃描位址
_pb=tab[cc]; //輸出 10 進制數字資料
Delay(10); //與輸出七段顯示器的亮度和掃描頻率有關 }
}
實驗心得與討論: