久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標(biāo)題: 基于AT89S51的單片機(jī)無線雙顯示搶答器 [打印本頁]

作者: 曾小文    時(shí)間: 2016-4-2 16:03
標(biāo)題: 基于AT89S51的單片機(jī)無線雙顯示搶答器
基于AT89S51的單片機(jī)無線雙顯示搶答器

1關(guān)于搶答器
1.1目前常見的搶答器有以下幾種類別:
(1) 數(shù)字電路:只要使用555定時(shí)電路作為時(shí)序觸發(fā),配合相應(yīng)的數(shù)字電路實(shí)現(xiàn)。
(2) 單片機(jī)式:以單片機(jī)為作為總控制單元利用單片機(jī)的掃描讀取外部輸入, 并進(jìn)行相應(yīng)的判斷以及數(shù)據(jù)處理。
(3) 電腦程序?qū)崿F(xiàn)的:以電腦作為上位機(jī),利用USB端口或者串口編程技術(shù)實(shí)現(xiàn),邏輯上面的判斷以及處理均由程序來完成。這種搶答器可以在電腦上面顯示并且可以與相應(yīng)的由高級(jí)語言完成答題系統(tǒng)一起使用,配合單片機(jī)控制能力強(qiáng)的優(yōu)勢,將會(huì)是完美的結(jié)合,這也是我們追求的目標(biāo)。
1.2搶答器的常見功能:
(1) 判斷搶答端的序號(hào)。
(2) 判斷是否犯規(guī)并且在主機(jī)顯示。
(3) 在搶答端顯示犯規(guī)或是搶答成功。
(4) 設(shè)定倒計(jì)時(shí)時(shí)間并顯示倒計(jì)時(shí)時(shí)間。
(5) 顯示各組分?jǐn)?shù)。
(6) 主持人的控制。既主持人可以開始和取消倒計(jì)時(shí)。
(7) 無線搶答端的實(shí)現(xiàn)
(8) 電腦顯示搶答情況
(9) 選擇搶答方式。一種是有倒計(jì)時(shí)有犯規(guī)的倒計(jì)時(shí)結(jié)束開始答題的,另外一種是無倒計(jì)時(shí)無犯規(guī)可以直接答題的,比如說像Lucky52那樣的,兩種只是在程序邏輯以及顯示上面稍有區(qū)別。
1.3功能實(shí)現(xiàn)的選擇
我們的搶答器選擇了上面的(1),(2)(3)(4)(6)(7)(8)進(jìn)行實(shí)現(xiàn)。
搶答的邏輯具體流程如下圖:
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1847.tmp.png 0009、八路掃描式搶答器設(shè)計(jì)論文.rar (159.69 KB, 下載次數(shù): 14)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1857.tmp.png

2主要芯片及設(shè)備的選擇:
2.1 AT89S51芯片
很熟悉的ATMEL公司的51單片機(jī),主要具有一下功能:
40個(gè)引腳
4k Bytes Flash片內(nèi)程序存儲(chǔ)器
128 bytes的隨機(jī)存取數(shù)據(jù)存儲(chǔ)器(RAM)
32個(gè)外部雙向輸入/輸出(I/O)口
5個(gè)中斷優(yōu)先級(jí)2層中斷嵌套中斷
2個(gè)16位可編程定時(shí)計(jì)數(shù)器
2個(gè)全雙工串行通信口
看門狗(WDT)電路
片內(nèi)時(shí)鐘振蕩器
2.2 Max7219芯片
MAX7219是一種串行接口的8位數(shù)碼管顯示驅(qū)動(dòng)器。它與通用微處理器只有3根串行線相連,最多可驅(qū)動(dòng)8個(gè)共陰數(shù)碼管或64個(gè)發(fā)光二極管。它內(nèi)部有可存儲(chǔ)顯示信息的8×8靜態(tài)RAM,動(dòng)態(tài)掃描電路,以及段、位驅(qū)動(dòng)器。
它的特點(diǎn)有:串行接口的傳輸速率可達(dá)10MHz;獨(dú)立的發(fā)光二極管段控制;譯碼與非譯碼兩種顯示方式可選;數(shù)字、模擬兩種亮度控制方式;可以級(jí)聯(lián)使用。
2.3 Max232芯片
Max232用于TTL電平向RS-232串口電平轉(zhuǎn)換。該產(chǎn)品是由德州儀器公司(TI)推出的一款兼容RS232標(biāo)準(zhǔn)的芯片。由于電腦串口rs232電平是-10v +10v,而一般的單片機(jī)應(yīng)用系統(tǒng)的信號(hào)電壓是ttl電平0 +5v,max232就是用來進(jìn)行電平轉(zhuǎn)換的,該器件包含2驅(qū)動(dòng)器、2接收器和一個(gè)電壓發(fā)生器電路提供TIA/EIA-232-F電平。
2.4 PT2262/2272芯片
PT2262和PT2272是CMOS三態(tài)編碼集成芯片,這組器件廣泛用于各種遙控器件上,只需較低的+3V電壓就能工作(本機(jī)選用12V作為發(fā)射電壓)。PT2262 是發(fā)射編碼芯片,PT2272是接收解碼芯片,兩者的地址必須配對,而且振蕩電阻必須符合要求。PT2262的TE端是發(fā)射允許端,接受低電平時(shí),17腳DOUT端輸出一串編碼。該串編碼在載波上發(fā)送出去,被接收端接受和解調(diào),輸入PT2272的14腳,當(dāng)?shù)刂放鋵r(shí),VT解碼有效端輸出高電平,數(shù)據(jù)端口就會(huì)輸出與PT2262發(fā)射端口一致的數(shù)據(jù),從而實(shí)現(xiàn)遙控功能。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1858.tmp.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1878.tmp.png
2.5 超再生無線發(fā)射模塊(F04P)與接收模塊(J04V)
2.5.1 超再生低功耗射頻發(fā)射模塊(315Hz)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1879.tmp.png

主要特點(diǎn):
低功耗發(fā)射,聲表穩(wěn)頻,無數(shù)據(jù)時(shí)發(fā)射電流為零,較寬的工作電壓范圍
發(fā)射電路:
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps187A.tmp.png

2.5.2超再生低功耗射頻接受模塊(315Hz)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps188B.tmp.png

