找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用Ran#函数制成的猜码游戏机源程序及仿真

[复制链接]
跳转到指定楼层
楼主
学习了随机数的产生
就打算写一个与随机数有关的游戏机
因此。。。。。。








main.c如下:

  1. #include <reg52.h>
  2. #include <stdlib.h> //该文件中包含随机数生成函数包含函数
  3. #include "lcd.c" //显示

  4. //二进制的形象表示方法,从左到右分别位第7 6 5 4 3 2 1 0位
  5. #define bin(_a,_b,_c,_d,_e,_f,_g,_h) ((_a)<<7|(_b)<<6|(_c)<<5|(_d)<<4|(_e)<<3|(_f)<<2|(_g)<<1|(_h))        //二进制的表示

  6. //定义按键
  7. sbit k1=P2^0;
  8. sbit k2=P2^1;
  9. sbit k3=P2^2;
  10. sbit k4=P2^3;
  11. sbit sp=P2^4;

  12. const uchar normal_man[]={ //正常脸CGRAM
  13. bin(0,0,0,0,0,0,0,0),
  14. bin(0,0,0,0,1,0,1,0),
  15. bin(0,0,0,0,1,0,1,0),
  16. bin(0,0,0,0,0,0,0,0),
  17. bin(0,0,0,0,0,0,0,0),
  18. bin(0,0,0,1,1,1,1,1),
  19. bin(0,0,0,0,0,0,0,0),
  20. bin(0,0,0,0,0,0,0,0)
  21. };

  22. const uchar yes_man[]={ //笑脸CGRAM
  23. bin(0,0,0,0,0,0,0,0),
  24. bin(0,0,0,0,1,0,1,0),
  25. bin(0,0,0,0,1,0,1,0),
  26. bin(0,0,0,0,0,0,0,0),
  27. bin(0,0,0,1,0,0,0,1),
  28. bin(0,0,0,0,1,1,1,0),
  29. bin(0,0,0,0,0,1,1,0),
  30. bin(0,0,0,0,0,0,0,0)
  31. };

  32. const uchar no_man[]={ //哭脸CGRAM
  33. bin(0,0,0,0,0,0,0,0),
  34. bin(0,0,0,0,1,0,1,0),
  35. bin(0,0,0,0,1,0,1,0),
  36. bin(0,0,0,0,0,0,0,0),
  37. bin(0,0,0,0,1,1,1,0),
  38. bin(0,0,0,1,0,0,0,1),
  39. bin(0,0,0,0,0,0,0,0),
  40. bin(0,0,0,0,0,0,0,0)
  41. };

  42. const uchar lives[]={ //机会旗CGRAM
  43. bin(0,0,0,1,0,0,0,0),
  44. bin(0,0,0,1,1,0,0,0),
  45. bin(0,0,0,1,1,1,0,0),
  46. bin(0,0,0,1,1,1,1,0),
  47. bin(0,0,0,1,1,1,1,1),
  48. bin(0,0,0,1,0,0,0,0),
  49. bin(0,0,0,1,0,0,0,0),
  50. bin(0,0,0,0,0,0,0,0)
  51. };

  52. const uchar pause[]={ //暂停符号CGRAM
  53. bin(0,0,0,1,1,0,1,1),
  54. bin(0,0,0,1,1,0,1,1),
  55. bin(0,0,0,1,1,0,1,1),
  56. bin(0,0,0,1,1,0,1,1),
  57. bin(0,0,0,1,1,0,1,1),
  58. bin(0,0,0,1,1,0,1,1),
  59. bin(0,0,0,1,1,0,1,1),
  60. bin(0,0,0,0,0,0,0,0)
  61. };

  62. const uchar key[]={ //钥匙CGRAM
  63. bin(0,0,0,0,0,1,1,0),
  64. bin(0,0,0,0,0,1,0,0),
  65. bin(0,0,0,0,0,1,1,0),
  66. bin(0,0,0,0,0,1,0,0),
  67. bin(0,0,0,0,1,1,1,0),
  68. bin(0,0,0,0,1,0,1,0),
  69. bin(0,0,0,0,1,1,1,0),
  70. bin(0,0,0,0,0,0,0,0)
  71. };

  72. void paused()
  73. {
  74.         uchar a,b;
  75.         LcdWriteCom(0x8a); //定义坐标(10,0)
  76.         LcdWriteData(0x04); //写暂停符号
  77.         while(1){
  78.                 if(sp==0){ //发现S/P按钮按下
  79.                         for(b=1;b>0;b--) //延时10微秒以实现消抖
  80.                         for(a=2;a>0;a--);
  81.                         if(sp==0){
  82.                                 while(!sp); //等待S/P按钮松开
  83.                                 LcdWriteCom(0x8a); //定义坐标(10,0)
  84.                                 LcdWriteData(0x20); //清除暂停符号
  85.                                 return; //返回
  86.                         }
  87.                 }
  88.         }
  89. }

  90. void game()
  91. {
  92.         uchar a,b,c,key,rnd,delay,lives=4; //定义数据槽
  93.         uint score=0; //定义得分槽
  94.         LcdWriteCom(0x01); //清屏
  95.         LcdPrintf(" 1  MAN:"); //放上必需字符
  96.         LcdWriteCom(0xc0); //定义坐标(0,1)
  97.         LcdPrintf("324 SCORE:000000"); //放上必需字符
  98.         LcdWriteCom(0x88); //定义坐标(8,0)
  99.         LcdWriteData(0x00); //放置正常脸CGRAM
  100.         LcdWriteCom(0x8c); //定义坐标(12,0)
  101.         LcdWriteData(0x03); //放置机会旗CGRAM
  102.         LcdWriteData(0x03); //放置机会旗CGRAM
  103.         LcdWriteData(0x03); //放置机会旗CGRAM
  104.         LcdWriteData(0x03); //放置机会旗CGRAM
  105.         while(1){
  106.                 LcdWriteCom(0xca); //定义坐标(10,1)
  107.                 LCDPrintNum(score,4); //显示得分
  108.                 if(c==0){
  109.                         rnd=rand()%4; //获取一个小于4的随机数
  110.                         c=1;
  111.                 }
  112.                 if(k1==0){ //发现1按钮按下
  113.                         delay=1;
  114.                         key=0;
  115.                 }
  116.                 if(k2==0){ //发现2按钮按下
  117.                         delay=1;
  118.                         key=1;
  119.                 }
  120.                 if(k3==0){ //发现3按钮按下
  121.                         delay=1;
  122.                         key=2;
  123.                 }
  124.                 if(k4==0){ //发现4按钮按下
  125.                         delay=1;
  126.                         key=3;
  127.                 }
  128.                 if(sp==0){ //发现S/P按钮按下
  129.                         for(b=1;b>0;b--) //延时10微秒以实现消抖
  130.                         for(a=2;a>0;a--);
  131.                         if(sp==0){
  132.                                 while(!sp); //等待S/P按钮松开
  133.                                 paused(); //暂停
  134.                         }
  135.                 }
  136.                 if(delay==1){
  137.                         if(rnd==0){
  138.                                 LcdWriteCom(0x81); //定义坐标(1,0)
  139.                                 LcdWriteData(0x05); //放置钥匙CGRAM
  140.                         }
  141.                         if(rnd==1){
  142.                                 LcdWriteCom(0xc1); //定义坐标(1,1)
  143.                                 LcdWriteData(0x05); //放置钥匙CGRAM
  144.                         }
  145.                         if(rnd==2){
  146.                                 LcdWriteCom(0xc0); //定义坐标(0,1)
  147.                                 LcdWriteData(0x05); //放置钥匙CGRAM
  148.                         }
  149.                         if(rnd==3){
  150.                                 LcdWriteCom(0xc2); //定义坐标(2,1)
  151.                                 LcdWriteData(0x05); //放置钥匙CGRAM
  152.                         }
  153.                         if(key==rnd){ //如果这个代码中找到钥匙
  154.                                 LcdWriteCom(0x88); //定义坐标(8,0)
  155.                                 LcdWriteData(0x01); //放置笑脸CGRAM
  156.                                 Lcd1602_Delay1ms(1000);
  157.                                 ++score;
  158.                         }
  159.                         else{
  160.                                 LcdWriteCom(0x88); //定义坐标(8,0)
  161.                                 LcdWriteData(0x02); //放置哭脸CGRAM
  162.                                 Lcd1602_Delay1ms(1000);
  163.                                 --lives;
  164.                         }
  165.                         c=0;
  166.                         delay=0;
  167.                         //恢复原状
  168.                         LcdWriteCom(0x81);
  169.                         LcdWriteData('1');
  170.                         LcdWriteCom(0xc1);
  171.                         LcdWriteData('2');
  172.                         LcdWriteCom(0xc0);
  173.                         LcdWriteData('3');
  174.                         LcdWriteCom(0xc2);
  175.                         LcdWriteData('4');
  176.                         LcdWriteCom(0x88);
  177.                         LcdWriteData(0x00);
  178.                         
  179.                 }
  180.                 //减少机会,机会旗消耗
  181.                 if(lives==3){
  182.                         LcdWriteCom(0x8f);
  183.                         LcdWriteData(0x20);
  184.                 }
  185.                 if(lives==2){
  186.                         LcdWriteCom(0x8e);
  187.                         LcdWriteData(0x20);
  188.                 }
  189.                 if(lives==1){
  190.                         LcdWriteCom(0x8d);
  191.                         LcdWriteData(0x20);
  192.                 }
  193.                 if(lives==0){
  194.                         LcdWriteCom(0x8c);
  195.                         LcdWriteData(0x20);
  196.                 }
  197.                
  198.                 //当没有机会旗时且某个代码中没有找到钥匙,游戏结束
  199.                 if(lives==0xff){
  200.                         LcdWriteCom(0x01); //清屏
  201.                         LcdWriteCom(0x80);
  202.                         LcdPrintf("GAME OVER"); //显示字符
  203.                         LcdWriteCom(0xc0); //定义坐标(0,1)
  204.                         LcdPrintf("SCORE:"); //显示字符
  205.                         //显示得分
  206.                         LCDPrintNum(score,4);
  207.                         LcdPrintf("00");
  208.                         
  209.                         return;
  210.                 }
  211.         }
  212. }

  213. void main()
  214. {
  215.         uchar a,b;
  216.         LcdInit(); //LCD初始化
  217.         //将所有CGRAM写入LCD
  218.         LcdWriteCGRAM(0x00,normal_man);
  219.         LcdWriteCGRAM(0x01,yes_man);
  220.         LcdWriteCGRAM(0x02,no_man);
  221.         LcdWriteCGRAM(0x03,lives);
  222.         LcdWriteCGRAM(0x04,pause);
  223.         LcdWriteCGRAM(0x05,key);
  224.         
  225.         LcdPrintf("Code Gamer"); //显示字符
  226.         LcdWriteCom(0xc0); //定义坐标(0,1)
  227.         LcdPrintf("Press S/P Button"); //显示字符
  228.         while(1){
  229.                 if(sp==0){ //发现S/P按钮按下
  230.                         for(b=1;b>0;b--) //延时10微秒以实现消抖
  231.                         for(a=2;a>0;a--);
  232.                         if(sp==0){
  233.                                 while(!sp); //等待S/P按钮松开
  234.                                 game(); //游戏开始
  235.                         }
  236.                 }
  237.         }
  238. }
