当前位置:首页 > 单片机 > 单片机
[导读]/************************************** PCF8563时钟程序 * * 文 件 名:1602_8563.c * * 版 本:V22.02 * * 主控芯片:Mega16L * * 工作频率:7.3728MHz * *************************************/ #inclu

/*************************************

* PCF8563时钟程序 *
* 文 件 名:1602_8563.c *
* 版 本:V22.02 *
* 主控芯片:Mega16L *
* 工作频率:7.3728MHz *
*************************************/
#include
#include
#include
#include
#include
#include
#include

//数据简化宏定义
#define uchar unsigned char
#define uint unsigned int

//全局变量定义
uchar timer[8]; //时钟数据

/**********************************
* 蜂鸣器发声函数 *
* 函数功能:蜂鸣器发出声响 *
* 入 口:n 声次数 *
* i 声时长,i*10ms *
* 返 回:无 *
* 发声频率:固定1KHz 无源 *
**********************************/
void spk(uchar i,uchar n)
{
uint a;
for(;n;n--)
{
a=i*10; //计算每声响的长度:MS
for(;a;a--)
{
delay_us(500); //响声频率为1KHZ
SPK_TG;
delay_us(500);
SPK_TG;
}
SPK_OFF; //响完关闭蜂鸣器
delay_ms(100); //每声响之间隔100MS
}
}

/**********************************
* 读出数据函数 *
**********************************/
uchar read_timer(void)
{
start(); //启动总线
waitack(); //等待启动完成
if(chkack()!=START)return I2C_ERR; //检查是否启动成功
write_tim(SLA_W); //发送写地址
write_tim(0x02); //写数据地址

start();
waitack(); //等待启动完成
if(chkack()!=RESTART)return I2C_ERR; //检查是否启动成功
write_tim(SLA_R); //发送读地址

timer[0]=read_tim()&0x7F; //读出秒数据
timer[1]=read_tim()&0x7F; //读出分数据
timer[2]=read_tim()&0x3F; //读出时数据
timer[3]=read_tim()&0x3F; //读出日数据
timer[4]=read_tim()&0x07; //读出周数据
if(timer[4]==0)timer[4]=7;
timer[5]=read_tim(); //读出月数据
if((timer[5]&0x80)==0)
timer[7]=0x20; //世纪位为0,是21世纪
else timer[7]=0x19; //世纪位不为0,是20世纪
timer[5]=timer[5]&0x1F;
timer[6]=read_tim(); //读出年数据
stop();
return I2C_CRR;
}

/**********************************
* 写入时钟函数 *
**********************************/
uchar write_timer(void)
{
start(); //启动总线
waitack(); //等待启动完成
if(chkack()!=START)return I2C_ERR; //检查是否启动成功
write_tim(SLA_W); //发送写地址
write_tim(0x00); //写数据首地址
write_tim(0x20); //写控制/状态寄存器1,暂停计时
write_tim(0x00); //写控制/状态寄存器2
write_tim(0x00); //写秒数据为0
write_tim(timer[1]); //写分数据
write_tim(timer[2]); //写时数据
write_tim(timer[3]); //写日数据
write_tim(timer[4]); //写周数据
write_tim(timer[5]); //写月数据
write_tim(timer[6]); //写年数据
stop();
return I2C_CRR;
}

/**********************************
* 启动时钟函数 *
**********************************/
uchar start_timer(void)
{
start(); //启动总线
waitack(); //等待启动完成
if(chkack()!=START)return I2C_ERR; //检查是否启动成功
write_tim(SLA_W); //发送写地址
write_tim(0x00); //写数据首地址
write_tim(0x00); //写控制/状态寄存器1,暂停计时
stop();
return I2C_CRR;
}

/**********************************
* 将时钟数据转换后在LCD上显示 *
**********************************/
void timer_lcd(void)
{
locate(1,4); //写指令:第1行第4列地址

lcd_da((timer[7]>>4)+0x30);
lcd_da((timer[7]&0x0f)+0x30);
lcd_da((timer[6]>>4)+0x30); //显示年
lcd_da((timer[6]&0x0f)+0x30);
lcd_da('/');
lcd_da((timer[5]>>4)+0x30); //显示月
lcd_da((timer[5]&0x0f)+0x30);
lcd_da('/');
lcd_da((timer[3]>>4)+0x30); //显示日
lcd_da((timer[3]&0x0f)+0x30);

locate(2,2); //写指令:第2行地址

lcd_da((timer[2]>>4)+0x30); //时
lcd_da((timer[2]&0x0f)+0x30);
lcd_da(':');
lcd_da((timer[1]>>4)+0x30); //分
lcd_da((timer[1]&0x0f)+0x30);
lcd_da(':');
lcd_da((timer[0]>>4)+0x30); //秒
lcd_da((timer[0]&0x0f)+0x30);

lcd_da(20); //时间与星期间留1空格
lcd_da('W'); //星期的前导字
lcd_da('e');
lcd_da('e');
lcd_da('k');
lcd_da((timer[4]&0x0f)+0x30); //星期数据
}

//定时器1:每秒从8563中读取4次数据,更新显示
void timer1_init(void) //定时器1初始化:250毫秒定时,预分频256
{
TCCR1B = 0x00; //停止定时器
TCNT1H = 0x8F; //初值高字节
TCNT1L = 0x81; //定时初值低字节
TCCR1A = 0x00;
TCCR1B = 0x03; //启动定时器
}

#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void) //定时器1中断入口:250MS中断一次
{
TCNT1H = 0x8F; //重装初值
TCNT1L = 0x81;
read_timer(); //读出当前时钟
timer_lcd(); //显示数据转换
}

