/******************************************************************* * 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; i<13; i++) {} }}/*************************************************************//* *//* 蜂鸣器响一声 *//* *//*************************************************************/void beep(){ unsigned char i; for (i=0;i<180;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)(P0&0x80); 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=temp&0x0F; 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; else key=16; P1=0xF0; //高四位输入 delay(1); temp=P1; //读P1口 temp=temp&0xF0; 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; else key=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~9 testdata[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()
51乘法口诀模拟答题器
时间:2024-06-11 20:37:11