复制代码


lcd.c如下:

  1. #include "lcd.h"

  2. /*******************************************************************************
  3. * 函 数 名         : Lcd1602_Delay1ms
  4. * 函数功能                   : 延时函数,延时1ms
  5. * 输    入         : c
  6. * 输    出         : 无
  7. * 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
  8. *******************************************************************************/

  9. void Lcd1602_Delay1ms(uint c)   //误差 0us
  10. {
  11.     uchar a,b;
  12.         for (; c>0; c--)
  13.         {
  14.                  for (b=199;b>0;b--)
  15.                  {
  16.                           for(a=1;a>0;a--);
  17.                  }      
  18.         }
  19.             
  20. }

  21. /*******************************************************************************
  22. * 函 数 名         : LcdWriteCom
  23. * 函数功能                   : 向LCD写入一个字节的命令
  24. * 输    入         : com
  25. * 输    出         : 无
  26. *******************************************************************************/
  27. #ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  28. void LcdWriteCom(uchar com)          //写入命令
  29. {
  30.         LCD1602_E = 0;     //使能
  31.         LCD1602_RS = 0;           //选择发送命令
  32.         LCD1602_RW = 0;           //选择写入
  33.         
  34.         LCD1602_DATAPINS = com;     //放入命令
  35.         Lcd1602_Delay1ms(1);                //等待数据稳定

  36.         LCD1602_E = 1;                  //写入时序
  37.         Lcd1602_Delay1ms(5);          //保持时间
  38.         LCD1602_E = 0;
  39. }
  40. #else
  41. void LcdWriteCom(uchar com)          //写入命令
  42. {
  43.         LCD1602_E = 0;         //使能清零
  44.         LCD1602_RS = 0;         //选择写入命令
  45.         LCD1602_RW = 0;         //选择写入

  46.         LCD1602_DATAPINS = com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  47.         Lcd1602_Delay1ms(1);

  48.         LCD1602_E = 1;         //写入时序
  49.         Lcd1602_Delay1ms(5);
  50.         LCD1602_E = 0;

  51.         LCD1602_DATAPINS = com << 4; //发送低四位
  52.         Lcd1602_Delay1ms(1);

  53.         LCD1602_E = 1;         //写入时序
  54.         Lcd1602_Delay1ms(5);
  55.         LCD1602_E = 0;
  56. }
  57. #endif
  58. /*******************************************************************************
  59. * 函 数 名         : LcdWriteData
  60. * 函数功能                   : 向LCD写入一个字节的数据
  61. * 输    入         : dat
  62. * 输    出         : 无
  63. *******************************************************************************/                  
  64. #ifndef         LCD1602_4PINS                  
  65. void LcdWriteData(uchar dat)                        //写入数据
  66. {
  67.         LCD1602_E = 0;        //使能清零
  68.         LCD1602_RS = 1;        //选择输入数据
  69.         LCD1602_RW = 0;        //选择写入

  70.         LCD1602_DATAPINS = dat; //写入数据
  71.         Lcd1602_Delay1ms(1);

  72.         LCD1602_E = 1;   //写入时序
  73.         Lcd1602_Delay1ms(5);   //保持时间
  74.         LCD1602_E = 0;
  75. }
  76. #else
  77. void LcdWriteData(uchar dat)                        //写入数据
  78. {
  79.         LCD1602_E = 0;          //使能清零
  80.         LCD1602_RS = 1;          //选择写入数据
  81.         LCD1602_RW = 0;          //选择写入

  82.         LCD1602_DATAPINS = dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  83.         Lcd1602_Delay1ms(1);

  84.         LCD1602_E = 1;          //写入时序
  85.         Lcd1602_Delay1ms(5);
  86.         LCD1602_E = 0;

  87.         LCD1602_DATAPINS = dat << 4; //写入低四位
  88.         Lcd1602_Delay1ms(1);

  89.         LCD1602_E = 1;          //写入时序
  90.         Lcd1602_Delay1ms(5);
  91.         LCD1602_E = 0;
  92. }
  93. #endif
  94. /*******************************************************************************
  95. * 函 数 名       : LcdInit()
  96. * 函数功能                 : 初始化LCD屏
  97. * 输    入       : 无
  98. * 输    出       : 无
  99. *******************************************************************************/                  
  100. #ifndef                LCD1602_4PINS
  101. void LcdInit()                                                  //LCD初始化子程序
  102. {
  103.          LcdWriteCom(0x38);  //开显示
  104.         LcdWriteCom(0x0c);  //开显示不显示光标
  105.         LcdWriteCom(0x06);  //写一个指针加1
  106.         LcdWriteCom(0x01);  //清屏
  107.         LcdWriteCom(0x80);  //设置数据指针起点
  108. }
  109. #else
  110. void LcdInit()                                                  //LCD初始化子程序
  111. {
  112.         LcdWriteCom(0x32);         //将8位总线转为4位总线
  113.         LcdWriteCom(0x28);         //在四位线下的初始化
  114.         LcdWriteCom(0x0c);  //开显示不显示光标
  115.         LcdWriteCom(0x06);  //写一个指针加1
  116.         LcdWriteCom(0x01);  //清屏
  117.         LcdWriteCom(0x80);  //设置数据指针起点
  118. }
  119. #endif
  120. /*******************************************************************************
  121. * 函 数 名       :LcdPrintf()
  122. * 函数功能                 : 向屏幕输出字符
  123. * 输    入       : *s
  124. * 输    出       : 无
  125. *******************************************************************************/
  126. void LcdPrintf(uchar *s){
  127.         while(*s>0)LcdWriteData(*s++);
  128. }
  129. /*******************************************************************************
  130. * 函 数 名       : LcdWriteCGRAM()
  131. * 函数功能                 : 建立一个自定义字符
  132. * 输    入       : index、*p
  133. * 输    出       : 无
  134. *******************************************************************************/
  135. void LcdWriteCGRAM(uchar index,uchar *p)
  136. {
  137.         uchar i;
  138.         index <<=3; //index *= 8
  139.         for(i=0;i<8;++i){
  140.                 LcdWriteCom(0x40 | index+i);//写CGRAM地址
  141.                 LcdWriteData(*p++);
  142.         }
  143.         LcdWriteCom(0x80);
  144. }

  145. /*******************************************************************************
  146. * 函 数 名       : LcdPrintNum
  147. * 函数功能                 : 显示数字
  148. * 输    入       : num、wei
  149. * 输    出       : 无
  150. *******************************************************************************/
  151. void LcdPrintNum(uint num,uchar wei)//wei 数字占的位数
  152. {
  153.         uchar tempstring[6];
  154.         uchar n[5];
  155.         uchar i,j=0;
  156.         n[0]=num/10000;
  157.         n[1]=num%10000/1000;
  158.         n[2]=num%1000/100;
  159.         n[3]=num%100/10;
  160.         n[4]=num%10;
  161.         i=5-wei;
  162.         for(i;i<5;i++){
  163.                 tempstring[j++]=n[i]+'0';        
  164.         }
  165.         tempstring[j]='\0';
  166.         LcdPrintf(tempstring);
  167. }