主要特點(diǎn):
(0.15mA)特低功耗超再生接收模塊,輸出無噪聲干擾,接收靈敏度高,具有接受鎖存功能
接受電路于發(fā)射電路基本相似。
2.5.3 發(fā)射接收簡要原理
通過引腳的接地,懸空或者接高電平設(shè)置好發(fā)射模塊的發(fā)射地址,當(dāng)發(fā)射使能端從高電位到低點(diǎn)位變化時(shí),獎(jiǎng)發(fā)射地址和發(fā)射的數(shù)據(jù)組成16為編碼發(fā)射。

2.6 ULN2003達(dá)林頓管陣列
ULN2003 是高耐壓、大電流達(dá)林頓陳列,由七個(gè)硅NPN 達(dá)林頓管組成。
達(dá)林頓管又稱復(fù)合管。它將二只三極管適當(dāng)?shù)倪B接在一起,以組成一只等效的新的三極管。這等于效三極管的放大倍數(shù)是二者之積。在電子學(xué)電路設(shè)計(jì)中,達(dá)林頓接法常用于功率放大器和穩(wěn)壓電源中。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps188C.tmp.png

最大的作用與特點(diǎn)是每路可以介紹500mA的灌流,這也是我們使用的目的。
2.7 USB轉(zhuǎn)串口模塊(USB/RS232)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps189D.tmp.png

采用USB轉(zhuǎn)串口的標(biāo)準(zhǔn)芯片PL2303和RS232電平接口芯片MAX211的組合。
2.8高亮度Super Red四寸共陰極數(shù)碼管
正常發(fā)光電壓約5--6V, 正常導(dǎo)通電流約40--80mA

3硬件電路的實(shí)現(xiàn)以及各個(gè)部分的作用
3.1 硬件電路圖(Proteus仿真圖)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps18EC.tmp.png

3.2各個(gè)模塊的說明與簡介
3.2.1 單片機(jī)最小系統(tǒng):
這個(gè)不用多說,可惜是買別人的。上面得是提供的是12MHz的晶振,與程序中的保持一樣.因?yàn)樵谟?jì)算定時(shí)的時(shí)候,要用到晶振的大小。
3.2.2 Max7219模塊
這個(gè),還是買的別人做的PCB,我們自己用面包版連了,可以不行,懷疑是沒有選擇正確的電容的問題,或者說,我們不會(huì)選擇電容。
3.2.3 無線搶答端發(fā)射模塊
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps18ED.tmp.png

無線搶答端采用PT2262發(fā)射編碼芯片+F05P發(fā)射模塊的組合,另外使用一根拉直的長24CM的天線。
關(guān)于按鈕,買的不知道用來控制什么的按鈕,反正正和我們意,買這個(gè)的時(shí)候要注意手感,要讓使用者用的舒適。從院科協(xié)L同學(xué)那里淘來的半圓形按鈕外殼。
3.2.4無線接收模塊
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps18FD.tmp.png

無線搶答端采用PT2272發(fā)射編碼芯片+F04V接收模塊的組合。Pt2272與PT2262要設(shè)置為地址相同,電阻匹配。接受到的信號(hào)傳至單片機(jī)中。
3.2.5 主持人控制按鍵
這里有兩個(gè)按鈕,分別為OK/START,CANCEL/CLEAR. 前者是用來設(shè)置完畢搶答倒計(jì)時(shí)時(shí)間和開始倒計(jì)時(shí),后者是用來取消搶答和清理數(shù)碼管并顯示倒計(jì)時(shí)開始時(shí)間,用來等待再次開始搶答。
3.2.6 設(shè)置倒計(jì)時(shí)時(shí)間的撥碼開關(guān)
仿“8421”碼設(shè)置的“2321”碼,全部低位的時(shí)候?yàn)椤?”,四個(gè)開關(guān)可以設(shè)置1-9任何數(shù)字。缺點(diǎn)就是買的撥碼開關(guān)小了點(diǎn)。
3.2.7 譯碼器以及搶答端的發(fā)光二極管
譯碼器從單片機(jī)得到輸入,然后低位選通發(fā)光二極管。
3.2.8 位選反向驅(qū)動(dòng)
說不清了,這樣的了。
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps191E.tmp.png

3.2.9 段選反向驅(qū)動(dòng)
兩個(gè)反向驅(qū)動(dòng)的本意在于,雖然Max7219驅(qū)動(dòng)的是共陰極數(shù)碼管,但是從datasheet上面可以看出來,段選的拉流不可以滿足這種型號(hào)的數(shù)碼管,位選的灌流也不能接受,所以這里配合ULN2003來使用。因?yàn)閁LN2003的特點(diǎn),高位接受灌流,低位為高阻,所以要使用反向驅(qū)動(dòng)。這里,段選的反向驅(qū)動(dòng)在程序里面的反向了,而對于位選,用于是該芯片自己進(jìn)行的,所以程序控制不了,所以在Max7219位選的下游使用了一個(gè)與非門來當(dāng)作反向器來使用。
3.3.10 上位機(jī)接口
采用MAX232芯片進(jìn)行RS232-TTL電平轉(zhuǎn)換,輸出至串口,然后再通過USB轉(zhuǎn)串口模塊連接至上位機(jī)。
3.2.11 大尺寸數(shù)碼管
這個(gè)前面說過了。

