找回密码
 立即注册
楼主: lclbf

8H2K12U制作电风扇遥控器

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:344
  • 最近打卡:2025-05-09 07:44:58

19

主题

205

回帖

844

积分

高级会员

积分
844
发表于 2024-10-29 21:45:47 | 显示全部楼层
关于PWM实现调速,遇到问题如下:
    单独用PWM输出,改变占空比可以实现速度变化,把PWM部分加入前面遥控功能正常的程序
    里面,不能要控。
程序代码如下:
/***********************
OUT(低电平可控硅导通) P54 1     8 P33 P11(蜂鸣器输出,高电平有效)
                                                                                        VCC 2     7 P32 P10 INTN0(遥控输入)
                      CAP 3     6 P31
                      GND 4     5 P30(按键)

遥控器键码值
                        01
                       
                        00
                       
                        01                        09
                       
                                        05
                                       
                        02        06        0A
                       
                                        04
                                       
                        03        07        0B
                       
                        40      48
                       
                                        44
***********************/
#include <STC8h.h>
#include <intrins.h>

/* IO引脚分配定义 */
sbit LED = P5^4;
sbit BUZZ = P3^3;
sbit KEY = P3^0;
bit LEDflag = 0; //0关闭风扇,1打开风扇
unsigned  char LEDSta = 1; //1,关闭风扇
unsigned char i = 0;
unsigned int Duty100 = 50000;
bit flag20ms = 0;
unsigned int flag1s;

bit AUOTOFF1 = 0;
bit AUOTOFF2 = 0;
bit AUOTOFF3 = 0;

extern bit irflag;
extern unsigned char ircode[4];
extern void InitInfrared();

#define PWM6_2      0x04        //P5.4

#define ENO6P       0x04
#define Duty        Duty100
#define Frequency   50000

void PWMB_config(void);
void Duty1(void);
void Duty2(void);
//void Duty3(void);

void kongzhi();
void Intimer1Init(); //12MHZ12T 1US
void myInit();

void main()
{
        unsigned int cnt = 0;
       
        myInit();
//        PWMB_config();
       
        EA = 1;      //开总中断       
       
        Intimer1Init();
        InitInfrared();   //初始化红外功能
       
        LED = 1;
        while (1)
        {
                PWMB_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,
                if(flag20ms==1)
                {
                        flag20ms = 0;
                       
                        kongzhi();                       
                }               
        }
}

void myInit()
{
        P_SW2 |= 0X80;
       
        P0M0 = 0XFF;
        P0M1 = 0X00;
        P1M0 = 0x00;
        P1M1 = 0x03;
        P2M0 = 0XFF;
        P2M1 = 0X00;
        P3M0 = 0XFB;
        P3M1 = 0X00;
        P4M0 = 0XFF;
        P4M1 = 0X00;
        P5M0 = 0XFF;
        P5M1 = 0X00;
       
        LED = 1;
}


//void Delay20ms(void)        //@11.0592MHz
//{
//        unsigned char data i, j, k;

//        i = 2;
//        j = 32;
//        k = 60;
//        do
//        {
//                do
//                {
//                        while (--k);
//                } while (--j);
//        } while (--i);
//}

