I Love mcu
欢迎光临我爱单片机博客!

基于51单片机的编码器调节灯光亮度C51源码

基于51单片机的编码器调节灯光亮度源码,编码器调节0-100的亮度值通过串口发送到灯具的控制板(也是单片机控制)进行调光。本人公司项目分享。
#include <reg52.h>

 

// 定义编码器引脚
sbit ENC_A = P3^2;  // 编码器A相 – 连接到外部中断0
sbit ENC_B = P3^3;  // 编码器B相 – 连接到外部中断1

 

// 全局变量
unsigned char encoder_value = 0;     // 当前编码器值 (0-100)
unsigned char last_enc_a = 1;        // 上一次A相状态
unsigned char debounce_timer = 0;    // 消抖定时器计数器
bit debounce_flag = 0;               // 消抖标志

 

// 串口初始化 – 115200波特率, 8位数据, 1位停止位, 无校验
void UART_Init(void) {
    TMOD |= 0x20;   // 定时器1工作在模式2 (自动重装)
    TH1 = 0xFA;     // 115200波特率 @ 11.0592MHz
    TL1 = 0xFA;
    TR1 = 1;        // 启动定时器1
    SCON = 0x50;    // 串口工作在模式1, 允许接收
    EA = 1;         // 开启总中断
    ES = 1;         // 开启串口中断
}

 

// 定时器0初始化 – 用于消抖, 约1ms中断一次
void Timer0_Init(void) {
    TMOD |= 0x01;   // 定时器0工作在模式1 (16位)
    TH0 = (65536 – 1000) / 256;   // 1ms @ 11.0592MHz
    TL0 = (65536 – 1000) % 256;
    TR0 = 1;        // 启动定时器0
    ET0 = 1;        // 开启定时器0中断
}

 

// 外部中断初始化
void EXTI_Init(void) {
    IT0 = 1;        // 外部中断0下降沿触发
    IT1 = 1;        // 外部中断1下降沿触发
    EX0 = 1;        // 开启外部中断0
    EX1 = 1;        // 开启外部中断1
}

 

// 发送字符串
void UART_Send_String(unsigned char *str) {
    while(*str) {
        SBUF = *str++;
        while(!TI);
        TI = 0;
    }
}

 

// 发送数字 (0-100)
void UART_Send_Number(unsigned char num) {
    unsigned char buf[4];
    buf[3] = ‘\0’;
    buf[2] = num % 10 + ‘0’;
    buf[1] = (num / 10) % 10 + ‘0’;
    buf[0] = (num / 100) % 10 + ‘0’;
    // 去除前导零
    if(buf[0] == ‘0’) {
        if(buf[1] == ‘0’) {
            UART_Send_String(&buf[2]);
        } else {
            UART_Send_String(&buf[1]);
        }
    } else {
        UART_Send_String(buf);
    }
}

 

// 定时器0中断服务程序 – 消抖处理
void Timer0_ISR() interrupt 1 {
    TH0 = (65536 – 1000) / 256;   // 重装初值
    TL0 = (65536 – 1000) % 256;
    if(debounce_flag) {
        debounce_timer++;
        // 消抖时间约10ms (10次中断)
        if(debounce_timer >= 10) {
            debounce_flag = 0;
            debounce_timer = 0;
        }
    }
}

 

// 编码器处理函数
void Process_Encoder(void) {
    unsigned char current_a = ENC_A;
    if(current_a != last_enc_a && !debounce_flag) {
        // 检测旋转方向
        if(ENC_B != current_a) {
            // 顺时针旋转 – 数值增加
            if(encoder_value < 100) {
                encoder_value++;
            }
        } else {
            // 逆时针旋转 – 数值减少
            if(encoder_value > 0) {
                encoder_value–;
            }
        }
        // 发送当前值
        UART_Send_Number(encoder_value);
        UART_Send_String(“\r\n”);
        last_enc_a = current_a;
        debounce_flag = 1;
        debounce_timer = 0;
    }
}

 

// 外部中断0服务程序 – 编码器A相触发
void EXTI0_ISR() interrupt 0 {
    Process_Encoder();
}

 

// 外部中断1服务程序 – 编码器B相触发
void EXTI1_ISR() interrupt 2 {
    Process_Encoder();
}

 

// 主函数
void main(void) {
    UART_Init();    // 初始化串口
    Timer0_Init();  // 初始化定时器0 (消抖用)
    EXTI_Init();    // 初始化外部中断
    UART_Send_String(“Encoder Ready!\r\n”);
    UART_Send_String(“Current Value: “);
    UART_Send_Number(encoder_value);
    UART_Send_String(“\r\n”);
    while(1) {
        // 主循环 – 可添加其他任务
    }
}

 

赞(0) 打赏
分享到

评论 抢沙发

评论前必须登录!

 

我爱单片机博客

单片机开发、学习、交流与分享博客!

关于我们联系我们

登录

找回密码

注册