4硬件實(shí)現(xiàn)的步驟
4.1硬件實(shí)現(xiàn)的各個(gè)步驟
(1) 通過實(shí)驗(yàn)板來驗(yàn)證各個(gè)主要功能模塊的正確實(shí)現(xiàn)。
這個(gè)就是在實(shí)驗(yàn)板接線,來分開的檢測各個(gè)部分的正確性,當(dāng)然有的部分還是沒有辦法驗(yàn)證的。
(2) 仿真器+面包板上面的插線實(shí)驗(yàn)
恩,仿真器很好使。就是上面的限流電阻給不小心被燒了,郁悶。
(3) 最小系統(tǒng)+面包板上面插線實(shí)驗(yàn)
使用仿真器的時(shí)候用的是電腦提供的+5V電壓,可能和用自己的供電的不太一樣,尤其是同時(shí)也在使用+12V電源的時(shí)候,電腦給出的+5V可能的比較低,這樣一來會(huì)有些不必要的問題,而用最小系統(tǒng)則沒有這些問題。
(4) 焊接萬能板
這個(gè)很有趣也很關(guān)鍵。
(5) 仿真器+電路板的實(shí)現(xiàn)
用來驗(yàn)證電路板上的各個(gè)部分是否焊接成功。
(6) 最小系統(tǒng)+電路板的實(shí)現(xiàn)
恩這個(gè)就是最后的驗(yàn)證了。
4.2一個(gè)原則
由上可見,在實(shí)驗(yàn)過程中,總體上也采取單變量原則,這樣方便有效地對于每一部分進(jìn)行檢驗(yàn)。另外,如果在檢驗(yàn)焊接板上面的錯(cuò)誤的話,要配合著面包板使用才行,也是保證單變量,這樣對比出來面包上成功的時(shí)候和現(xiàn)在失敗的時(shí)候只有哪個(gè)地方不同,那百分之九十就是這個(gè)地方了。

5軟件實(shí)現(xiàn)(單片機(jī)上的軟件)
5.1程序編寫
模塊化,使整個(gè)程序的每個(gè)部分具有較好的可移植性。
5.2程序測試
在Keil Uvision + Proteus聯(lián)調(diào)環(huán)境下進(jìn)行邏輯的測試,不過這個(gè)只是邏輯上面的測試,距離能成功還有很遠(yuǎn)。
5.3最終代碼
最后的代碼將在另見。

6電腦端(上位機(jī))顯示程序
電腦端使用C#編寫程序,利用了.Net的SerialPort類對電腦端口檢測和接受數(shù)據(jù)。這個(gè)將會(huì)另有介紹。


7 后續(xù)工作和幾個(gè)問題
(1) 電源還需優(yōu)化, 可以采用三穩(wěn)壓管電源。
(2) 電阻發(fā)熱問題: 我們使用的3W的大功率電阻竟然不到1.5W的情況下就發(fā)熱了,還沒有搞懂。
(3) 我們的74HC00與非門在未加高電平的情況下就已經(jīng)正常工作了,不清楚這是什么情況。
(4) 可以考慮增加搶答模式與小組積分,實(shí)現(xiàn)按著使用者的要求對于程序進(jìn)行選擇。
(5) 無線端搶答端電池的問題。因?yàn)槟壳暗脑O(shè)計(jì)是電池如果沒有取出的話,將一直對發(fā)射系統(tǒng)供電,這樣會(huì)消耗電池,但采用一次按鍵先后接通電路,發(fā)射編碼的方法,總是不穩(wěn)定
#include <REG51.h>
#include <STRING.H>

/******************************************************************
*    自定義Macro
*******************************************************************/

//編碼的均為反向編碼

#define CLEAR 0x7f                  //定義清空的反碼
#define LED_BEGIN 0x01            // 定義開始時(shí)數(shù)碼管的顯示
#define LED_FOUL 0x38             // 犯規(guī)后顯示字母"F",數(shù)碼管編碼
#define LED_C 0x31                // 字母"C"的編碼
#define LED_L 0x71                // 字母"L"的編碼,兩個(gè)用來在主持人取消之后顯示"CL"--cancel
#define GET 1                     // 這個(gè)是作為一個(gè)函數(shù)的參數(shù)來混的,就是成功搶答的意思
#define FOUL 0                    // 和上面的參數(shù)一起混的,犯規(guī)---這兩個(gè)的用法在后面體現(xiàn)
#define READY 0x7e

//下面是給上位機(jī)發(fā)送的指令,對應(yīng)的是cmdID
#define _STRING_READY_ 9//調(diào)整好搶答倒計(jì)時(shí),準(zhǔn)備開始搶答
#define _STRING_START_ 8//讀秒結(jié)束,搶答開始
#define _STRING_CANCEL_ 7//取消搶答
#define _CHANGE_TIME_ 6//每次讀秒
//發(fā)送1--4的指令代表搶答端的序號(hào)

//因?yàn)樵诎遄由厦娌捎玫氖?/font>12M的晶振,仿真時(shí)候采用的是11.0529M的晶振,為了方便不同時(shí)候編譯方便,這里與后面的條件編譯一起使程序修改參數(shù)比較方便
//#define CLOCK_FREQUENCY_12M 1

/******************************************************************
*    自定義數(shù)據(jù)類型
*******************************************************************/
typedef unsigned char Byte;       // 一個(gè)字節(jié)
typedef unsigned int Word;        // 一個(gè)字,兩個(gè)字節(jié)
typedef bit Bool;                 // 模仿布爾型變量
//typedef sbit Port;              // 本想用自定義一個(gè)端口類型的變量,比較方便,但是這句話步知道為何通不過編譯

/******************************************************************
*    定義MAX7219寄存器
*******************************************************************/
#define REG_NO_OP 0x00        // 定義空操作 register
#define DIG_1 0x01            // 定義數(shù)碼管1 register
#define DIG_2 0x02            // 定義數(shù)碼管2 register
#define DIG_3 0x03            // 定義數(shù)碼管3 register
#define DIG_4 0x04            // 定義數(shù)碼管4 register
#define DIG_5 0x05            // 定義數(shù)碼管5 register
#define DIG_6 0x06            // 定義數(shù)碼管6 register
#define DIG_7 0x07            // 定義數(shù)碼管7 register
#define DIG_8 0x08            // 定義數(shù)碼管8 register
#define REG_DECODE 0x09       // 定義解碼控制 register
#define REG_INTENSITY 0x0a    // 定義顯示亮度 register
#define REG_SCAN_LIMIT 0x0b   // 定義掃描限制 register
#define REG_SHUTDOWN 0x0c     // 定義"shutdown"模式 register
#define REG_DISPLAY_TEST 0x0f // 定義"display test"模式 register
#define INTENSITY_MIN 0x00    // 定義最低顯示亮度
#define INTENSITY_MAX 0x0f    // 定義最高顯示亮度

/*********************************************************************
*    定義硬件引腳連接
**********************************************************************/
sbit DATA=P2^0;               // MAX7219的數(shù)據(jù)口
sbit LOAD=P2^1;               // MAX7219的鎖存端口
sbit CLK=P2^2;                // MAX7219的時(shí)鐘端口

