📄 时钟.c
字号:
/*-----------------------------------------*/
#include <c8051f120.h> // SFR declarations
#include <stdio.h>
#include <string.h>
#include <absacc.h>
#define uint unsigned int //简化定义
#define uchar unsigned char
#define comm 0
#define dat 1
/*-------------函数定义-------------------*/
void Port_IO_Init();
void Oscillator_Init();
void Init_Device(void);
void wr_lcd (uchar dat_comm,uchar content);
void write_clock(unsigned char ord, unsigned char dd);
void Init_1302(void); //设置1302的初始时间
void write_clock(uchar ord, uchar dd);
uchar read_clock(uchar ord);
uchar clock_in(void);
void clock_out(uchar dd);
void delay (uint us);
void delay1 (uint ms);
/*************变量定义*********************/
uchar h , m , s;
/*-------------引脚定义---------------------*/
sbit cs = P4^7;
sbit std = P4^5;
sbit sclk = P4^6;
sbit led = P7^7;
/****************ds1302端口定义******************************/
sbit clock_clk = P6^4;//ds1302_clk
sbit clock_dat = P6^3;//ds1302_dat
sbit clock_Rst = P6^2;//ds1302_Rst
sbit a0 = ACC ^ 0;
sbit a7 = ACC ^ 7;
/*------------------初始化-----------------*/
void Port_IO_Init()
{
SFRPAGE = CONFIG_PAGE;
P1MDOUT = 0x40;
XBR2 = 0x40;
}
void Oscillator_Init() //设定时钟频率为88473600Hz
{
int i = 0;
SFRPAGE = CONFIG_PAGE;
OSCXCN = 0x67;
for (i = 0; i < 3000; i++); // Wait 1ms for initialization
while ((OSCXCN & 0x80) == 0);
OSCICN = 0x83;
PLL0CN = 0x04;
CCH0CN &= ~0x20;
SFRPAGE = LEGACY_PAGE;
FLSCL = 0xB0;
SFRPAGE = CONFIG_PAGE;
CCH0CN |= 0x20;
PLL0CN |= 0x01;
PLL0DIV = 0x01;
PLL0FLT = 0x01;
PLL0MUL = 0x04;
for (i = 0; i < 15; i++); // Wait 5us for initialization
PLL0CN |= 0x02;
while ((PLL0CN & 0x10) == 0);
CLKSEL = 0x02;
}
void init_cpu(void)
{
Oscillator_Init();
Port_IO_Init();
wr_lcd (comm,0x30); /*30---基本指令动作*/
wr_lcd (comm,0x01); /*清屏,地址指针指向00H*/
wr_lcd (comm,0x06); /*光标的移动方向*/
wr_lcd (comm,0x0c); /*开显示,关游标*/
}
/*----------------显示整数-----------------*/
void disnum(uint i,uchar stradd)
{
unsigned char thou,hun,ten,ge;
wr_lcd (comm,0x06);
thou=i/1000;
hun=i%1000/100;
ten=i%100/10;
ge=i%10;
wr_lcd (comm,stradd); //显示地址
if (thou==0) wr_lcd (dat,0x20|thou);
else wr_lcd (dat,0x30|thou);
if (thou==0&&hun==0) wr_lcd (dat,0x20|hun);
else wr_lcd (dat,0x30|hun);
if (thou==0&&hun==0&&ten==0) wr_lcd (dat,0x20|ten);
else wr_lcd (dat,0x30|ten);
wr_lcd (dat,0x30|ge);
}
/*----------------显示整数2-----------------*/
void disnum2(uchar ii,uchar strad)
{
unsigned char ten,ge;
ten=ii/10;
ge=ii%10;
wr_lcd (comm,strad); //显示地址
wr_lcd (dat,0x30|ten);
wr_lcd (dat,0x30|ge);
}
/*----------开机画面-------------------------------*/
uchar code tab0[]={
" 山西华鑫电器 "
"电话:03537042431"
"阳泉市四矿煤山路"
"传真:03537042431"
};
/*---------------显示汉字或字符----------------*/
void chn_disp (uchar code *chn)
{
uchar i,j;
wr_lcd (comm,0x30);
wr_lcd (comm,0x80);
for (j=0;j<4;j++)
{
for (i=0;i<16;i++)
wr_lcd (dat,chn[j*16+i]);
}
}
/*--------------清DDRAM------------------*/
void clrram (void)
{
wr_lcd (comm,0x30);
wr_lcd (comm,0x01);
delay1 (5);
}
/*---------------------------------------*/
void wr_lcd (uchar dat_comm,uchar content)
{
uchar a,i,j;
delay1(20);
a=content;
cs=1;
delay(4);
sclk=0;
delay(4);
std=1;
delay(4);
for(i=0;i<5;i++)
{
sclk=1;
delay(4);
sclk=0;
delay(4);
}
std=0;
delay(4);
sclk=1;
delay(4);
sclk=0;
delay(4);
if(dat_comm)
{
std=1; //data
delay(4);
}
else
{
std=0; //command
delay(4);
}
sclk=1;
delay(4);
sclk=0;
delay(4);
std=0;
delay(4);
sclk=1;
delay(4);
sclk=0;
delay(4);
for(j=0;j<2;j++)
{
for(i=0;i<4;i++)
{
a=a<<1;
std=CY;
delay(4);
sclk=1;
delay(4);
sclk=0;
delay(4);
}
std=0;
delay(4);
for(i=0;i<4;i++)
{
sclk=1;
delay(4);
sclk=0;
delay(4);
}
}
}
/******************ds1302驱动*****************/
void clock_out(uchar dd)
{
uchar i;
ACC=dd;
for(i=8;i>0;i--)
{
clock_dat=a0;
clock_clk=1;
clock_clk=0;
ACC=ACC>>1;
}
}
uchar clock_in(void)
{
uchar i;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
a7=clock_dat;
clock_clk=1;
clock_clk=0;
}
return(ACC);
}
uchar read_clock(uchar ord)
{
uchar dd=0;
clock_Rst=0;
clock_clk=0;
clock_Rst=1;
clock_out(ord);
dd=clock_in();
clock_Rst=0;
clock_clk=1;
return(dd);
}
void write_clock(uchar ord, uchar dd)
{
clock_Rst=0;
clock_clk=0;
clock_Rst=1;
clock_out(ord);
clock_out(dd);
clock_Rst=0;
clock_clk=1;
}
/*--------时钟初始化---------------*/
void Init_1302(void) //设置1302的初始时间
{
write_clock(0x8e,0x00);//允许写操作
write_clock(0x8c,0x07);//年
write_clock(0x8a,0x04);//星期
write_clock(0x88,0x12);//月
write_clock(0x86,0x05);//日
write_clock(0x84,0x16);//小时
write_clock(0x82,0x20);//分钟
write_clock(0x80,0x50);//秒
write_clock(0x90,0xa5);//充电
write_clock(0x8e,0x80);//禁止写操作
}
/*-----------延时子程序------------------------*/
void delay (uint us) //微秒
{
while(us--);
}
void delay1 (uint ms) //毫秒
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<15;j++)
delay(10);
}
/*------------------主程序--------------------*/
void main ()
{
WDTCN = 0xde; // Disable watchdog timer
WDTCN = 0xad;
SFRPAGE = CONFIG_PAGE;
init_cpu( );
clrram();
chn_disp (tab0);
delay1(10000);
clrram();
delay1(500);
Init_1302( ) ;
while(1){
s=read_clock(0x81);//读秒
s=((s&0x70)>>4)*10+(s&0x0f);
disnum2(s,0x86);
m=read_clock(0x83);//读分
m=((m&0x70) >>4)*10+(m&0x0f);
disnum2(m,0x82);
h=read_clock(0x85);//读时
h=((h&0xf0)>>4)*10+(h&0x0f);
disnum2(h,0x80);
led=~led ;
delay1(1000);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -