字数统计:0
阅读时间:0 分钟
Toni·Wang
Toni·Wang
发布于 2025-03-20 / 10 阅读
0
0

第一个实训作业通过proteus与keil实现简单的开关灯

前言

昨天也就是星期三,倒数第二节实训课。老师给我们布置了一个实训作业。目的是通过Proteus和keil实现继电器控制白炽灯的亮灭,以及用数码管记录次数.
进阶玩法通过变压器,电桥,稳压器将220V转化成5V的元

Proteus

器件

主体

No. Component Quantity Specifications
1 AT89C51 1 8-bit microcontroller
2 RES 3 1kΩ (×1), 200Ω (×1), 10kΩ (×1)
3 CAP 2 30pF
4 DIO 1 -
5 BUTTON 3 -
6 LED-GREEN 1 -
7 NPN 1 Transistor
8 VSINE 1 Sine wave voltage source
9 RX8 1 -
10 7SEG-COM-AN-GRN 1 Common anode green 7-segment display
11 LAMP 1 -
12 RELAY 1 -
13 CAP ELEC 1 Electrolytic capacitor
14 GROUND 2 -
14 CRYSTAL 1 -

变压器

No. Component Quantity Specifications
1 VSINE 1 Sine wave voltage source
2 TRAN-2P2S 1 Transformer with 2 primary and 2 secondary windings
3 BRIDGE 1 Bridge rectifier
4 CAP 3 100μF (×2), 1nF (×1)
5 7805 1 5V voltage regulator
6 GROUND 1 Ground connection

配置

主体

  1. 主体的RX8设置为100
  2. VSINE设置为220v50Hz

变压器

  1. VSINE 220v 50Hz
  2. TRAN-2P2S 1H 0.015H

示意图

2538748908.png

2979729470.png

keil

代码

#include <reg51.h>

// 定义 P2 口的位
sbit LED = P1^7;
sbit BUTTON = P3^6;
sbit LAMP = P3^2;
sbit SWITCH1 = P1^2;  // 双控开关位置在P1.2

// 数码管段码表(共阳极)
unsigned char code SEG_CODE[] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

// 延时函数,延时 1ms
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 123; j++);
}

// 串口初始化函数
void UART_Init() {
    TMOD = 0x20;  // 设置定时器 1 为模式 2
    TH1 = 0xFD;   // 波特率 9600
    TL1 = 0xFD;
    SCON = 0x50;  // 设置串口为模式 1
    TR1 = 1;      // 启动定时器 1
}

// 串口发送字符函数
void UART_SendChar(unsigned char c) {
    SBUF = c;
    while (TI == 0);
    TI = 0;
}

// 主函数
void main() {
    unsigned char count = 0;
    bit button_state = 0;
    bit switch_state = 0;
    bit led_state = 0;
    LAMP = 0;

    P0 = 0xFF;  // 模拟上拉电阻
    UART_Init(); // 初始化串口

    while (1) {
        // 检测双控开关状态变化
        if (SWITCH1 == 0) {
            delay_ms(20);  // 消抖
            if (SWITCH1 == 0 && !switch_state) {
                switch_state = 1;
            
                // 增加计数值
                if (count < 15) {
                    count++;
                } else {
                    count = 0;  // 复位计数
                }
            
                // 在数码管上显示计数
                P0 = SEG_CODE[count];
            
                // 通过串口发送当前段码值
                UART_SendChar(SEG_CODE[count]);
            
                // 切换LED状态
                if (!led_state) {
                    LED = 0; 
                    led_state = 1;
                    LAMP = 1;
                } else {
                    LED = 1; 
                    LAMP = 0;
                    led_state = 0;
                }
            
                delay_ms(100);  // 增加显示延时
            }
        } else {
            switch_state = 0;
        }
    
        // 原有按钮检测逻辑
        if (BUTTON == 0) {
            delay_ms(20);  // 消抖
            if (BUTTON == 0) {
                if (!button_state) {
                    button_state = 1;
                    if (count < 15) {
                        count++;
                    } else {
                        count = 0;  // 复位计数
                    }
                    P0 = SEG_CODE[count];  // 在数码管上显示计数
                    delay_ms(100);  // 增加显示延时

                    // 通过串口发送当前段码值
                    UART_SendChar(SEG_CODE[count]);

                    if (!led_state) {
                        LED = 0;  // 开灯
                        led_state = 1;
                        LAMP = 1;
                    } else {
                        delay_ms(200);  // 延时 200ms
                        LED = 1;  // 关灯
                        LAMP = 0;
                        led_state = 0;
                    }
                }
            }
        } else {
            button_state = 0;
        }
    }
}

链接

gitee:https://gitee.com/blankzsh/proteus
lanzou: https://saem.lanzouq.com/i2FrT2r3rwbi


评论