lcd1602和单片机接口自己在程序中看
单片机源程序如下:
- #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[i]=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 0x16:LCD_Write_Com(0x80+a);LCD_Write_Data('0');k=0; a++; break;//0
- case 0x0c:LCD_Write_Com(0x80+a);LCD_Write_Data('1');k=1; a++; break;//1 显示相应的按键值
- case 0x18:LCD_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[i]=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;
- }
- }
- }
-
复制代码
所有资料51hei提供下载:
程序.zip
(48.59 KB, 下载次数: 20)
|