📄 51
字号:
686 1 LCM_E = 0; //若晶振速度太高可以在这后加小的延时
687 1 LCM_E = 0; //延时
688 1 LCM_E = 1;
689 1 }
690 //写指令
691 void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
692 {
693 1 if (BuysC) ReadStatusLCM(); //根据需要检测忙
694 1 LCM_Data = WCLCM;
695 1 LCM_RS = 0;
696 1 LCM_RW = 0;
697 1 LCM_E = 0;
698 1 LCM_E = 0;
699 1 LCM_E = 1;
700 1 }
701 //读状态
702 unsigned char ReadStatusLCM(void)
703 {
704 1 LCM_Data = 0xFF;
705 1 LCM_RS = 0;
706 1 LCM_RW = 1;
707 1 LCM_E = 0;
708 1 LCM_E = 0;
709 1 LCM_E = 1;
710 1 while (LCM_Data & Busy); //检测忙信号
711 1 return(LCM_Data);
712 1 }
713 //LCM初始化
714 void LCMInit(void)
715 {
716 1 LCM_Data = 0;
717 1 WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
718 1 Delay5Ms();
719 1 WriteCommandLCM(0x38,0);
720 1 Delay5Ms();
721 1 WriteCommandLCM(0x38,0);
722 1 Delay5Ms();
723 1 WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
724 1 WriteCommandLCM(0x08,1); //关闭显示
725 1 WriteCommandLCM(0x01,1); //显示清屏
726 1 WriteCommandLCM(0x06,1); // 显示光标移动设置
727 1 WriteCommandLCM(0x0C,1); // 显示开及光标设置
728 1 }
729 //按指定位置显示一个字符
730 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
731 {
732 1 Y &= 0x1;
733 1 X &= 0xF; //限制X不能大于15,Y不能大于1
734 1 if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
735 1 X |= 0x80; //算出指令码
736 1 WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
737 1 WriteDataLCM(DData);
C51 COMPILER V8.02 CLOCK 07/24/2009 14:39:44 PAGE 13
738 1 }
739 //按指定位置显示一串字符 ***原来的遇到空格0x20就不显示***
740 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
741 {
742 1 unsigned char ListLength,j;
743 1 ListLength = strlen(DData);
744 1 Y &= 0x1;
745 1 X &= 0xF; //限制X不能大于15,Y不能大于1
746 1 if (X <= 0xF) //X坐标应小于0xF
747 1 {
748 2 for(j=0;j<ListLength;j++)
749 2 {
750 3 DisplayOneChar(X, Y, DData[j]); //显示单个字符
751 3 X++;
752 3 }
753 2 }
754 1 }
755 //5ms延时
756 void Delay5Ms(void)
757 {
758 1 unsigned int TempCyc = 5552;
759 1 while(TempCyc--);
760 1 }
761 //400ms延时
762 void Delay400Ms(void)
763 {
764 1 unsigned char TempCycA = 5;
765 1 unsigned int TempCycB;
766 1 while(TempCycA--)
767 1 {
768 2 TempCycB=7269;
769 2 while(TempCycB--);
770 2 };
771 1 }
772
773 //********DS1302读写程序***************
774 /********************************************************************
775 函 数 名:RTInputByte()
776 功 能:实时时钟写入一字节
777 说 明:往DS1302写入1Byte数据 (内部函数)
778 入口参数:d 写入的数据
779 返 回 值:无
780 ***********************************************************************/
781 void RTInputByte(uchar d)
782 {
783 1 uchar i;
784 1 ACC = d;
785 1 for(i=8; i>0; i--)
786 1 {
787 2 T_IO = ACC0; /*相当于汇编中的 RRC */
788 2 T_CLK = 1;
789 2 T_CLK = 0;
790 2 ACC = ACC >> 1;
791 2 }
792 1 }
793 /********************************************************************
794 函 数 名:RTOutputByte()
795 功 能:实时时钟读取一字节
796 说 明:从DS1302读取1Byte数据 (内部函数)
797 入口参数:无
798 返 回 值:ACC
799 设 计:zhaojunjie 日 期:2002-03-19
C51 COMPILER V8.02 CLOCK 07/24/2009 14:39:44 PAGE 14
800 修 改: 日 期:
801 ***********************************************************************/
802 uchar RTOutputByte(void)
803 {
804 1 uchar i;
805 1 for(i=8; i>0; i--)
806 1 {
807 2 ACC = ACC >>1; /*相当于汇编中的 RRC */
808 2 ACC7 = T_IO;
809 2 T_CLK = 1;
810 2 T_CLK = 0;
811 2 }
812 1 return(ACC);
813 1 }
814 /********************************************************************
815 函 数 名:W1302()
816 功 能:往DS1302写入数据
817 说 明:先写地址,后写命令/数据 (内部函数)
818 调 用:RTInputByte() , RTOutputByte()
819 入口参数:ucAddr: DS1302地址, ucData: 要写的数据
820 返 回 值:无
821 ***********************************************************************/
822 void W1302(uchar ucAddr, uchar ucDa)
823 {
824 1 T_RST = 0;
825 1 T_CLK = 0;
826 1 T_RST = 1;
827 1 RTInputByte(ucAddr); /* 地址,命令 */
828 1 RTInputByte(ucDa); /* 写1Byte数据*/
829 1 T_CLK = 1;
830 1 T_RST = 0;
831 1 }
832 /********************************************************************
833 函 数 名:R1302()
834 功 能:读取DS1302某地址的数据
835 说 明:先写地址,后读命令/数据 (内部函数)
836 调 用:RTInputByte() , RTOutputByte()
837 入口参数:ucAddr: DS1302地址
838 返 回 值:ucData :读取的数据
839 ***********************************************************************/
840 uchar R1302(uchar ucAddr)
841 {
842 1 uchar ucData;
843 1 T_RST = 0;
844 1 T_CLK = 0;
845 1 T_RST = 1;
846 1 RTInputByte(ucAddr); /* 地址,命令 */
847 1 ucData = RTOutputByte(); /* 读1Byte数据 */
848 1 T_CLK = 1;
849 1 T_RST = 0;
850 1 return(ucData);
851 1 }
852
853 /********************************************************************
854 函 数 名:Set1302()
855 功 能:设置初始时间
856 说 明:先写地址,后读命令/数据(寄存器多字节方式)
857 调 用:W1302()
858 入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
859 7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
860 返 回 值:无
861 ***********************************************************************/
C51 COMPILER V8.02 CLOCK 07/24/2009 14:39:44 PAGE 15
862 void Set1302(uchar *pClock)
863 {
864 1 uchar i;
865 1 uchar ucAddr = 0x80;
866 1 W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
867 1 for(i =7; i>0; i--)
868 1 {
869 2 W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */
870 2 pClock++;
871 2 ucAddr +=2;
872 2 }
873 1 W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/
874 1 }
875
876 //*********** 18B20驱动 **************************
877 //延时
878 void delay(unsigned int num)
879 {
880 1 while( --num ) ;
881 1 }
882
883 //复位
884 byte ow_reset(void)
885 {
886 1 byte presence;
887 1 DQ = 0; //拉低总线
888 1 delay(29); // 保持 480us
889 1 DQ = 1; // 释放总线
890 1 delay(3); // 等待回复
891 1 presence = DQ; // 读取信号
892 1 delay(25); // 等待结束信号
893 1 return(presence); // 返回 0:正常 1:不存在
894 1 }
895
896 //从 1-wire 总线上读取一个字节
897 byte read_byte(void)
898 {
899 1 byte i;
900 1 byte value = 0;
901 1 for (i=8;i>0;i--)
902 1 {
903 2 value>>=1;
904 2 DQ = 0;
905 2 DQ = 1;
906 2 delay(1);
907 2 if(DQ)value|=0x80;
908 2 delay(6);
909 2 }
910 1 return(value);
911 1 }
912
913 //向 1-WIRE 总线上写一个字节
914 void write_byte(char val)
915 {
916 1 byte i;
917 1 for (i=8; i>0; i--) // 一次写一位
918 1 {
919 2 DQ = 0; //
920 2 DQ = val&0x01;
921 2 delay(5); //
922 2 DQ = 1;
923 2 val=val/2;
C51 COMPILER V8.02 CLOCK 07/24/2009 14:39:44 PAGE 16
924 2 }
925 1 delay(5);
926 1 }
927
928 //读取和显示温度
929 Read_Temperature(char xx,char yy)
930 {
931 1 unsigned char i,tl_temp;
932 1 unsigned int x;
933 1 unsigned char ct[8];
934 1 union{byte c[2]; int x;}temp;
935 1
936 1 ow_reset();
937 1 write_byte(0xCC); // Skip ROM
938 1 write_byte(0x44); // 转换温度
939 1 ow_reset();
940 1 write_byte(0xCC); //Skip ROM
941 1 write_byte(0xbe); // 读取寄存器
942 1 temp.c[1]=read_byte();//读出温度低8位
943 1 temp.c[0]=read_byte();//读出温度高8位
944 1
945 1 // 零下温度判断
946 1 sflag=0; //温度零下标志 0:零上,1:零下
947 1 if((temp.c[0]&0xf8)!=0x00)
948 1 {
949 2 sflag=1; //零下标志位置1
950 2 temp.c[1]=~temp.c[1]; //低8位取反
951 2 temp.c[0]=~temp.c[0]; //高8位取反
952 2 tl_temp=temp.c[1]+1; //低8位加1
953 2 temp.c[1]=tl_temp; //计算后重新存入数组
954 2 if(tl_temp>255) temp.c[0]++; //如果低8位大于255,向高8位进1
955 2 }
956 1
957 1 x=((temp.c[0]&0x07)*256+temp.c[1])*.625;
958 1 for(i=0;i<8;i++)
959 1 {
960 2 ct[i]=0;
961 2 }
962 1 i=0;
963 1 while(x/10)
964 1 {
965 2 ct[i]=x%10;
966 2 x=x/10;
967 2 i++;
968 2 }
969 1 ct[i]=x;
970 1
971 1 if(sflag==1) DisplayOneChar(xx-1,yy,0x2d);
972 1 else DisplayOneChar(xx-1,yy,0x20);
973 1 DisplayOneChar(xx, yy,ct[2]+0x30);//显示温度十位数
974 1 DisplayOneChar(xx+1,yy,ct[1]+0x30);//显示温度个位数
975 1 DisplayOneChar(xx+2,yy,0x2e);//显示小数点
976 1 DisplayOneChar(xx+3,yy,ct[0]+0x30);//显示温度小数位
977 1 DisplayOneChar(xx+4,yy,0x01);//显示自定义字符
978 1 DisplayOneChar(xx+5,yy,0x43);//显示字符“C
979 1 }
980
981 //温度分辨率调整
982 void adjust_res(char res) ///res 分别等于 0x1f, 0x3f, 0x5f 温度读数分辨率分别对应
983 // 0.5, 0.25, 0.125
984 {
985 1 ow_reset(); //复位
C51 COMPILER V8.02 CLOCK 07/24/2009 14:39:44 PAGE 17
986 1 write_byte(0xcc); //跳过Rom
987 1 write_byte(0x4e); //写暂存器
988 1 write_byte(0x02); //写TH
989 1 write_byte(0x01); //写TL
990 1 //write_byte(0x5f); //写结构寄存器
991 1 write_byte(res);
992 1 ow_reset(); //复位
993 1 write_byte(0xcc); //跳过Rom
994 1 write_byte(0x48); //把暂存器内容写到EPRam中
995 1 }
996
997 void mychar()//自定义字符
998 {
999 1 ///////////////////////自定义字符
1000 1 WriteCommandLCM(0x48, 0); //第一行
1001 1 WriteDataLCM(0x02);
1002 1 WriteCommandLCM(0x49, 0); //第2行
1003 1 WriteDataLCM(0x05);
1004 1 WriteCommandLCM(0x4a, 0); //第3
1005 1 WriteDataLCM(0x05);
1006 1 WriteCommandLCM(0x4b, 0); //第4
1007 1 WriteDataLCM(0x02);
1008 1 WriteCommandLCM(0x4c, 0); //第5
1009 1 WriteDataLCM(0x00);
1010 1 WriteCommandLCM(0x4d, 0); //第6
1011 1 WriteDataLCM(0x00);
1012 1 WriteCommandLCM(0x4e, 0); //第7
1013 1 WriteDataLCM(0x00);
1014 1 WriteCommandLCM(0x4f, 0); //第8
1015 1 WriteDataLCM(0x00);
1016 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 2805 ----
CONSTANT SIZE = 6 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 13 39
IDATA SIZE = ---- ----
BIT SIZE = 16 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -