世纪电源网社区logo
社区
Datasheet
标题
返回顶部
未解决

PIC单片机产生两路频率变化PWM

[复制链接]
查看: 13202 |回复: 20
1
s362987123
  • 积分:294
  • |
  • 主题:19
  • |
  • 帖子:81
积分:294
LV3
助理工程师
  • 2010-1-17 19:47:28
10问答币
我用PIC16F684单片机产生两路频率不断变化的互补且占空比为0.5的PWM波形,结果波形中总是有间歇,如图所示,请高手指教


源程序如下:#include <pic.h>
//系统配置
__CONFIG(HS&WRTEN&BOREN&ROTECT&WDTDIS);
//打开看门狗,选择高速晶振,上电延时复位,掉电复位使能,代码保护,复位引脚使能
//***********************************变量定义**************************************
//周期寄存器值查询表
const unsigned char pr2_[]={109,108,108,107,107,106,106,105,105,104,
103,102,101,101,100,99,99,98,98,97,
97,96,95,94,94,94,93,93,92,92,
91,90,90,89,89,88,87,87,86,86,
84,84,83,82,82,81,80,79,78,76,
76,74,73,73,72,71,70,69,68,67,
66,66,65,64,63,62,62,61,61,60,
60,59,59,58,58,57,57,56,56,56,
55,55,55,54,54,54,53,53,53,53,
52,52,52,52,51,51,51,51,50,50,
50,50,49,49,49,49,48,48,48,48,
48,48,47,47,47,47,47,47,47,47,
47,47,47,46,46,46,46,46,46,46,
46,46,46,46,46,46,46,46,46,46,46};
const unsigned char pr3_[]={46,46,46,46,46,46,46,46,46,46,
46,46,46,46,46,46,46,46,47,47,
47,47,47,47,47,47,47,47,47,48,
48,48,48,48,48,49,49,49,49,50,
50,50,50,51,51,51,51,52,52,52,
52,53,53,53,53,54,54,54,55,55,
55,56,56,56,57,57,58,58,59,59,
60,60,62,62,63,64,65,66,66,67,
68,69,70,71,72,73,73,74,75,76,
78,79,80,81,82,82,83,84,85,86,
86,87,87,88,89,89,90,90,91,92,
92,93,93,94,94,94,95,96,97,97,
98,98,99,99,100,101,101,102,103,104,
105,105,106,106,107,107,108,108,109};
unsigned char pr2_1; //转换结果存储中间值
unsigned char pr3_1;

int j;

//*********************************子程序*******************************************
void CCPINIT() //CCP模块的PWM工作方式初始化子程序
{
INTCON=0X00; //禁止总中断和外围中断
CCP1CON=0X8C; //设置CCP1模块为半桥式PWM工作方式
PR2=89; //初始周期
CCPR1L=PR2/2; //初始占空比
PWM1CON=0X0B; //死区2.75uS
TRISC=0X01; //设置PORTC引脚为输出方式
}

void RA_INT() //RA和RC端口初始化
{
ANS0=1;
ANS4=1;
ANS2=0;
TRISA=0x3F; //配置RA口为输入
INTEDG=0; //INT中断下降沿
}
//TMR0初始化
void TMR0_INT()
{
T0CS=0; //内部指令周期计数
PSA=1; //预分频为1:1
T0IE=1;
TMR0=178;
}
//中断服务程序
void interrupt A_INT()
{
if(INTF)
{
INTF=0;
j=0;
}
if(T0IF) //定时器0中断,20us中断一次
{
T0IF=0;
j=j+1;
TMR0=TMR0+178; //定时器0写初值
}
}
//***************************************主程序*******************************************
main()
{
CCPINIT(); //CCP模块的PWM工作方式初始化
TMR0_INT();
RA_INT();
PEIE=1; //外围模块中断使能
GIE=1;
INTE=1;
j=0;
T2CON=0X04; //打开TMR2,且使其前分频为0,同时开始输出PWM波形
while(1) //主循环
{
if(j<65) //根据时间变量j设置PWM的工作周期
{
PR2=220;
CCPR1L=110;
}
else if(j<206)
{
pr2_1=j-65;
PR2=pr2_[pr2_1]*2;
CCPR1L=pr2_[pr2_1];
}
else if(j<259)
{
PR2=90;
CCPR1L=45;
}
else if(j<398)
{
pr3_1=j-259;
PR2=pr3_[pr3_1]*2;
CCPR1L=pr3_[pr3_1];
}
else if(j<501)
{
PR2=220;
CCPR1L=110;
}
else
{
j=500;
}
}
}
micropower
  • 积分:7357
  • |
  • 主题:49
  • |
  • 帖子:2717
