单元训练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;
    }
}
相关推荐
a东方青24 分钟前
[蓝桥杯 2023 国 B] AB 路线 (BFS)
c++·算法·职场和发展·蓝桥杯·宽度优先
aerror3 小时前
使用mpu6500/6050, PID,互补滤波实现一个简单的飞行自稳控制系统
单片机·飞控
WIZnet 中国社区官方博客4 小时前
【第二十三章 IAP】
嵌入式硬件·wiznet·高性能以太网单片机·w55mh32·单片机外设·iap简介·iap程序设计
yifa201604046 小时前
STM32、Arduino和51单片机
stm32·学习·51单片机
tyl21108 小时前
凌科芯安国产安全MCU简介
单片机·嵌入式硬件·安全
郦7778 小时前
国产入门级32位单片机PY32F002A开发板
单片机·嵌入式硬件
电院工程师8 小时前
轻量级密码算法CHAM的python实现
python·嵌入式硬件·算法·安全·密码学
咚咚轩9 小时前
蓝桥杯第十届国B 求值
蓝桥杯
飞凌嵌入式9 小时前
基于RK3588,飞凌教育品牌推出嵌入式人工智能实验箱EDU-AIoT ELF 2
linux·人工智能·嵌入式硬件·arm·nxp
13631676419侯17 小时前
ESP32-C3FH4X—低功耗、高集成度的 MCU 系统级芯片 (SoC)
嵌入式硬件·智能家居·芯片