實驗用到8155作為51單片機的IO擴展外設有3*3矩陣鍵盤,和4位數碼管
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (20.74 KB, 下載次數: 36)
下載附件
2017-12-8 00:43 上傳
系統方案:
硬件設計
電源電路
電源電路由電源插座,電源開關和電源指示燈組成,其輸出為VCC;
系統方案.001.jpg (5.96 KB, 下載次數: 30)
下載附件
2017-12-8 00:47 上傳
電源電路
單片機最小系統
系統方案.002.jpg (56.88 KB, 下載次數: 35)
下載附件
2017-12-8 00:47 上傳
89c51最小系統電路
單片機最小系統:由晶振電路,復位電路,電源電路構成;晶振電路:12MHz的晶振,兩個30Pf的瓷片電容連接而成;復位電路:10uf的電解電容,按鍵開關,1K的電阻連接而成。
8155擴展
系統方案.003.jpg (72.38 KB, 下載次數: 38)
下載附件
2017-12-8 00:47 上傳
8155擴展矩陣電路和數碼管
數碼管顯示驅動電路
4位共陰數碼管,由8位的段選端口和4位的位選端口,8位段選端口提供字母,數字,小數點的顯示,4位位選端口控制各個數碼管的點亮,其低電平有效,數碼管的額定工作電流為20mA,PA口的工作電壓為5V,所以保證數碼管的正常點亮必須接250歐姆的上拉電阻。
3*3矩陣按鍵電路
由三行三列的按鍵構成,主要功能的實現在于程序的編寫,本實驗中用到的行掃描程序,高三位輪流輸出低電平,低三位輸出高電平,檢測低三位的輸入電平的變化,如果有變化,則有按鍵按下,識別出具體的按鍵位置。
軟件設計
定時器0配置
8155的配置
8155的AD0~AD7提供8位地址,CE端口提供8155的IO端口的高8位地址低8位地址:0x00~0x04,分別為命令/狀態寄存器,PA口,PB口,PC口;IO/M端口提供8155的工作方式是IO擴展還是RAM擴展。PA口,PB口,PC口的輸入還是輸出由命令控制寄存器控制;高四位本實驗暫時沒有用到,所以低四位控制輸入輸出方式。
按鍵行掃描
矩陣鍵盤的6的端口,行端口接PB口的高三位,列端口接PB口的低三位,由于PB口的輸入輸出方式是分時進行的所以在行掃描過程中要更改8155的命令控制寄存器的內容,改變PB口的IO工作方式,具體為先設置PB口的工作方式為輸出方式,接著PB口高三位輪流輸出低電平,低三位輸出高電平,接著更改PB口的IO方式為輸入方式,檢測低三位的電平變化,從而檢測出具體按鍵的按下,分別進入功能函數中。
數碼管的顯示
數碼管由8位段選端口和4位位選端口,控制4位位選端口的先后點亮,同時點亮8位段選端口輸出其特定的數字,字母,小數點。由于人眼的視覺暫留效應大約為50ms,4位位選端口的先后點亮時間差小于50ms,所以人眼會觀察到連續的數字點亮。
電路焊接
仿真結果
電路調試
設計制作中的問題及解決方法
程序流程圖:
0.png (42.11 KB, 下載次數: 39)
下載附件
2017-12-8 00:45 上傳
實驗心得體會:
本實驗我主要負責程序的編寫,首先通過數字秒表的實驗,掌握了對一個未知芯片的開發的步驟;本實驗中用到的8155芯片,通過查看資料掌握其IO擴展的使用方法,首先對8155的16位地址進行了解,高8位由CE端提供,低八位0x00~0x04,還有就是行掃描鍵盤程序的編寫,本實驗3*3矩陣鍵盤,所以為簡便高三位PB4~PB6控制行,PB0~PB2控制列,先讓高三位輪流輸出低電平:110 ,101,011,低三位輸出高電平;后檢測低三位的輸入電平高低,如果有低電平輸入則判斷有按鍵按下;各個按鍵的控制作用有:1開始記秒2停止3清零,4倒計時設置5倒計時時間設置的加6倒計時時間設置的減7啟動倒計時,每個按鍵的功能都有函數控制。再有就是定時中斷的使用,本實驗用到定時器0的模式1,定時時間為10ms;數碼管的編程方式,首先掌握0~F每個字母數字的真值表,4位共陰數碼管有8個段選端口和4個位選端口,8個段選端口控制輸出字母數字,位選端口控制那個數碼管亮,且位選端口低電平有效。本實驗用到的數碼管額定電流為20mA,端口輸出電壓5V,所以上拉電阻的大小為250歐姆。
其次,也懂得學習不僅僅是上課看書,也最重要的是實踐將課堂的知識轉化為真正的能力,也通過實驗學會設計一個硬件系統步驟,設計方案,設計硬件電路,設計程序調試和焊接,最終完成實驗;最為重要的是一個團隊工作,各自分工大大縮短開發時間。
單片機源程序如下:
- #include<REG51.h>
- #include<ABSACC.h>
- #define COM8155 XBYTE[0X7F00]
- #define PA8155 XBYTE[0X7F01]
- #define PB8155 XBYTE[0X7F02]
- #define PC8155 XBYTE[0X7F03]
- typedef unsigned char uchar;
- typedef unsigned int uint;
- //8051的內部RAM的地址范圍為0000H~00FFH
- //A :0X7F01 B:0X7F02 C:0X7F03 定時器低字節 0404H 定時器高字節:0405H
- //命令/狀態:0X7F00
- uchar code DIG_CODE[10]={
- 0x3f,0x06,0x5b,0x4f,0x66,
- 0x6d,0x7d,0x07,0x7f,0x6f
- };
- uchar code PCx[4] = {0xee,0xdd,0xbb,0x77};
- sbit IO_M = P2^0;
- sbit CE = P2^7;
- uchar KeyValue=0;
- uchar time1=0,time2=0;
- uint msec = 0;
- static uchar flag=0;
- uint second=0;
- uint CountDownSecond=0;
- uchar c0,c1,c2,c3;
- uchar KeyBoardScan();
- void Delay10ms(uchar s);
- void TimerConfig();
- void digitronDisplay(uint second);
- void Config_8155();
- void operate(uchar KeyValue);
- void Start();
- void Stop();
- void Pause();
- void CountDown();
- void SureStart();
- void main(){
- Config_8155();
- while(1){
- digitronDisplay(second);
- operate(KeyBoardScan());
- }
-
- }
- void Delay10ms(uchar s) //誤差 0us
- {
- unsigned char a,b;
- for(s=1;s>0;s--)
- for(b=38;b>0;b--)
- for(a=130;a>0;a--);
- }
- void operate(uchar KeyValue){
- switch(KeyValue){
- case(1):Start();break;//開始
- case(2):Stop();break;//清零
- case(3):Pause();break;//暫停
- case(4):CountDown();break;//倒計時
- }
- }
- void Start(){
- flag=1;
- TimerConfig();
- while(1){
- digitronDisplay(second);
- if(second==10000){
- second=0;
- }
- digitronDisplay(second);
- if(KeyBoardScan()!=1){
- operate(KeyBoardScan());
- }
- }
- }
-
- void Stop(){
- EA=0;//關總中斷
- ET0=0;//關定時器0中斷
- second = 0;
- CountDownSecond=0;
- while(1){
- digitronDisplay(second);
- operate(KeyBoardScan());
- }
- }
- void Pause(){
- ET0=0;//關定時器0中斷
- while(1){
- digitronDisplay(second);
- operate(KeyBoardScan());
- }
-
- }
- void CountDown(){ //設置倒計時時間
- uint a=1;
- while(1){
- if(CountDownSecond<10000&&CountDownSecond>=0){ //顯示倒計時定時時間,如果倒計時時間超過范圍,倒計時定時時間為0
- digitronDisplay(CountDownSecond);
- }else{
- CountDownSecond=0;
- }
- KeyValue = KeyBoardScan();//獲取鍵盤數字
- switch(KeyValue){
- case(7):{
- CountDownSecond = CountDownSecond + a*100; //秒位加加
- break;
- }//定時間加
- case(8):{
- CountDownSecond = CountDownSecond - a*100;//秒位減減
- break;
- }//定時間減
- case(9):SureStart();break;//啟動倒計時
- }
- }
-
- }
- void SureStart(){ //啟動倒計時
- flag=2;
- TimerConfig(); //配置定時中斷,中斷時間為10ms
- while(1){
- digitronDisplay(CountDownSecond);
- if(KeyBoardScan()!=9){
- operate(KeyBoardScan());
- }
- }
- }
- uchar KeyBoardScan(){ //行鍵盤掃描
- uchar key;
- uchar temp;
- uchar i,j=0;
- for(i=0;i<3;i++){
- COM8155=0x0f; //pb輸出
- if(i==0) PB8155 = 0xfe; //11111110
- if(i==1) PB8155 = 0xfd;// 11111101
- if(i==2) PB8155 = 0Xfb; //11111011
- COM8155 = 0X0D; //pb輸入
- temp=PB8155; //pb輸入讀取
- temp=temp&0xf0;
- if(temp!=0xf0){
- Delay10ms(1);
- temp = PB8155;
- temp = temp&0xf0;
- if(temp!=0xf0){
- switch(temp){
- case 0xe0:{
- key = 7-i*3;
- }
- break;
- case 0xd0:{
- key = 8-i*3;
- }
- break;
- case 0xb0:{
- key = 9-i*3;
- }
- break;
- }
- }
- return key;
- }
- }
- return 10;
- }
- void Config_8155(){ //8155芯片的配置
- CE = 0; //片選段,為8155的16位地址提供高8位地址 P2.0~P2.7:1
- IO_M = 1; //作為I/O擴展
- COM8155 = 0X0F; //A,B口做為輸出 C口作為輸入
- }
- void digitronDisplay(uint second){
- uchar i=0;
- uchar num[4];
- num[3]=second/1000;
- num[2]=second%1000/100;
- num[1]=second%1000%100/10;
- num[0]=second%1000%100%10;
- PA8155=0xff;//消隱
- for(i=0;i<4;i++){
- switch(i){
- case(3): PC8155=0x08;break;
- case(2): PC8155=0x04;break;
- case(1): PC8155=0x02;break;
- case(0): PC8155=0x01;break;
- }
- if(i==2){
- PA8155=~DIG_CODE[num[i]]&0x7f;
- Delay10ms(1);
- PA8155=0xff;//消隱
- }else{
- PA8155=~DIG_CODE[num[i]];
- Delay10ms(1);
- PA8155=0xff;//消隱
- }
- }
- }
- void TimerConfig(){
- TMOD=0x01; //模式設置,00000001,可見采用的是定時器0,工作與模式1(M1=0,M0=1)。
- TR0=1; //打開定時器
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (12.79 KB, 下載次數: 33)
下載附件
2017-12-8 00:43 上傳
所有資料51hei提供下載:
微控.zip
(215.07 KB, 下載次數: 47)
2017-12-7 18:28 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|