/**********************************
* 调整显示函数1 *
**********************************/
void set_xs1(uchar i)
{
lcd_da((timer>>4)+0x30); //显示数据
lcd_da((timer&0x0f)+0x30);
}

/**********************************
* 调整显示函数2 *
**********************************/
void set_xs2(uchar data)
{
lcd_da((data>>4)+0x30); //显示数据
lcd_da((data&0x0f)+0x30);
lcd(0x20);
}

/**********************************
* 程序主函数 *
**********************************/
void main(void)
{
uchar set_flag=0; //调整与正常工作标志
uchar set_time; //调整数据类型标志
uchar set_bh=0; //调整变化标志
uchar a,a1;

port_init();
LED_ON; //开LCD背光
lcd_init();
delay_ms(500);
tonghe();
delay_ms(2000);

Twi_Init();
delay_ms(100);
CLI(); //关总中断
timer1_init();//定时器1初始化
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x04; //开放定时器0中断和比较中断
SEI(); //开总中断

cls();
delay_ms(50);

while(1)
{
a=KEY_RD;
if(a!=0)
{
delay_ms(20);
a1=KEY_RD;
if(a1==a)
{
switch(a)
{
case 0x01:
spk(10,1);
if(set_flag==0)
{
TCCR1B=0x00;
LED_ON;
set_flag=1;
cls();
locate(1,4); //显示“时间调整”
xs_lcd("SET:");
}
else
{
TCCR1B=0x04; //开启时钟
set_flag=0;
if(set_bh==1)
{
write_timer(); //写入新时间
set_bh=0;
}
}
break;
case 0x02:
if(set_flag==1)
{
spk(10,1);
set_time++;
locate(2,2); //显示待调整的数据
switch(set_time)
{
case 1:
xs_lcd("year:");
set_xs1(6); //显示年
break;
case 2:
xs_lcd("muth:");
set_xs1(5); //显示月
break;
case 3:
xs_lcd(" day:");
set_xs1(3); //显示日
break;
case 4:
xs_lcd("hour:");
set_xs1(2); //显示时
break;
case 5:
xs_lcd("mine:");
set_xs1(1); //显示分
break;
case 6:
xs_lcd("week:");
set_xs1(4); //显示周
break;
default:set_time=0;break;
}
}
break;
case 0x04:
if(set_flag==1)
{
spk(10,1);
set_bh=1;
locate(2,7); //显示“时间调整”
switch(set_time)
{
case 1:
timer[6]-=0x01;
if((timer[6]&0x0F)==0x0F)timer[6]&=0xF9;
if(timer[6]>0x99)timer[6]=0x99;
set_xs1(6); //显示年
break;
case 2:
timer[5]-=0x01;
if((timer[5]&0x0F)==0x0F)timer[5]&=0xF9;
if(timer[5]==0x00)timer[5]=0x12;
set_xs1(5); //显示月
break;
case 3:
timer[3]-=0x01;
if((timer[3]&0x0F)==0x0F)timer[3]&=0xF9;
if(timer[3]==0x00)timer[3]=0x30;
set_xs1(3); //显示日
break;
case 4:
timer[2]-=0x01;
if((timer[2]&0x0F)==0x0F)timer[2]&=0xF9;
if(timer[2]>0x24)timer[2]=0x23;
set_xs1(2); //显示时
break;
case 5:
timer[1]-=0x01;
if((timer[1]&0x0F)==0x0F)timer[1]&=0xf9;
if(timer[1]>0x59)timer[1]=0x59;
set_xs1(1); //显示分
break;
case 6:
timer[4]-=0x01;
if(timer[4]>6)timer[4]=0x06;
set_xs1(4); //显示周
break;
default:set_time=0;break;
}
}
else
start_timer();
break;
case 0x08:
if(set_flag==1)
{
spk(10,1);
set_bh=1;
locate(2,7); //显示“时间调整”
switch(set_time)
{
case 1:
timer[6]+=0x01;
if((timer[6]&0x0F)==0x0A)timer[6]=(timer[6]&0xF0)+0x10;
if(timer[6]>0x99)timer[6]=0x00;
set_xs1(6); //显示年
break;
case 2:
timer[5]+=0x01;
if((timer[5]&0x0F)==0x0A)timer[5]=(timer[5]&0xF0)+0x10;
if(timer[5]>=0x13)timer[5]=0x01;
set_xs1(5); //显示月
break;
case 3:
timer[3]+=0x01;
if((timer[3]&0x0F)==0x0A)timer[3]=(timer[3]&0xF0)+0x10;
if(timer[3]>=0x31)timer[3]=0x01;
set_xs1(3); //显示日
break;
case 4:
timer[2]+=0x01;
if((timer[2]&0x0F)==0x0A)timer[2]=(timer[2]&0xF0)+0x10;
if(timer[2]>=0x24)timer[2]=0x00;
set_xs1(2); //显示时
break;
case 5:
timer[1]+=0x01;
if((timer[1]&0x0F)==0x0A)timer[1]=(timer[1]&0xf0)+0x10;
if(timer[1]>0x59)timer[1]=0x00;
set_xs1(1); //显示分
break;
case 6:
timer[4]+=0x01;
if(timer[4]>6)timer[4]=0x00;
set_xs1(4); //显示周
break;
default:set_time=0;break;
}
}
else
LED_OFF; //关背光
break;
default:break;
}
}
while(a!=0)
{
a=KEY_RD;
delay_ms(10);
}
}
}
}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