本文最后更新于101 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
led原理



LED控制代码
LED底层代码一共有两种,一种为状态控制版本,一种为直接赋值法,前者适合状态控制,可以实现每个灯互不影响,后者适合流水灯,PWM灯
//状态控制版本
void led(uchar * LED,uchar pos)
{
static uchar temp=0xff;
if(LED[pos])
temp &= ~(0x01<<pos);
else
temp |= 0x01<<pos;
P0=temp;
hc573(4);
}
void display_task()
{
LED[0] = (col_flag == 0 && display_state1 == 0) ? 1 : 0;
LED[1] = (col_flag == 0 && display_state1 == 1) ? 1 : 0;
LED[2] = (col_flag == 1) ? 1 : 0;
LED[3] = (count_tri >0 && temp > temp_par) ? L4_state : 0;
LED[4] = (count_tri >0 && (hum>90||hum<10)) ? 1 : 0;
LED[5] = (count_tri >= 2) ? L6_state : 0;
LED[6] = 0;
LED[7] = 0;
//直接赋值法
}
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
if(++count_200ms == 200)
{
count_200ms = 0;
P0 = 0xff << position; //整体赋值
hc573(4);
if(++position == 9) position = 0;
}
if(++pos == 8) pos = 0;
relay(state_relay);
}
LED考点分析
流水灯
以第二届省赛为例
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
if(++count_200ms == 200)
{
count_200ms = 0;
P0 = 0xff << position; //整体赋值
hc573(4);
if(mode)
{
if(++position == 9) position = 0;
}
else
{
if(position > 0)
position--;
else
position = 8;
}
}
if(++pos == 8) pos = 0;
relay(state_relay);
}
PWM流水灯
以第九届省赛为例
ledpwm调光的频率大概在100HZ左右,对应时间10ms,题目要求分四个PWM占空比,25%,50%,75%,100%,这样的话需要在2.5ms改变一次LED状态,有点不合理,所以我们将周期改为12ms,频率83HZ。 需要注意的是LED低电平点亮 下面以实现25%亮度为例
需要在0ms时点亮led,在3ms时熄灭led,加到12ms归零 代码如下(示例):
uint count_ms;
uint mode_time;
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
if(++count_ms == mode_time) //控制移位
{
count_ms = 0;
if(++position == 9)
position = 0;
}
if(pwm_count == 0) //等于0点亮LED
{
P0 = 0xff << position; //整体赋值
hc573(4);
}
else if(pwm_count == pwm_duty) //等于占空比时熄灭
{
P0 = 0xff; //整体赋值
hc573(4);
}
if(++pwm_count == 12) //加到12归零
pwm_count = 0;
if(++pos == 8) pos = 0;
relay(state_relay);
}
led闪烁(以x秒为间隔闪烁指的是亮和灭的时间间隔)
题目一 
uint count_ms;
uint mode_time;
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
if(++count_ms == mode_time)
{
count_ms = 0;
L1_flag ^= 1;
}
if(++pos == 8) pos = 0;
relay(state_relay);
}
LED[0] = L1_flag;
LED[1] = 0;
LED[2] = 0;
LED[3] = 0;
LED[4] = 0;;
LED[5] = 0;
LED[6] = 0;
LED[7] = 0;
题目二 
uint count_ms;
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
if(++count_ms == 100)
{
count_ms = 0;
L8_flag ^= 1;
}
if(++pos == 8) pos = 0;
relay(state_relay);
}
LED[0] = 0;
LED[1] = 0;
LED[2] = 0;
LED[3] = 0;
LED[4] = 0;;
LED[5] = 0;
LED[6] = 0;
LED[7] = (mode) ? L8_flag : 0;
led亮一定时间后熄灭
题目一 
LED[0] = (Time[1] == 0 && (Time[0] >=0 && Time[0] < 5)) ? 1 : 0;
LED[1] = 0;
LED[2] = 0;
LED[3] = 0;
LED[4] = 0;;
LED[5] = 0;
LED[6] = 0;
LED[7] = 0;
题目二 
uint count_ms;
uchar count;
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
if(state == 1)
{
if(++count_ms == 200)
{
count_ms = 0;
if(++count == 20)//亮灭各十次
{
count = 0;
state = 0;
}
}
}
if(++pos == 8) pos = 0;
relay(state_relay);
}
LED[0] = (state == 1) ? count % 2 : 0;
LED[1] = 0;
LED[2] = 0;
LED[3] = 0;
LED[4] = 0;;
LED[5] = 0;
LED[6] = 0;
LED[7] = 0;
状态指示灯

LED[0] = (vol > vol_old) ? 1 : 0;
LED[1] = (fre > fre_old) ? 1 : 0;
LED[2] = (state_display == 0) ? 1 : 0;
LED[3] = (state_display == 1) ? 1 : 0;
LED[4] = (state_display == 2) ? 1 : 0;
LED[5] = 0;
LED[6] = 0;
LED[7] = 0;
二进制灯
用程序员计算器计算发现80的二进制为01010000;与LED的显示正好相反,所以需要进行取反
void timer1() interrupt 3
{
systick_ms++;
key_dly++;
display_dly++;
collect_dly++;
smg(SMG,dot,pos);
P0 = ~(distance);
hc573(4);
if(++pos == 8) pos = 0;
relay(state_relay);
}