void kongzhi()
{       
        if (irflag)  //接收到红外数据时刷新显示
                {
                        irflag = 0;
                        if (ircode[2] == 0x01)  //0x01为+键码ON,开风扇
                        {
                                LEDflag = 1;
                                LEDSta = 0;
                        }

                        else if (ircode[2] == 0x09)  //0x09为-键码OFF,关风扇
                        {
                                LEDflag = 0;
                                LEDSta = 1;
                        }
                        else if ((ircode[2] == 0x02)&&(1==LEDflag))  //0x02为-键码+,风扇1档风,最大
                        {
                                LEDflag = 1;
                                LEDSta = 2;
                        }
                        else if ((ircode[2] == 0x06)&&(1==LEDflag))  //0x06为-键码M,风扇2档风,最次大
                        {
                                LEDflag = 1;
                                LEDSta = 3;
                        }
                        else if ((ircode[2] == 0x0A)&&(1==LEDflag))  //0x0A为-键码-,风扇3档风,最小
                        {
                                LEDflag = 1;
                                LEDSta = 4;                                                                                               
                        }
                        else if((ircode[2] == 0x40)&&(1==LEDflag)) //40 3H 遥控定时3H关机按键
                        {
                                AUOTOFF1 = 1;
                                flag1s = 0;
                        }       
                        else if((ircode[2] == 0x48)&&(1==LEDflag)) //48 5H 遥控定时5H关机按键
                        {
                                AUOTOFF2 = 1;
                                flag1s = 0;
                        }       
                        else if((ircode[2] == 0x44)&&(1==LEDflag)) //44  8H 遥控定时8H关机按键
                        {
                                AUOTOFF3 = 1;
                                flag1s = 0;
                        }       
        }
        if(AUOTOFF1==1)
        {
                if(flag1s>=10800)
                {
                        LEDflag = 0;
                        LEDSta = 1;
                        AUOTOFF1 = 0;
                }
        }
        else if(AUOTOFF2==1)
        {
                if(flag1s>=18000)
                {
                        LEDflag = 0;
                        LEDSta = 1;
                        AUOTOFF2 = 0;
                }
        }
        else if(AUOTOFF3==1)
        {
                if(flag1s>=28800)
                {
                        LEDflag = 0;
                        LEDSta = 1;
                        AUOTOFF3 = 0;
                }
        }
                       
        switch(LEDSta)
        {

                case 0:LED = 0;break;
                case 1:LED = 1;break;
                case 2:LED = 0;break;
                case 3:
//                                        LED = 0;
//                                        Delay20ms();Delay20ms();Delay20ms();
//                                        Delay20ms();Delay20ms();Delay20ms();
//                                        Delay20ms();Delay20ms();Delay20ms();
//                                        Delay20ms();Delay20ms();Delay20ms();
//                                        Delay20ms();
//                                        LED = 1;
//                                        Delay20ms();
                                        Duty1();
                                        break;
                case 4:
//                                        LED = 0;
//                                        Delay20ms();Delay20ms();Delay20ms();
//                                        Delay20ms();Delay20ms();Delay20ms();
//                                        Delay20ms();
//                                        LED = 1;                                                       
//                                        Delay20ms();
                                        Duty2();
                                        break;
                default:break;
        }
}

void Intimer1Init() //12MHZ12T 1mS
{
        TMOD &= 0X0F;
        TMOD |= 0X10;
        TH1 = 0XFC;
        TL1 = 0X18;
        ET1 = 1;
        TR1 = 1;
}


void Intimer1() interrupt 3
{
        static unsigned char cnt = 0;
        static unsigned int cnt1s = 0;
       
        TH1 = 0XFC;  //12MHz 1ms
        TL1 = 0X18;
       
        cnt++;
        if(cnt>=20)
        {
                cnt = 0;
                flag20ms = 1; //20ms
        }
        cnt1s++;
        if(cnt1s>=1000)
        {
                cnt1s = 0;
                if(flag1s<65535)
                {
                        flag1s++;         //1s++
                }
        }
}

void PWMB_config(void)
{
        P_SW2 |= 0x80;                //SFR enable   

        PWMB_PSCR = 0x0000;        // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
        PWMB_DTR  = 0;                // 死区时间配置,   n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,  
                                                // 对PWMB没有意义  0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
        PWMB_ARR = Frequency;        // 自动重装载寄存器,  控制PWM周期
        PWMB_CCER1  = 0;
        PWMB_CCER2  = 0;
        PWMB_SR1    = 0;
        PWMB_SR2    = 0;
        PWMB_ENO    = 0;                // IO输出允许,  bit6: ENO8P, bit4: ENO7P,  bit2: ENO6P,  bit0: ENO5P
        PWMB_PS     = 0;
        PWMB_IER    = 0;

        PWMB_CCMR2  = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
        PWMB_CCR6   = Duty;                // 比较值, 控制占空比(高电平时钟数)
        PWMB_CCER1 |= 0x10;                // 开启比较输出, 高电平有效
        PWMB_PS    |= (1<<2);        // 0:选择P2.1, 1:选择P5.4, 2:选择P0.1, 3:选择P7.5,
        PWMB_ENO   |= 0x04;                // IO输出允许,  bit6: ENO8P, bit4: ENO7P,  bit2: ENO6P,  bit0: ENO5P
//        PWMB_IER   |= 0x04;                // 使能中断

        PWMB_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
        PWMB_BKR    = 0x80;                // 主输出使能 相当于总开关
        PWMB_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
}


void Duty1(void)
{
        Duty100 = 40000;
}

void Duty2(void)
{
        Duty100 = 10000;
}

//void Duty3(void)
//{

//}
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-9 09:23 , Processed in 0.104970 second(s), 45 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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