找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6651|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机开发数字秒表实验心得体会 含仿真源码等资料

[复制链接]
跳转到指定楼层
楼主
实验用到8155作为51单片机的IO扩展外设有3*3矩阵键盘,和4位数码管

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

系统方案:

硬件设计
电源电路
电源电路由电源插座,电源开关和电源指示灯组成,其输出为VCC;

电源电路

单片机最小系统

   89c51最小系统电路

单片机最小系统:由晶振电路,复位电路,电源电路构成;晶振电路:12MHz的晶振,两个30Pf的瓷片电容连接而成;复位电路:10uf的电解电容,按键开关,1K的电阻连接而成。

8155扩展

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,所以人眼会观察到连续的数字点亮。

电路焊接
仿真结果
电路调试
设计制作中的问题及解决方法


程序流程图:



实验心得体会:
      本实验我主要负责程序的编写,首先通过数字秒表的实验,掌握了对一个未知芯片的开发的步骤;本实验中用到的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欧姆。

      其次,也懂得学习不仅仅是上课看书,也最重要的是实践将课堂的知识转化为真正的能力,也通过实验学会设计一个硬件系统步骤,设计方案,设计硬件电路,设计程序调试和焊接,最终完成实验;最为重要的是一个团队工作,各自分工大大缩短开发时间。

