长汀无线电厂交流论坛

 找回密码
 注册
查看: 6095|回复: 20
打印 上一主题 下一主题

CT_3位LCD屏+2051+实时时钟

  [复制链接]
楼主
发表于 2011-3-22 20:53:41 | 显示全部楼层
/*
3位LCD字段屏显示时钟,
原程序不全,我把它弄好了,还加了声音、减、背光控制,大家看看还有什么需要的
*/
#include <REG52.H>

sbit           LCD_DATA = P0^0;//=14-2051,14脚
sbit        LCD_CLK = P0^1;//=15
sbit        LCD_CS1 = P0^2;//=16

sbit         clock_clk=P1^4;//=8
sbit         clock_dat=P1^5;//=6
sbit         clock_rst=P2^2;//=7

sbit         ks5=P1^0;//=2  设置位
sbit         ks4=P1^1;//=3  加
sbit         ks3=P1^2;//=3  减
sbit         ks2=P1^3;//=3  背光

sbit    beep=P2^7;//=声音

bit bg=0;
//bit         keyshi=1;//zhishi=9         没有意义
//bit         keyfen=1;//=11

sbit a0 = ACC ^ 0;//为了编程方便定义的位变量
sbit a1 = ACC ^ 1;
sbit a2 = ACC ^ 2;
sbit a3 = ACC ^ 3;
sbit a4 = ACC ^ 4;
sbit a5 = ACC ^ 5;
sbit a6 = ACC ^ 6;
sbit a7 = ACC ^ 7;
unsigned char code digi[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x58,0x5e,0x79,0x71,0x76,0x37,0x6b,0x6e,0x48,0x40};
//0,   1,         2,         3,          4,   5,   6,   7,   8,   9,   A,   b,   c,   d,   E,   F,   H,   17,  18,  y,   20   -
unsigned char lcd_data[3],dat,set,d,e,t;   

void dealy(unsigned int dealy_time)   //延时子程序
{
        for(;dealy_time>0;dealy_time--)
        {}
}

void Beep()//BELL-扬声器--开机
{
        unsigned char a;//定义变量用于发声的长度设置
//        Led_EA = 1;//关列显示驱动,防止屏幕出现乱码
        for(a=60;a>0;a--)//第一个声音的长度
        {
                beep = ~beep;//取反扬声器驱动口,以产生音频
                dealy(100);//音调设置延时
        }
        for(a=100;a>0;a--)//同上
        {
                beep = ~beep;
                dealy(80);//
        }
        for(a=100;a>0;a--)//同上
        {
                beep = ~beep;
                dealy(30);//
        }
}
//---------------------------------------------------       
void Beep_set()        //BELL -扬声器--按键
{
        unsigned char a;//定义变量用于发声的长度设置
//        Led_EA = 1;//关列显示驱动,防止屏幕出现乱码
        for(a=250;a>0;a--)//第一个声音的长度
        {
                beep = ~beep;//取反扬声器驱动口,以产生音频
                dealy(20);//音调设置延时
        }
        for(a=100;a>0;a--)//同上
        {
                beep = ~beep;
                dealy(80);//
        }
}       

void delay_ms(unsigned int a)                       
{
        unsigned char i;
        while( --a != 0)
        {               
                for(i = 0; i < 100; i++);         
        }                                   
}

void LCD_init(void)
{
        LCD_CS1=0;
        LCD_DATA=0;
        LCD_CLK=0;
        LCD_CS1=1;
        delay_ms(100);
        LCD_CLK=1;
}

