如何用pic单片机写PWM信号的产生
发布网友
发布时间:2022-04-24 17:10
我来回答
共3个回答
热心网友
时间:2022-06-03 23:17
展开1全部假设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<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=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产生一次中断,即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=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;
}
}
*/来自:求助得到的回答
热心网友
时间:2022-06-03 23:17
这个是一节课的内容,这里不容易讲清楚,请看请参考北航的《PIC16系列单片机C程序设计与PROTEUS仿真》一书,里面有这个内容的实际程序与线路图。
热心网友
时间:2022-06-03 23:18
用CCP模块 配置成PWM模式
首先初始化CCP和Timer2模块
然后令CCPRxL = 占空比(8 bits精度)