久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

51乘法口訣模擬答題器

作者:佚名   來源:本站原創   點擊數:  更新時間:2010年06月02日   【字體:
/*******************************************************************          

* 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 int

bit  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();
       key_num=0;
     }
     if(key_buf<10)
     {          
       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_buf<10)
     {            
       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;m<16;m++)
   lcd_wdat(cdis1

-);

   lcd_pos(0x40);               //設置顯示位置為第二行     
   for(m=0;m<16;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();
  }
   } 
}

/*********************************************************/
關閉窗口

相關文章

主站蜘蛛池模板: 亚洲视频一区二区三区四区 | 国产精品视频久久 | 九九热在线视频免费观看 | 亚洲视频在线观看一区二区三区 | 精品一区二区三区在线视频 | 亚洲成人av | 色男人的天堂 | 国产精品永久在线观看 | 久久久久久久一区二区 | 亚州综合一区 | 一区二区三区四区在线视频 | 国产精品色 | 91精品国产91久久久久久吃药 | 久久99精品久久久久久琪琪 | 亚洲成人一区二区 | 91视频中文 | 久久青青 | 亚洲一区av在线 | 日本福利视频 | 亚洲精品一区二区三区在线 | 日日噜噜噜夜夜爽爽狠狠视频, | www.国产一区 | 美女福利视频网站 | 亚洲视频在线播放 | 91在线看网站 | 国产乱码精品一区二区三区中文 | 日韩在线一区二区 | 久久久久国产精品 | 欧美久久精品一级黑人c片 91免费在线视频 | 国产一区二区三区网站 | 欧美日韩国产一区二区三区不卡 | 国产一区三区视频 | 欧美一区二区在线观看 | 一区二区亚洲 | 91综合在线视频 | 国精品一区二区 | aaa在线观看 | 影音av| 香蕉一区 | 国产视频精品区 | 精品一级电影 |