sbit HOST_START=P0^0;             //主持人按鍵,用來重新開始的按鍵    start
sbit HOST_CANCEL=P0^1;            //主持人用來取消搶答的按鍵        clear

sbit SWITCH1_3=P1^4;    // 調(diào)節(jié)倒計(jì)時(shí)時(shí)間的撥碼開關(guān),下劃線前面的號(hào)代表開關(guān)的序號(hào),下劃線后面的號(hào)代表該開關(guān)的數(shù)值
sbit SWITCH2_2=P1^5;          // 同上
sbit SWITCH3_2=P1^6;          // 同上
sbit SWITCH4_1=P1^7;          // 同上

sbit BEEP=P0^7;            //定義蜂鳴器端口

#ifdef USE_SOUND       //可以通過define來選擇要不要使用仿真時(shí)候的聲音
sbit LS138_C=P2^4;       //定義譯碼器輸入端
sbit LS138_B=P2^5;       //同上                  
sbit LS138_A=P2^6;       //同上
sbit LS138_E1=P2^7;       //定義譯碼器使能端
#endif

/*********************************************************************
*    定義全局變量
**********************************************************************/
Byte data intrCounter; // 計(jì)時(shí)器中斷次數(shù)
Byte data beginNum;    // 開始倒計(jì)時(shí)的時(shí)間
Byte data counterBack;  // 將中斷次數(shù)放在里面以備后用
Byte data showNum;     // 數(shù)碼管正在顯示的時(shí)間
Bool data isStart;     // 是否開始搶答  
Bool data isFoul;      // 是否犯規(guī)
Bool data isPressed;   // 是否有搶答的鍵按下
Byte data number_temp; // 用來記錄P1口上次狀態(tài)的一個(gè)變量
Bool data needResetTimes;//記錄是否需要重設(shè)Timer0的溢出次數(shù)

code unsigned char C51BOX2[3] _at_ 0x43; //使用C51Box時(shí)候防止程序跑丟

/***********************************************************************
*   共陰極七段數(shù)碼管顯示對應(yīng)段查詢表(數(shù)字0-9分別對應(yīng)code_table[0]-[9]
***********************************************************************/
Byte code code_table_zheng[10]=
{0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b};

Byte code code_table[10]=
{0x01,0x4f,0x12,0x06,0x4c,0x24,0x20,0x0f,0x00,0x04};

/***********************************************************************
*   函數(shù)聲明
***********************************************************************/
void MAX7219_SendByte (Byte dataout);
void MAX7219_Write (Byte reg_number, Byte dataout);
void MAX7219_DisplayChar(Byte digit, Byte character);
void MAX7219_Clear (void);
void MAX7219_SetBrightness (Byte brightness);
void MAX7219_DisplayTestStart (void);
void MAX7219_DisplayTestStop (void);
void MAX7219_ShutdownStart (void);
void MAX7219_ShutdownStop (void);
void MAX7219_Init (void);
void Delay10ms(void);
Bool GetHostStartKey (void);
Bool GetHostCancelKey (void);
void GetCounter(void);
Byte GetPressed(Byte KeyState);
Byte GetPressedWireless(Byte KeyState);
void IT0_Init(void);
void Timer0_Overflow();
void PressedHandle(Byte keyPressed);
void GetOrFoulHandle(Bool state);
void CancelHandle();
void SPEAKER_count (void);    //聲明倒計(jì)時(shí)聲音函數(shù)
void SPEAKER_start(void);        //聲明開始搶答聲音函數(shù)
void SPEAKER_get(void);    //聲明搶到聲音函數(shù)
void SPEAKER_foul(void);   //  聲明犯規(guī)聲音函數(shù)
void initialSerial();
void sendNumber(int number);//串口發(fā)送數(shù)字,這里發(fā)送的是CommandID
void sendString(unsigned char *string);//串口發(fā)送字符串

/***********************************************************************
* MAX7219_SendByte()
*
* 描述: MAX7219傳送一個(gè)字節(jié)的數(shù)據(jù)
* Arguments : dataout = data to send
* Returns : none
*************************************************************************/
void MAX7219_SendByte (Byte dataout)
{
    Byte i;
    for (i=8;i>0;i--)
    {
        Byte mask=1<<(i-1);//mask是個(gè)掩碼,取位使用
        CLK=0;//MAX7219的位傳入是在時(shí)鐘的上升沿之前,所以在每發(fā)一位之前都要變?yōu)榈碗娖?/font>
        if (dataout&mask)
            DATA=1;
        else
            DATA=0;
        CLK=1;//八個(gè)bit都傳遞完成后變?yōu)楦唠娖?/font>,鎖存
    }
}

/***********************************************************************
* MAX7219_Write()
*
* 描述: MAX7219 寫命令
* Arguments : reg_number = register to write to
* dataout = data to write to MAX7219
* Returns : none
未完~
***************************************************************************/
void MAX7219_Write (Byte reg_number, Byte dataout)
{
        LOAD=0;//也是鎖存上升沿之前的,發(fā)這兩個(gè)字節(jié)之前要變?yōu)榈碗娖?/font>
        MAX7219_SendByte(reg_number);//發(fā)送寄存器地址
        MAX7219_SendByte(dataout);//發(fā)送數(shù)據(jù)
        LOAD=1;//變?yōu)楦唠娖?/font>,鎖存
}

/**************************************************************************
* MAX7219_DisplayChar()
*
* 描述: 使某一位顯示一個(gè)數(shù)字
* Arguments : digit = digit number (0-7)
* character = character to display (0-9, A-Z)
* Returns : none
**************************************************************************/
void MAX7219_DisplayChar(Byte digit, Byte character)
{
         MAX7219_Write(digit, character);
}

/**************************************************************************
* MAX7219_Clear()
*
* 描述: 清除所有位的顯示
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_Clear (void)
{
         Byte i;
         for (i=1; i<=2; i++)
         MAX7219_Write(i, CLEAR);//把八個(gè)數(shù)碼管全都清零了,已經(jīng)寫反了^_^
}

/**************************************************************************
* MAX7219_SetBrightness()
*
* 描述: 設(shè)置數(shù)碼管顯示亮度
* Arguments : brightness (0-15)
* Returns : none
***************************************************************************/
void MAX7219_SetBrightness (Byte brightness)
{
         brightness &= 0x0f;
         MAX7219_Write(REG_INTENSITY, brightness);
}

