找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的大脑智力检测仪全套资料

[复制链接]
跳转到指定楼层
楼主
之前给别人做的,通过51单片机产生伪随机数,通过定时器控制时间,3S时间计算结果并通过矩阵键盘显示到液晶1602上。话不多说,看仿真:


单片机源程序如下:

  1. //程序头函数
  2. #include <reg52.h>
  3. #include <stdlib.h>
  4. #include <intrins.h>
  5. //宏定义
  6. #define uint unsigned int
  7. #define uchar unsigned char
  8. #define keyIo P1
  9. //1602液晶
  10. sbit rs=P2^5;
  11. sbit rw=P2^6;
  12. sbit e=P2^7;
  13. //led
  14. sbit led_red=P2^3;
  15. sbit led_green=P2^0;
  16. /*******************************定义全局变量********************************/
  17. uint num1=100,num2=100,num3,round,round_t,cod,keyNo;
  18. uint count;
  19. int sec=3;
  20. bit flag_ok;
  21. uint tab[4]={0};
  22. uint sum,i=0;
  23. uint num1_t,num2_t,key_off,result;

  24. /****************************************************************************
  25. 函数功能:延时子程序
  26. 入口参数:
  27. 出口参数:
  28. ****************************************************************************/
  29. void delay(uint k)
  30. {
  31.         uint m;
  32.         while(k--)
  33.                 for(m=0;m<121;m++);
  34. }
  35. void delay_uint(uint z)
  36. {
  37.         while(z--);
  38. }
  39. /****************************************************************************
  40. 函数功能:1602显示子程序
  41. 入口参数:
  42. 出口参数:
  43. ****************************************************************************/

  44. /********************************************************************
  45. * 名称 : write_com(uchar com)
  46. * 功能 : 1602命令函数
  47. * 输入 : 输入的命令值
  48. * 输出 : 无
  49. ***********************************************************************/
  50. void write_com(uchar com)
  51. {
  52.         e=0;
  53.         rs=0;
  54.         rw=0;
  55.         P0=com;
  56.         delay_uint(25);
  57.         e=1;
  58.         delay_uint(100);
  59.         e=0;
  60. }
  61. /********************************************************************
  62. * 名称 : write_data(uchar dat)
  63. * 功能 : 1602写数据函数
  64. * 输入 : 需要写入1602的数据
  65. * 输出 : 无
  66. ***********************************************************************/
  67. void write_data(uchar dat)
  68. {
  69.         e=0;
  70.         rs=1;
  71.         rw=0;
  72.         P0=dat;
  73.         delay_uint(25);
  74.         e=1;
  75.         delay_uint(100);
  76.         e=0;        
  77. }
  78. /***********************lcd1602上显示两位十进制数************************/
  79. void write_sfm1(uchar hang,uchar add,uint date)
  80. {
  81.         if(hang==1)   
  82.                 write_com(0x80+add);
  83.         else
  84.                 write_com(0x80+0x40+add);
  85.         write_data(0x30+date);        
  86. }
  87. void write_sfm2(uchar hang,uchar add,uint date)
  88. {
  89.         if(hang==1)   
  90.                 write_com(0x80+add);
  91.         else
  92.                 write_com(0x80+0x40+add);
  93.         write_data(0x30+date/10%10);
  94.         write_data(0x30+date%10);        
  95. }
  96. void write_sfm3(uchar hang,uchar add,uint date)
  97. {
  98.         if(hang==1)   
  99.                 write_com(0x80+add);
  100.         else
  101.                 write_com(0x80+0x40+add);
  102.         write_data(0x30+date/100);
  103.         write_data(0x30+date/10%10);
  104.         write_data(0x30+date%10);        
  105. }
  106. void write_sfm4(uchar hang,uchar add,uint date)
  107. {
  108.         if(hang==1)   
  109.                 write_com(0x80+add);
  110.         else
  111.                 write_com(0x80+0x40+add);
  112.         write_data(0x30+date/1000);
  113.         write_data(0x30+date/100%10);
  114.         write_data(0x30+date/10%10);
  115.         write_data(0x30+date%10);        
  116. }
  117. /***********************lcd1602上显示字符函数************************/
  118. void write_string(uchar hang,uchar add,uchar *p)
  119. {
  120.         if(hang==1)   
  121.                 write_com(0x80+add);
  122.         else
  123.                 write_com(0x80+0x40+add);
  124.                 while(1)                                                                                                                 
  125.                 {
  126.                         if(*p == '\0')  break;
  127.                         write_data(*p);
  128.                         p++;
  129.                 }        
  130. }

  131. /***********************lcd1602初始化设置************************/
  132. void init_1602()        //lcd1602初始化
  133. {
  134.         write_com(0x38);        
  135.         write_com(0x0c);
  136.         write_com(0x06);
  137.         delay_uint(1000);  
  138.         write_string(1,0," Welcom to use ");
  139.         write_string(2,0," Brain Tester  ");
  140. }
  141. /*=======按键采集函数========*/
  142. /*-------------------------------------------------------------------------------------------------
  143. 说明:
  144.                 1.每次只采集1个按键,多个按键按下时,只采集程序前面的键值.
  145.                 2.该函数只要采集到按键后.只有当按键松开后才能再次采集按键.
  146.                 3.采集的结果与按键数字对应.(0~15)方便其它函数处理.如果没有按键按下.采集结果为100.
  147. --------------------------------------------------------------------------------------------------*/
  148. unsigned int key16 (void)                                                                        //4*4矩阵键盘扫描.
  149. {
  150.         static unsigned int key_new = 0;                                                //声明1个静态变量,用来记录按键在没有松开的情况下,只能被采集1次.
  151.         static unsigned int key_l;                                                                //声明1个静态变量,用来存放扫描后的数据,方便判断是哪个键被按下了.
  152.                
  153.         keyIo = 0x0f;                                                                                        //初始化按键扫描IO口,
  154.         if(keyIo != 0x0f)                                                                                //如果有任意按键按下,按键扫描IO口肯定不是初始值(这个要参考电路)
  155.         {
  156.                 delay(10);                                                                                //按键延时去抖动
  157.                 if((keyIo != 0x0f) && (key_new == 0))                                //如果判断按键还被按下,并且是按键在松开的情况下按下的.
  158.                 {
  159.                         key_new = 1;                                                                        //按键松开记录清0,表示下次如果按键没有松开,就不再进入
  160.                         key_off = 1;                                                                        //记录按键被按下.1表示按下,0表示松开.
  161.                         key_l = (keyIo | 0xf0);   //矩阵键盘扫描
  162.                         keyIo = key_l;
  163.                         switch(keyIo)                                                                        //判断键值.
  164.                         {
  165.                                 case 0xee:  return 0;                                                //返回按键值. 1110 1110
  166.                                 case 0xde:  return 4;                                                //返回按键值. 1101 1110
  167.                                 case 0xbe:  return 8;                                                //返回按键值. 1011 1110
  168.                                 case 0x7e:  return 12;                                                //返回按键值. 0111 1110
  169.         
  170.                                 case 0xed:  return 1;                                                //返回按键值. 1110 1101
  171.                                 case 0xdd:  return 5;                                                //返回按键值. 1101 1101
  172.                                 case 0xbd:  return 9;                                                //返回按键值. 1011 1101
  173.                                 case 0x7d:  return 13;                                                //返回按键值. 0111 1101
  174.         
  175.                                 case 0xeb:  return 2;                                                //返回按键值. 1110 1011
  176.                                 case 0xdb:  return 6;                                                //返回按键值. 1101 1011
  177.                                 case 0xbb:  return 10;                                                //返回按键值. 1011 1011
  178.                                 case 0x7b:  return 14;                                                //返回按键值. 0111 1011
  179.         
  180.                                 case 0xe7:  return 3;                                                //返回按键值. 1110 0111
  181.                                 case 0xd7:  return 7;                                                //返回按键值. 1101 0111
  182.                                 case 0xb7:  return 11;                                                //返回按键值. 1011 0111
  183.                                 case 0x77:  return 15;                                                //返回按键值. 0111 0111
  184.                         }
  185.                 }                        
  186.         }
  187.         else
  188.         {
  189.                 key_new = 0;                                                                                //按键松开时,记录按键松开复位,可以再次进入按键采集
  190.                 key_off = 0;                                                                                //记录按键被按下.1表示按下,0表示松开.
  191.         }

  192.         return 100;                                                                                                //如果没有检测到按键,直接反回100.这个值只要不是有效键值就行.
  193. }
  194. //**********************************************************
  195. //初始化
  196. //**********************************************************
  197. void Init()
  198. {
  199.         EA=1;                                                //开总中断
  200.         ET0=1;                                                //定时器0中断使能
  201.         ET1=1;                                                //定时器1中断使能
  202.         TMOD=0x21;                                        //定时器0模式1,定时器1模式2
  203.         TH0=(65535-50000)/256;                //定时器0设定初值
  204.         TL0=(65535-50000)%256;
  205.         TH1=0x00;                                        //定时器1设定初值
  206.         TH1=0x00;
  207.         TR0=1;                                                //定时器0不开启
  208.         TR1=0;                                                //定时器1开启
  209. }
  210. //**********************************************************
  211. //随机函数
  212. //**********************************************************
  213. void Random_Dot()
  214. {
  215.         num1_t=rand()%1000;                                //取出100-999中的任意一个值
  216.         num2_t=rand()%1000;
  217.         if(num1_t>100)
  218.                 num1=num1_t;
  219.         if(num2_t>100)
  220.                 num2=num2_t;
  221. }
  222. /****************************************************************************
  223. 函数功能:主程序
  224. 入口参数:
  225. 出口参数:
  226. ****************************************************************************/
  227. void main(void)
  228. {         
  229.         unsigned char key_16mun;                                                        //声明1个变量,用来暂存按键的值.
  230.         init_1602();
  231.         Init();
  232.         
  233.         delay(2000);
  234.         write_string(1,0,"Round:  Code:   ");
  235.         write_string(2,0,"T: N000+000=0000");
  236.         write_sfm2(1,6,round);
  237.         write_sfm2(1,13,cod);
  238.         write_sfm1(2,2,sec);
  239.         TR1=1;Random_Dot(); TR1=0; sum=num1+num2;
  240.         num3=result;
  241.         write_sfm3(2,4,num1);               
  242.         write_sfm3(2,8,num2);
  243.         write_sfm4(2,12,num3);
  244.     while(1)       //主循环                  
  245.     {
  246.                 key_16mun = key16();
  247.                 if(key_16mun==15)
  248.                 {
  249.                         TR0=1;
  250.                         round=round_t=0;
  251.                         cod=0;
  252.                         num3=result=i=0;
  253.                         TR1=1;Random_Dot(); TR1=0; sum=num1+num2;
  254.                 }
  255.                 if(key_16mun < 10)                                                                                        //如果输入的键值是数字键
  256.                 {
  257.                         tab[i]=key_16mun;
  258.                         result=result*10+tab[i];
  259.                         i++;                                                                                //每输入一位密码,位数自增1.
  260.                         if(i == 5)                                                                //密码输入位数控制在6位
  261.                         {
  262.                                 i = 0;
  263.                                 result=0;
  264.                         }                                                                                
  265.                 }
  266.                 num3=result;                                 
  267.                 sum=num1+num2;
  268.                 if((num3==sum)&&(round!=round_t))
  269.                 {
  270.                         led_green=0;
  271.                         led_red=1;
  272.                         cod+=10;
  273.                         round_t=round;
  274.                 }                          
  275.                 else
  276.                 {
  277.                         led_green=1;
  278.                         led_red=0;
  279.                 }               
  280.                 write_sfm2(1,6,round);
  281.                 write_sfm2(1,13,cod);
  282.                 write_sfm1(2,2,sec);
  283.                 write_sfm3(2,4,num1);
  284.                 write_sfm3(2,8,num2);
  285.                 write_sfm4(2,12,num3);
  286.             }
  287. }

  288. //**********************************************************
  289. //定时器中断0
  290. //**********************************************************
  291. void time0() interrupt         1
  292. {
  293.         TH0=(65535-50000)/256;                //定时器0设定初值
  294.         TL0=(65535-50000)%256;
  295.         count++;
  296. ……………………

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

所有资料51hei提供下载:
058-大脑运算能力智力测试仪.zip (237 KB, 下载次数: 20)




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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