- 打卡等级:以坛为家I
- 打卡总天数:344
- 最近打卡:2025-05-09 07:44:58
高级会员
- 积分
- 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)
//{
//} |
|