lclbf 发表于 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打开风扇
unsignedchar 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;
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 == 0x01)//0x01为+键码ON,开风扇
                        {
                                LEDflag = 1;
                                LEDSta = 0;
                        }

                        else if (ircode == 0x09)//0x09为-键码OFF,关风扇
                        {
                                LEDflag = 0;
                                LEDSta = 1;
                        }
                        else if ((ircode == 0x02)&&(1==LEDflag))//0x02为-键码+,风扇1档风,最大
                        {
                                LEDflag = 1;
                                LEDSta = 2;
                        }
                        else if ((ircode == 0x06)&&(1==LEDflag))//0x06为-键码M,风扇2档风,最次大
                        {
                                LEDflag = 1;
                                LEDSta = 3;
                        }
                        else if ((ircode == 0x0A)&&(1==LEDflag))//0x0A为-键码-,风扇3档风,最小
                        {
                                LEDflag = 1;
                                LEDSta = 4;                                                                                               
                        }
                        else if((ircode == 0x40)&&(1==LEDflag)) //40 3H 遥控定时3H关机按键
                        {
                                AUOTOFF1 = 1;
                                flag1s = 0;
                        }       
                        else if((ircode == 0x48)&&(1==LEDflag)) //48 5H 遥控定时5H关机按键
                        {
                                AUOTOFF2 = 1;
                                flag1s = 0;
                        }       
                        else if((ircode == 0x44)&&(1==LEDflag)) //448H 遥控定时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)
//{

//}
页: 1 [2]
查看完整版本: 8H2K12U制作电风扇遥控器