找回密码
 注册
关于网站域名变更的通知
查看: 712|回复: 2
打印 上一主题 下一主题

51单片机的红外计算器程序源码

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-10-22 10:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 Taio 于 2018-10-22 18:26 编辑 5 W+ Y2 Q$ V( L0 L5 {6 P8 c7 a+ r/ a; M
' v' z5 W, A* ^! `
lcd1602和单片机接口自己在程序中看9 [& X/ S& b% y; B2 ~3 G! v
单片机源程序如下:2 b+ O- _. Z7 q3 ~' @
  • #include<reg52.h>    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  • #include<intrins.h>
  • sbit RS = P1^7;   //定义端口
  • sbit RW = P1^6;
  • sbit EN = P1^5;
  • sbit datk=P1^2;
  • sbit rest=P1^3;
  • sbit IR=P3^2;//中断0,红外接口                                                                                                                                                                                                                                                                                     //红外接口标志
  • #define RS_CLR RS=0          //选择指令寄存器
  • #define RS_SET RS=1          //选择数据寄存器
  • #define RW_CLR RW=0          //把单片机数据写入lcd
  • #define RW_SET RW=1          // 把lcm的数据读出到单片机
  • #define EN_CLR EN=0          // 允许对lcm进行读写操作
  • #define EN_SET EN=1          // 禁止对lcm进行读写操作
  • #define DataPort P2 //定义数据端口 程序中遇到DataPort 则用P2 替换
  • /*------------------------------------------------
  •                 全局变量声明
  • ------------------------------------------------*/
  • unsigned int p=0,flag1,qingchu;
  • static int a; //静态变量a
  • unsigned char table1[4];
  • unsigned char  irtime;//红外用全局变量
  • bit irpro_ok,irok;
  • unsigned char IRcord[4];     //四组数据,
  • unsigned char irdata[33];        //前导码加32位数据
  • unsigned char dat[] ={'0','1','2','3','4','5','6','7','8','9'};
  • /*------------------------------------------------
  •                   函数声明
  • ------------------------------------------------*/
  • void Ir_work(void);          //红外键值散转函数
  • void Ircordpro(void);  //红外码值处理
  • void Delay10ms();                //延时函数
  • void delay1ms(void);           //延时函数
  • void music(z);                        //语音函数
  • /*------------------------------------------------
  • uS延时函数,含有输入参数 unsigned char t,无返回值
  • unsigned char 是定义无符号字符变量,其值的范围是
  • 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  • 长度如下 T=tx2+5 uS
  • ------------------------------------------------*/
  • void DelayUs2x(unsigned char t)
  • {
  • while(--t);
  • }
  • /*------------------------------------------------
  • mS延时函数,含有输入参数 unsigned char t,无返回值
  • unsigned char 是定义无符号字符变量,其值的范围是
  • 0~255 这里使用晶振12M,精确延时请使用汇编
  • ------------------------------------------------*/
  • void DelayMs(unsigned char t)
  • {
  • while(t--)
  • {
  •      //大致延时1mS
  •      DelayUs2x(245);
  •          DelayUs2x(245);
  • }
  • }
  • /*------------------------------------------------
  •               判忙函数
  • ------------------------------------------------*/
  • bit LCD_Check_Busy(void)
  • {
  • DataPort= 0xFF;
  • RS_CLR;     //选择指令寄存器
  • RW_SET;         //把lcm的数据读出到单片机
  • EN_CLR;         //禁止对lcm进行读写操作
  • _nop_();
  • EN_SET;
  • return (bit)(DataPort & 0x80);
  • }
  • /*------------------------------------------------
  •               写入命令函数
  • ------------------------------------------------*/
  • void LCD_Write_Com(unsigned char com)
  • {
  • while(LCD_Check_Busy()); //忙则等待
  • RS_CLR;
  • RW_CLR;
  • EN_SET;
  • DataPort= com;
  • _nop_();
  • EN_CLR;
  • }
  • /*------------------------------------------------
  •               写入数据函数
  • ------------------------------------------------*/
  • void LCD_Write_Data(unsigned char Data)
  • {
  • while(LCD_Check_Busy()); //忙则等待
  • RS_SET;
  • RW_CLR;
  • EN_SET;
  • DataPort= Data;
  • _nop_();
  • EN_CLR;
  • }
  • /*------------------------------------------------
  •                 清屏函数
  • ------------------------------------------------*/
  • void LCD_Clear(void)
  • {
  • LCD_Write_Com(0x01);
  • DelayMs(5);
  • }
  • /*------------------------------------------------
  •               初始化函数
  • ------------------------------------------------*/
  • void LCD_Init(void)
  • {
  •    LCD_Write_Com(0x38);    /*显示模式设置*/
  •    DelayMs(5);
  •    LCD_Write_Com(0x38);
  •    DelayMs(5);
  •    LCD_Write_Com(0x38);
  •    DelayMs(5);
  •    LCD_Write_Com(0x38);
  •    LCD_Write_Com(0x08);    /*显示关闭*/
  •    LCD_Write_Com(0x01);    /*显示清屏*/
  •    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  •    DelayMs(5);
  •    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  •    }
  • /*------------------------------------------------
  •                   定时器0中断处理
  • ------------------------------------------------*/
  • void tim0_isr (void) interrupt 1 using 1
  • {
  •   irtime++;  //用于计数2个下降沿之间的时间
  • }
  • /*------------------------------------------------
  •                   外部中断0中断处理
  • ------------------------------------------------*/
  • void EX0_ISR (void) interrupt 0 //外部中断0服务函数
  • {
  •   static unsigned char  i;             //接收红外信号处理
  •   static bit startflag;                //是否开始处理标志位
  • if(startflag)
  •    {
  •     if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
  •                         i=0;
  •                     irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
  •                     irtime=0;
  •                  i++;
  •                             if(i==33)
  •                               {
  •                                    irok=1;
  •                                  i=0;
  •                                   }
  •           }
  •            else
  •                 {
  •                 irtime=0;
  •                 startflag=1;
  •                 }
  • }
  • void music(int z)
  • {
  • rest=1;
  • delay1ms();
  • delay1ms();
  • rest=0;
  • delay1ms();
  • delay1ms();
  •             //前面给语音复位,详情看语音资料
  • while(z>0) //给b 个脉冲让语音播放b段语音
  • {
  • datk=1;
  • delay1ms();
  • datk=0;
  • delay1ms();
  • z--;
  • }         }
  • //************************************************************
  • void delay1ms()
  • {
  •          unsigned char iii, jjj;
  •         _nop_();
  •         iii = 2;
  •         jjj = 199;
  •         do
  •         {
  •                 while (--jjj);
  •         } while (--iii);
  • }
  • void delay(void)   //误差 -0.000000000227us
  • {
  •     unsigned char a,b,c;
  •     for(c=13;c>0;c--)
  •         for(b=247;b>0;b--)
  •             for(a=142;a>0;a--);
  •     _nop_;  //if Keil,require use intrins.h
  • }
  • /*------------------------------------------------
  •                 定时器0初始化
  • ------------------------------------------------*/
  • void TIM0init(void)//定时器0初始化
  • {
  •   TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  •   TH0=0x00; //重载值
  •   TL0=0x00; //初始化值
  •   ET0=1;    //开中断
  •   TR0=1;
  • }
  • /*------------------------------------------------
  •                   外部中断0初始化
  • ------------------------------------------------*/
  • void EX0init(void)
  • {
  • IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  • EX0 = 1;   //使能外部中断
  • EA = 1;    //开总中断
  • }
  • /*------------------------------------------------
  •                   键值处理
  • ------------------------------------------------*/
  • int display(int j)
  • {
  •         int k;
  •         switch(j)//判断第三个数码值
  •                  {
  •                          case 0x16CD_Write_Com(0x80+a);LCD_Write_Data('0');k=0; a++; break;//0
  •                          case 0x0cCD_Write_Com(0x80+a);LCD_Write_Data('1');k=1; a++; break;//1 显示相应的按键值
  •                          case 0x18CD_Write_Com(0x80+a);LCD_Write_Data('2');k=2; a++;break;//2
  •                          case 0x5e:LCD_Write_Com(0x80+a);LCD_Write_Data('3');k=3; a++;break;//3
  •                          case 0x08:LCD_Write_Com(0x80+a);LCD_Write_Data('4');k=4; a++;break;//4
  •                          case 0x1c:LCD_Write_Com(0x80+a);LCD_Write_Data('5');k=5; a++;break;//5
  •                          case 0x5a:LCD_Write_Com(0x80+a);LCD_Write_Data('6');k=6; a++;break;//6 显示相应的按键值
  •                          case 0x42:LCD_Write_Com(0x80+a);LCD_Write_Data('7');k=7; a++;break;//7
  •                          case 0x52:LCD_Write_Com(0x80+a);LCD_Write_Data('8');k=8; a++;break;//8
  •                          case 0x4a:LCD_Write_Com(0x80+a);LCD_Write_Data('9');k=9; a++;break;//9
  •            }
  •         return k;
  • }
  • void Ir_work(void)//红外键值散转程序
  • {
  •          int k=0,flag1,count1,count2,count3,count4;
  •          int table1[6];
  •          int count;
  •          if(IRcord[2]!=0x09&&IRcord[2]!=0x44&&IRcord[2]!=0x15&&IRcord[2]!=0x40&&IRcord[2]!=0x43&&IRcord[2]!=0x07)
  •          {
  •          k=display(IRcord[2]);
  •          table1[p++]=k;
  •          }
  •         else  if(IRcord[2]==0x09||IRcord[2]==0x44||IRcord[2]==0x15||IRcord[2]==0x40)
  •          {
  •                  switch(IRcord[2])
  •                 {
  •                           case 0x09:LCD_Write_Com(0x80+a);LCD_Write_Data('+');flag1=1;a++;break;//+
  •                          case 0x15:LCD_Write_Com(0x80+a);LCD_Write_Data('-');flag1=2;a++;break;//-显示相应的按键值
  •                          case 0x44:LCD_Write_Com(0x80+a);LCD_Write_Data('*');flag1=3;a++;break;//*
  •                          case 0x40:LCD_Write_Com(0x80+a);LCD_Write_Data('/');flag1=4;a++;break;///
  •                         //case  0x10:
  •                 }
  •          }
  •         else if(IRcord[2]==0x07)
  •          {
  •                          LCD_Write_Com(0x80+a);
  •                         LCD_Write_Data('=');
  •                          switch(flag1)
  •                         {
  •                                 case 1:        count=table1[0]*10+table1[1]+table1[2]*10+table1[3];
  •                                 if(count<100)
  •                                 {
  •                                         count1=count/10;
  •                                         count2=count%10;
  •                                         LCD_Write_Com(0x80+a+1);
  •                                         LCD_Write_Data(dat[count1]);
  •                                         LCD_Write_Com(0x80+a+2);
  •                                         LCD_Write_Data(dat[count2]);
  •                                         delay();
  •                                         music(count1+1);
  •                                         delay();
  •                                 music(count2+1);
  •                                         delay();
  •                                 }
  •                                 else if(count>=100)
  •                                 {
  •                                         count1=count/100;         LCD_Write_Com(0x80+a+1);LCD_Write_Data(dat[count1]);
  •                                         count2=count/10%10;         LCD_Write_Com(0x80+a+2);LCD_Write_Data(dat[count2]);
  •                                         count3=count%10;         LCD_Write_Com(0x80+a+3);LCD_Write_Data(dat[count3]);
  •                                         delay();
  •                                         music(count1+1);
  •                                         delay();
  •                                         music(count2+1);
  •                                         delay();
  •                                         music(count3+1);
  •                                         delay();
  •                                 }
  •                                                                 break;
  •                                 case 2:          count=table1[0]*10+table1[1]-(table1[2]*10+table1[3]);
  •                                                 count1=count/10;           LCD_Write_Com(0x80+a+1);LCD_Write_Data(dat[count1]);
  •                                                 count2=count%10;        LCD_Write_Com(0x80+a+2); LCD_Write_Data(dat[count2]);
  •                                                 music(count1+1);
  •                                            delay();
  •                                            music(count2+1);
  •                                            delay();
  •                                                 break;
  •                                 case 3:count=(table1[0]*10+table1[1])*(table1[2]*10+table1[3]);
  •                                         if(count<10) { LCD_Write_Com(0x80+a+1);LCD_Write_Data(dat[count]);}
  •                                         else if(count<100)
  •                                         {
  •                                                 count1=count/10;  LCD_Write_Com(0x80+a+1);        LCD_Write_Data(dat[count1]);
  •                                                 count2=count%10;   LCD_Write_Com(0x80+a+2);        LCD_Write_Data(dat[count2]);
  •                                             delay();
  •                                                 music(count1+1);
  •                                             delay();
  •                                                 music(count2+1);
  •                                             delay();
  •                                         }
  •                                         else if(count<1000)
  •                                         {
  •                                                 count1=count/100;        LCD_Write_Com(0x80+a+1);        LCD_Write_Data(dat[count1]);
  •                                                 count2=count/10%10;          LCD_Write_Com(0x80+a+2);        LCD_Write_Data(dat[count2]);
  •                                                 count3=count%10;          LCD_Write_Com(0x80+a+3);        LCD_Write_Data(dat[count3]);
  •                                                 delay();
  •                                                 music(count1+1);
  •                                             delay();
  •                                                 music(count2+1);
  •                                             delay();
  •                                                 music(count3+1);
  •                                             delay();
  •                                         }
  •                                         else   if(count<10000)
  •                                          {
  •                                                   count1=count/1000;                   LCD_Write_Com(0x80+a+1);        LCD_Write_Data(dat[count1]);
  •                                                 count2=count/100%10;          LCD_Write_Com(0x80+a+2);        LCD_Write_Data(dat[count2]);
  •                                                 count3=count/10%10;                   LCD_Write_Com(0x80+a+3);        LCD_Write_Data(dat[count3]);
  •                                                 count4=count%10;                 LCD_Write_Com(0x80+a+4);        LCD_Write_Data(dat[count4]);
  •                                             delay();
  •                                                 music(count1+1);
  •                                             delay();
  •                                                 music(count2+1);
  •                                             delay();
  •                                                 music(count3+1);
  •                                             delay();
  •                                             music(count4+1);
  •                                             delay();
  •                                          }
  •                                                         break;
  •                                 case 4:                count=(table1[0]*10+table1[1])/(table1[2]*10+table1[3]);
  •                                  if(count<10)
  •                                                 {
  •                                                   LCD_Write_Com(0x80+a+1);LCD_Write_Data('0');        //LCD_Write_Data(dat[count]);
  •                                                   LCD_Write_Com(0x80+a+2);LCD_Write_Data(dat[count]);
  •                                                   delay();
  •                                                   music(1);
  •                                               delay();
  •                                                   music(count+1);
  •                                               delay();
  •                                                 }
  •                                                 else
  •                                                 {
  •                                                         count1=count/10;  LCD_Write_Com(0x80+a+1);        LCD_Write_Data(dat[count1]);
  •                                                         count2=count%10;  LCD_Write_Com(0x80+a+2);        LCD_Write_Data(dat[count2]);
  •                                                         delay();
  •                                                     music(count1+1);
  •                                                 delay();
  •                                                     music(count2+1);
  •                                                 delay();
  •                                                 }
  •                                                 break;
  •                         }
  •                         flag1=0;
  •          }
  •          else
  •          {
  •          if(IRcord[2]==0x43)
  •          {
  •                 LCD_Write_Com(0x01);
  •          qingchu=1;
  •          }
  • }
  • }
  • /*------------------------------------------------
  •                 红外码值处理
  • ------------------------------------------------*/
  • void Ircordpro(void)//红外码值处理函数
  • {
  •   unsigned char i, j, k;
  •   unsigned char cord,value;
  •   k=1;
  •   for(i=0;i<4;i++)      //处理4个字节
  •      {
  •       for(j=1;j<=8;j++) //处理1个字节8位
  •          {
  •           cord=irdata[k];
  •           if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
  •              value|=0x80;
  •           if(j<8)
  •                     {
  •                          value>>=1;
  •                         }
  •            k++;
  •          }
  •      IRcord=value;
  •      value=0;
  •      }
  •          irpro_ok=1;//处理完毕标志位置1
  • }
  • /*------------------------------------------------
  •                     主函数
  • ------------------------------------------------*/
  • void main(void)
  • {
  • int m;
  • EX0init(); //初始化外部中断
  • TIM0init();//初始化定时器
  • LCD_Init();
  • LCD_Clear();//清??
  • while(1)//主循环
  •    {
  •     while(irok==0);                        //如果接收好了进行红外处理
  •                  irok=0 ;
  •            Ircordpro();
  •           while(irpro_ok==0);                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
  •                    irpro_ok=0;
  •            Ir_work();
  •            if(qingchu==1)
  •            {
  •                            qingchu=0;
  •                         a=0;
  •                  LCD_Write_Com(0x01);
  •                  LCD_Write_Com(0x80);
  •                         p=0;
  •                  for(m=0;m<6;m++)
  •                          table1[m]=0;
  •            }
  •         }
  •         }

  • & Y4 Q- c' i: P
- R& O* U* w9 P$ p! e
游客,如果您要查看本帖隐藏内容请回复

# p3 W: W! R5 B* s3 W8 s

该用户从未签到

2#
发表于 2018-10-22 18:23 | 只看该作者
  谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-6-7 13:43 , Processed in 0.109375 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表