热心网友
回答时间:2025-02-14 11:00
STC89C52好象不带硬件PWM功能,建议用STC12C5A系列 和STC89C52管脚兼容,带AD和PWM功能,如果用不了那么多管脚的话,也可用STC12C5410 或STC12C5628系列
我可以给你一个手动PWM程序供参考
STC单片机单/双键控制LED亮度PWM调光程序
输出口为P3.7(PWM0) S2 S3为亮度调节(可用来调速)按钮
液晶屏LCD1602用来显示1-20亮度或速度级数,可以去掉
************************************************/
#include<STC12C54.H>
#define uchar unsigned char
#define uint unsigned int
uchar vx=10;
//vx=10 在上电时为半亮度状态,可根据自己的用途及要求任意设定 vx=20为最亮
sbit rw=P1^4;
sbit rs=P1^3;
sbit lcden=P1^5;
sbit s2=P3^2;
sbit s3=P3^3;
sbit led=P3^7;
#define db P2
void Delay1ms(uint i) //1ms延时程序
{
uint j;
for(;i>0;i--)
{
for(j=0;j<125;j++)
{;}
}
}
void write_com(uchar com) //液晶屏写命令
{
db=com;
rs=0;
rw = 0;
lcden=0;
Delay1ms(10);
lcden=1;
Delay1ms(10);
lcden=0;
}
void write_date(uchar date)//液晶屏写数据
{
db=date;
rs=1;
rw = 0;
lcden=0;
Delay1ms(10);
lcden=1;
Delay1ms(10);
lcden=0;
}
void init2()//液晶屏初始化
{
rw=0;
write_com(0x38);
Delay1ms(10);
write_com(0x0f);
Delay1ms(10);
write_com(0x06);
Delay1ms(10);
write_com(0x01);
Delay1ms(10);
}
void display_brightness (uchar temp1) //I液晶屏显示程序 级数
{
uchar A1,A2;
init2();
A1=temp1/10;
A2=temp1%10;
write_com(0x80);
Delay1ms(10);
write_date(0x30+A1);
write_com(0x81);
Delay1ms(10);
write_date(0x30+A2);
}
/*******************************************************************************/
void PWM_init (void){//PWM初始化函数
CMOD=0x02; //设置PCA定时器
CL=0x00;
CH=0x00;
CCAPM0=0x42; //PWM0设置PCA工作方式为PWM方式(0100 0010)
CCAP0L=0x00; //设置PWM0初始值与CCAP0H相同
CCAP0H=0x00; // PWM0初始时为0
CR=1; //启动PCA定时器
}
/******************************************************************************/
void PWM1_set (uchar a){//PWM1占空比设置函数
CCAP0L=a; //设置值直接写入CCAP1L
CCAP0H=a; //设置值直接写入CCAP1H
}
/*****************************************************************************/
void DelayM(unsigned int a){//延时函数 1mS/次(用于1T单片机)
unsigned char n,i,j;
while(--a!=0){
for(n=1;n>0;n--)
for(j=222;j>0;j--)
for(i=12;i>0;i--);
} }
/****************************************************************************/
void main(void)
{
s2= 1;
s3 = 1;
PWM_init ();
display_brightness (vx);
while(1)
{
PWM1_set(vx*12);//数字12是配合vx调试取得的,此时vx的赋值范围约为1-20对应最暗-最亮
if (s2 == 0 )//--------减调整---------//
{
DelayM(20); //延时20毫秒消抖动
if(s2 == 0) //如果20SM后KEY_L还是0状态则确认下调键是按下的
{
vx--;
if(vx<1) //如果设定vx=20,将语句改为if(vx<1){vx=10;}则为单按键循环控制,则可去除加调整控制部分
{
vx=10;
}
}
display_brightness (vx);
while(s2 == 0);//等待键松开
}
//--------加调整---------//
if (s3== 0 )
{
DelayM(20);
if(s3 == 0)
{
vx++;
if(vx>20)
{
vx=10;
}
}
display_brightness (vx);
while(s3 == 0);
}
}
}
收起