📄 wannianli.c
字号:
}
/**********************************************************************************************/
void Beep_key(void){//-扬声器--按键音
uchar a;//定义变量用于发声的长度设置
Led_EA = 1;//关列显示驱动,防止屏幕出现乱码
for(a=100;a>0;a--){//声音的长度
Bell_Out = ~Bell_Out;
Delay(50);//音调设置延时
}
}
/**********************************************************************************************/
void clock_out(unsigned char dd){ //-1302驱动程序(底层协议)
ACC=dd;
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; clock_clk=0;
}
/**********************************************************************************************/
unsigned char clock_in(void){ //-DS1302写入字节(底层协议)
clock_dat=1;
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);
}
/**********************************************************************************************/
uchar read_clock(uchar ord){ //-DS1302读数据(底层协议)
uchar dd=0;
clock_clk=0;
clock_Rst=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){ //-DS1302写数据(底层协议)
clock_clk=0;
clock_Rst=0;
clock_Rst=1;
clock_out(ord);
clock_out(dd);
clock_Rst=0;
clock_clk=1;
}
/**********************************************************************************************/
void Set_time(unsigned char sel,unsigned char a){ //根据选择调整的相应项目加1并写入DS1302-调时用加1程序
signed char address,item;
signed char max,mini;
//if(sel==7) {address=0x80; max=0;mini=0;} //秒7
if(sel==6) {address=0x82; max=59;mini=0;} //分钟6
if(sel==5) {address=0x84; max=23;mini=0;} //小时5
if(sel==3) {address=0x86; max=31;mini=1;} //日3
if(sel==2) {address=0x88; max=12;mini=1;} //月2
if(sel==1) {address=0x8c; max=99; mini=0;} //年1
if(sel==4) {address=0x8a; max=7;mini=1;} //星期4
if(sel==200) {address=0xc2+a*6; max=6;mini=0;} //MODE
if(sel==201) {address=0xc2+a*6+2; max=23;mini=0;} //星期4
if(sel==202) {address=0xc2+a*6+4; max=59;mini=0;} //星期4
//读取1302某地址上的数值转换成10进制赋给item
item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;
if(Add_Key == 0){ key_off ();//等待键放开
item++;//数值加1
Beep_key();//调时提示音
}
if(Add2_Key == 0){ key_off ();//等待键放开
item--;//数值减1
Beep_key();//调时提示音
}
if(item>max) item=mini;//查看数值有效范围
if(item<mini) item=max;
write_clock(0x8e,0x00);//允许写操作
write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302
if(sel == 6 && (Add_Key == 0 || Add2_Key == 0)){
write_clock(0x80,0x00);//秒值=0
}
write_clock(0x8e,0x80);//写保护,禁止写操作
}
/**********************************************************************************************/
void Init_1302(void){//-设置1302的初始时间(2007年1月1日00时00分00秒星期一)
uchar f;
if(read_clock(0xc1) != 0xaa){
write_clock(0x8e,0x00);//允许写操作
write_clock(0x8c,0x07);//年
write_clock(0x8a,0x01);//星期
write_clock(0x88,0x01);//月
write_clock(0x86,0x01);//日
write_clock(0x84,0x00);//小时
write_clock(0x82,0x00);//分钟
write_clock(0x80,0x00);//秒
write_clock(0x90,0xa5);//充电
write_clock(0xc0,0xaa);//写入初始化标志RAM(第00个RAM位置)
for(f=0;f<60;f=f+2){//清除闹钟RAM位为0
write_clock(0xc2+f,0x00);
}
write_clock(0x8e,0x80);//禁止写操作
}
}
/**********************************************************************************************/
void clearRAM (void){//寄存器清空函数-32个寄存器清空(0x00)
uchar a;//定义变量用于清空数据指针
for(a=0;a<32;a++){//指向32个寄存器
Ledplay[a] = 0;//将指向的寄存器清空
}
}
/**********************************************************************************************/
void putin (uchar u){//字符载入函数-将字符装入显示寄存器
uchar a = 0;//定义变量用于数据提取指针
do{
Ledplay[bn] = no[u][a];//将二维数组中的一组数据放入显示缓冲区
a++;//换下一个提取字节
bn++;//换下一个显示缓冲字节
}
while(no[u][a] != 0);//当显示数据为0时结束循环
bn++;//换下一个显示缓冲字节
Ledplay[bn] = 0;//显示一列的空位,便于字符区分
}
/**********************************************************************************************/
void display (void){//点阵屏驱动函数-32*8点阵显示驱动
uchar ac,aa=7;//定义两个数据变量
for(ac=0x28;ac<0x30;ac++){//扫描后两块LED屏(由于P1.5接扬声器所以高4位为2,旨在关声音)
Led_E = ac;//用ac值驱动使能列信号
Led_24 = DL(Ledplay[aa+8]);//将显示寄存器数据写入2、4屏(嵌入DL汇编是为了翻转字节数据,如果接线正确可省去)
Led_13 = Ledplay[aa];//将显示寄存器数据写入1、3屏
Delay(60);//延时1.2微秒
Led_13 = 0;//数据总线清空
Led_24 = 0;
aa--;//aa减1,换下一列显示
}
aa = 23;//指定后16个数据的提取
for(ac=0x20;ac<0x28;ac++){//扫描前两块LED屏
Led_E = ac;//用ac值驱动使能列信号
Led_24 = DL(Ledplay[aa+8]);//将显示寄存器数据写入2、4屏
Led_13 = Ledplay[aa];//将显示寄存器数据写入1、3屏
Delay(60);//延时1.2微秒
Led_13 = 0;//数据总线清空
Led_24 = 0;
aa--;//aa减1,换下一列显示
}
}
/**********************************************************************************************/
void search_time(void){//验证闹钟时间到
uchar i;
write_clock(0x8e,0x00);//允许写操作
for(i=1;i<9;i++){
if( read_clock(0xc3+i*6) != 0 && //不为0则表示这项已经设置
read_clock(0xc3+i*6+2) == read_clock(0x85) && //小时对比
read_clock(0xc3+i*6+4) == read_clock(0x83)&& //分值对比
read_clock(0x81) < 0x09 && //这里保证秒值小于8秒动作,防止再操作
v != read_clock(0x83))//按键停止防再响
{
switch (read_clock(0xc3+i*6)){//显示设置项的说明
case 1://只响一次,之后自动关闭
BEEP_bit = 1;
write_clock(0xc2+i*6,0);
break;//
case 2://常开
BEEP_bit = 1;
break;//
case 3://周六、日除外
if(read_clock(0x8b) < 6){
BEEP_bit = 1;
}
break;//
case 4://周日除外
if(read_clock(0x8b) < 7){
BEEP_bit = 1;
}
break;//
case 5://周六、日响
if(read_clock(0x8b) > 5){
BEEP_bit = 1;
}
break;//
case 6://周日响
if(read_clock(0x8b) == 7){
BEEP_bit = 1;
}
break;//
}
v = read_clock(0x83);
}
}
write_clock(0x8e,0x80);//禁止写操作
}
/**********************************************************************************************/
void Timer0_Init(void){//定时器0初始(主函数中被调用一次)
TMOD=0x01;//定时器方式设置(定时器工作方式1-16位定时)
TH0=(65535-50000)/256;//50MS
TL0=(65535-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断允许
TR0=1;//启动定时器0
}
/**********************************************************************************************/
void Timer0(void) interrupt 1 using 0{//定时器中断入口,使用第1工作组寄存器=定时器中断函数(产生显示切换)
uchar pp;//定义静态小时更新用数据变量
TH0=(65535-50000)/256; //50ms定时(定时器工作方式1)
TL0=(65535-50000)%256;
timecount++;//软件计数加1
if(timecount == 20){//软件计数加到20时显示日期(1S)
Led_EA = 1;//关列显示驱动,防止屏幕出现乱码
clearRAM();//清空显示缓冲区数据
bn = 0;//显示位累加寄存器清零(从头开始写入显示缓冲区)
if(read_clock(0x89)/16 != 0){//为0时消隐
putin(read_clock(0x89)/16);//显示月值(十位,为0时消隐)
}
putin(read_clock(0x89)%16);//显示月值(个位)
putin(21);//显示“月”
if(read_clock(0x87)/16 != 0){//为0时消隐
putin(read_clock(0x87)/16);//显示日值(十位,为0时消隐)
}
putin(read_clock(0x87)%16);//显示日值(个位)
putin(22);//显示“日”
}
if(timecount == 40){//软件计数加到40时显示时间(2S)
Led_EA = 1;//关列显示驱动,防止屏幕出现乱码
clearRAM();//清空显示缓冲区数据
bn = 0;//显示位累加寄存器清零(从头开始写入显示缓冲区)
if(read_clock(0x85) > read_clock(0xc3) && read_clock(0x85) < read_clock(0xc5)){//整点报时
if(pp != read_clock(0x85)){//当小时值更新时则启动报时
pp = read_clock(0x85);//将新的小时值放入更新寄存器
Beep();//启动正点报时
}
}
putin(read_clock(0x85)/16);//显示小时值(十位,为0时消隐)
putin(read_clock(0x85)%16);//显示小时值(个位)
putin(17);//显示冒号“:”
putin(read_clock(0x83)/16);//显示分钟值(十位)
putin(read_clock(0x83)%16);//显示分钟值(个位)
search_time();//----------------------------------------------------检测闹钟
}
if(timecount > 80){////软件计数加到80时显示时间(1S)
uchar ty = 0;//定义温度寄存器变量
timecount = 0;//软件计数清零
Led_EA = 1;//关列显示驱动,防止屏幕出现乱码
ty = printTemperature();//将DSS汇编程序取得的温度值放入温度寄存器变量
clearRAM();//清空显示缓冲区数据
bn = 0;//显示位累加寄存器清零(从头开始写入显示缓冲区)
if(ty >60){//当温度高于99度或未发现温度传感器(DS18B20)时显示“--”
putin(18);//显示“--”
putin(18);
}
else{//温度小于99度并发现温度传感器(DS18B20)时,显示温度值
if(ty/10 != 0){//为0时消隐
putin(ty/10);//温度值的十位
}
putin(ty%10);//温度值的个位
}
putin(19);//显示摄氏度符号“oC”
putin(read_clock(0x8b)+9);//显示星期数据
}
}
/**********************************************************************************************/
void MENUadd1 (void){//主菜单加1或减1
if(Add_Key == 0 || Add2_Key == 0){
DelayM(20);//去抖
if(Add_Key == 0){
MENU++;
Beep_key();//调时提示音
if(MENU >11){
MENU = 1;
}
}
if(Add2_Key == 0){
MENU--;
Beep_key();//调时提示音
if(MENU <1){
MENU = 11;
}
}
key_off ();//等待键放开
}
}
/**********************************************************************************************/
void MENUexit (void){//退出菜单项 回到时钟显示
if(int_Key == 0){
DelayM(20);//去抖
if(int_Key == 0){
key_off ();//等待键放开
Beep_set();//调时提示音
clearRAM();//清空显示缓冲区数据
timecount = 19;//将显示切换值调到41,使开机画面停留2秒
MENU = 0;
Timer0_Init();//定时器初始化
}
}
}
/**********************************************************************************************/
void main(void){ //主函数
uchar b,a = 0;//定义变量用于数据提取指针
Init_1302();//调用时间初始化函数
Beep();//启动发出报时音(测试扬声器)
do{//显示开机画面“DoYoung”
Ledplay[bn] = DoYoung[a];//将二维数组中的一组数据放入显示缓冲区
a++;//换下一个提取字节
bn++;//换下一个显示缓冲字节
}
while(DoYoung[a] != 0x99);//当显示数据为0时结束循环
timecount = 41;//将显示切换值调到41,使开机画面停留2秒
Timer0_Init();//定时器初始化
MENU = 0;//显示标志为0表示正常显示
BEEP_bit = 0;
/**********************************************************************************************/
while(1){//主线程
/**********************************************************************************************/
if(BEEP_bit == 1 && read_clock(0xc7) == 1){
for(b=0;b<140;b++){//
ET0 = 0;//关定时器中断(停止显示切换)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -