系列文章目次
前言
用的是普中A2开发板,用到板上的矩阵按键,还必要外接一个LCD1602液晶显示屏。
【单片机】STC89C52RC
【频率】12T@11.0592MHz
效果查看/操作演示:B站搜索“甘腾胜”或“gantengsheng”查看。
源代码下载:B站对应视频的简介有工程文件下载链接。
一、效果展示
二、原理分析
1、数字的输入与清除
输入数字时,通过十进制的移位和加法,将刚输入的数字及时保存到int变量中。
2、随机数的产生
设置的最大范围是:1~9999,我发现当范围较大时,虽然每次获取键码时用了定时器0的低八位做种子,但发现产生的随机数比力会集,会集在其中的一个小范围内。然后我将随机数的产生的算式弄复杂一些,就比力随机了,但还是有一定的伪随机性。道友有更好的办法请跟我说一下,谢谢了!
3、随机数的范围
由于屏幕巨细有限,以是限定随机数的范围是1~9999,最多四位数。设定范围的时间要注意,最大值要比最小值大2以上,如果不公道,则必要重置后重新输入。
4、按键的检测
矩阵按键通过行列扫描检测,使用定时器0,每隔20ms检测一次,防止阻塞步伐运行。
三、各模块代码
1、LCD1602
h文件
- #ifndef __LCD1602_H__
- #define __LCD1602_H__
- void LCD_WriteCommand(unsigned char Command);
- void LCD_WriteData(unsigned char Data);
- void LCD_SetCursor(unsigned char Line,unsigned char Column);
- void LCD_Init();
- void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
- void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
- void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
- void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
- void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
- void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
- void LCD_Clear(void);
- void LCD_IsShowCursor(unsigned char State);
- void LCD_Show16Char(unsigned char Line,unsigned char Column,char *String);
- #endif
复制代码 c文件
- #include <REGX52.H>
- /*引脚配置*/
- sbit LCD_RS=P2^6;
- sbit LCD_RW=P2^5;
- sbit LCD_EN=P2^7;
- #define LCD_DataPort P0
- /*函数定义*/
- /**
- * 函 数:LCD1602私有延时函数,延时约50us
- * 参 数:无
- * 返 回 值:无
- */
- void LCD_Delay50us(void) //12T@11.0592MHz
- {
- unsigned char i;
- i=20;
- while(--i);
- }
- /**
- * 函 数:LCD1602私有延时函数,延时约2ms
- * 参 数:无
- * 返 回 值:无
- */
- void LCD_Delay2ms(void) //12T@11.0592MHz
- {
- unsigned char i,j;
- i=4;
- j=146;
- do
- {
- while(--j);
- }while(--i);
- }
- /**
- * 函 数:LCD1602写指令
- * 参 数:Command 要写入的指令
- * 返 回 值:无
- */
- void LCD_WriteCommand(unsigned char Command)
- {
- LCD_RS=0;
- LCD_RW=0;
- LCD_DataPort=Command;
- LCD_EN=1;
- LCD_Delay50us();
- LCD_EN=0;
- LCD_Delay50us();
- }
- /**
- * 函 数:LCD1602写数据
- * 参 数:Data 要写入的数据
- * 返 回 值:无
- */
- void LCD_WriteData(unsigned char Data)
- {
- LCD_RS=1;
- LCD_RW=0;
- LCD_DataPort=Data;
- LCD_EN=1;
- LCD_Delay50us();
- LCD_EN=0;
- LCD_Delay50us();
- }
- /**
- * 函 数:LCD1602设置光标位置
- * 参 数:Line 行位置,范围:1~2
- * 参 数:Column 列位置,范围:1~16
- * 返 回 值:无
- */
- void LCD_SetCursor(unsigned char Line,unsigned char Column)
- {
- if(Line==1)
- {
- LCD_WriteCommand(0x80|(Column-1));
- }
- else if(Line==2)
- {
- LCD_WriteCommand(0x80|(Column-1+0x40));
- }
- }
- /**
- * 函 数:LCD1602初始化函数
- * 参 数:无
- * 返 回 值:无
- */
- void LCD_Init()
- {
- LCD_WriteCommand(0x38); //八位数据接口,两行显示,5*7点阵
- LCD_WriteCommand(0x0C); //显示开,光标关,闪烁关
- LCD_WriteCommand(0x06); //数据读写操作后,光标自动加一,画面不动
- LCD_WriteCommand(0x01); //光标复位,清屏
- LCD_Delay2ms(); //清屏指令执行需要较长时间,需要较长的延时
- }
- /**
- * 函 数:在LCD1602指定位置上显示一个字符
- * 参 数:Line 行位置,范围:1~2
- * 参 数:Column 列位置,范围:1~16
- * 参 数:Char 要显示的字符
- * 返 回 值:无
- */
- void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
- {
- LCD_SetCursor(Line,Column);
- LCD_WriteData(Char);
- }
- /**
- * 函 数:在LCD1602指定位置开始显示所给字符串
- * 参 数:Line 起始行位置,范围:1~2
- * 参 数:Column 起始列位置,范围:1~16
- * 参 数:String 要显示的字符串
- * 返 回 值:无
- */
- void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
- {
- unsigned char i;
- LCD_SetCursor(Line,Column);
- for(i=0;String[i]!='\0';i++)
- {
- LCD_WriteData(String[i]);
- }
- }
- /**
- * 函 数:返回值=X的Y次方
- */
- int LCD_Pow(int X,int Y)
- {
- unsigned char i;
- int Result=1;
- for(i=0;i<Y;i++)
- {
- Result*=X;
- }
- return Result;
- }
- /**
- * 函 数:在LCD1602指定位置开始显示所给数字
- * 参 数:Line 起始行位置,范围:1~2
- * 参 数:Column 起始列位置,范围:1~16
- * 参 数:Number 要显示的数字,范围:0~65535
- * 参 数:Length 要显示数字的长度,范围:1~5
- * 返 回 值:无
- */
- void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
- {
- unsigned char i;
- LCD_SetCursor(Line,Column);
- for(i=Length;i>0;i--)
- {
- LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
- }
- }
- /**
- * 函 数:在LCD1602指定位置开始以有符号十进制显示所给数字
- * 参 数:Line 起始行位置,范围:1~2
- * 参 数:Column 起始列位置,范围:1~16
- * 参 数:Number 要显示的数字,范围:-32768~32767
- * 参 数:Length 要显示数字的长度,范围:1~5
- * 返 回 值:无
- */
- void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
- {
- unsigned char i;
- unsigned int Number1;
- LCD_SetCursor(Line,Column);
- if(Number>=0)
- {
- LCD_WriteData('+');
- Number1=Number;
- }
- else
- {
- LCD_WriteData('-');
- Number1=-Number;
- }
- for(i=Length;i>0;i--)
- {
- LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
- }
- }
- /**
- * 函 数:在LCD1602指定位置开始以十六进制显示所给数字
- * 参 数:Line 起始行位置,范围:1~2
- * 参 数:Column 起始列位置,范围:1~16
- * 参 数:Number 要显示的数字,范围:0~0xFFFF
- * 参 数:Length 要显示数字的长度,范围:1~4
- * 返 回 值:无
- */
- void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
- {
- unsigned char i,SingleNumber;
- LCD_SetCursor(Line,Column);
- for(i=Length;i>0;i--)
- {
- SingleNumber=Number/LCD_Pow(16,i-1)%16;
- if(SingleNumber<10)
- {
- LCD_WriteData(SingleNumber+'0');
- }
- else
- {
- LCD_WriteData(SingleNumber-10+'A');
- }
- }
- }
- /**
- * 函 数:在LCD1602指定位置开始以二进制显示所给数字
- * 参 数:Line 起始行位置,范围:1~2
- * 参 数:Column 起始列位置,范围:1~16
- * 参 数:Number 要显示的数字,范围:0~1111 1111 1111 1111
- * 参 数:Length 要显示数字的长度,范围:1~16
- * 返 回 值:无
- */
- void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
- {
- unsigned char i;
- LCD_SetCursor(Line,Column);
- for(i=Length;i>0;i--)
- {
- LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
- }
- }
- /**
- * 函 数:LCD1602的光标复位,清屏
- * 参 数:无
- * 返 回 值:无
- */
- void LCD_Clear(void)
- {
- LCD_WriteCommand(0x01);
- LCD_Delay2ms();
- }
- /**
- * 函 数:LCD1602设置光标是否显示
- * 参 数:State 光标状态,1:显示,0:不显示
- * 返 回 值:无
- */
- void LCD_IsShowCursor(unsigned char State)
- {
- if(State){LCD_WriteCommand(0x0E);}
- else{LCD_WriteCommand(0x0C);}
- }
复制代码 2、矩阵按键
h文件
- #ifndef __MATRIXKEYSCAN_H__
- #define __MATRIXKEYSCAN_H__
- unsigned char MatrixKey(void);
- void MatrixKey_Tick(void);
- #endif
复制代码 c文件
3、定时器0
h文件
- #ifndef __TIMER0_H__
- #define __TIMER0_H__
- void Timer0_Init(void);
- #endif
复制代码 c文件
- #include <REGX52.H>
- /**
- * 函 数:定时器0初始化
- * 参 数:无
- * 返 回 值:无
- */
- void Timer0_Init(void)
- {
- // AUXR&=0x7F; //定时器时钟12T模式(STC89C52RC是12T单片机,无需设置)
- TMOD&=0xF0; //设置定时器模式(高四位不变,低四位清零)
- TMOD|=0x01; //设置定时器模式(通过低四位设为16位不自动重装)
- TL0=0x00; //设置定时初值,定时10ms,12T@11.0592MHz
- TH0=0xDC; //设置定时初值,定时10ms,12T@11.0592MHz
- TF0=0; //清除TF0标志
- TR0=1; //定时器0开始计时
- ET0=1; //打开定时器0中断允许
- EA=1; //打开总中断
- PT0=0; //当PT0=0时,定时器0为低优先级,当PT0=1时,定时器0为高优先级
- }
- /*定时器中断函数模板
- void Timer0_Routine() interrupt 1 //定时器0中断函数
- {
- static unsigned int T0Count; //定义静态变量
- TL0=0x00; //设置定时初值,定时10ms,12T@11.0592MHz
- TH0=0xDC; //设置定时初值,定时10ms,12T@11.0592MHz
- T0Count++;
- if(T0Count>=1000)
- {
- T0Count=0;
-
- }
- }
- */
复制代码 四、主函数
main.c
- /*by甘腾胜@20250423
- 【效果查看/操作演示】B站搜索“甘腾胜”或“gantengsheng”查看
- 【单片机】STC89C52RC
- 【频率】12T@11.0592MHz
- 【外设】LCD1602、矩阵按键
- 【简单的原理分析】https://blog.csdn.net/gantengsheng/article/details/143581157
- 【注意】点阵屏旁边的跳线帽接三根排针中的右边两根
- 【操作】
- S1 S2 S3 S4
- S5 S6 S7 S8
- S9 S10 S11 S12
- S13 S14 S15 S16
- S1~S9:数字1~9
- S10:数字0
- S11:清空/返回
- S12:确认键
- (1)输入错误可按S11(松手瞬间)清空后重新输入
- (2)按S12(松手瞬间)表示确认完成输入
- (3)猜对数字后按S11(松手瞬间)返回设置范围的界面
- */
- #include <REGX52.H> //51单片机头文件
- #include "LCD1602.h" //LCD1602液晶显示屏
- #include "MatrixKeyScan.h" //矩阵按键
- #include "Timer0.h" //定时器0
- #include <STDLIB.H> //随机函数
- unsigned char KeyNum; //存储获得的键码
- unsigned char Mode; //模式,0:显示游戏英文名,1:设置数字范围界面,2:猜数字过程,3:猜对后的屏幕显示
- unsigned char OnceFlag=1; //某些前提下只执行一次的标志(各模式中用来判断是否要初始化),1:执行,0:不执行
- unsigned char InputLength; //输入位数,范围:1~4
- unsigned char LastInputLength; //上一次的输入位数,范围:1~4,用来判断是否有按下数字键0~9
- bit ConfirmFlag; //确认按键按下的标志,1:确认按键按下,0:确认按键未按下
- unsigned char NowNumber; //刚刚输入的数字按键对应的数字,范围:0~9
- bit SetMinFlag; //正在设置数字范围最小值的标志,1:正在设置,0:没有在设置
- bit SetMaxFlag; //正在设置数字范围最大值的标志,1:正在设置,0:没有在设置
- unsigned int MinNumber; //所设置的数字范围的最小值,范围:1~9997
- unsigned int MaxNumber; //所设置的数字范围的最大值,范围:3~9999
- unsigned char MinLength; //最小值的位数,范围:1~4
- unsigned char MaxLength; //最大值的位数,范围:1~4
- bit CheckFlag; //设置完范围后检查范围是否合理的标志,1:检查,0:不检查
- bit ReenterFlag; //重新输入的标志,1:重新输入,0:不重新输入
- unsigned int PlayerNumber; //玩家输入的数字,范围:2~9998
- unsigned char PlayerLength; //玩家输入数字的位数,范围:1~4
- unsigned int RandomNumber; //产生的随机数,范围:MinNumber<RandomNumber<MaxNumber
- unsigned char RandomLength; //随机数的位数,范围:1~4
- unsigned int GuessTimes; //玩家猜测的次数
- unsigned char GuessLength; //玩家猜测的次数的位数,范围:1~4
- /**
- * 函 数:延时函数,延时约xms毫秒
- * 参 数:xms 延时的时间,范围:0~65535
- * 返 回 值:无
- */
- void Delay(unsigned int xms) //12T@11.0592MHz
- {
- unsigned char i,j;
- while(xms--)
- {
- i=2;
- j=199;
- do
- {
- while(--j);
- }while(--i);
- }
- }
- /**
- * 函 数:主函数(有且仅有一个)
- * 参 数:无
- * 返 回 值:无
- * 说 明:主函数是程序执行的起点,负责执行整个程序的主要逻辑
- */
- void main()
- {
- Timer0_Init(); //定时器0初始化
- LCD_Init(); //LCD1602初始化
- while(1)
- {
- KeyNum=MatrixKey(); //获取键码
-
- if(KeyNum) //如果有按键按下
- {
- if(Mode==0) //如果是显示游戏名称的界面
- {
- if(KeyNum>=33 && KeyNum<=48) //如果按下任意按键(松手瞬间)
- {
- Mode=1;
- OnceFlag=1;
- }
- }
- else if(Mode==1) //如果是设置数字范围的界面
- {
- if(KeyNum>=33 && KeyNum<=42) //如果按下“0~9”(松手瞬间),即按下S1~S10,S10为0
- {
- if(InputLength<4) //限制输入的最大位数为4
- {
- if(InputLength!=0 || KeyNum!=42) //第一个数字不能为0
- {
- NowNumber=(KeyNum-32)%10;
- InputLength++;
- }
- }
- }
- if(KeyNum==27) //如果按下S11(长按超1s)
- {
- OnceFlag=1; //重置
- }
- if(KeyNum==43) //如果按下S11(松手瞬间),则清空,重新输入
- {
- ReenterFlag=1;
- }
- if(KeyNum==44) //如果按下S12(松手瞬间),表示确认
- {
- if(InputLength){ConfirmFlag=1;} //按了数字键,才能确认
- }
- }
- else if(Mode==2) //如果是正在猜数字
- {
- if(KeyNum>=33 && KeyNum<=42) //如果按下“0~9”(松手瞬间),即按下S1~S10,S10为0
- {
- if(InputLength<4) //限制输入的最大位数为4
- {
- if(InputLength!=0 || KeyNum!=42) //第一个数字不能为0
- {
- NowNumber=(KeyNum-32)%10;
- InputLength++;
- }
- }
- }
- if(KeyNum==27) //如果按下S11(长按超1s)
- {
- Mode=1; //返回设置范围的界面
- OnceFlag=1;
- }
- if(KeyNum==43) //如果按下S11(松手瞬间),则清空,重新输入
- {
- ReenterFlag=1;
- }
- if(KeyNum==44) //如果按下S12(松手瞬间),表示确认
- {
- if(InputLength){ConfirmFlag=1;} //按了数字键,才能确认
- }
- }
- else if(Mode==3) //如果是猜对之后的屏幕显示
- {
- if(KeyNum==43) //如果按下S11(松手瞬间)
- {
- Mode=1; //返回设置范围的界面
- OnceFlag=1;
- }
- }
- }
- if(Mode==0) //显示游戏名称
- {
- if(OnceFlag)
- {
- OnceFlag=0; //标志置0
-
- /*初始化*/
- LCD_Clear(); //LCD1602清屏
- LCD_ShowString(1,3,"Guess Number"); //显示游戏英文名
- }
- }
- else if(Mode==1) //设置要猜的数字的范围
- {
- if(OnceFlag)
- {
- OnceFlag=0;
- //初始化
- LastInputLength=0; //上一次输入的位数清零
- InputLength=0; //输入的位数清零
- ConfirmFlag=0; //确认标志清零
- CheckFlag=0; //检查的标志置0
- ReenterFlag=0; //重新输入的标志置0
- SetMinFlag=1; //正在设置最小值的标志置1
- SetMaxFlag=0; //正在设置最大值的标志置0
- MinNumber=0; //最小值清零
- MaxNumber=0; //最大值清零
- MinLength=0; //最小值的位数清零
- MaxLength=0; //最大值的位数清零
- GuessTimes=0; //猜数字的次数清零
- LCD_Clear(); //清屏
- LCD_ShowString(1,1,"Set Range");
- LCD_ShowString(2,1,"Min:");
- LCD_ShowString(2,9,"Max:"); //显示英文提示
- LCD_SetCursor(2,5); //设置光标在第2行第5列
- LCD_IsShowCursor(1); //显示光标
- }
- if(LastInputLength!=InputLength) //如果按了S1~S10(0~9),S10为0
- {
- LastInputLength=InputLength; //更新上一次的输入长度
- if(SetMaxFlag) //如果正在设置最大值
- {
- LCD_ShowNum(2,12+InputLength,NowNumber,1); //将所按的数字显示在屏幕上
- MaxNumber*=10;MaxNumber+=NowNumber; //将刚刚所按的数字键对应的数字保存到变量MaxNumber中
- MaxLength++; //最大数字的位数增加一
- }
- if(SetMinFlag) //如果正在设置最小值
- {
- LCD_ShowNum(2,4+InputLength,NowNumber,1); //将所按的数字显示在屏幕上
- MinNumber*=10;MinNumber+=NowNumber;
- MinLength++;
- }
- }
- if(ConfirmFlag || InputLength==4) //如果按了确认键,或者输入长度达到4
- {
- if(SetMaxFlag) //如果是正在设置最大值
- {
- SetMaxFlag=0; //正在设置最大值的标志置0
- ConfirmFlag=0; //确认的标志置0
- LastInputLength=0;
- InputLength=0;
- CheckFlag=1; //检查范围是否合理的标志置1
- }
- if(SetMinFlag) //如果是正在设置最小值
- {
- SetMinFlag=0; //正在设置最小值的标志置0
- ConfirmFlag=0;
- LastInputLength=0;
- InputLength=0;
- LCD_SetCursor(2,13); //光标设置在第2行第13列
- SetMaxFlag=1; //正在设置最大值的标志置1
- }
- }
- if(CheckFlag) //如果检查范围是否合理的标志为真
- {
- CheckFlag=0; //标志置0
- if(MinNumber+1<MaxNumber) //如果最小值要比最大值小,且最小值和最大值要至少相差2
- { //说明设置得合理
- Mode=2; //切换到玩家输入数字猜测的界面
- OnceFlag=1;
- }
- else //如果不合理
- {
- OnceFlag=1; //重置,即初始化
- LCD_ShowString(1,14,"ERR"); //第一行后三个位置显示错误的英文的前三个字母
- Delay(1000); //延时1s
- }
- }
- if(ReenterFlag) //如果重新输入的标志为真
- {
- ReenterFlag=0; //标志置0
- if(SetMinFlag) //如果是正在设置最小值
- {
- LastInputLength=0;
- InputLength=0;
- MinNumber=0;
- MinLength=0;
- LCD_ShowString(2,5," "); //清空显示
- LCD_SetCursor(2,5); //光标设置在第2行第5列
- }
- if(SetMaxFlag) //如果是正在设置最大值
- {
- LastInputLength=0;
- InputLength=0;
- MaxNumber=0;
- MaxLength=0;
- LCD_ShowString(2,13," "); //清空显示
- LCD_SetCursor(2,13); //光标设置在第2行第13列
- }
- }
- }
- else if(Mode==2) //猜数字过程
- {
- if(OnceFlag)
- {
- OnceFlag=0;
- //初始化
- LastInputLength=0;
- InputLength=0;
- ConfirmFlag=0;
- srand(TL0); //每次进入此if,以定时器低八位做随机数的种子
- //RandomNumber=(rand()%(MaxNumber-MinNumber-1)+MinNumber+1); //这样也可以,但是发现产生的随机数很集中
- //按下面这样,利用定时器0的高低八位来使计算复杂一些,产生的随机数更加随机
- RandomNumber=((rand()+TH0*TL0+TL0/TH0)*(TH0-TL0)%(MaxNumber-MinNumber-1)+MinNumber+1);//产生一个所设置范围内的随机数(不包含最小值和最大值)
- LCD_Clear();
- LCD_ShowString(1,1,"Range:");
- LCD_ShowNum(1,8,MinNumber,MinLength);
- LCD_ShowChar(1,8+MinLength,'~'); //显示一个右箭头→
- LCD_ShowNum(1,9+MinLength,MaxNumber,MaxLength);
- LCD_SetCursor(2,1); //设置光标在第2行第1列
- }
- if(LastInputLength!=InputLength)
- {
- LastInputLength=InputLength;
- LCD_ShowNum(2,InputLength,NowNumber,1);
- PlayerNumber*=10;PlayerNumber+=NowNumber;
- PlayerLength++;
- }
- if(ConfirmFlag || InputLength==4)
- {
- ConfirmFlag=0;
- LastInputLength=0;
- InputLength=0;
- GuessTimes++; //每比较一次,猜的次数增加一
- if(PlayerNumber==RandomNumber) //如果输入的数字跟随机数字相等
- { //说明猜对了
- Mode=3; //切换到下一模式
- OnceFlag=1;
- }
- else if(PlayerNumber<RandomNumber && PlayerNumber>MinNumber) //如果输入数字小于随机数,且大于范围最小值
- {
- MinNumber=PlayerNumber;
- MinLength=PlayerLength;
- }
- else if(PlayerNumber>RandomNumber && PlayerNumber<MaxNumber) //如果输入数字大于随机数,且小于范围最大值
- {
- MaxNumber=PlayerNumber;
- MaxLength=PlayerLength;
- }
- else //如果不是以上情况,说明输入的数字不在范围内
- {
- GuessTimes--; //输入错误不算次数
- LCD_ShowString(2,14,"ERR"); //第2行最后三个位置显示错误的英文的前三个字母
- Delay(1000); //延时1s
- LCD_ShowString(2,14," "); //清空三个英文字母的显示
- }
- PlayerNumber=0; //玩家输入的数字清0
- PlayerLength=0; //玩家输入数字的位数清零
- LCD_ShowString(1,8," "); //第1行右半屏清空显示
- LCD_ShowNum(1,8,MinNumber,MinLength);
- LCD_ShowChar(1,8+MinLength,'~');
- LCD_ShowNum(1,9+MinLength,MaxNumber,MaxLength); //根据玩家输入的数字显示缩小后的范围
- LCD_SetCursor(2,1);
-
- LastInputLength=0;
- InputLength=0;
- LCD_ShowString(2,1," "); //清空玩家输入的数字
- LCD_SetCursor(2,1); //设置光标在第2行第1列
- }
- if(ReenterFlag)
- {
- ReenterFlag=0;
- LastInputLength=0;
- InputLength=0;
- PlayerNumber=0; //玩家输入的数字清0
- PlayerLength=0; //玩家输入数字的位数清零
- LCD_ShowString(2,1," ");
- LCD_SetCursor(2,1);
- }
- }
- else if(Mode==3) //猜中之后的屏幕显示
- {
- if(OnceFlag)
- {
- OnceFlag=0;
- LCD_Clear();
- LCD_ShowString(1,1,"Yes!");
- LCD_ShowString(1,6,"Number:");
- if(RandomNumber/1000){RandomLength=4;}
- else if(RandomNumber/100){RandomLength=3;}
- else if(RandomNumber/10){RandomLength=2;}
- else{RandomLength=1;}
- LCD_ShowNum(1,13,RandomNumber,RandomLength);
- LCD_ShowString(2,1,"Times:");
- if(GuessTimes/1000){GuessLength=4;}
- else if(GuessTimes/100){GuessLength=3;}
- else if(GuessTimes/10){GuessLength=2;}
- else{GuessLength=1;}
- LCD_ShowNum(2,7,GuessTimes,GuessLength);
- LCD_IsShowCursor(0);
- }
- }
- }
- }
- /**
- * 函 数:定时器0中断函数
- * 参 数:无
- * 返 回 值:无
- */
- void Timer0_Routine() interrupt 1
- {
- static unsigned char T0Count1; //定时器0计数变量
- TL0=0x00; //设置定时初值,定时10ms,12T@11.0592MHz
- TH0=0xDC; //设置定时初值,定时10ms,12T@11.0592MHz
- T0Count1++;
- if(T0Count1>=2) //每隔20ms检测一次按键
- {
- T0Count1=0;
- MatrixKey_Tick();
- }
- }
复制代码 总结
根据设置的范围产生真随机数这一块,感觉还必要改进一下。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |