#include
__CONFIG (0x20F1); __CONFIG (0x3FFF); //调试用
#define LCD_E RD6 //LCD E 读写使能控制 #define LCD_RW RD5 //LCD 读(1)/写(0)控制线
#define LCD_RS RD4 //LCD 寄存器选择 数据(1)指令(0) //RD4-RD7分别接DB4-DB7,RD7为忙标志 #define COM 0 //在LCD_WRITE()中的第2参数为0表示写命令 #define DAT 1 //在LCD_WRITE()中的第2参数为1表示写数据
#define mod RB3//模式选择(时间、闹钟、温度、秒表) #define set RB0//选择按键 #define add RB1//加按键 #define miu RB2//减按键
#define RTR 0b00000000 //TC74的读温度命令 #define TC74_ADD 0b1001101 //TC74的7位地址
#define LINE1 0b10000000 #define LINE2 0b11000000
signed char hourt,mint,sect;//闹钟设置位 int f;//闹钟显示清零判断 char flag=0;//按键标志位
char WW,QW,BW,SW,GW,M;
char table[]=\星期 signed char year,month,day,week,hour,min,sec,a,T;
bank1 char DD[16]; //一行LCD显示数据暂存 char A[7];//DS1307读数
//====LCD程序 void CSH(void); //初始化 void LCD_CSH(void); //LCD初始化 void LCD_BUSY(void); //检测LCD是否忙 char LCD_READ(void); //读LCD,忙检测用 void LCD_WRITE(char,char); //LCD写1字节,命令或数据 void LCD_WRITE_4(char,char); //LCD写半字节 void DISP_C(char); //在指定行中显示字符,字符在数组DD中 void DISP_MENU(const char *); //由常数数组显示整屏字符
void DELAY_US(char); void DELAY(unsigned int); void delaynms(unsigned int);
//===DS1307
void IIC_SEND(char); void IIC_CSH(void);
void READ_DS1307(char addr,char n); void write_DS1307(char addr,char data); void DS1307_CSH(void);//DS1307初始化 void MENU_DS1307(void);
//==温度
void DISP_T(signed char R1); //温度在R1
signed char READ_T(void);
void clock();//闹钟
void set_time(void);//按键
void bcd_dec(char adr,char R); char dec_bcd(char dec); void BCD(unsigned int R1);
void guangbiao(void);//光标
//========主程序 void main() { CSH(); READ_DS1307(0,7);//读DS1307 if(A[0]&0x80) DS1307_CSH();//判断是否初始化 while(1) { clock(); set_time();//按键检测 delaynms(50); if(flag==0) { READ_DS1307(0,7);//读DS1307
MENU_DS1307();//显示DS1307 T=READ_T();//读温度 DISP_T(T);//显示温度 } } }
//========初始化端口 void CSH(void) { TRISD=0b00000000; //控制LCD1604,全为输出 RD7=1; //背光 TRISB=0x0FF; RBPU=0;
WPUB=0x0FF; ANSELH=0; PORTB=0x00; //===PWM设置 TRISC1=0; //RC1为输出 RC1=0; PR2=124; //周期为1ms CCPR2L=0x32; CCP2CON=0b00000000;//关闭PWM T2CON=0b00000110; //TMR2预分频1:16,开始工 IIC_CSH(); LCD_CSH(); }
//LCD模块初始化 void LCD_CSH(void) { DELAY(20); //延时20ms LCD_WRITE_4(0b0011,COM); //发送控制序列 DELAY_US(10); //延时100us LCD_WRITE_4(0b0011,COM); //发送控制序列 DELAY_US(10); //延时100us LCD_WRITE_4(0b0011,COM); //发送控制序列 DELAY_US(10); //延时100us LCD_WRITE_4(0b0010,COM); //4位数据格式 LCD_BUSY(); //LCD忙检测 LCD_WRITE(0b00101000,COM); //4位数据格式,2行,5×7点阵
LCD_WRITE(0b00001100,COM); //D(d2)=1:打开显示,C(d1)=1:光标打开,B(d0)=1:光标不闪烁 LCD_WRITE(0b00000001,COM); //清除显示 DELAY(2); //延时2ms LCD_WRITE(0b00000110,COM); //输入模式,I/D(d1)=1:地址加1,S(d0)=1:显示移位关闭 }
//========读LCD状态 char LCD_READ(void) { unsigned char R1; TRISD|=0X0F; //LCD数据线为输入 LCD_RS=0; //寄存器选择 LCD_RW=1;NOP(); //读为1 LCD_E=1;NOP(); //使能 R1=0; //短延时 R1=(PORTD<<4 )& 0xF0; //读数据的高4位给R1高四位 LCD_E=0;NOP(); //读数据结束 LCD_E=1;NOP(); //使能 R1 |= (PORTD & 0x0F); //读PORTD的低4位,R1的高4位不变! LCD_E=0;NOP(); //读数据结束 LCD_RW=0; return (R1); }
//写一字节数R1,FLAG为写命令或数据选择,0为写命令,1为写数据 //写之前先检查是否忙,写完后延时100us,分二次写4位数据/命令 void LCD_WRITE(char R1,char FLAG) { char R2; TRISD&=0XF0; LCD_BUSY(); R2=R1 & 0xF0; //低4位清0 R2=R2>>4; //取高4位 LCD_WRITE_4(R2,FLAG); //先写高4位 R2=(R1 & 0x0F); //高4位清0,取低4位 LCD_WRITE_4(R2,FLAG); //再送低4位 DELAY_US(10); //延时100us }
//写R1的低4位,FLAG为寄存器选择,1为命令,0为数据 void LCD_WRITE_4(char R1,char FLAG) { TRISD&=0XF0; LCD_RW=0;NOP(); //写模式 LCD_RS=FLAG;NOP(); //寄存器选择
PORTD &= 0xF0;NOP(); //RD低4位先清0 LCD_E=1;NOP(); //使能 R1=(R1&0x0F); //R1低4位送至低4位 PORTD |=R1;NOP(); //送4位 LCD_E=0;NOP(); //数据送入有效,下降沿送入 LCD_RS=0;NOP(); PORTD &= 0xF0; //RD低4位清0 }
//========检测LCD是否忙 void LCD_BUSY(void) { unsigned char R1; while(1) { R1=LCD_READ(); //读寄存器 if ((R1 & 0x80)==0x00) //最高位为忙标志位 break; }; }
//======延时(n)ms
void DELAY(unsigned int n) { unsigned int j; char k; for (j=0;j
//======延时(n)ms
void delaynms(unsigned int n) { unsigned int j; char k; for (j=0;j
//======延时(n×10)us void DELAY_US(char n) { char j; for (j=0;j