积分:7357
版主
  • 2010-1-22 19:34:31
 
没细看程序,请认真查看占空比是否为0或是大于周期数。
s362987123
  • 积分:294
  • |
  • 主题:19
  • |
  • 帖子:81
积分:294
LV3
助理工程师
  • 2010-1-27 16:14:44
 
占空比设的值没有大于零,也没有大于周期数,就是丢失脉冲,可能是频繁对PR2进行读写造成的,请问版主有什么办法没?改动时注意当前状态,是指注意哪方面?
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-1-26 11:52:48
 
你仔细看看PWM模块启动要求,按要求做,一般不要轻易在中途动PR2等寄存器,必须要改动时也要讲究时机,否则会出现毛刺或者丢失PWM脉冲。另外中断20us有何意义?可能与PWM产生冲突的
我的684程序,从来不出问题:
PR2=55;CCP1CON=12;CCPR1L= 0; // PWM准备
bu=124;z=x=k=0; // 全故障标记
......
if(bu<2){TMR2IF=0;T2CON=4; // PWM准备
while(!TMR2IF);TRISC=7;} // PWM开始
micropower
  • 积分:7357
  • |
  • 主题:49
  • |
  • 帖子:2717
积分:7357
版主
  • 2010-1-26 12:58:05
 
楼上正解。
也就是说改动时注意当前状态。
s362987123
  • 积分:294
  • |
  • 主题:19
  • |
  • 帖子:81
积分:294
LV3
助理工程师
  • 2010-1-27 16:11:28
 
谢谢指导,我中断20uS是用来记时目的是在一个工频周期内让PWM频率随时间不断变化,但是占空比不变。
必须要改动时也要讲究时机?能否指点在什么时间改变不会出现问题,现在问题就是丢失PWM脉冲。
还有,我没有用定时器2中断,这样定时器0中断也会影响PWM吗?
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-1-28 11:14:38
 
TMR2随时钟逐渐增加,到与PR2匹配时产生PWM脉冲,过一个CCPR1L占空值,该脉冲消失,这个就是一个PWM周期 过程。
在此过程中,如果改小PR2值,错过了一个匹配时机,就掉了一个PWM脉冲,另外这些寄存器操作过程都有读写过程,不仅仅是你程序所表达的读就是读,写就是写,所以容易产生毛刺,如果再在无关的中断里面处理,问题就更多了。特别不能动的是TMR2(必然产生毛刺),其次是PR2,而CCPR1L的值则可以随时改动。
如果非要改动,应该在匹配(中断)发生后立即改,这个时候TMR2最小,马上改一般不会导致数据溢出,就是比较恰当的时机。
显然,匹配中断就是TMR2中断,要改只能在这个中断里面改。即使这样改也有问题,如果此时有其他中断先发生,其处理过程错过了允许时机,仍然会掉脉冲或者产生毛刺。
你的问题的最佳解决办法,就是将固定占空变频率方式改成固定频率变占空方式,因为占空(CCPR1L)的值可以随时改动。
关于划分工频周期的方法,不一定非得用定时器中断,一般用工频周期计数器来做,比如TMR1,适当分频后使其产生一个工频周期计数,比如是25600,则每100步进代表对工频周期的256分频,写出来的程序就是:
t=25600/256;
T1=0;
while(TMR1>T1)
{ 处理
T1+=t;
}
flashsnow
  • 积分:848
  • |
  • 主题:9
  • |
  • 帖子:47
积分:848
LV6
高级工程师
  • 2010-4-21 11:09:04
 
我用的是pic16f73,就是网上流传的那个程序,出来的波形和上面的很类似,我是搞硬件的,对软件不是很懂,那个软件也是类似的程序错误么?该程序地址:https://cdn13.21dianyuan.com/bbs/attachments/rar/2008/09/21/122196465148d5b36b1f553.rar
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-4-21 11:31:04
 
