之前给别人做的,通过51单片机产生伪随机数,通过定时器控制时间,3S时间计算结果并通过矩阵键盘显示到液晶1602上。话不多说,看仿真:
单片机源程序如下:
- //程序头函数
- #include <reg52.h>
- #include <stdlib.h>
- #include <intrins.h>
- //宏定义
- #define uint unsigned int
- #define uchar unsigned char
- #define keyIo P1
- //1602液晶
- sbit rs=P2^5;
- sbit rw=P2^6;
- sbit e=P2^7;
- //led
- sbit led_red=P2^3;
- sbit led_green=P2^0;
- /*******************************定义全局变量********************************/
- uint num1=100,num2=100,num3,round,round_t,cod,keyNo;
- uint count;
- int sec=3;
- bit flag_ok;
- uint tab[4]={0};
- uint sum,i=0;
- uint num1_t,num2_t,key_off,result;
- /****************************************************************************
- 函数功能:延时子程序
- 入口参数:
- 出口参数:
- ****************************************************************************/
- void delay(uint k)
- {
- uint m;
- while(k--)
- for(m=0;m<121;m++);
- }
- void delay_uint(uint z)
- {
- while(z--);
- }
- /****************************************************************************
- 函数功能:1602显示子程序
- 入口参数:
- 出口参数:
- ****************************************************************************/
- /********************************************************************
- * 名称 : write_com(uchar com)
- * 功能 : 1602命令函数
- * 输入 : 输入的命令值
- * 输出 : 无
- ***********************************************************************/
- void write_com(uchar com)
- {
- e=0;
- rs=0;
- rw=0;
- P0=com;
- delay_uint(25);
- e=1;
- delay_uint(100);
- e=0;
- }
- /********************************************************************
- * 名称 : write_data(uchar dat)
- * 功能 : 1602写数据函数
- * 输入 : 需要写入1602的数据
- * 输出 : 无
- ***********************************************************************/
- void write_data(uchar dat)
- {
- e=0;
- rs=1;
- rw=0;
- P0=dat;
- delay_uint(25);
- e=1;
- delay_uint(100);
- e=0;
- }
- /***********************lcd1602上显示两位十进制数************************/
- void write_sfm1(uchar hang,uchar add,uint date)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- write_data(0x30+date);
- }
- void write_sfm2(uchar hang,uchar add,uint date)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- write_data(0x30+date/10%10);
- write_data(0x30+date%10);
- }
- void write_sfm3(uchar hang,uchar add,uint date)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- write_data(0x30+date/100);
- write_data(0x30+date/10%10);
- write_data(0x30+date%10);
- }
- void write_sfm4(uchar hang,uchar add,uint date)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- write_data(0x30+date/1000);
- write_data(0x30+date/100%10);
- write_data(0x30+date/10%10);
- write_data(0x30+date%10);
- }
- /***********************lcd1602上显示字符函数************************/
- void write_string(uchar hang,uchar add,uchar *p)
- {
- if(hang==1)
- write_com(0x80+add);
- else
- write_com(0x80+0x40+add);
- while(1)
- {
- if(*p == '\0') break;
- write_data(*p);
- p++;
- }
- }
- /***********************lcd1602初始化设置************************/
- void init_1602() //lcd1602初始化
- {
- write_com(0x38);
- write_com(0x0c);
- write_com(0x06);
- delay_uint(1000);
- write_string(1,0," Welcom to use ");
- write_string(2,0," Brain Tester ");
- }
- /*=======按键采集函数========*/
- /*-------------------------------------------------------------------------------------------------
- 说明:
- 1.每次只采集1个按键,多个按键按下时,只采集程序前面的键值.
- 2.该函数只要采集到按键后.只有当按键松开后才能再次采集按键.
- 3.采集的结果与按键数字对应.(0~15)方便其它函数处理.如果没有按键按下.采集结果为100.
- --------------------------------------------------------------------------------------------------*/
- unsigned int key16 (void) //4*4矩阵键盘扫描.
- {
- static unsigned int key_new = 0; //声明1个静态变量,用来记录按键在没有松开的情况下,只能被采集1次.
- static unsigned int key_l; //声明1个静态变量,用来存放扫描后的数据,方便判断是哪个键被按下了.
-
- keyIo = 0x0f; //初始化按键扫描IO口,
- if(keyIo != 0x0f) //如果有任意按键按下,按键扫描IO口肯定不是初始值(这个要参考电路)
- {
- delay(10); //按键延时去抖动
- if((keyIo != 0x0f) && (key_new == 0)) //如果判断按键还被按下,并且是按键在松开的情况下按下的.
- {
- key_new = 1; //按键松开记录清0,表示下次如果按键没有松开,就不再进入
- key_off = 1; //记录按键被按下.1表示按下,0表示松开.
- key_l = (keyIo | 0xf0); //矩阵键盘扫描
- keyIo = key_l;
- switch(keyIo) //判断键值.
- {
- case 0xee: return 0; //返回按键值. 1110 1110
- case 0xde: return 4; //返回按键值. 1101 1110
- case 0xbe: return 8; //返回按键值. 1011 1110
- case 0x7e: return 12; //返回按键值. 0111 1110
-
- case 0xed: return 1; //返回按键值. 1110 1101
- case 0xdd: return 5; //返回按键值. 1101 1101
- case 0xbd: return 9; //返回按键值. 1011 1101
- case 0x7d: return 13; //返回按键值. 0111 1101
-
- case 0xeb: return 2; //返回按键值. 1110 1011
- case 0xdb: return 6; //返回按键值. 1101 1011
- case 0xbb: return 10; //返回按键值. 1011 1011
- case 0x7b: return 14; //返回按键值. 0111 1011
-
- case 0xe7: return 3; //返回按键值. 1110 0111
- case 0xd7: return 7; //返回按键值. 1101 0111
- case 0xb7: return 11; //返回按键值. 1011 0111
- case 0x77: return 15; //返回按键值. 0111 0111
- }
- }
- }
- else
- {
- key_new = 0; //按键松开时,记录按键松开复位,可以再次进入按键采集
- key_off = 0; //记录按键被按下.1表示按下,0表示松开.
- }
- return 100; //如果没有检测到按键,直接反回100.这个值只要不是有效键值就行.
- }
- //**********************************************************
- //初始化
- //**********************************************************
- void Init()
- {
- EA=1; //开总中断
- ET0=1; //定时器0中断使能
- ET1=1; //定时器1中断使能
- TMOD=0x21; //定时器0模式1,定时器1模式2
- TH0=(65535-50000)/256; //定时器0设定初值
- TL0=(65535-50000)%256;
- TH1=0x00; //定时器1设定初值
- TH1=0x00;
- TR0=1; //定时器0不开启
- TR1=0; //定时器1开启
- }
- //**********************************************************
- //随机函数
- //**********************************************************
- void Random_Dot()
- {
- num1_t=rand()%1000; //取出100-999中的任意一个值
- num2_t=rand()%1000;
- if(num1_t>100)
- num1=num1_t;
- if(num2_t>100)
- num2=num2_t;
- }
- /****************************************************************************
- 函数功能:主程序
- 入口参数:
- 出口参数:
- ****************************************************************************/
- void main(void)
- {
- unsigned char key_16mun; //声明1个变量,用来暂存按键的值.
- init_1602();
- Init();
-
- delay(2000);
- write_string(1,0,"Round: Code: ");
- write_string(2,0,"T: N000+000=0000");
- write_sfm2(1,6,round);
- write_sfm2(1,13,cod);
- write_sfm1(2,2,sec);
- TR1=1;Random_Dot(); TR1=0; sum=num1+num2;
- num3=result;
- write_sfm3(2,4,num1);
- write_sfm3(2,8,num2);
- write_sfm4(2,12,num3);
- while(1) //主循环
- {
- key_16mun = key16();
- if(key_16mun==15)
- {
- TR0=1;
- round=round_t=0;
- cod=0;
- num3=result=i=0;
- TR1=1;Random_Dot(); TR1=0; sum=num1+num2;
- }
- if(key_16mun < 10) //如果输入的键值是数字键
- {
- tab[i]=key_16mun;
- result=result*10+tab[i];
- i++; //每输入一位密码,位数自增1.
- if(i == 5) //密码输入位数控制在6位
- {
- i = 0;
- result=0;
- }
- }
- num3=result;
- sum=num1+num2;
- if((num3==sum)&&(round!=round_t))
- {
- led_green=0;
- led_red=1;
- cod+=10;
- round_t=round;
- }
- else
- {
- led_green=1;
- led_red=0;
- }
- write_sfm2(1,6,round);
- write_sfm2(1,13,cod);
- write_sfm1(2,2,sec);
- write_sfm3(2,4,num1);
- write_sfm3(2,8,num2);
- write_sfm4(2,12,num3);
- }
- }
- //**********************************************************
- //定时器中断0
- //**********************************************************
- void time0() interrupt 1
- {
- TH0=(65535-50000)/256; //定时器0设定初值
- TL0=(65535-50000)%256;
- count++;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
058-大脑运算能力智力测试仪.zip
(237 KB, 下载次数: 20)
|