• <rp id="wfxtb"><acronym id="wfxtb"></acronym></rp><em id="wfxtb"></em><dd id="wfxtb"><big id="wfxtb"><video id="wfxtb"></video></big></dd>
  • <rp id="wfxtb"></rp>

    <mark id="wfxtb"><center id="wfxtb"></center></mark>

      <rp id="wfxtb"><span id="wfxtb"><u id="wfxtb"></u></span></rp>

      <rp id="wfxtb"><object id="wfxtb"></object></rp>

      注意:訪問本站需要Cookie和JavaScript支持!請設置您的瀏覽器! 打開購物車 查看留言付款方式聯系我們
      初中電子 單片機教材一 單片機教材二
      搜索上次看見的商品或文章:
      商品名、介紹 文章名、內容
      首頁 電子入門 學單片機 免費資源 下載中心 商品列表 象棋在線 在線繪圖 加盟五一 加入收藏 設為首頁
      本站推薦:
      簡易計算器,用1602顯示,紅外線輸入,請多指教
      文章長度[19170] 加入時間[2007/12/14] 更新時間[2025/4/22 10:13:35] 級別[3] [評論] [收藏]

      10為"0"


      11為小數點


      12為"="號


      13/14/15/16為加/減/乘/除


      這個是輸出程序PUTCHAR.C


      #include <reg51.h>
      #define uchar unsigned char
      #define uint unsigned int
      sbit RS=P3^0;
      sbit RW=P3^1;
      sbit E=P3^5;
      sbit P1_7=P1^7;
      static bit biao;


      static delayn(uint j) //延時
      { uint i;
      for(i=0;i<j;i++)
      {;}
      }
      static void Nop()
      {;}


      static mang() //檢查忙信號
      { P1|=0xff;
      RS=0;
      RW=1;
      E=1;
      Nop();
      while(P1_7);
      E=0;
      Nop();
      Nop();
      }


      static void writer(uchar mn,i) //寫命令
      { if (i==1)
      mang(); //i=1檢查忙
      RS=0;
      RW=0;
      P1=mn;
      E=1;
      Nop();
      Nop();
      E=0;
      Nop();

      }
      static void wrdata(uchar da,i) //寫數據
      { if (i==1)
      mang();
      RS=1;
      RW=0;
      P1=da;
      E=1;
      Nop();
      Nop();
      E=0;
      Nop();
      }
      void rest() //復位
      { delayn(15000);
      writer(0x38,0);
      delayn(5000);
      writer(0x38,0);
      delayn(5000);
      writer(0x38,1);
      writer(0x01,1);
      writer(0x06,1);
      writer(0x0f,1);
      writer(0x80,1);
      }
      //static uchar code type[]={"0123456789abcdef"};
      uchar putchar(uchar c)
      { if(c=='\n') //換行
      { if(!biao)
      { writer(0xc0,1);
      biao=1;
      }
      else
      { writer(0x80,1);
      biao=0;
      }
      }
      else if(c=='s') //清屏
      { writer(0x01,1);
      writer(0x80,1); //回到首行
      biao=0;
      }
      else
      { wrdata(c,1); //寫字符
      return (c);
      }
      }


      這個是輸入程序GETKEY.C


      #include "reg51.h"


      #define uchar unsigned char
      #define uint unsigned int
      sbit in=P3^7;
      sbit P1_1=P1^1;
      sbit P3_3=P3^3;
      uchar bdata message,dat[4];
      uchar mess,incon,suma,j;
      uint k,*m;


      sbit redmsg=message^0; //紅外線遙控消息
      sbit redread=message^1; //紅外接收過程完


      void t0int() interrupt 1 //定時中0
      { if(mess!=3)
      mess++;
      switch(mess)
      { case 1:
      if(in) //8ms內為低電平,出錯
      { redmsg=0;
      mess=0;
      }
      else
      { while(1)
      { if(in) //等待高電平取同步
      { TH0=0xed;
      TL0=0x7c; //4.74ms中斷,閉過4.5ms結果碼
      redread=1; //接收過程標志位
      break;
      }
      }
      }
      break;
      case 2:
      while(1)
      { if(in) //取同步
      {TH0=0xfc;
      TL0=0x8e; //0.882ms延時
      break;
      }
      }
      break;
      case 3:
      TR0=0;
      TH0=0xfc;
      TL0=0x8e; //延時0.882MS
      if(incon==8)
      { j=j+1;
      incon=0;
      }
      incon=incon+1;
      if(in) //如果IN為1,則加1后左移,否則直接左移
      { dat[j]=dat[j]>>1;
      dat[j]=dat[j]+128;
      while(in);
      while(!in);
      }
      else
      { dat[j]=dat[j]>>1;
      while(!in);
      }
      if((incon==8)&(j==3)) //32位接收完,退出
      { redread=1; //接收完成
      j=0;
      incon=0;
      redmsg=0;
      mess=0;
      P1_1=0;
      }
      TR0=1;
      break;
      }
      }


      bit panduan() //判斷接收是否正確
      { TR0=0;
      if(dat[0]!=0x00)
      return(0);
      if(dat[1]!=0xff)
      return(0);
      if(dat[2]!=(~dat[3]))
      return(0);
      return(1);
      }
      daima()
      {
      switch(dat[2])
      { case 0x10:suma='1';break;
      case 0x03:suma='2';break;
      case 0x01:suma='3';break;
      case 0x06:suma='4';break;
      case 0x09:suma='5';break;
      case 0x1d:suma='6';break;
      case 0x1f:suma='7';break;
      case 0x0d:suma='8';break;
      case 0x19:suma='9';break;
      case 0x1b:suma='0';break;
      case 0x11:suma='.';break;
      case 0x15:suma='=';break;
      case 0x17:suma='+';break;
      case 0x12:suma='-';break;
      case 0x16:suma='*';break;
      case 0x4c:suma='/';break;
      case 0x40:suma=' ';break;
      default :suma='0';break;
      }
      }
      lia() //連發處理子函數
      { uint i;
      m=&k;
      for(i=0;i<1000;i++) //4MS之后.還是低電平,則為連發
      { if(in)
      return;
      }
      while(!in);
      *m=0; //K值清0
      }

      uchar _getkey()
      { while(1)
      { if(!in)
      redmsg=1;
      if(redmsg)
      { TH0=0xde;
      TL0=0xcc; //8.5ms中斷
      TR0=1;
      ET0=1;
      }
      else
      { TR0=0;
      ET0=0;
      }
      while(redmsg);
      if(panduan()&redread) //判斷接收是否正確
      { TR0=0;
      daima(); //解代碼
      for(k=0;k<10000;k++) //118MS內出現低電平,可能連發
      { if(!in) //判斷是否有連發
      lia(); //如果有,執行
      }
      redread=0;
      return(suma);
      }
      }
      }


      這個是計算程序JISAN.C


      #include <reg52.h>
      #include <stdio.h>
      #include <stdlib.h> //函數atol()
      #define uchar unsigned char
      #define uint unsigned int
      extern void rest();
      bit biao1=0,biaoden=0;
      uchar value[10] _at_ 0x30;
      uint a,c;
      char b,n;
      float x,y,d;
      void del() //延時函數
      { uchar j;
      for(j=0;j<=10;j++)
      value[j]=0;
      }


      float getvalue()
      { uchar j;
      char k;
      del();
      while(1)
      { for(j=0;j<10;j++)
      { k=getkey();
      if(biaoden)
      { putchar('s');
      biaoden=0;
      }
      putchar(k);
      if((k>='0')&(k<='9')|(k=='.')) //數字0-9
      { if(j<=9)
      { value[j]=k;
      biao1=1;
      }
      else
      return(atof(value));
      }
      else
      { b=k; //輸入的為符號
      return(atof(value));
      }
      }
      }
      }


      void main()
      { TMOD=0x11; //T1,T0都工作于方式1
      EA=1; //允許中斷
      rest();
      while(1)
      { start: x=getvalue(); //輸入的數據
      if(!biao1) //輸入的為符號
      x=d;
      if(b==' ') //收到清0
      { x=0;
      d=0;
      putchar('s');
      goto start;
      }
      n=b;
      del();
      y=getvalue();
      biao1=0;
      switch(n) //判斷運算方法
      { case '+': d=x+y ;
      break ;
      case '-': d=x-y ;
      break ;
      case '*': d=x*y ;
      break ;
      case '/': d=x/y ;
      break ;
      case '=': putchar(d) ;
      x=d ;
      biaoden=1 ;
      break ;
      case ' ': d=0 ; //為清除鍵
      x=0 ;
      putchar('s') ;
      goto start ;
      }
      if(b=='=')
      { biaoden=1;
      putchar('s');
      printf("%g%c%g=\n",x,n,y);
      printf("%g",d);
      putchar('\n');
      }
      if(b==' ')
      { d=0;
      x=0;
      putchar('s');
      }
      }
      }


      把這三個程序放到一個工程里就OK了,程序有點大要用52系列的單片機!


      請高手多多指教


      發貼心情

      呵呵,沒想到這個兄弟,在我之前把代碼給貼出來了


      我也來一份了!


      /********************************************************************************/
      /* Project: 計算器(Calculator) 版本號:V1。0 */
      /* */
      /* */
      /* Designed By: whoami CPU:AT89S51 or C51 */
      /* */
      /* */
      /* 鍵盤布局如下: */
      /* K2(0) K4(1) K6(2) K8(3) K10(8) K12(9) K14(.) K16(+) */
      /* K3(4) K5(5) K7(6) K9(7) K11(-) K13(*) K15(/) K17(=) */
      /* */
      /* 功能描述: */
      /* 可以運算+,-,*,/等計算,運算的長度可以自行設定 */
      /* 修改 Max_disp_buff 即可。 */
      /* */
      /* http://www.mculover.net */
      /* http://www.mculover.net/bbs 湘靈電子版權所有 */
      /* */
      /* 轉載請保留以上信息,謝謝合作 ! */
      /* */
      /********************************************************************************/


      #include <reg51.h>
      #include <math.h>
      #include <stdlib.h>


      #define Lcd_Data P0 //定義數據端口
      #define TH0_TL0 (65536-5000)//設定中斷的間隔時長


      #define Max_disp_buff 10 //定義最大的顯示位數
      #define Key_con P1 //定義44鍵盤的連接口線


      sbit RS = P2 ^ 0; //定義和LCM的連接端口
      sbit RW = P2 ^ 1;
      sbit E = P2 ^ 2;
      sbit Busy = P0 ^ 7;


      unsigned char Key_value, Time_delay;
      static float left_value = 0;
      static float right_value = 0;


      //開機畫面預定義
      unsigned char code welcome[] = {"Welcome to : "};
      unsigned char code website[] = {"www.mculover.net"};
      unsigned char code designed[]= {"Designed By: "};
      unsigned char code whoami[] = {" whoami"};


      //定義數組變量
      unsigned char code keycodes[16]={'0','1','2','3','4','5','6','7','8','9','.','+','-','*','/','=',};
      unsigned char number[Max_disp_buff + 1];//定義按鍵數字的緩沖大小


      //函數聲明
      void Delay(unsigned char x);//延時處理
      void Delay_1ms(unsigned char t);//延時子程序,延時 1MS*t S
      unsigned char Read_key(void);//按鍵處理,返回按鍵的值
      unsigned char Test_key(void);//按鍵檢測函數
      void Read_Busy(void);//讀忙信號判斷
      void Write_Comm(unsigned char lcdcomm); //寫指令函數
      void Write_Data(unsigned char lcddata);//寫數據函數
      void Init_LCD_Cal(void);//初始化LCD
      void Init_LCD_Logo(void);//初始化LCD
      void Init_Timer0(void);//定時器0初始化
      void Display (char *buf); //顯示函數
      void Display_Logo(unsigned char code *DData);//顯示LOGO
      void Digit_input_calcul(void);//字符輸入
      void Fun_calculator(unsigned int fuhao);//運算函數
      void Calculator_output(float value);//輸出計算結果函數
      void Show_logo(void);//顯示開機畫面


      /******************************************************************************/
      void Delay(unsigned char x)//延時處理
      {
      Time_delay = x;


      while(Time_delay != 0);
      }


      /******************************************************************************/
      void Delay_1ms(unsigned char t)//延時子程序,延時 1MS*t S
      {
      unsigned char a;
      while(--t != 0)
      {
      for(a = 0; a < 125; a++);
      }
      }


      /******************************************************************************/
      unsigned char Read_key(void)//按鍵處理,返回按鍵的值
      {
      unsigned char j, k, s, key;


      Key_con = 0xf0;//

      if(Key_con != 0xf0)
      {
      Delay_1ms(30);//延時消抖
      if(Key_con != 0xf0)
      {
      Key_con=0xfe;
      k=0xfe;
      for(j=0;j<4;j++)
      {
      s=Key_con & 0xf0;
      switch(s)
      {
      case 0xe0: key=4*j+0; break;
      case 0xd0: key=4*j+1; break;
      case 0xb0: key=4*j+2; break;
      case 0x70: key=4*j+3; break;
      default: break;
      }
      k = (k << 1) | 0x01;
      Key_con = k;


      }//for

      Key_value = keycodes[key];
      }
      }//if

      else
      Key_value = 0x00;//如果為O, 則表示無鍵按下


      return Key_value;
      }


      /******************************************************************************/
      void Timer0_int(void) interrupt 1 using 1//定時0中斷處理
      {
      // 調整出入棧的時間,在精度不高的場合可不要!
      TR0 = 0;
      TL0 += (TH0_TL0 + 9) % 256;
      TH0 += (TH0_TL0 + 9) / 256 + (char)CY;
      TR0 = 1;


      if(Time_delay != 0)//延時函數用
      {
      Time_delay--;
      }


      Read_key();//讀取鍵盤的值
      }


      /******************************************************************************/
      unsigned char Test_key(void)//按鍵檢測函數
      {
      unsigned char mykey;


      while((mykey = Key_value) == 0x00);//等待


      return mykey;
      }


      /******************************************************************************/
      void Read_Busy(void)//讀忙信號判斷
      {
      do{
      Lcd_Data = 0xff;
      RS = 0;
      RW = 1;
      E = 0;
      Delay(2);//調用中斷延時
      E = 1;
      }while(Busy);
      }


      /******************************************************************************/
      void Write_Comm(unsigned char lcdcomm) //寫指令函數
      {
      Lcd_Data = lcdcomm;
      RS = 0;
      RW = 0;
      E = 0;
      Read_Busy();
      E = 1;
      }


      /******************************************************************************/
      void Write_Data(unsigned char lcddata)//寫數據函數
      {
      Lcd_Data = lcddata;
      RS = 1;
      RW = 0;
      E = 0;
      Read_Busy();
      E = 1;
      }


      /******************************************************************************/
      void Init_LCD_Cal(void)//初始化LCD
      {
      Delay_1ms(400); //稍微延時,等待LCM進入工作狀態
      Write_Comm(0x01);//清顯示


      Write_Comm(0x38); // 8位 2行.
      Write_Comm(0x0c); //
      Write_Comm(0x07); // 顯示模式,從左至右增加
      Write_Comm(0x80+0x10); // 定義首地址.
      }


      /******************************************************************************/
      void Init_LCD_Logo(void)//初始化LCD
      {
      Delay_1ms(400); //稍微延時,等待LCM進入工作狀態
      Write_Comm(0x01);//清顯示


      Write_Comm(0x38);//8位2行5*8
      Write_Comm(0x06);//文字不動,光標右移
      Write_Comm(0x0c);//顯示開/關,光標開閃爍開
      }


      /******************************************************************************/
      void Init_Timer0(void)//定時器0初始化
      {
      TMOD=0x01;
      TH0=TH0_TL0 / 256;
      TL0=TH0_TL0 % 256;
      TR0=1;
      ET0=1;
      EA=1;
      }


      /******************************************************************************/
      void Display(char *buf)//顯示函數
      {
      unsigned char i;

      Write_Comm(0x01);//clearscreen,清屏命令
      Write_Comm(0x80+0x10);


      for (i=0 ; buf[i] != 0; i++)
      Write_Data(buf[i]);
      }


      /******************************************************************************/
      void Display_Logo(unsigned char code *DData)//顯示LOGO
      {
      unsigned char j;

      for(j=0;j<16;j++)
      {
      Write_Data(DData[j]); //顯示單個字符
      Delay(20);
      }
      }


      /*******************************************************************************/
      void Digit_input_calcul(void)//字符輸入
      {
      static unsigned char pos;
      float tmp;


      unsigned int last_op = 0;


      Write_Data('0'); //上電顯示" 0 "
      pos = 0;//位置為0


      while(1)
      {
      Key_value = Test_key();//判斷是數字還是運算符號,具有等待功能


      if((Key_value == '.') || ((Key_value >= '0') && (Key_value <= '9')))//如果是數字或小數點
      {
      if (pos != Max_disp_buff ) //最大計算位
      {
      number[pos++] = Key_value;
      number[pos] = 0;
      Display(number);
      }
      }
      else //如果輸入的是運算符號(+,-,*,/,=)
      {


      tmp = atof(number);//atof函數就是把字符轉換成雙精度的值


      if((Key_value == '+') || (Key_value == '-') || (Key_value == '*') || (Key_value == '/'))
      {
      left_value = tmp;
      last_op = Key_value;
      }
      else if (Key_value == '=')
      {
      right_value = tmp;


      Fun_calculator(last_op);//計算
      }

      pos = 0;//從新歸位,輸入右值
      }//else
      }//for
      }


      /**********************************************************************************/
      void Fun_calculator(unsigned int fuhao)//運算函數
      {
      bit result = 1;


      switch(fuhao)
      {
      case '+': left_value += right_value;result = 1;break;
      case '-': left_value -= right_value;result = 1;break;
      case '*': left_value *= right_value;result = 1;break;
      case '/':
      if(right_value != 0)
      {
      left_value /= right_value;
      result = 1;
      }
      else
      result = 0;//出錯
      break;
      default : break;
      }


      if(result == 1)
      Calculator_output(left_value);
      else
      Display("*ERROR*");
      }


      /******************************************************************************/
      void Calculator_output(float value)//輸出計算結果函數
      {
      unsigned char buff[Max_disp_buff + 1];//定義顯示緩沖
      unsigned char p1=0, p=0;
      float divisor = 100000000;//除數
      float digit = 0;


      if(value >= 0)
      buff[p++] = ' ';
      else
      {
      buff[p++] = '-';
      value = -value;
      }


      if(value >= divisor )
      buff[p++]='E';
      else
      while((p < Max_disp_buff ) && (divisor > 1 || value >= 0.00000001))
      {
      divisor /= 10;
      digit = floor(value/divisor);//小于指定數的最小整數
      if (divisor < 1 && divisor > 0.01)
      buff[p++] = '.';
      if (digit != 0 || divisor < 10)
      {
      buff[p++] = digit + '0';
      p1 = 1;
      }
      else if (p1)
      buff[p++] = '0';
      value -= digit*divisor;
      }
      buff[p] = 0;
      Display(buff);
      }


      /******************************************************************************/
      void Show_logo(void)//顯示開機畫面
      {
      Write_Comm(0x80);//寫入"welcome to"首地址(第一行)
      Display_Logo(welcome);


      Write_Comm(0xc0);//寫入"website"首地址(第2行)
      Display_Logo(website);
      Delay(200);


      Write_Comm(0x01);//清屏


      Write_Comm(0x80);//寫入"designed "首地址(第一行)
      Display_Logo(designed);



      Write_Comm(0xc0);//寫入"whoami"首地址(第2行)
      Display_Logo(whoami);
      Delay(200);


      Write_Data(0x01);//清屏
      }


      /******************************************************************************/
      void main(void)//主函數
      {
      Init_Timer0();//初始化T0
      Init_LCD_Logo(); //初始化 Logo


      Show_logo();//開機畫面顯示

      Init_LCD_Cal(); //初始化 LCM
      Digit_input_calcul();//計算值輸入函數
      }

      1、 本站不保證以上觀點正確,就算是本站原創作品,本站也不保證內容正確。
      2、如果您擁有本文版權,并且不想在本站轉載,請書面通知本站立即刪除并且向您公開道歉! 以上可能是本站收集或者轉載的文章,本站可能沒有文章中的元件或產品,如果您需要類似的商品請 點這里查看商品列表!
      本站協議。 版權信息。 關于我們。 本站地圖。 營業執照。 發票說明。 付款方式。 聯系方式
      深圳市寶安區西鄉五壹電子商行——粵ICP備16073394號-1;地址:深圳西鄉河西四坊183號;郵編:518102
      E-mail:51dz$163.com($改為@);Tel:(0755)27947428
      工作時間:9:30-12:00和13:30-17:30和18:30-20:30,無人接聽時可以再打手機13537585389
      91嫩草黄片动漫版