void LCD_write_char(unsigned char dat)
{      
        unsigned char i;
        for(i=8;i>0;i--)
        {
                LCD_DATA=0;
                if (dat&0x01)  LCD_DATA=1;
                LCD_CLK=0;
                delay_ms(3);
                LCD_CLK=1;
                delay_ms(3);        
                dat=dat >> 1;   
        }
}
/*
void LCD_on()
{
        LCD_CS1=0;
        LCD_write_char(0x05);    // 背光on  0x05 开
        LCD_CS1=1;
        delay_ms(3);
}

void LCD_off()
{
        LCD_CS1=0;
        LCD_write_char(0x01);    // 背光off         0x04 关
        LCD_CS1=1;
        delay_ms(3);
}
*/
/**************读出一个字节,时序***************/
unsigned char clock_read()   //读出一个字节,时序
{
        clock_clk=1; clock_clk=0; a0=clock_dat;
        clock_clk=1; clock_clk=0; a1=clock_dat;
        clock_clk=1; clock_clk=0; a2=clock_dat;
        clock_clk=1; clock_clk=0; a3=clock_dat;
        clock_clk=1; clock_clk=0; a4=clock_dat;
        clock_clk=1; clock_clk=0; a5=clock_dat;
        clock_clk=1; clock_clk=0; a6=clock_dat;
        clock_clk=1; clock_clk=0; a7=clock_dat;
        return(ACC);
}
/****************************************************
ds1302程序
写入一个字节,
****************************************************/
void clock_write(unsigned char dd)   //写入一个字节,DS1302时序
{
        ACC=dd;
        clock_clk=0 ;clock_dat=a0; clock_clk=1;
        clock_clk=0 ;clock_dat=a1; clock_clk=1;
        clock_clk=0 ;clock_dat=a2; clock_clk=1;
        clock_clk=0 ;clock_dat=a3; clock_clk=1;
        clock_clk=0 ;clock_dat=a4; clock_clk=1;
        clock_clk=0 ;clock_dat=a5; clock_clk=1;
        clock_clk=0 ;clock_dat=a6; clock_clk=1;
        clock_clk=0 ;clock_dat=a7; clock_clk=1;
}
/******************** 向reg2写入date数据  向指定地址写数据 */
void write_clock(unsigned char reg2, unsigned char date)//向reg2写入date数据
{
        clock_clk=0;
        clock_rst=0;
        clock_rst=1;
        clock_write(reg2);
        clock_write(date);
        clock_rst=0;
}
/****从reg1寄存器读数据*     从指定地址读数据 **/
unsigned char read_clock(unsigned char reg1)//从reg1寄存器读数据 ///read_clock        从指定地址读数据           write_clock 向指定地址写数据
{
        unsigned char dd=0;
        clock_clk=0;
        clock_rst=0;
        clock_rst=1;
        clock_write(reg1);
        dd=clock_read();
        clock_rst=0;
        return(dd);
}
/*显示1*/
void display_lcd1(unsigned char num)        //显示 小时        数据拆分
{
        unsigned char i;
        lcd_data[0] = digi[num%10];
        lcd_data[1] = digi[(num%100)/10];
        lcd_data[2] = 0x40;
        LCD_CS1=0;
        LCD_write_char(0x08);        //写数据
        for(i=0;i<3;i++) LCD_write_char(lcd_data[i]);
        LCD_CS1=1;
        delay_ms(3);
}
/*显示2*/
void display_lcd2(unsigned char num)        //显示 分钟         数据拆分
{
        unsigned char i;
        lcd_data[0] = 0x40;
        lcd_data[1] = digi[num%10];
        lcd_data[2] = digi[(num%100)/10];
        LCD_CS1=0;
        LCD_write_char(0x08);        //写数据
        for(i=0;i<3;i++) LCD_write_char(lcd_data[i]);
        LCD_CS1=1;
        delay_ms(3);
}
//键盘  1 设置 2  加  3 减  4背光  成功
void key()
{
        if(ks5==0)
        {
                delay_ms(30);
                if(ks5==0)
                {
                        while(ks5==0);
                        Beep_set();
                        set++;
                        if(set==3) set=0;
                }
        }

        switch(set)
        {
                case 1:
                t=((read_clock(0x83))/16)*10 + (read_clock(0x83))%16;
                display_lcd1(t);
                if(ks4==0)
                {
                        delay_ms(30);
                        if(ks4==0)
                        {
                                while(ks4==0);
                                Beep_set();
                                write_clock(0x8e,0x00);//取消写保护
                                write_clock(0x80,0x80);//停止时钟
                                d=((read_clock(0x83))/16)*10 + (read_clock(0x83))%16;  //16转10
                                d++;
                                if(d==60)d=0;
                                d=d/10*16+d%10;//十进制转换成DS1302要求的DCB码          10转16
                                write_clock(0x82,d);//  写分钟
                                write_clock(0x80,0x00);//启动时钟
                                write_clock(0x8e,0x80);//写保护
                                delay_ms(20);                       
                        }
                }

                if(ks3==0)
                {
                        delay_ms(30);
                        if(ks3==0)
                        {
                                while(ks3==0);
                                Beep_set();
                                write_clock(0x8e,0x00);//取消写保护
                                write_clock(0x80,0x80);//停止时钟
                                d=((read_clock(0x83))/16)*10 + (read_clock(0x83))%16;  //16转10
                                d--;
                                if(d==0)d=59;
                                d=d/10*16+d%10;//十进制转换成DS1302要求的DCB码          10转16
                                write_clock(0x82,d);//  写分钟
                                write_clock(0x80,0x00);//启动时钟
                                write_clock(0x8e,0x80);//写保护
                                delay_ms(20);                       
                        }
                }   
                break;
                case 2:
                t=((read_clock(0x85))/16)*10 + (read_clock(0x85))%16;
                display_lcd2(t);
                if(ks4==0)
                {
                        delay_ms(30);
                        if(ks4==0)
                        {
                                while(ks4==0);
                                Beep_set();
                                write_clock(0x8e,0x00);//取消写保护
                                write_clock(0x80,0x80);//停止时钟
                                d=((read_clock(0x85))/16)*10 + (read_clock(0x85))%16;  //16转10
                                d++;
                                if(d==24)d=0;
                                d=d/10*16+d%10;//十进制转换成DS1302要求的DCB码          10转16
                                write_clock(0x84,d);//  写分钟
                                write_clock(0x80,0x00);//启动时钟
                                write_clock(0x8e,0x80);//写保护
                                delay_ms(20);                       
                        }
                }

                if(ks3==0)
                {
                        delay_ms(30);
                        if(ks3==0)
                        {
                                while(ks3==0);
                                Beep_set();
                                write_clock(0x8e,0x00);//取消写保护
                                write_clock(0x80,0x80);//停止时钟
                                d=((read_clock(0x85))/16)*10 + (read_clock(0x85))%16;  //16转10
                                d--;
                                if(d==0)d=23;
                                d=d/10*16+d%10;//十进制转换成DS1302要求的DCB码          10转16
                                write_clock(0x84,d);//  写分钟
                                write_clock(0x80,0x00);//启动时钟
                                write_clock(0x8e,0x80);//写保护
                                delay_ms(20);                       
                        }
                }
                break;
        }
        //*背光控制
        if(ks2==0)
        {
                delay_ms(30);
                if(ks2==0)
                {
                        while(ks2==0);
                        Beep_set();
                        bg=~bg;
                        if(bg==0)
                        {
                                LCD_CS1=0;
                                LCD_write_char(0x04);    // 背光off        原=0x01
                                LCD_CS1=1;
                                delay_ms(3);                
                        }
                        else
                        {
                                LCD_CS1=0;
                                LCD_write_char(0x05);    // 背光on         
                                LCD_CS1=1;
                                delay_ms(3);
                        }
                }
        }          
}

