/*=================================================================================================
;**************************************************************************************************
;函数名称 :main.c
;函数功能 :主程序
;函数说明 :C-V3各个子程序调用
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
/***************************************************************
-----------------------Includes define-------------------------*
***************************************************************/
#include "BS87D20A-3.h"
/***************************************************************
-----------------------Mcu Io definitions----------------------*
***************************************************************/
#define com1 _pc1
#define com2 _pc0
#define com3 _pc2
#define com4 _pc3
#define key1 _pd2
#define key2 _pd3
#define key3 _pa1
#define key4 _pa4
#define beep _pc4
/***************************************************************
---------------------------FLAG define-------------------------*
***************************************************************/
volatile bit Flag_T1ms;
volatile bit Flag_T5ms;
volatile bit flag_keylong;
volatile bit flag_keyshort;
volatile bit flash_state;
volatile bit flag_timeon;
volatile bit flag_beep;
volatile bit flag_blink_min;
volatile bit flag_blink_sec;
volatile bit flag_blink_dot;
volatile bit ffbeep;
/***************************************************************
-----------------------Variables definitions-------------------*
***************************************************************/
unsigned char strtab[5];//缓冲区
unsigned char key_number=0;
unsigned char sec=0,min=0,hour=0;
static int temp=0;
unsigned long s; //秒
unsigned long ms5;
unsigned char keyvalue;
unsigned char sys_state;
unsigned char set_state;
/***************************************************************
-----------------------Code definitions------------------------*
***************************************************************/
const unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/***************************************************************
-----------------------Constant data---------------------------*
***************************************************************/
#define keyup 0x01
#define keydown 0x02
#define keychange 0x04
#define keysys 0x08
#define sys_off 0x00
#define sys_on 0x01
#define sys_power 0x02
#define set_on 0x00
#define set_hour 0x01
#define set_min 0x02
/***************************************************************
---------------------Function declaration----------------------*
***************************************************************/
void fuc_key_up();
void fuc_key_down();
void display_time_state();
void display_pro();
void time_clock();
void display_min();
void display_sec();
/**************************************************************************************************
;函数名称 :funcbeep()
;函数功能 :蜂鸣器1s鸣叫
;函数说明 :子函数
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void funcbeep()
{
if(flag_beep==1)
{
static long tt;
beep=1;
if(tt++==100)
{
tt=0;
flag_beep=0;
beep=0;
}
}
}
/**************************************************************************************************
;函数名称 :read_key()
;函数功能 :按键扫描
;函数说明 :调用各个子程式
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void read_key()
{
unsigned char keybak;
keybak=0;
static char key_state=0x00,press_20ms,press_long;
if(!key1)keybak|=0x01;
if(!key2)keybak|=0x02;
if(!key3)keybak|=0x04;
if(!key4)keybak|=0x08;
switch (key_state)
{
case 0x00: // 按键初始态
if (keybak!=0)
{
press_20ms=0;
key_state=0x01; // 键被按下,状态转换到键确认态
}
break;
case 0x01: // 按键确认态
if (keybak!=0)
{
key_state=0x02;
keyvalue=keybak;
}
else
{
key_state=0x00;
}
break;
case 0x02:
if (keybak==0)
{
press_long=0;
if(++press_20ms>3)
{
press_20ms=0;
key_state=0x00;
flag_keyshort=1;
flag_beep=1;
}
}
else
{
press_20ms=0;
if(++press_long>100)
{
flag_keylong=1;
flag_beep=1;
press_20ms=0;
press_long=0;
key_state=0x04;
}
}
break;
case 0x04:
if(keybak==0)
{
if(++press_20ms>3)
{
key_state=0x00;
}
}
else
{
press_20ms=0;
if(++press_long>50)
{
flag_keylong=1;
press_long=0;
}
}
break;
default:
break;
}
}
/**************************************************************************************************
;函数名称 :key_do()
;函数功能 :按键功能扫描
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void key_do()
{
if(flag_keyshort||flag_keylong)
{
switch(keyvalue)
{
case keyup:
switch(sys_state)
{
case sys_off:
break;
case sys_on:
fuc_key_up();
break;
default:
break;
}
break;
case keydown:
switch(sys_state)
{
case sys_off:
break;
case sys_on:
fuc_key_down();
break;
default:
break;
}
break;
case keychange:
switch(sys_state)
{
case sys_off:
break;
case sys_on:
if(set_state++==0x02)set_state=0x00;
flag_blink_min=1;
flag_blink_sec=1;
break;
default:
break;
}
break;
case keysys:
if(sys_state++==0x01)sys_state=0x00;
flag_timeon=1;
break;
default:
break;
}
flag_keyshort=0;
flag_keylong=0;
}
}
/**************************************************************************************************
;函数名称 :fuc_key_up()
;函数功能 :按键加
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void fuc_key_up()
{
switch(set_state)
{
case set_hour:
flag_blink_min=0;
if(min++==59)min=0;
flash_state=0;
break;
case set_min:
flag_blink_sec=0;
if(sec++==59)sec=0;
flash_state=0;
break;
default:
break;
}
}
/**************************************************************************************************
;函数名称 :fuc_key_down()
;函数功能 :按键减
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void fuc_key_down()
{
switch(set_state)
{
case set_hour:
flag_blink_min=0;//停止闪烁
if(min--==0)min=59;
flash_state=0;//闪烁状态为0,显示
break;
case set_min:
flag_blink_sec=0;
if(sec--==0)sec=59;
flash_state=0;
break;
}
}
/**************************************************************************************************
;函数名称 :display_pro()
;函数功能 :数码管显示
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void display_pro()
{
com1=1;com2=1;com3=1;com4=1;
switch(temp)
{
case 0:com4=0;
_pb=strtab[temp]; break;
case 1:com3=0;
_pb=strtab[temp]; break;
case 2: com3=0;com4=0;
_pb=strtab[temp]; break;
case 3:com2=0;
_pb=strtab[temp]; break;
case 4:com1=0;
_pb=strtab[temp]; break;
default:break;
}
if(temp++==4)
temp=0;
}
/**************************************************************************************************
;函数名称 :display_time_state()
;函数功能 :显示状态 (闪烁等)
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void display_time_state()
{
static long display_time;
switch(set_state)
{
case set_on:
flag_timeon=1;
switch(sys_state)
{
case sys_off:
flag_blink_dot=0;
_pb=0xff;
set_state=0x00;
break;
case sys_on:
flag_blink_dot=1;
strtab[2]=0xff;
if(flash_state==0)
{ //调整小时,小时闪烁 闪烁状态为0
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
if(display_time++==250)
{
display_time=0;
flash_state=1;
}
}
else
{
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
strtab[2]=0xff;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
flag_timeon=1;
if(display_time++==250)
{//闪烁状态为1,闪烁时间到
flash_state=0;
display_time=0;
}
}
break;
case sys_power:
break;
default:break;
}
break;
case set_hour:
flag_timeon=0;
switch(sys_state)
{
case sys_off:
flag_blink_dot=0;
_pb=0xff;
set_state=0x00;
break;
case sys_on:
flag_blink_dot=1;
strtab[2]=0xff;
display_min();
if(flag_blink_min)
{
if(flash_state==0)
{ //状态0,亮
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
if(display_time++==300)
{
display_time=0;
flash_state=1;
}
}
else
{ //状态1 ,灭 状态切换闪烁
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=0xff;
strtab[4]=0xff;
display_pro();
if(display_time++==300)
{
flash_state=0; //切换为0
display_time=0;
}
}
}
break;
case sys_power:
break;
default:break;
}
break;
case set_min:
flag_timeon=0;
switch(sys_state)
{
case sys_off:
flag_blink_dot=0;
_pb=0xff;
set_state=0x00;
break;
case sys_on:
flag_blink_dot=1;
strtab[2]=0xff;
display_sec();
if(flag_blink_sec)
{
if(flash_state==0)
{ //状态0,亮
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
if(display_time++==300)
{
display_time=0;
flash_state=1;
}
}
else
{ //状态1 ,灭 状态切换闪烁
strtab[0]=0xff;
strtab[1]=0xff;
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
if(display_time++==300)
{
flash_state=0; //切换为0
display_time=0;
}
}
}
break;
default:break;
}
break;
default:break;
}
}
/**************************************************************************************************
;函数名称 :display_min()
;函数功能 :分钟显示
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void display_min()
{
if(flash_state==0)
{
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
}
else
{
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=0xff;
strtab[4]=0xff;
display_pro();
}
}
/**************************************************************************************************
;函数名称 :display_sec()
;函数功能 :秒显示
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void display_sec()
{
if(flash_state==0)
{
strtab[0]=tab[sec%10];
strtab[1]=tab[sec/10];
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
}
else
{
strtab[0]=0xff;
strtab[1]=0xff;
if(flag_blink_dot)strtab[2]=0x7f;
strtab[3]=tab[min%10];
strtab[4]=tab[min/10];
display_pro();
}
}
/**************************************************************************************************
;函数名称 :time_clock()
;函数功能 :1s计数 秒 分钟 小时
;函数说明 :子函数
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void time_clock()
{
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
/**************************************************************************************************
;函数名称 :init()
;函数功能 :初始化配置
;函数说明 :
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void init()
{
_ctm1c0=0x20; // fh/16 2us
_ctm1c1=0xc1; // 定时/计数器模式 比较器a ctm1
_ctm1al=0xf4; // 1ms
_ctm1ah=0x01;
_pbc=0; //输出
_pcc0=0;
_pcc1=0;
_pcc2=0;
_pcc3=0;
_pcc4=0;
beep=0;
_pcpu4=1;
_pac1=1;
_pac4=1;
_pdc2=1;
_pdc3=1;
_pdpu3=1;
_pdpu2=1;
_papu1=1;
_papu4=1;
s=1000;
ms5=5;
temp=0;
_mfe=1; //开多功能中断
_ctm1ae=1;
_emi=1; //开总中断
_ct1on=1;
}
/**************************************************************************************************
;函数名称 :main()
;函数功能 :主函数
;函数说明 :调用各个子程式
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void main()
{
init();
while(1)
{
if(Flag_T1ms)
{ static int t;
funcbeep();
Flag_T1ms=0;
if(t++==2)
{
t=0;
display_time_state();
}
}
if(Flag_T5ms)
{
Flag_T5ms=0;
read_key();
key_do();
}
GCC_CLRWDT();
}
}
/**************************************************************************************************
;函数名称 :__attribute__((interrupt(0x20))) ISR_CTM1(void)
;函数功能 :CTM1中断
;函数说明 :中断函数
;函数参数 :无
;函数返回值 :无
;函数修改说明 :1.修改时间【 】
2.修改内容【 】
;开始编辑时间 :2017-12-22
;程序编写人 :leegj
;函数版本 :V1.0.0
;函数编辑最后时间 :2017-12-22
;*************************************************************************************************/
void __attribute__((interrupt(0x20))) ISR_CTM1(void)
{
_ctm1af=0;
ms5--;
Flag_T1ms=1;
if(!ms5)
{
ms5=5;
Flag_T5ms=1;
}
s--;
if(! s)
{
s=1000;//1s电子钟计数
if(flag_timeon==1){
time_clock();
}
}
}
|