#include<reg51h>
sbit PWMOUT=P1^0;
unsigned char PWM=5;//此处调节占空比
unsigned char n=0;
void Init()
{
EA=1;
ET0=1;
TMOD=0X01;
TH0=0Xfe;
TL0=0X33;
TR0=1;
}
bit PWMOption(unsigned char nn)
{
static bit temp;
switch(nn)
{
case 0:
temp=0;
break;
case 1:
if(n>1)
temp=0;
else
temp=1;
break;
case 2:
if(n>2)
temp=0;
else
temp=1;
break;
case 3:
if(n>3)
temp=0;
else
temp=1;
break;
case 4:
if(n>4)
temp=0;
else
temp=1;
break;
case 5:
if(n>5)
temp=0;
else
temp=1;
break;
case 6:
if(n>6)
temp=0;
else
temp=1;
break;
case 7:
if(n>7)
temp=0;
else
temp=1;
break;
case 8:
if(n>8)
temp=0;
else
temp=1;
break;
case 9:
if(n>9)
temp=0;
else
temp=1;
break;
case 10:
temp=1;
break;
}
return temp;
}
void main()
{
Init();
while(1)
{
PWMOUT=PWMOption(PWM);
}
}
void timer0() interrupt 1
{
TH0=0Xfc;
TL0=0X66;
n++;
n%=10;
}
keil2下通过调试 proteus通过仿真 110592晶振
你那个地方不明白?能具体说说吗?我看程序已经有不少注释了啊?
下面的比较多,复杂些,先简单的说下吧:
一、加速减速,就是增加或减少脉冲宽度,改变电机速度!脉冲的宽度由
1、CLK=0的状态持续,由T1的定时决定;
2、CLK=1的状态持续,由(T0-T1)的时间决定;
二、定时器中断TH0=0x00 ; TL0=0x00 ;
1、T0定时器工作1方式,T0定时器启动后,从TH0、TL0赋值的计数值开始增加,增加到0XFFFF后,T0中断!
2、T0溢出后(中断),T0计数器不会自动停止,所以需要重新给T0定时器赋值!赋值后,进入下一个计数周期!
3、例子中,T0定时器从0x0000开始计数,也就是增加0xFFFF后进行中断!定时时间为 (0xFFFF / ( 晶振周期/12 ))) 秒,若晶振为12M,则定时为,65536ms!
分析程序,从main开始分析,先将起始开始的时序图画出:
如下图!
从时序图可以看出,CLK为PWM输出,
1、CLK=0的状态持续,由T1的定时决定;
2、CLK=1的状态持续,由T0-T1的时间决定;
而 main 函数中的 while(1) 部分,进行的就是PWM调整程序。
1、 if (K3==0) //高电平逆时钟转,低电平顺时钟转
{
ZF=0;
}
else
{
ZF=1;
}
根据程序推测,程序若为电机控制,K3开关为0时,ZF=0,顺时针转,K3开关为1时,ZF=1,逆时针转。
2、
if(K1==0) //按下加速键
{
delay(1);
PWML++; //调宽值低四位加1
if(PWML==0x00)
{
PWMH++;
} //调宽值高四位加1
if (PWMH==0xFF) //最大值时
{
PWMH=0xFE;
}
}
K1按键,加速按键,增加T1定时器计数起始时间,也就是减少T1计数时间,减少CLK=0的时间。
3、
if(K2==0) //按下减速键
{
delay(1);
PWML-- ; //调宽值低四位减1
if (PWML==0x00)
{
PWMH--;
} //调宽值高四位减1
if (PWMH==0x00)
{
PWMH=0x01;
} //最小值时
}
K2按键,减速按键,降低T1定时器计数起始时间,也就是增加T1计数时间,增加CLK=0的时间。
4、不论加速、减速,T0的时间都不变,CLK=0和CLK=1总持续时间不变{ (Tclk0+Tclk1)=T0 }。
程序不难,图不好画啊!
这是因为在PROTEUS仿真中,我们所看到的实际上是一个动画,它以每秒20帧的速度播放,因此,在一秒的这20个时刻中,LED是亮或灭,没有亮度的显示同时,由于你的电脑速度跟不上实际运行的速度,因此显示了你所说的提示(**感叹号),这样看到的更是亮或灭的情况
假设PPWM的脉宽为20,TH是高电平输出时间,TL是低电平输出时间,你只要在程序中满足TH+TL = 20就可以了
假设用延时程序来实现,delay(char i);为延时100us的程序,i为循环次数
void delay(uchar i)
{
uint x,y;
for(x=i;x>0;x--)
for(y=100;y>0;y--);
}
void main()
{
uchar pwm = 1,h = 20;
while(1)
{
RC3 =1;
delay(pwm);
RC3 = 0;
delay(h - pwm);
}
}
改变pwm的值(1-19)就可以改变输出高电平的宽度
例如:
//利作RC3控制输出PWM信号,控制电机正反转及转速,
//RC2为按键,默认为上拉高电平,当RC2按下为低电平时,RC1为电机以一定的速度转动,(松开默认为停止)长按停止
//MOS3205控制电机的管,高电平导通,低电平停止
//PIC16F877A,晶振4MHz
#include<pich>
#define uchar unsigned char
#define uint unsigned int
__CONFIG(0X3B31);
//uint initnum,Speed,motor;//定义一个溢出中断的变量
void delay_ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
void init()//初始化接LED的RD端口为输出,及设置OPTION寄存器关闭TMR0定时计时器
{
TRISC0=0;
TRISC1=1;
TRISC2=1;
TRISC3=0;
TRISC4=0;
RC0=0;
RC1=1;
RC2=1;
RC3=0;
RC4=0;
/
TRISD=0;//输出状态
INTCON=0xc0;//设置中断控制寄存器为11000000,始终只用到两个位开总中断,开第二外设允许中断
PIE1=0x02;//使能定时器1为00000010开中断,始终只用一最后一个其他的不用理会
PR2=200;//装初值,定时器2是8位的寄存器有256个数但是可以设定一个周期寄存器到了就可以溢出,如果不设周期寄存器就为256溢出,初值56则200us溢出
TMR2=0;//这样用PR2表示初值,在中断函数中就不用加初值了;51的模式2中,THn是下限,也就是开始计时的值;PIC中的PR2是上限,也就是计时到这个值就归零
T2CON=0x04;//设置预分频器和后分频器就是开始启到动定时器2;这里都是1:1的比例
// T2CON=0x05;//设置预分频器1:4和后分频器就是开始启到动定时器2;这时候的时间是乘以后4倍,原本以200us产生一次中断现在则以800us产生一次中断,即8001000的时间闪动
// T2CON=0x0d;//设置预分频器1:4和后分频器1:2就是开始启到动定时器2;这时候的时间是乘以后4倍,再乘以2倍,原本以200us产生一次中断现在则以1600us产生一次中断即16001000的时间闪动
// PR2=100;设置周期寄存器,值设为100,到了就溢出,同时要将其初值设置为零才够精确
/
}
void delay_us(uint i)//1表示100us,2表示200us
{
uint a,b;
for(a=i;a>0;a--)
{
for(b=7;b>0;b--);
}
}
/
void pwm()
{
uchar pwm=10,h=20;//要输出pwm500hz的频率脉宽是2ms
while(1)
{
RC3=1;
delay_us(pwm);
RC3=0;
delay_us(h-pwm);
if(RC2==1)//加上这两句就可以退出了
break;
}
}/
void main()
{
uchar aa,pwm=10,h=20;
init();
while(1)////判断按键状态////长按可以调光
{
if(RC2==0)//判断RC2按下
{
delay_ms(10);
while(!RC2)
{
for(aa=0;aa<255;aa++)//当前输出延时一段时间,这样才能看出速度的变化
{
RC3=1;
delay_us(pwm);
RC3=0;
delay_us(h-pwm);
}
if(++pwm > 19)
pwm = 10;
}
}
else
{
RC3=0;
}
}
}
/
void go(uint motor1)//电机的速度参数
{
Speed=motor1;//给电机速度参数赋速度参数的变量
motor=0x64+Speed;//0x64为100在中间加上速度参数
}
void interrupt time0()//定时器的程序,后面不用写和51单片机那样的序号,也不用就算写在主函数的后面也不用声明
{ //51的模式2中,THn是下限,也就是开始计时的值;PIC中的PR2是上限,也就是计时到这个值就归零
TMR2IF=0;//先清零,
TMR2=0;
initnum++;//加一
if(initnum<motor)
{
RC3=1;
RC4=0;
}
else
{
RC3=0;
RC4=1;
}
if(initnum==0xc8)//判断值加1是否不等于200
{
initnum=0;
}
}
/
以上就是关于100分求一单片机定时器PWM输出可以调节C语言程序全部的内容,包括:100分求一单片机定时器PWM输出可以调节C语言程序、帮我解释一下这个PWM控制电机调速的程序。、proteus仿真不了pwm波等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)