void show()//显示和闪烁函数
{
        e=((read_clock(0x83))/16)*10 + (read_clock(0x83))%16;
        display_lcd1(e);   //显示分钟
        delay_ms(1000);

        e=((read_clock(0x85))/16)*10 + (read_clock(0x85))%16;
        display_lcd2(e);   //显示小时*/
        delay_ms(1000);
        // d=read_clock(0x87);//读日
        //d=read_clock(0x89);//读月
        //    delay_ms(50);
        //d=read_clock(0x8d);//读年
        //d=read_clock(0x8b);//读年
}

/*--------------------时钟的初始化---------------------------*/
void Init_1302()//这部分是把杜样的初始化拿来的
{
  ///read_clock        从指定地址读数据           write_clock 向指定地址写数据
        unsigned char Second,f,x=0;
        Second=read_clock(0xc1);         //read_clock
        if(Second != 0x80) //第一次开机
        {
                write_clock(0x8e,0x00); //  允许写入
                write_clock(0x8c,0x10); // 10 年                    
                write_clock(0x88,0x11); // 11 月
                write_clock(0x86,0x12); // 10 日
                write_clock(0x8a,0x05); // 3  星期
                write_clock(0x84,0x20); //  时
                write_clock(0x82,0x52); //  分
                write_clock(0x80,0x55); //  秒
                write_clock(0xc0,0x80); //  二次开机标志
                write_clock(0x90,0xa5); //  允许充电 一个二极管 2K电阻

                for(f=0;f<60;f=f+2)//清除闹钟RAM位为0
                {
                        write_clock(0xc2+f,0x00);         //存储报时用
                }                                                                //第一次开机要清除其余30个寄存器
                write_clock(0x8e,0x80);                         //  禁止写入
        }
}

void main()
{
//        LCD_on();        // 背光OFF
        set=0;
        ks5=1;
        ks4=1;
        Beep();                        //开机声
        LCD_init();
//        LCD_off();        // 背光ON
        Init_1302();//DS1302寄存器初始化
//        keyshi=1;
//        keyfen=1;  
        delay_ms(10);

        while(1)
        {     
                key();
                if(set==0)
                {
                        show();  
                }
        }
}

点评

前面定义的端口有些乱了。。咋还出来P0和P2了捏?是2051不了?  发表于 2012-1-29 10:50
回复 支持 反对

使用道具 举报

沙发
发表于 2011-3-22 20:57:49 | 显示全部楼层
欢迎大家拍砖,谁有更好的建议咱们一起探讨
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|Archiver|长汀无线电厂交流论坛  

GMT+8, 2024-5-19 07:55 , Processed in 0.745606 second(s), 18 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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