单片机源程序如下:
  1. #include<REG51.h>
  2. #include<ABSACC.h>
  3. #define COM8155  XBYTE[0X7F00]
  4. #define PA8155 XBYTE[0X7F01]
  5. #define PB8155 XBYTE[0X7F02]
  6. #define PC8155 XBYTE[0X7F03]
  7. typedef unsigned char uchar;
  8. typedef unsigned int uint;

  9. //8051的内部RAM的地址范围为0000H~00FFH
  10. //A :0X7F01  B:0X7F02   C:0X7F03  定时器低字节 0404H   定时器高字节:0405H
  11. //命令/状态:0X7F00
  12. uchar code DIG_CODE[10]={
  13.                                                 0x3f,0x06,0x5b,0x4f,0x66,
  14.                                                 0x6d,0x7d,0x07,0x7f,0x6f
  15.                                                 };
  16. uchar code PCx[4] = {0xee,0xdd,0xbb,0x77};
  17. sbit IO_M = P2^0;  
  18. sbit CE = P2^7;
  19. uchar KeyValue=0;
  20. uchar time1=0,time2=0;
  21. uint msec = 0;
  22. static uchar flag=0;
  23. uint second=0;
  24. uint CountDownSecond=0;
  25. uchar c0,c1,c2,c3;
  26. uchar KeyBoardScan();
  27. void Delay10ms(uchar s);
  28. void TimerConfig();
  29. void digitronDisplay(uint second);
  30. void Config_8155();
  31. void operate(uchar KeyValue);
  32. void Start();
  33. void Stop();
  34. void Pause();
  35. void CountDown();
  36. void SureStart();
  37. void main(){
  38.          Config_8155();
  39.         while(1){
  40.                 digitronDisplay(second);       
  41.                 operate(KeyBoardScan());       
  42.         }
  43.        
  44. }
  45. void Delay10ms(uchar s)   //误差 0us
  46. {
  47.     unsigned char a,b;
  48.     for(s=1;s>0;s--)
  49.           for(b=38;b>0;b--)
  50.             for(a=130;a>0;a--);
  51. }
  52. void operate(uchar KeyValue){

  53.         switch(KeyValue){
  54.          case(1):Start();break;//开始
  55.          case(2):Stop();break;//清零
  56.          case(3):Pause();break;//暂停
  57.          case(4):CountDown();break;//倒计时
  58.         }
  59. }
  60. void Start(){
  61.         flag=1;
  62.         TimerConfig();
  63.                 while(1){
  64.                                         digitronDisplay(second);
  65.                                         if(second==10000){
  66.                                                  second=0;
  67.                                         }             
  68.                         digitronDisplay(second);
  69.                          if(KeyBoardScan()!=1){
  70.                          operate(KeyBoardScan());
  71.                     }          
  72.                 }
  73. }
  74.        

  75. void Stop(){
  76.         EA=0;//关总中断
  77.         ET0=0;//关定时器0中断
  78.         second = 0;
  79.         CountDownSecond=0;
  80.         while(1){
  81.            digitronDisplay(second);
  82.            operate(KeyBoardScan());
  83.         }
  84. }
  85. void Pause(){
  86.         ET0=0;//关定时器0中断
  87.         while(1){
  88.                      digitronDisplay(second);
  89.                     operate(KeyBoardScan());
  90.         }
  91.        
  92. }
  93. void CountDown(){                 //设置倒计时时间
  94.   uint a=1;
  95.    while(1){
  96.    if(CountDownSecond<10000&&CountDownSecond>=0){  //显示倒计时定时时间,如果倒计时时间超过范围,倒计时定时时间为0
  97.                     digitronDisplay(CountDownSecond);
  98.    }else{
  99.               CountDownSecond=0;
  100.    }
  101.         KeyValue = KeyBoardScan();//获取键盘数字
  102.         switch(KeyValue){
  103.          case(7):{
  104.                   CountDownSecond = CountDownSecond + a*100; //秒位加加       
  105.            break;      
  106.          }//定时间加
  107.          case(8):{
  108.          CountDownSecond = CountDownSecond - a*100;//秒位减减
  109.          break;
  110.          }//定时间减
  111.          case(9):SureStart();break;//启动倒计时
  112.         }
  113.    }
  114.          
  115. }

  116. void SureStart(){           //启动倒计时
  117.                 flag=2;
  118.          TimerConfig();           //配置定时中断,中断时间为10ms
  119.                  while(1){
  120.                         digitronDisplay(CountDownSecond);  
  121.                          if(KeyBoardScan()!=9){
  122.                                  operate(KeyBoardScan());
  123.                     }       
  124.                 }
  125. }                               

  126. uchar  KeyBoardScan(){        //行键盘扫描
  127.   uchar key;
  128.   uchar temp;
  129.   uchar i,j=0;
  130.   for(i=0;i<3;i++){
  131.            COM8155=0x0f;        //pb输出
  132.          if(i==0) PB8155 = 0xfe; //11111110
  133.          if(i==1) PB8155 = 0xfd;// 11111101
  134.          if(i==2) PB8155 = 0Xfb; //11111011
  135.          COM8155 = 0X0D; //pb输入
  136.          temp=PB8155;  //pb输入读取
  137.          temp=temp&0xf0;
  138.          if(temp!=0xf0){
  139.                   Delay10ms(1);
  140.                  temp = PB8155;
  141.                  temp = temp&0xf0;
  142.                  if(temp!=0xf0){
  143.                  switch(temp){
  144.                          case 0xe0:{
  145.                                    key = 7-i*3;
  146.                         }
  147.                         break;
  148.                         case 0xd0:{
  149.                                 key = 8-i*3;
  150.                         }
  151.                         break;
  152.                         case 0xb0:{
  153.                                 key = 9-i*3;
  154.                         }
  155.                         break;
  156.                  }
  157.                 }
  158.                  return key;
  159.          }
  160.   }
  161.   return 10;
  162. }
  163. void Config_8155(){         //8155芯片的配置
  164.          CE = 0;                  //片选段,为8155的16位地址提供高8位地址        P2.0~P2.7:1
  165.          IO_M = 1;                  //作为I/O扩展
  166.          COM8155 = 0X0F;          //A,B口做为输出 C口作为输入         
  167. }
  168. void digitronDisplay(uint second){
  169.    uchar i=0;
  170.         uchar num[4];
  171.                 num[3]=second/1000;               
  172.                 num[2]=second%1000/100;       
  173.                 num[1]=second%1000%100/10;
  174.                 num[0]=second%1000%100%10;
  175.                 PA8155=0xff;//消隐
  176.                 for(i=0;i<4;i++){
  177.                   switch(i){
  178.                   case(3): PC8155=0x08;break;
  179.                   case(2): PC8155=0x04;break;
  180.                   case(1): PC8155=0x02;break;
  181.                   case(0): PC8155=0x01;break;
  182.                   }
  183.                       if(i==2){
  184.                                      PA8155=~DIG_CODE[num[i]]&0x7f;
  185.                                            Delay10ms(1);       
  186.                                         PA8155=0xff;//消隐
  187.                           }else{
  188.                                      PA8155=~DIG_CODE[num[i]];
  189.                                            Delay10ms(1);       
  190.                                         PA8155=0xff;//消隐
  191.                           }       
  192.                 }     
  193. }         
  194. void TimerConfig(){
  195.     TMOD=0x01;                 //模式设置,00000001,可见采用的是定时器0,工作与模式1(M1=0,M0=1)。
  196.         TR0=1;                         //打开定时器
  197. ……………………

  198. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
微控.zip (215.07 KB, 下载次数: 47)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2017-12-8 01:07 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:219666 发表于 2017-12-10 15:34 | 只看该作者
赞一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表