这类问题的解决最好找软件方面的人来,不然说不明白
flashsnow
  • 积分:848
  • |
  • 主题:9
  • |
  • 帖子:47
积分:848
LV6
高级工程师
  • 2010-4-21 14:38:43
 
写那个程序的人也太不负责任了,程序有问题就放出来了
htyfhj
  • 积分:102
  • |
  • 主题:0
  • |
  • 帖子:1
积分:102
LV2
本网技师
  • 2010-5-4 21:42:52
 
楼主的问题是出在中断中
当TMR产生中断时,降执行TMR中断,而此时PWM中断产生,不会立刻就启动PWM中断,而是在TMR中断处理完以后再执行PWM中断,从而导致此处没有脉冲。
处理方法:
将TRM中断禁止,直接将在main中的死循环中判断TMRIF是否为真,这样就可以解决问题!
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-5-4 21:57:18
  • 倒数10
 
PIC单片机的PWM模块是独立工作的,不依赖中断
s362987123
  • 积分:294
  • |
  • 主题:19
  • |
  • 帖子:81
积分:294
LV3
助理工程师
  • 2010-5-5 09:34:18
  • 倒数9
 
这里用到TMR中断,但是并没有用到PWM中断,也没有PWM的中断服务程序,这样也互相影响吗?
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-5-5 10:04:51
  • 倒数8
 
这么久了你还没有解决?
s362987123
  • 积分:294
  • |
  • 主题:19
  • |
  • 帖子:81
积分:294
LV3
助理工程师
  • 2010-5-6 16:39:24
  • 倒数7
 
惭愧啊,没有解决,只是在控制上饶了个弯先凑合着用了
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-5-6 16:47:31
  • 倒数6
 
你的问题的最佳解决办法,就是将固定占空变频率方式改成固定频率变占空方式
s362987123
  • 积分:294
  • |
  • 主题:19
  • |
  • 帖子:81
积分:294
LV3
助理工程师
  • 2010-5-6 16:59:05
  • 倒数5
 
多谢指教,用这个做谐振式的变换器,类似于LLC电路,适于变频控制。
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-5-6 17:10:13
  • 倒数4
 
如果要跟踪频率,建议不要用PWM模块
ahome
  • ahome
  • 离线
  • LV4
  • 初级工程师
  • 积分:340
  • |
  • 主题:22
  • |
  • 帖子:93
积分:340
LV4
初级工程师
  • 2010-5-7 16:39:32
  • 倒数3
 
不能用查表的方式吧
nc965
  • 积分:93618
  • |
  • 主题:115
  • |
  • 帖子:27343
积分:93618
版主
  • 2010-5-7 16:50:12
  • 倒数2
 
不知道你的工作模式,不能给建议。见过有人用外部中断捕捉频率
yang-shuang1989
  • 积分:130
  • |
  • 主题:4
  • |
  • 帖子:9
积分:130
LV2
本网技师
最新回复
  • 2012-1-5 09:56:48
  • 倒数1
 
楼主,你之前的问题解决没啊?如果解决了可不可以帮帮我啊,我现在要用PIC16F877产生两路互补的PWM波控制全桥逆变电路,要求频率可调,输入400V直流输出300V交流电~楼主,可否帮帮忙,万分感谢啊
热门技术、经典电源设计资源推荐

世纪电源网总部

地 址:天津市南开区黄河道大通大厦8层

电 话:400-022-5587

传 真:(022)27690960

邮 编:300110

E-mail:21dy#21dianyuan.com(#换成@)

世纪电源网分部

广 东:(0755)82437996 /(138 2356 2357)

北 京:(010)69525295 /(15901552591)

上 海:(021)24200688 /(13585599008)

香 港:HK(852)92121212

China(86)15220029145

网站简介 | 网站帮助 | 意见反馈 | 联系我们 | 广告服务 | 法律声明 | 友情链接 | 清除Cookie | 小黑屋 | 不良信息举报 | 网站举报

Copyright 2008-2024 21dianyuan.com All Rights Reserved    备案许可证号为:津ICP备10002348号-2   津公网安备 12010402000296号