100分求一单片机定时器PWM输出可以调节C语言程序

100分求一单片机定时器PWM输出可以调节C语言程序,第1张

#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波等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10133597.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存