[分享]51模拟PWM控制LED

2020-01-15 19:19发布

看了论坛上的所发的51模拟PWM来控制LED亮度变化,现在自己整理一下调试通过,感觉效果不错,回报大家献上源码

如果有什么不好,请大家指教,并指出,谢谢!

#include"delay.h"
//#include"com.h"
#include"key.h"
#include"beep.h"

sfr  T2MOD = 0xC9;                // 定时器2

#define         PWM_COUST        10                                // PWM细分数
volatile unsigned char PWM_H;                         // PWM占空比调节
volatile unsigned char PWM_CNT = 0;                // PWM自增值

/***************************************************************
*                                                定时器2中断程序
***************************************************************/
void Timer2(void) interrupt 5 using 1
{
        if (PWM_CNT < PWM_H)                 // 预设占空比输出
        {
                P1 = 0x00;                // 开LED               
        }
        else
        {
                P1 = 0xFF;                // 关LED
        }

        if (PWM_CNT >= PWM_COUST)        // PWM计数清零
        {
                PWM_CNT = 0;
        }
        else
        {
                PWM_CNT ++;                // 自增值加1
        }       
}

/***************************************************************
*                                                定时器2初始化
***************************************************************/
#define MSB_reload_value 0xDB         // msb reload value exemple 高位重载值:延时10ms
#define LSB_reload_value 0xF0         // lsb reload value exemple 低位重载值
void Timer2Init(void)
{
        // T2OE=0;定时器2输出不允许  
        T2MOD = 0x01;        // DCEN=1;可以设置为向上/下计数:此程序中为向上达到0xff时溢出
        T2CON = 0;                // TF2 EXF2 RCLK TCLK EXEN2 TR2 C_T2 CP_RL2
        // EXF2=0;  reset flag 定时器2外部标志位清除
        // TCLK=0;RCLK=0;  disable baud rate generator 不用于波特率发生器
        // EXEN2=0; ignore events on T2EX 视T2EX(P1.1)端信号无效
        // C_T2=0; timer mode 定时模式
        // CP_RL2=0;  reload mode 重载模式
        TH2           = MSB_reload_value; // Init msb_value 填入初始化值
        TL2           = LSB_reload_value; // Init lsb_value  
        RCAP2H = MSB_reload_value; // reload msb_value重载值  
        RCAP2L = LSB_reload_value; // reload lsb_value  

        ET2 = 1;         // enable timer2 interrupt 允许T2中断
}


void Init(void)
{
        DelayMs(100);                // 等待系统稳定
       
        P0 = 0xFF;                        // 初始化IO
        P1 = 0xFF;
        P2 = 0xFF;
        P3 = 0xFF;
       
        //InitSerial();                // 串口初始化

        Timer2Init();                // 定时器2初始化
        EA  = 1;                    // 开总中断

        PWM_H         = 5;                // 初始占空比5
        PWM_CNT = 0;                // 初始化PWM自增值
}
       
main()
{
        unsigned char ucKey;

        Init();                // 初始化

        TR2 = 1;        // 启动定时器2
        while(1)
        {
                ucKey = KeyScan();                // 读取键盘值

                if (ucKey != ValNull)        // 如果不为空
                {
                        if (ucKey == ValKey1)        // 如果等于key1
                        {
                                if (PWM_H <= PWM_COUST)  // 如果PWM_H在PWM范围内
                                {
                                        PWM_H ++;                         // 增加PWM_H
                                }
                                else
                                {
                                        BeepMs(5);                // 等于最大值报警
                                }
                        }
                        if (ucKey == ValKey2)         // 如果等于key2
                        {
                                if (PWM_H)                        // 如果PWM_H不等于0
                                {
                                        PWM_H --;            //  减少PWM_H
                                }
                                else
                                {
                                        BeepMs(1);                 // 等于最小值报警
                                }
                        }
                        //SendByte(PWM_H);        // 串口发送当前PWM_H
                }
                //_CLRWDT_        // 清看门口
        }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。