微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于51单片机设计的乘法口诀模拟答题器

基于51单片机设计的乘法口诀模拟答题器

时间:10-24 来源:互联网 点击:
/******************************************************************* 
* LCD1602显示                                                      **Copyright(C) JAS  All Rights Reserved  **此程序仅用于学习与参考,引用请注明版权和作者信息!        **                                                                  **********************************************************************                                                                  ** 描述:                                                           **      F--- 模拟出题控制开关; C--- 输入正确答案;                   **      (0-9)--- 有效数字输入;                                      **      答题正确,蜂鸣器响4声。                                     **                                                                  ********************************************************************/#include  reg51.h >#include  intrins.h >#define uchar unsigned char#define uint  unsigned intbit  F_in=0,truer;  sbit LCD_RS = P2^0;             sbit LCD_RW = P2^1;sbit LCD_EN = P2^2;uchar code  cdis1[ ] = {" MULTIPLICATION "}; uchar code  cdis2[ ] = {"TABLE: 0*0=00   "};#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};sbit BEEP = P3^7;          //蜂鸣器驱动线uchar  key_buf;            //显示缓存uchar  temp;uchar  key,key_num=0;                //键顺序吗uchar data testdata[] = {0x00,0x00,0x00,0x00};uchar data in_data[] = {0x01,0x02};uchar shift ;/**********************************************************延时子程序**********************************************************/void delay(uint ms) {uchar t;while(ms--){ for(t = 0; t  120; t++);}}/*************************************************************//*                                                           *//* 延时 x*0.14ms                                             *//*                                                           *//*************************************************************/void delay0(uchar x)    {unsigned char i;while(x--){for (i = 0; i13; i++) {}}}/*************************************************************//*                                                           *//* 蜂鸣器响一声                                              *//*                                                           *//*************************************************************/void beep(){unsigned char i;for (i=0;i180;i++){delay0(6);BEEP=!BEEP;       //BEEP取反} BEEP=1;           //关闭蜂鸣器delay(250);       //延时     }/*************************************************************//*                                                           *//*检查LCD忙状态                                              *//*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据  *//*                                                           *//*************************************************************/ bit lcd_busy(){                          bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;delayNOP();result = (bit)(P00x80);LCD_EN = 0;return(result); }/*******************************************************************//*                                                                 *//*写指令数据到LCD                                                  *//*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             *//*                                                                 *//*******************************************************************/void lcd_wcmd(uchar cmd){                          while(lcd_busy());LCD_RS = 0;LCD_RW = 0;LCD_EN = 0;_nop_();_nop_(); P0 = cmd;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;  }/*******************************************************************//*                                                                 *//*写显示数据到LCD                                                  *//*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               *//*                                                                 *//*******************************************************************/void lcd_wdat(uchar dat){                          while(lcd_busy());LCD_RS = 1;LCD_RW = 0;LCD_EN = 0;P0 = dat;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0; }/*************************************************************//*                                                           *//*  LCD初始化设定                                            *//*                                                           *//*************************************************************/void lcd_init(){ delay(15);                   lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据delay(5);lcd_wcmd(0x38);         delay(5);lcd_wcmd(0x38);         delay(5);lcd_wcmd(0x0c);      //显示开,关光标delay(5);lcd_wcmd(0x06);      //移动光标delay(5);lcd_wcmd(0x01);      //清除LCD的显示内容delay(5);}/*************************************************************//*                                                           *//*  设定显示位置                                             *//*                                                           *//*************************************************************/void lcd_pos(uchar pos){                          lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量}/*************************************************************键扫描子程序                                             *************************************************************/void  keyscan(void){ P1=0x0F;                 //低四位输入  delay(1);temp=P1;                 //读P1口 temp=temp0x0F;temp=~(temp|0xF0);if(temp==1)key=0;else if(temp==2)key=1;else if(temp==4)key=2;else if(temp==8)key=3;elsekey=16;P1=0xF0;                //高四位输入delay(1);temp=P1;                //读P1口       temp=temp0xF0;temp=~((temp>>4)|0xF0);if(temp==1)key=key+0;else if(temp==2)key=key+4;else if(temp==4)key=key+8;else if(temp==8)key=key+12;elsekey=16;key_buf = key;              //键值入显示缓存key_buf = key_buf  0x0f;}/*************************************************************判断键是否按下                                             *************************************************************/void  keydown(void){  P1=0xF0;while(P1==0xf0);{keyscan();beep();}}/**********************************************************随机出题函数**********************************************************/void  rubric(){uchar  num1,num2,temp1;TR1=0;temp1=TL1;                   //取T1当前的计数值temp1=~temp1;                //取反得到对应的题号num2=temp1/9;                //就题目分成9组num2++;                      //将组号0~8转换为被乘数1~9testdata[3]=num2+0x30;       //保存被乘数num1=temp1%9;              num1++;                      //将组号0~8转换为乘数1~9。testdata[2]=num1+0x30;       //保存乘数temp1=num2*num1;             //计算乘积testdata[1]=temp1/10+0x30;   //乘积的高位testdata[0]=temp1%10+0x30;   //乘积的低位TR1=1;   } /**********************************************************键入正确答案函数**********************************************************/void  right(){if(testdata[1]==0x30){testdata[1]=0x20;}lcd_pos(0x4b);in_data[1]=testdata[1];in_data[0]=testdata[0];lcd_wdat(in_data[1]);lcd_wdat(in_data[0]);}/**********************************************************键入答案函数**********************************************************/void  key_input(){ if(testdata[1]==0x30)        //先判断十位数是否为0{       in_data[1]=0x30;           key_num=1;}else{keydown();if(key_buf==0x0c)          //C 键显示正确答案{right();key_num=0;}if(key_buf10){          key_buf=key_buf+0x30; //转换为ASCII码in_data[1]=key_buf;      //输入乘积高位lcd_pos(0x4b);lcd_wdat(in_data[1]);    //显示乘积高位lcd_wdat(0x20);key_num=1;}}if(key_num==1){keydown();if(key_buf==0x0c)          //C 键显示正确答案{right();key_num=0;}if(key_buf10){            key_buf=key_buf+0x30;    //转换为ASCII码in_data[0]=key_buf;      //输入乘积低位lcd_pos(0x4c);lcd_wdat(in_data[0]);    //显示乘积低位key_num=0;}         }}/**********************************************************数据比较函数**********************************************************/void  datacomp(){if(testdata[1]-in_data[1]==0)    //比较乘积高位{if(testdata[0]-in_data[0]==0) //比较乘积低位{beep();                //计算正确蜂鸣器响3声beep();beep();truer=1;               //比较正确F_in=0;                //可以重新出题}else  truer=0;            //比较错误}else  truer=0;               //比较错误if(truer==0)          {lcd_pos(0x4B);             //清除错误答案lcd_wdat(0x20);lcd_wdat(0x3f);F_in=1;                    //禁止重新出题}}/**********************************************************主函数**********************************************************/main(){uchar  m;lcd_init();                  //初始化LCD             lcd_pos(0x00);               //设置显示位置为第一行for(m=0;m16;m++)lcd_wdat(cdis1-);lcd_pos(0x40);               //设置显示位置为第二行     for(m=0;m16;m++)lcd_wdat(cdis2-);TMOD=0x21;                 //将T1设置为8位自动重装工作方式。TH1=175;                     //对T1定时常数进行预置。TL1=175;TR1=1;                       //启动T1。while(1)                {keydown();if(key_buf==0x0f)          //F 键为模拟出题开关{rubric();lcd_pos(0x47); lcd_wdat(testdata[3]);   //显示被乘数lcd_pos(0x49); lcd_wdat(testdata[2]);   //显示乘数lcd_pos(0x4B);lcd_wdat(0x20);lcd_wdat(0x3f);          //显示 ?key_buf=0x00;F_in=1;                  //出题目完毕标志}while(F_in==1){key_input();datacomp();}} }/*********************************************************/

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top