/**************************************************************************
* MAX7219_DisplayTestStart()
*
* 描述: 進(jìn)入 test 模式
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_DisplayTestStart (void)
{
    MAX7219_Write(REG_DISPLAY_TEST, 1);
}

/**************************************************************************
* MAX7219_DisplayTestStop()
*
* 描述: 退出 test 模式
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_DisplayTestStop (void)
{
    MAX7219_Write(REG_DISPLAY_TEST, 0);
}

/**************************************************************************
* MAX7219_ShutdownStart()
*
* 描述: 進(jìn)入 shutdown 模式
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_ShutdownStart (void)
{
    MAX7219_Write(REG_SHUTDOWN, 0);
}

/**************************************************************************
* MAX7219_ShutdownStop()
*
* 描述: 退出 shutdown 模式
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_ShutdownStop (void)
{
        MAX7219_Write(REG_SHUTDOWN, 1);
}

/**************************************************************************
* MAX7219_Init()
*
* Description: MAX7219初始化模塊; 應(yīng)該先于其他MAX7219函數(shù)而被調(diào)用
* Arguments : none
* Returns : none
***************************************************************************/
void MAX7219_Init (void)
{
    DATA=1;
    CLK=1;
    LOAD=1;
    MAX7219_Write(REG_SCAN_LIMIT,1);//這里設(shè)置的是掃描兩個(gè)數(shù)碼管
    MAX7219_Write(REG_DECODE, 0x00);
    MAX7219_SetBrightness(INTENSITY_MAX);//設(shè)置最大亮度顯示
    MAX7219_DisplayTestStart();
    MAX7219_DisplayTestStop();
    MAX7219_ShutdownStop();
    MAX7219_Clear();
}

/**************************************************************************
* Delay_100us()
*
* 描述: 延時(shí)100us,主要用在消除開關(guān)抖動(dòng)時(shí)
* Arguments : none
* Returns : none
***************************************************************************/
void Delay10ms(void)
{
unsigned char i,j;
for(i=20;i>0;i--)
for(j=248;j>0;j--);
}
/**************************************************************************
* GetHostStartKey()
*
* Description: 取得主持人開始按鍵的鍵值
* Arguments : none
* Returns : 1-->主持人按鍵; 0-->主持人未按鍵
***************************************************************************/
Bool GetHostStartKey (void)
{
    if (HOST_START ==1)
        return 0;
    else
        Delay10ms ();//如果發(fā)現(xiàn)主持人按鍵接通,要先延時(shí)100us,防止抖動(dòng)
    if (HOST_START==1)
        return 0;
    else
        return 1;//延時(shí)時(shí)候還是接通,則判斷為該鍵確實(shí)按下   
}

/**************************************************************************
* GetHostCancelKey()
*
* Description: 取得主持人取消按鍵的鍵值
* Arguments : none
* Returns : 1-->主持人按鍵; 0-->主持人未按鍵
***************************************************************************/
Bool GetHostCancelKey (void)
{
    if (HOST_CANCEL ==1)
        return 0;
    else
        Delay10ms ();//如果發(fā)現(xiàn)主持人按鍵接通,要先延時(shí)100us,防止抖動(dòng)
    if (HOST_CANCEL ==1)
        return 0;
    else
        return 1;//延時(shí)時(shí)候還是接通,則判斷為該鍵確實(shí)按下   
}

/**************************************************************************
* GetCounter
*
* Description: 取得預(yù)先設(shè)置的倒計(jì)時(shí)時(shí)間
* Arguments : none
* Returns : none
***************************************************************************/
void GetCounter(void)
{
    beginNum=1;//在所有開關(guān)都沒有撥動(dòng)的時(shí)候倒計(jì)時(shí)為1,比設(shè)置為0秒要好
    intrCounter=20;//每一秒對應(yīng)的中斷次數(shù)為20
    if (SWITCH1_3==1)
    {
        beginNum+=3;
    }
    if (SWITCH2_2==1)
    {
        beginNum+=2;
    }
    if (SWITCH3_2==1)
    {
        beginNum+=2;
    }
    if (SWITCH4_1==1)
    {
        beginNum+=1;
    }//以上判斷語句為判斷撥碼開關(guān)狀態(tài)
    intrCounter=20*beginNum;//計(jì)算總掃描次數(shù)
}

/**************************************************************************
* GetPressed
*
* Description: P2口連接搶答端的四位來判斷搶答情況
* Arguments : Byte KeyState-->P2 state
* Returns : 搶答端的號(hào)碼 ; 0-->沒人搶答
***************************************************************************/
Byte GetPressed(Byte KeyState)
{
    Byte key;//記錄搶答端的號(hào)碼
    KeyState&=0xf0;//P1口的低四位
   
    switch (KeyState)
    {
        case 0xf0: key=0;break;//全高,無人搶答
        case 0xe0: key=1;break;//只有P1.1,key1搶答
        case 0xd0: key=2;break;//只有P1.2,key2搶答
        case 0xb0: key=3;break;//只有P1.3,key3搶答
        case 0x70: key=4;break;//只有P1.4,key4搶答
    }
    /*
    switch (KeyState)
    {
        case 0x00: key=0;break;//全高,無人搶答
        case 0x01: key=1;break;//只有P1.0,key1搶答
        case 0x02: key=2;break;//只有P1.1,key2搶答
        case 0x04: key=3;break;//只有P1.2,key3搶答
        case 0x08: key=4;break;//只有P1.3,key4搶答
    }
    */
    //上面是在用高電平來判斷搶答狀態(tài)時(shí)的程序,經(jīng)證明不知道為何無效

    return key;   
}

