● 改编自国信长天蓝桥杯官方蓝皮书例程,按照自己的习惯进行了补充和修改
蓝桥杯单片机第八届省赛-电子钟
2021.3.20
做到三个半小时的时候,卡在了数码管闪烁的地方。晚上又参考例程补了上去。
总之……得……二刷……
Notes1:数码管闪烁
1、在数码管数据处理函数void SEG_Proc(void)
中实现。
2、在sprintf(puc_SEG_Buf,……)"
之后实现,
3、在sprintf
打印完字符串puc_SEG_Buf
后,即得到完整数据后,再用下面语句将数组puc_SEG_Buf
中的某一位单独置为空,对应数码管段码就是灭。
puc_SEG_Buf[0] = ' ';
4、再用
if( (ul_Sec%2) == 0)
或
if( ul_Sec >= 2)
来实现以1s为间隔闪亮。
例
case 6: //闹钟设置
{
sprintf(puc_SEG_Buf,"%02u-%02u-%02u",(uint)puc_Alarm[0],(uint)puc_Alarm[1],(uint)puc_Alarm[2]);
if( (ul_Sec%2) == 0)
{
switch(close_wei)
{
case 1:
{
puc_SEG_Buf[0] = ' ';
puc_SEG_Buf[1] = ' ';
}break;
case 2:
{
puc_SEG_Buf[3] = ' ';
puc_SEG_Buf[4] = ' ';
}break;
case 3:
{
puc_SEG_Buf[6] = ' ';
puc_SEG_Buf[7] = ' ';
}break;
}
}
}break;
Notes2:通过按键设置DS1302
1、加操作
if(++puc_RTC[0] == 24) puc_RTC[0] = 0;
数组可以对其中的单个元素进行赋值操作,先++
再判断,所以临界值写为24,注意时分秒的临界值分别为24,60,60。
1、减操作
if(!puc_RTC[0]) puc_RTC[0]=23;
else puc_RTC[0]--;
if(!puc_RTC[1]) puc_RTC[1]=59;
else puc_RTC[1]--;
先判断数组相应位是否为0,再对其进行操作。若在减操作前就已经为0,再减就是借位了。
0→1→2……58→59→,0→1→2→3……58→59
Notes3:LED以一定频率闪烁一定时间
指示灯L1以0.2s为间隔闪烁,持续5s。
放在定时器1的中断服务函数中,1ms执行一次。
if(uc_Alarm_num)
{
if(!(ul_ms%200))
{
if(--uc_Alarm_num) uc_LED ^=1;
else LED_OFF(ALL);
LED_Disp(uc_LED);
}
}
Notes4:程序分层思想
Notes5:状态机在逻辑结构里的应用
第一次接触状态机是在数电和FPGA的课本里,数电将时序电路称为状态机(State Machine,SM),指的是,电路时序电路在工作时是在电路的有限个状态间按照一定的规律转换的。
绝对严谨的状态机,构建了完整逻辑严谨的程序框架,再去写程序就不会出现逻辑错误,减少Bug。