新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于51單片機(jī)設(shè)計(jì)的乘法口訣模擬答題器

基于51單片機(jī)設(shè)計(jì)的乘法口訣模擬答題器

作者: 時(shí)間:2012-10-24 來源:網(wǎng)絡(luò) 收藏
/******************************************************************* 
* LCD1602顯示                                                      **【版權(quán)】Copyright(C) JAS  All Rights Reserved  **【聲明】此程序僅用于學(xué)習(xí)與參考,引用請(qǐng)注明版權(quán)和作者信息!        **                                                                  **********************************************************************                                                                  ** 描述:                                                           **      F--- 模擬出題控制開關(guān); C--- 輸入正確答案;                   **      (0-9)--- 有效數(shù)字輸入;                                      **      答題正確,蜂鳴器響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;          //蜂鳴器驅(qū)動(dòng)線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 ;/**********************************************************延時(shí)子程序**********************************************************/void delay(uint ms) {uchar t;while(ms--){ for(t = 0; t  120; t++);}}/*************************************************************//*                                                           *//* 延時(shí) 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;           //關(guān)閉蜂鳴器delay(250);       //延時(shí)     }/*************************************************************//*                                                           *//*檢查LCD忙狀態(tài)                                              *//*lcd_busy為1時(shí),忙,等待。lcd-busy為0時(shí),閑,可寫指令與數(shù)據(jù)  *//*                                                           *//*************************************************************/ bit lcd_busy(){                          bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;delayNOP();result = (bit)(P00x80);LCD_EN = 0;return(result); }/*******************************************************************//*                                                                 *//*寫指令數(shù)據(jù)到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;  }/*******************************************************************//*                                                                 *//*寫顯示數(shù)據(jù)到LCD                                                  *//*RS=H,RW=L,E=高脈沖,D0-D7=數(shù)據(jù)。                               *//*                                                                 *//*******************************************************************/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初始化設(shè)定                                            *//*                                                           *//*************************************************************/void lcd_init(){ delay(15);                   lcd_wcmd(0x38);      //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)delay(5);lcd_wcmd(0x38);         delay(5);lcd_wcmd(0x38);         delay(5);lcd_wcmd(0x0c);      //顯示開,關(guān)光標(biāo)delay(5);lcd_wcmd(0x06);      //移動(dòng)光標(biāo)delay(5);lcd_wcmd(0x01);      //清除LCD的顯示內(nèi)容delay(5);}/*************************************************************//*                                                           *//*  設(shè)定顯示位置                                             *//*                                                           *//*************************************************************/void lcd_pos(uchar pos){                          lcd_wcmd(pos | 0x80);  //數(shù)據(jù)指針=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();}}/**********************************************************隨機(jī)出題函數(shù)**********************************************************/void  rubric(){uchar  num1,num2,temp1;TR1=0;temp1=TL1;                   //取T1當(dāng)前的計(jì)數(shù)值temp1=~temp1;                //取反得到對(duì)應(yīng)的題號(hào)num2=temp1/9;                //就題目分成9組num2++;                      //將組號(hào)0~8轉(zhuǎn)換為被乘數(shù)1~9testdata[3]=num2+0x30;       //保存被乘數(shù)num1=temp1%9;              num1++;                      //將組號(hào)0~8轉(zhuǎn)換為乘數(shù)1~9。testdata[2]=num1+0x30;       //保存乘數(shù)temp1=num2*num1;             //計(jì)算乘積testdata[1]=temp1/10+0x30;   //乘積的高位testdata[0]=temp1%10+0x30;   //乘積的低位TR1=1;   } /**********************************************************鍵入正確答案函數(shù)**********************************************************/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]);}/**********************************************************鍵入答案函數(shù)**********************************************************/void  key_input(){ if(testdata[1]==0x30)        //先判斷十位數(shù)是否為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; //轉(zhuǎn)換為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;    //轉(zhuǎn)換為ASCII碼in_data[0]=key_buf;      //輸入乘積低位lcd_pos(0x4c);lcd_wdat(in_data[0]);    //顯示乘積低位key_num=0;}         }}/**********************************************************數(shù)據(jù)比較函數(shù)**********************************************************/void  datacomp(){if(testdata[1]-in_data[1]==0)    //比較乘積高位{if(testdata[0]-in_data[0]==0) //比較乘積低位{beep();                //計(jì)算正確蜂鳴器響3聲beep();beep();truer=1;               //比較正確F_in=0;                //可以重新出題}else  truer=0;            //比較錯(cuò)誤}else  truer=0;               //比較錯(cuò)誤if(truer==0)          {lcd_pos(0x4B);             //清除錯(cuò)誤答案lcd_wdat(0x20);lcd_wdat(0x3f);F_in=1;                    //禁止重新出題}}/**********************************************************主函數(shù)**********************************************************/main(){uchar  m;lcd_init();                  //初始化LCD             lcd_pos(0x00);               //設(shè)置顯示位置為第一行for(m=0;m16;m++)lcd_wdat(cdis1-);lcd_pos(0x40);               //設(shè)置顯示位置為第二行     for(m=0;m16;m++)lcd_wdat(cdis2-);TMOD=0x21;                 //將T1設(shè)置為8位自動(dòng)重裝工作方式。TH1=175;                     //對(duì)T1定時(shí)常數(shù)進(jìn)行預(yù)置。TL1=175;TR1=1;                       //啟動(dòng)T1。while(1)                {keydown();if(key_buf==0x0f)          //F 鍵為模擬出題開關(guān){rubric();lcd_pos(0x47); lcd_wdat(testdata[3]);   //顯示被乘數(shù)lcd_pos(0x49); lcd_wdat(testdata[2]);   //顯示乘數(shù)lcd_pos(0x4B);lcd_wdat(0x20);lcd_wdat(0x3f);          //顯示 ?key_buf=0x00;F_in=1;                  //出題目完畢標(biāo)志}while(F_in==1){key_input();datacomp();}} }/*********************************************************/


評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