/**************************************************************************
* GetPressedWireless
*
* Description: P2口的高四位于Pt2272接受模塊相連,該方法用來判斷無線搶答序號(hào)
* Arguments : Byte KeyState-->P2 state
* Returns : 搶答端的號(hào)碼 ; 0-->沒人搶答
***************************************************************************/
Byte GetPressedWireless(Byte KeyState)
{
    Byte key;//記錄搶答端的號(hào)碼
    KeyState&=0xf0;//P2口的高四位
   
    /*
    switch (KeyState)
    {
        case 0x0f: key=0;break;//全高,無人搶答
        case 0x0e: key=1;break;//只有P1.1,key1搶答
        case 0x0d: key=2;break;//只有P1.2,key2搶答
        case 0x0b: key=3;break;//只有P1.3,key3搶答
        case 0x07: key=4;break;//只有P1.4,key4搶答
    }
    */

    switch (KeyState)
    {
        case 0x00: key=0;break;//全低,無人搶答
        case 0x10: key=1;break;//只有P1.0,key1搶答
        case 0x20: key=2;break;//只有P1.1,key2搶答
        case 0x40: key=3;break;//只有P1.2,key3搶答
        case 0x80: key=4;break;//只有P1.3,key4搶答
    }
    return key;   
}

/**************************************************************************
* IT0_Init
*
* Description: 初始化計(jì)時(shí)器T0的狀態(tài)
* Arguments : none
* Returns : none
***************************************************************************/
void IT0_Init(void)
{
    TMOD=0x21;//設(shè)置T0在方式1下工作,同時(shí)還要保證T1,也就是波特率所學(xué)的定時(shí)器的正常工作

    #ifdef CLOCK_FREQUENCY_12M//對使用哪種晶振進(jìn)行條件編譯
    TH0=0x3C;//12M晶振時(shí)的裝入值
    TL0=0xAF;
    #else
    TH0=0x4C;//11.0529M晶振時(shí)裝入值
    TL0=0x00;
    #endif

    ET0=1;//使T0中斷可以溢出
    EA=1;//開啟總中斷
    TF0=0;//溢出位清零
    TR0=1;//開啟T0
}

/**************************************************************************
* Timer0_Overflow() interrupt 1
*
* Description: 中斷溢出服務(wù)程序, 采用的是中斷方式1, 后面最好不加using選擇寄存器組以免與系統(tǒng)用在主程序的寄存器沖突
* Arguments : none
* Returns : none
***************************************************************************/
void Timer0_Overflow() interrupt 1
{
    static Byte times=20;//溢出次數(shù),20次中斷來判斷1
    //這里存在重大bug,到由于有相應(yīng)而停止Timer0,再次啟用時(shí),這里的second沒有回歸原值

    if (needResetTimes==1)
    {
        times=20;
        needResetTimes=0;//已重設(shè),不需要再次重新設(shè)置溢出次數(shù)
    }

    #ifdef CLOCK_FREQUENCY_12M//對使用哪種晶振進(jìn)行條件編譯
    TH0=0x3C;//12M晶振時(shí)的裝入值
    TL0=0xAF;//這兩個(gè)寄存器存的是計(jì)數(shù)器的計(jì)數(shù)開始的值,計(jì)算發(fā)現(xiàn)這兩個(gè)值累加至溢出后正好是50ms
    #else
    TH0=0x4C;//11.0529M晶振時(shí)裝入值
    TL0=0x00;//同理,這兩個(gè)寄存器存的是計(jì)數(shù)器的計(jì)數(shù)開始的值,計(jì)算發(fā)現(xiàn)這兩個(gè)值累加至溢出后正好是50ms
    #endif

    times--;
    intrCounter--;

    /* 原來使用的方法
    if (times==0)//每隔一秒的操作
    {
        MAX7219_DisplayChar(DIG_2,code_table[--showNum]); //要避免用上面的會(huì)造成顯示"0"后面一秒鐘,才進(jìn)入開始
        times=20;//重新賦值每秒計(jì)數(shù)器
        if (intrCounter==0)
        {
            TR0=0;//關(guān)閉T0計(jì)數(shù)器
            isStart=1;//計(jì)時(shí)結(jié)束,進(jìn)入正常搶答
            //SPEAKER_start();//開始搶答的聲音
        }
        //待顯示"0"以后就開始搶答
        else
        {
            //SPEAKER_count();//倒計(jì)時(shí)聲音        
        }
    }
    */

    if (times==0)//每隔一秒的操作
    {
        //if (showNum!=1) SPEAKER_count();//倒計(jì)時(shí)聲音
        //else SPEAKER_start();//開始搶答的聲音
        MAX7219_DisplayChar(DIG_2,code_table[--showNum]);//顯示數(shù)字
        sendNumber(_CHANGE_TIME_);//給上位機(jī)發(fā)送要顯示數(shù)字的命令
        times=20;//重新賦值每秒計(jì)數(shù)器
     }//待顯示"0"以后就開始搶答

     if (intrCounter==0)
     {
        TR0=0;//關(guān)閉T0計(jì)數(shù)器
        isStart=1;//計(jì)時(shí)結(jié)束,進(jìn)入正常搶答
     }

}

/**************************************************************************
* PressedHandle
*
* Description: 按鍵處理
* Arguments : Byte keyPressed-->按下的按鍵
* Returns : none
***************************************************************************/
void PressedHandle(Byte keyPressed)
{
    MAX7219_Clear();//LED clear
    MAX7219_DisplayChar(DIG_2,code_table[keyPressed]);//在右側(cè)數(shù)碼管顯示搶答選手號(hào)碼,此時(shí)沒有去判斷是否犯規(guī)
   
    //給上位機(jī)發(fā)搶答選手的號(hào)碼
    sendNumber(keyPressed);
}

/**************************************************************************
* GetOrFoulHandle(Bool state)
*
* Description: 正常搶答或是犯規(guī)處理
* Arguments : Bool state-->GETFOUL兩個(gè)宏的取之之一
* Returns : none
***************************************************************************/
void GetOrFoulHandle(Bool state)
{
    if (!state)
    {
        MAX7219_DisplayChar(DIG_1,LED_FOUL);//如果是犯規(guī)的話左邊的LED要顯示"F",foul
    }
}

/**************************************************************************
* CancelHandle()
*
* Description: 處理主持人取消倒計(jì)時(shí)
* Arguments : none
* Returns : none
***************************************************************************/
void CancelHandle()
{   
    MAX7219_DisplayChar(DIG_1,LED_C);
    MAX7219_DisplayChar(DIG_2,LED_L);//主持人取消倒計(jì)時(shí)之后,兩個(gè)數(shù)碼管顯示"CL"-->cancel
}

