PIC单片机输出PWM波的C语言源程序

PIC单片机输出PWM波的C语言源程序,第1张

#ifndef __PWM__H__

#define __PWM__H__

void pwm_ccp1(unsigned char a,unsigned char b)

void pwm_ccp2(unsigned char a,unsigned char b)

#endif

void pwm_ccp1(unsigned char a,unsigned char b)//左边PWM

//CCP1 模块的 PWM 工作方式,周期为(b+1)*4*Tosc*(TMR2前分频值)=b+1 us //pwm高电平=a:CCP1CON(第四五位)Tosc*(TMR2前分频值)

//pwm高电平=a:CCP1CON(第四五位)Tosc*(TMR2前分频值)

{//a>b时有最高转速

CCPR1L=a //* 设置工作循环的高 8bit 为 a

CCP1CON=0X0C //0000 1100 设置 CCP1 为 PWM 工作方式,且工作循环的低 bit2 为 11*/

CCP1IE=0//* 禁止总中断和外围中断 */

PR2=b //* 设置 PWM 周期 */

TRISC2=0 //* 设置 RC2/CCP1 为输出 */

T2CON=0X04 //* 0000 1000前分频比为 1:1 ,后分频器1:2,打开 TMR2 ,同时输出 PWM 信号 */

}

void pwm_ccp2(unsigned char a,unsigned char b) //右边PWM

//CCP2 模块的 PWM 工作方式,周期为(b+1)*4*Tosc*(TMR2前分频值),

//pwm高电平=a:CCP2CON(第四五位)Tosc*(TMR2前分频值)

{

CCPR2L=a //* 设置工作循环的高 8bit 为 a

CCP2CON=0X0C //* 设置 CCP2 为 PWM 工作方式,且工作循环的低 bit2 为 11*/

CCP2IE=0 //* 中断屏蔽

PR2=b //* 设置 PWM 周期 */

TRISC1=0 //* 设置 RC1/CCP2 为输出 */

T2CON=0X04 //* 前分频比为 1 ,打开 TMR2 ,同时输出 PWM 信号 */

}

假设PPWM的脉宽为20,TH是高电平输出时间,TL是低电平输出时间,你只要在程序中满足TH+TL = 20就可以了

假设用延时程序来实现,delay(char i)为延时100us的程序,i为循环次数

void delay(uchar i)

{

uint x,y

for(x=ix>0x--)

for(y=100y>0y--)

}

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<pic.h>

#define uchar unsigned char

#define uint unsigned int

__CONFIG(0X3B31)

//uint initnum,Speed,motor//定义一个溢出中断的变量

void delay_ms(uint z)

{

uint x,y

for(x=zx>0x--)

for(y=100y>0y--)

}

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产生一次中断,即800*1000的时间闪动

// T2CON=0x0d//设置预分频器1:4和后分频器1:2就是开始启到动定时器2这时候的时间是乘以后4倍,再乘以2倍,原本以200us产生一次中断现在则以1600us产生一次中断即1600*1000的时间闪动

// PR2=100设置周期寄存器,值设为100,到了就溢出,同时要将其初值设置为零才够精确

*/

}

void delay_us(uint i)//1表示100us,2表示200us

{

uint a,b

for(a=ia>0a--)

{

for(b=7b>0b--)

}

}

/*

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=0aa<255aa++)//当前输出延时一段时间,这样才能看出速度的变化

{

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

}

}

*/


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

原文地址: http://outofmemory.cn/yw/11258040.html

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

发表评论

登录后才能评论

评论列表(0条)

保存