单元训练02:蜂鸣器与继电器的控制

蓝桥杯

小蜜蜂

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;
    }
}
相关推荐
清风66666637 分钟前
基于单片机的螺旋藻生长大棚PH智能控制设计
单片机·嵌入式硬件·毕业设计·课程设计
ting_zh2 小时前
微控制器(Micro Controller Unit, MCU)基础整理
单片机·嵌入式硬件
清风6666662 小时前
基于单片机的图书馆智能座位管理平台
数据库·单片机·嵌入式硬件·毕业设计·课程设计
得单片机的运4 小时前
STM32的以太网的搭建
stm32·单片机·嵌入式硬件·物联网·以太网·iot·w5500
酷飞飞4 小时前
RTC和看门狗基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·mcu
WD137298015576 小时前
WD5030A,24V降5V,15A 大电流,应用于手机、平板、笔记本充电器
stm32·单片机·嵌入式硬件·智能手机·汽车·电脑·51单片机
日更嵌入式的打工仔6 小时前
GPIO 中断通用配置指南
stm32·单片机·嵌入式硬件
平凡灵感码头6 小时前
基于 STM32 的智能门锁系统,系统界面设计
stm32·单片机·嵌入式硬件
Truffle7电子8 小时前
STM32理论 —— 存储、中断
stm32·嵌入式硬件·嵌入式·存储·中断
报错小能手8 小时前
linux学习笔记(32)网络编程——UDP
单片机·嵌入式硬件