/**************************************************************************
* delayus()
*
* Description: 延時(shí)程序
* Arguments : t-->us
* Returns : time delayed
***************************************************************************/
void delayus(unsigned char t )
{
     unsigned char j;
    for(;t>0;t--)
        for(j=19;j>0;j--);
}

/**************************************************************************
* SPEAKER_count/start/foul/get()
*
* Description: speaker發(fā)聲程序->計(jì)數(shù)/開始/犯規(guī)/搶答 四種聲音
* Arguments : none
* Returns : none
***************************************************************************/
void SPEAKER_count(void)
{
    unsigned char i;
    for    (i=0;i<10;i++)
    {
        BEEP =1; //點(diǎn)亮
        delayus(20);
        BEEP =0; //熄滅   
        delayus(20);
     }
}
                                                              
void  SPEAKER_start(void)
{
    unsigned char i;
    for(i=0;i<200;i++)
    {
          BEEP =1; //點(diǎn)亮
        delayus(10);
        BEEP =0; //熄滅   
        delayus(10);
    }
}

void  SPEAKER_foul(void)
{
    unsigned char i;
    for(i=0;i<250;i++)
    {
          BEEP =1; //點(diǎn)亮
        delayus(15);
        BEEP =0; //熄滅   
        delayus(17);
    }

}

void  SPEAKER_get(void)
{
    unsigned char i;
    for(i=0;i<250;i++)
    {
          BEEP =1; //點(diǎn)亮
        delayus(10);
        BEEP =0; //熄滅   
        delayus(10);
    }
            
    for(i=0;i<250;i++)
    {
          BEEP =1; //點(diǎn)亮
        delayus(20);
        BEEP =0; //熄滅   
        delayus(20);
    }
}

/**************************************************************************
* initialSerial()
*
* Description: 初始化串口
* Arguments : none
* Returns : none
***************************************************************************/
void initialSerial()
{
    EA=0;//關(guān)閉所有中斷
    TMOD=0x21;//設(shè)置T1定時(shí)器的工作模式:方式2;同時(shí)保證T0的工作模式正常.這兒太重要了
    TH1=0xFA;
    TL1=0xFA;
    PCON=0x80;//設(shè)置SMOD=1
    SCON=0x50;//選擇工作方式1,即為UART
    TR1=1;//設(shè)置好定時(shí)器并打開定時(shí)器,定好波特率9600bit/s
}

/**************************************************************************
* sendNumber(int number)
*
* Description: 通過串口發(fā)送一位數(shù)字
* Arguments : number->要發(fā)送的數(shù)字
* Returns : none
***************************************************************************/
void sendNumber(int number)
{
    TI=0;
    SBUF=number+48;
    while(!TI);
    TI=0;
}

