找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 579|回复: 0
打印 上一主题 下一主题
收起左侧

单片机光电计数程序设计

[复制链接]
跳转到指定楼层
楼主
光电计数




单片机源程序如下:
#include <reg51.h>
#include <intrins.h>

sbit irled = P1^0;        // 红外LED输出引脚
sbit irrec = P3^2;        // 光电接收器输入引脚
sbit led1 = P2^0;         // LED1输出引脚,第一位数码管
sbit led2 = P2^1;         // LED2输出引脚,第二位数码管
sbit led3 = P2^2;         // LED3输出引脚,第三位数码管

unsigned int counter = 0; // 计数器变量,取值0~999
unsigned int alarm = 999; // 报警阈值变量,取值0~999,初始值999
unsigned char delay_count = 0; // 延时计数器变量,取值0~30,用于关闭报警延时30秒
unsigned char alarm_enabled = 0; // 报警标志位,0表示未触发报警,1表示已触发报警
```

2. 定义一个延时函数,并在主函数中初始化计时器和中断:

```
void delay(unsigned int t)
{
    unsigned int i, j;
    for (i = 0; i < t; i++)
    {
        for (j = 0; j < 120; j++)
        {
            _nop_();
        }
    }
}

void main()
{
    TMOD = 0x01; // 定时器0工作模式为16位自动重装计数模式
    TH0 = 0xFC;  // 定时器高位,计时0.1秒
    TL0 = 0x18;  // 定时器低位,计时0.1秒
    TR0 = 1;     // 启动计时器
    ET0 = 1;     // 允许计时器中断
    EA = 1;      // 允许总中断

    while (1)
    {
        // TODO: 添加其他功能代码
    }
}
```

3. 在主函数中添加计数器、报警阈值的设置和处理逻辑,以及对应的LED显示、报警控制、计数重置等:

```
// 报警控制函数,声音和光线均有警示效果
void alarm_on()
{
    if (delay_count == 0)      // 延时时间到达
    {
        if (alarm_enabled == 0) // 报警未启用
        {
            alarm_enabled = 1;  // 启用报警标志
            led2 = 1;           // LED2闪烁
            for (int i = 0; i < 6; i++)
            {
                irled = i % 2;
                delay(200);
            }
        }
        else                      // 报警已启用
        {
            alarm_enabled = 0;   // 关闭报警标志
            delay_count = 0;      // 延时清零
            led2 = 0;             // LED2熄灭
            irled = 0;            // 关闭红外LED
        }
    }
    else                        // 延时时间未到
    {
        delay_count--;          // 延时计数器减少
    }
}

// 重置计数器和LED显示
void reset()
{
    counter = 0;
    led1 = 0; led2 = 0; led3 = 0; // 清空LED显示
}

// 主函数中添加的其他功能代码
void main()
{
    // 省略计时器和中断的初始化

    while (1)
    {
        // 检测红外LED是否需要开启
        if (counter > alarm && !alarm_enabled)
        {
            irled = 1;
        }
        else if (counter <= alarm || alarm_enabled)
        {
            irled = 0;
        }

        // 检测光电接收器状态变化,更新计数器和LED显示
        if (irrec == 0) // 光电接收器输入信号有效
        {
            delay(1);   // 短暂延时去抖动
            if (irrec == 0) // 仍有效
            {
                counter++;  // 计数器加1
                if (counter >= 1000) // 计数器溢出,报警并重置计数器
                {
                    alarm_on();
                    reset();
                }
                else
                {
                    // 更新LED显示
                    led1 = counter / 100; // 显示百位数字
                    led2 = (counter % 100) / 10; // 显示十位数字
                    led3 = counter % 10; // 显示个位数字   
                }

                // 检测是否触发报警,并更新延时计数器
                if (counter > alarm && !alarm_enabled)
                {
                    delay_count = 30;
                }
                else if (counter <= alarm || alarm_enabled)
                {
                    delay_count = 0;
                }
            }
        }

        // 检测加减按钮状态变化,更新报警阈值和LED显示
        // TODO: 添加按键检测和处理代码
    }
}



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表