复制代码


lcd.h如下:
  1. #ifndef __LCD_H_
  2. #define __LCD_H_
  3. /**********************************
  4. 当使用的是4位数据传输的时候定义,
  5. 使用8位取消这个定义
  6. **********************************/
  7. //#define LCD1602_4PINS

  8. /**********************************
  9. 包含头文件
  10. **********************************/
  11. #include<reg52.h>

  12. //---重定义关键词---//
  13. #ifndef uchar
  14. typedef unsigned char uchar;
  15. #endif

  16. #ifndef uint
  17. typedef unsigned int uint;
  18. #endif

  19. /**********************************
  20. PIN口定义
  21. **********************************/
  22. #define LCD1602_DATAPINS P0
  23. sbit LCD1602_E=P2^7;
  24. sbit LCD1602_RW=P2^5;
  25. sbit LCD1602_RS=P2^6;

  26. /**********************************
  27. 函数声明
  28. **********************************/
  29. /*在51单片机12MHZ时钟下的延时函数*/
  30. void Lcd1602_Delay1ms(uint c);   //误差 0us
  31. /*LCD1602写入8位命令子函数*/
  32. void LcdWriteCom(uchar com);
  33. /*LCD1602写入8位数据子函数*/        
  34. void LcdWriteData(uchar dat)        ;
  35. /*LCD1602初始化子程序*/               
  36. void LcdInit();                                                  
  37. /*LCD1602向屏幕输出字符*/
  38. void LcdPrintf(uchar *s);
  39. /*建立一个自定义字符*/
  40. void LcdWriteCGRAM(uchar index,uchar *p);
  41. /*显示数字*/
  42. void LcdPrintNum(uint num,uchar wei);
  43. #endif

复制代码

code.zip

50.75 KB, 下载次数: 8, 下载积分: 黑币 -5

程序文件及仿真

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:218023 发表于 2018-8-6 18:34 | 只看该作者
紧急更新:
回复

使用道具 举报

板凳
ID:218023 发表于 2018-8-6 18:35 | 只看该作者
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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