蓝桥杯
小蜜蜂
cpp
#include "STC15F2K60S2.h"
// 定义控制LED
#define Led(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0x80; \
P2 &= 0x1f; \
}
// 定义控制蜂鸣器
#define Buzz(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xA0; \
P2 &= 0x1F; \
}
// 定义控制继电器
#define Relay(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xA0; \
P2 &= 0x1F; \
}
typedef unsigned char u8; // 自定义类型
u8 TimerCounter = 0; // 时间计数
u8 Bool500msOn = 0; // 0.5s是否达到
u8 LedInfo = 0xff; // LED灯状态信息
u8 LedCounter = 0; // LED计数,切换灯
u8 RelayCounter = 0; // 继电器计数,打开时间
u8 BuzzCounter = 0; // 蜂鸣器计数,蜂鸣时间
u8 BoolRelay = 0; // 继电器是否启用
u8 BoolBuzz = 0; // 蜂鸣器是否启用
u8 LedStatus = 0; // LED状态机
u8 RelayStatus = 0; // 继电器状态机
u8 BuzzStatus = 0; // 蜂鸣器状态机
void Timer0_Init(void) // 5毫秒@12.000MHz,STC-ISP产生
{
AUXR |= 0x80; // 定时器时钟1T模式
TMOD &= 0xF0; // 设置定时器模式
TL0 = 0xA0; // 设置定时初始值
TH0 = 0x15; // 设置定时初始值
TF0 = 0; // 清除TF0标志
TR0 = 1; // 定时器0开始计时
ET0 = 1; // 使能定时器0中断
EA = 1;
}
void LedProc()
{
switch (LedStatus)
{
case 0: // 默认状态为3次闪烁
LedInfo = ~LedInfo;
Led(LedInfo);
if (LedCounter++ == 5) // 计到5时,正好是3次亮灭重复出现
{
LedStatus = 1; // 切换到下一个状态机
LedCounter = 0; // 计数归0
LedInfo = 0xff; // 设置下个状态的LED状态
}
break;
case 1: // 依次点亮情况
LedInfo = LedInfo << 1; // 左移
Led(LedInfo); // 点亮
if (++LedCounter == 8) // 一共8位LED,所以计数8
{
LedStatus = 2; // 切换状态机
LedCounter = 0; // 计数归0
BoolRelay = 1; // 依次点亮LED后,就是操作继电器,所以设定继电器状态启用
}
break;
case 2: // 等待状态,等待继电器 吸合 再断开后,进行依次熄灭LED的中间过渡
LedInfo = 0x00; // 因为依次熄灭使用的是取反操作,所以初始状态设为0x00。
if (!BoolRelay) // 继电器关闭,进入LED下一状态
LedStatus = 3;
break;
case 3:
LedInfo = ~(0xff << ++LedCounter); // 依次熄灭
Led(LedInfo);
if (LedCounter == 8) // LED8位,所以计数8
{
LedStatus = 4; // LED依次熄灭后,需要操作蜂鸣器,所以再加一个状态4
LedCounter = 0; // 计数归0
LedInfo = 0xff; // 状态0时进入LED初始情况
BoolBuzz = 1; // 蜂鸣器准备启用
}
break;
case 4:
if (!BoolBuzz) // 蜂鸣器关闭,开始回到最初3次8位LED闪烁情况
LedStatus = 0;
}
}
void RelayProc()
{
switch (RelayStatus)
{
case 0: // 默认状态,等待继电器启用
if (BoolRelay)
RelayStatus = 1; // 启用后,进入下一状态
break;
case 1:
Relay(0x10); // 继电器吸合情况
if (RelayCounter++ == 2) // 1s,此处可调整
RelayStatus = 2; // 吸合一会后,要断开,进入状态2,即要断开
break;
case 2:
Relay(0x00); // 继电器断开
RelayStatus = 0; // 继电器状态归 0
BoolRelay = 0; // 继电器关闭
RelayCounter = 0; // 计数归0
break;
}
}
void BuzzProc()
{
switch (BuzzStatus)
{
case 0: // 蜂鸣器初始状态,等待启用
if (BoolBuzz)
BuzzStatus = 1; // 启用,转到下一状态
break;
case 1:
Buzz(0x40); // 蜂鸣器响,
if (BuzzCounter++ == 2) // 1s,响的时长,可调整
BuzzStatus = 3; // 进入下一状态
break;
case 3:
Buzz(0x00); // 蜂鸣器关闭
BuzzStatus = 0; // 状态归0,关闭
BuzzCounter = 0; // 计数归0
BoolBuzz = 0; // 蜂鸣器不启用
break;
default:
break;
}
}
void main()
{
Led(0xFF); // 设置LED初始状态
Timer0_Init(); // 启用定时器
while (1)
{
if (Bool500msOn) // 达到计数间隔,0.5s,可调整
{
LedProc(); // 操作LED
RelayProc(); // 操作继电器
BuzzProc(); // 操作蜂鸣器
}
Bool500msOn = 0; // 重新计数
}
}
void Timer0_Isr(void) interrupt 1
{
if (TimerCounter++ == 100) // 0.5s
{
TimerCounter = 0;
Bool500msOn = 1;
}
}