/**************************************************************************
* sendString(unsigned char *string)
*
* Description: 通過串口發(fā)送字符串
* Arguments : 要發(fā)送的字符串的頭指針
* Returns : none
***************************************************************************/
void sendString(unsigned char *string)
{
    do
    {
        SBUF=*string;
        while(!TI);
        TI=0;
        string++;
    }while(*(string-1)!='\0');

/**************************************************************************
* 主程序
***************************************************************************/
void main()
{   
    //P1=0xff;
    Byte keyPressed,i;//選手按鍵號(hào)碼,沒有的話為0   
    Bool hostPressed;//用來記錄主持人按鍵取消,0為沒有動(dòng)作,1為取消
    Byte buf[10];//設(shè)置發(fā)送緩沖區(qū)
    number_temp=P1&0xf0;//P1口上次的狀態(tài),在調(diào)整倒計(jì)時(shí)時(shí)間的時(shí)候用到的   
   
    #ifdef USE_SOUND
    LS138_E1=1;         //譯碼器初始化
    #endif

    needResetTimes=0;//不需要重新設(shè)置溢出次數(shù)
   
    MAX7219_Init();//數(shù)碼管初始化
    initialSerial();//初始化串口發(fā)送
   
    GetCounter();//獲取開始時(shí)候設(shè)置的倒計(jì)時(shí)時(shí)間   
    MAX7219_DisplayChar(DIG_1,code_table[beginNum]);
//顯示開始時(shí)設(shè)置的倒計(jì)時(shí)時(shí)間,在左位設(shè)置     
    MAX7219_DisplayChar(DIG_2,READY);//調(diào)時(shí)間的時(shí)候右位的顯示
   
    while(GetHostStartKey()==0)//當(dāng)主持人沒有按鍵的時(shí)候進(jìn)入循環(huán)
    {
        if (number_temp!=(P1&0xf0))
//若調(diào)整了倒計(jì)時(shí)時(shí)間,P1口狀態(tài)變了,就要重新設(shè)置和顯示
        {
            GetCounter();//獲取調(diào)整以后的倒計(jì)時(shí)時(shí)間
            MAX7219_DisplayChar(DIG_1,code_table[beginNum]);
//顯示調(diào)整以后的倒計(jì)時(shí)時(shí)間
            number_temp=P1&0xf0;//記錄下來現(xiàn)在P1口的狀態(tài),以備后面的比較
        }            
    }    //當(dāng)主持人按鍵以后就結(jié)束調(diào)整進(jìn)入搶答倒計(jì)時(shí)
    sendNumber(beginNum);

    MAX7219_DisplayChar(DIG_1,READY);
    while(GetHostCancelKey()==0);
   
    sendNumber(_STRING_READY_);//發(fā)送調(diào)節(jié)完畢準(zhǔn)備搶答的命令;

    //調(diào)整好倒計(jì)時(shí)時(shí)間后,按下start顯示"--",再按下cancel則顯示倒計(jì)時(shí)時(shí)間,此時(shí)可以開始倒計(jì)時(shí)了.
    MAX7219_DisplayChar(DIG_1,READY);//清空右邊一位數(shù)碼管
    MAX7219_DisplayChar(DIG_2,code_table[beginNum]);
    for (i=100;i--;i>0)
        Delay10ms();//防止后面出現(xiàn)連讀的情況..

    counterBack=intrCounter; //備份要中斷的總次數(shù)
    while(1)//這里要用自己加的循環(huán)來把程序束縛在這里運(yùn)行
    {
        showNum=beginNum;//設(shè)置要顯示的時(shí)間,當(dāng)然時(shí)從倒計(jì)時(shí)時(shí)間開始
        intrCounter=counterBack;//設(shè)置總中斷的次數(shù)
        TR0=0;//禁用計(jì)時(shí)器0
        isPressed=0;//記錄是否有人按鍵
        isStart=0;//沒有開始搶答
        while(GetHostStartKey()==0);

        //給上位機(jī)發(fā)送開始倒計(jì)時(shí)的指令
        sendNumber(_STRING_START_);

        needResetTimes=1;//Timer0已經(jīng)是第二輪開始,需要重新設(shè)置溢出次數(shù)
        IT0_Init();//初始化計(jì)時(shí)器0, 啟用.

        MAX7219_DisplayChar(DIG_1,CLEAR);//清空左邊一位數(shù)碼管
        while(!isPressed)//如果沒有記錄到有人按鍵就進(jìn)入
        {
            keyPressed=GetPressed(P2);
//查詢一下P2口的狀態(tài),即按鍵情況,P2口的后四位作為搶答端輸入,有線時(shí)候使用
            //keyPressed=GetPressedWireless(P2);//查詢一下P2口的狀態(tài),即按鍵情況,無線使用
            hostPressed=GetHostCancelKey();
            if (!keyPressed&&!hostPressed)//如果沒有人按鍵,就進(jìn)入下次循環(huán)
                continue;
            else
            {
                TR0=0;//關(guān)閉定時(shí)器
                isPressed=1;//記錄到有人按鍵,提供條件跳出循環(huán)
            }
        }

        if (keyPressed!=0)
        {
            if (isStart)//如果已經(jīng)開始搶答
            {
                PressedHandle(keyPressed);//處理按鍵,即顯示搶答選手號(hào)碼
                GetOrFoulHandle(GET);//處理搶答

                #ifdef USE_SOUND//對是否使用揚(yáng)聲器進(jìn)行條件編譯
                LS138_E1=0;       //譯碼器準(zhǔn)備工作
                switch (keyPressed)
                {
                    case 1:      LS138_A=0;LS138_B=0;LS138_C=0;break;       //1號(hào)成功燈亮
                    case 2:      LS138_A=0;LS138_B=1;LS138_C=0;break;       //2號(hào)成功燈亮
                    case 3:  LS138_A=1;LS138_B=0;LS138_C=0;break;       //3號(hào)成功燈亮
                    case 4:  LS138_A=1;LS138_B=1;LS138_C=0;break;       //4號(hào)成功燈亮
                    default : break;
                }
                #endif
            }   
                                                  
            else//否則,沒有開始搶答
            {   
                PressedHandle(keyPressed);//處理按鍵,即顯示搶答選手號(hào)碼
                GetOrFoulHandle(FOUL);//處理犯規(guī),必須要放在后面,因?yàn)轱@示數(shù)字的里面有一個(gè)clear

                #ifdef USE_SOUND//對是否使用揚(yáng)聲器進(jìn)行條件編譯
                LS138_E1=0;       //譯碼器準(zhǔn)備工作
                switch (keyPressed)
                {
                    case 1: LS138_A=0;LS138_B=0;LS138_C=1;break;                                       //1號(hào)犯規(guī)燈亮
                    case 2:  LS138_A=0;LS138_B=1;LS138_C=1;break;       //2號(hào)犯規(guī)燈亮
                    case 3:  LS138_A=1;LS138_B=0;LS138_C=1;break;       //3號(hào)犯規(guī)燈亮
                    case 4:  LS138_A=1;LS138_B=1;LS138_C=1;break;       //4號(hào)犯規(guī)燈亮
                    default : break;
                }
                #endif
            }
        }

        if (hostPressed==1)
        {
            CancelHandle();
            //向上位機(jī)發(fā)送主持人取消的指令
            sendNumber(_STRING_CANCEL_);
            for (i=100;i--;i>0)
                Delay10ms();//防止后面出現(xiàn)連讀的情況..        
        }
        while(GetHostCancelKey()==0);//如果主持人沒有按鍵再次開始,則停在次死循環(huán)處
         
        #ifdef USE_SOUND//對是否使用揚(yáng)聲器進(jìn)行條件編譯
        LS138_E1=1;        //關(guān)閉譯碼器
        #endif

        MAX7219_DisplayChar(DIG_1,READY);//清空右邊一位數(shù)碼管
        MAX7219_DisplayChar(DIG_2,code_table[beginNum]);//左位顯示設(shè)置的倒計(jì)時(shí)時(shí)間

        //給上位機(jī)發(fā)送重新開始倒計(jì)時(shí)的指令
        sendNumber(_STRING_READY_);

         //到這里一次循環(huán)結(jié)束
    }
}   

51智能8路搶答器.zip

109.62 KB, 下載次數(shù): 22, 下載積分: 黑幣 -5


作者: tgyh    時(shí)間: 2016-6-14 00:39
學(xué)習(xí)下感謝樓主




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 欧美激情精品久久久久久变态 | 韩国理论电影在线 | 亚洲欧洲成人av每日更新 | 久久99久久99 | 欧美男人天堂 | 国产一区欧美 | 欧美精品一二三 | 综合色站导航 | 九九亚洲| 女人一区| 国产日韩欧美 | 第四色播日韩第一页 | www.国产视频 | 在线亚洲一区二区 | 久久久久亚洲国产| www.9191.com| 日韩精品在线视频免费观看 | 国产中文字幕在线观看 | 久久婷婷国产麻豆91 | 精品久久久久久久久久久久久久 | 国产精品久久久久久高潮 | 一区二区在线 | 亚洲毛片| 操操日| 中文一区 | 日韩不卡视频在线 | 亚洲激情一区二区三区 | 久久精品久久综合 | 国产探花在线精品一区二区 | 亚洲日本欧美日韩高观看 | 中文字幕免费视频 | 作爱视频免费观看 | 精品日韩在线 | 久久久精品一区二区三区 | www.youjizz.com日韩 | 黄色片视频网站 | 噜久寡妇噜噜久久寡妇 | 国产精品久久久久久久久久妇女 | 97视频网站 | 国产96色在线 | 欧美在线国产精品 |