完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嘿,各位,我是一个新的编程微控制器,我在PIC16F690上有一个PWM发生器的问题。我使用PWM模式在Halfbridge模式发送信号到一个全桥(左上和右下一个PWM A和左下和右上PWM PWM)。不幸的是,我不能仅仅配置PWM,让它运行,我必须控制它。我要做的是,打开PWM 1周期,在我的情况下80秒和76秒。然后停止生成PWM几秒钟,然后再次打开,但继续在当前的方向。我能够达到这个目标,我最想的,我的主要问题是,在暂停我编程的一些原因,PWM变高,由于某种原因,我不知道为什么。我的程序和我增加了一些图片来显示问题。所以目标是在80秒的时间内,然后在78秒的关闭时间之后,停用PWM,等待一个设定的时间,打开PWM,但是在前面的方向上,意思是,如果PWM B在中断之前高,把它再高一点。Rs重复。时间到目前为止,但在突破区的尖峰,在PWM再次打开之前,我不能理解,我不能摆脱。通过实验,我发现,如果我在TMR2之前写下的值增加或减少,在停用之前,它对尖峰持续时间有影响,TMR0值相同,但是设定时间,这是我能得到的最小值。我希望有人能告诉我我做了什么WR。东。谢谢!编辑FoGoTT以添加范围图片。
以上来自于百度翻译 以下为原文 Hey everyone, i'm fairly new into programming Microcontrollers and i've a bit of a problem with the PWM Generator on a PIC16F690. I use the PWM generater in Halfbridge mode to send signals toa full bridge (Top left and Bottom Right PWM A and Bottom left and Top Right PWM B). Now i unfortunately can't just configurate the PWM and let it run, i have to take controll over it. What i want to do is, Turn on PWM for 1 cycle, in my case 80µS on and 76µs off. Then stop generating pwm for a few µS and then turn in on again but continuing in the current direction. I was able to achiev this goal like i want mostly, the main problem i have is, that in the pauses i programmed for some Reason the PWM turns high for some reason and i can't figure out why. Here is my Programm and i added some pictures with scope to show the problem. list p=16f690 ; list directive to define processor #include #define GREEN PORTC,7 #define RED PORTC,6 __CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF ;******************************************************************************* w_temp EQU 0x7D ; Variable for saving W register status_temp EQU 0x7E ; Variable for saving STATUS register pclath_temp EQU 0x7F ; Variable for saving PCLATH w register cblock 0x20 ; Block of variables starts at address 20 h counter counter1 loop1 loop2 endc ; End of block of variables ;******************************************************************************* ; Reset Vector ;******************************************************************************* RES_VECT CODE 0x0000 ; processor reset vector GOTO START ; go to beginning of program ;******************************************************************************* ; ISR ;******************************************************************************* ORG 0x0004 ; Interrupt vector address movwf w_temp ; Save value of W register movf STATUS,w ; Save value of STATUS register movwf status_temp movf PCLATH,w ; Save value of PCLATH register movwf pclath_temp ;first we look if the ISR hat to respond to TMR2 interrupt1 BTFSS INTCON,T0IE goto exit_ISR ;now we check if the interrupt WAS a TMR2 interrupt btfss INTCON, T0IF goto exit_ISR ;T0_int_Handler banksel CCP1CON movlw b'00000000' ; deactivate Halfbridge, 4LSB auf 0 = CCP, PWM off, 1100 for PWM P1A P1B high active movwf CCP1CON ;movlw .198 ;movwf TMR2 movlw .50 movwf counter decfsz counter goto $-1 movlw .194 ; set TMR2 short for end of PWM period movwf TMR2 incf counter1 movlw b'10001111' ; activate halfbridge, 2LSB von 100 = 00, P1A active highe, P1B active low btfsc counter1,0 ; if counter uneven, P1A P1B active high movlw b'10001100' ; activate halfbridge, 2LSB von 100 = 00, P1A active highe, P1B active high movwf CCP1CON movlw .62 ; start TMR0 with 65 movwf TMR0 ; 4 Prescaler and 20MHZ -> interrupt after 156,8µs bcf INTCON, T0IF ; clear T0IF goto exit_ISR exit_ISR movf pclath_temp,w movwf PCLATH ; PCLATH is given its original value movf status_temp,w movwf STATUS ; STATUS is given its original value swapf w_temp,f swapf w_temp,w ; W is given its original value retfie ;******************************************************************************* ; MAIN PROGRAM ;******************************************************************************* MAIN_PROG CODE ; let linker place main program START ;******************************************************************************* ; INITIALISING PWM ;******************************************************************************* banksel TRISC clrf TRISC banksel PORTC clrf PORTC banksel ANSEL clrf ANSEL clrf ANSELH banksel T2CON movlw B'00000101' ; no Postscaler, Timer 2 on, Prescaler 4 movwf T2CON banksel PR2 movlw .197 ; .49 in Pr 2 register for 160µs Period. movwf PR2 ;******************************************************************************* ; INITIALISING TMR0 ;******************************************************************************* banksel OPTION_REG movlw b'11000001' ; PulUps on PORTA/PORTB disabled movwf OPTION_REG ; Interrupt on rising edge, Internal Clock, increment on rising edge ; Prescaler assigned to TMR0, Prescaler = 4 ;******************************************************************************* ; ENABLEING INTERUPTS ;******************************************************************************* bcf INTCON, T0IF bsf INTCON, T0IE bsf INTCON, PEIE bsf INTCON, GIE BTFSS INTCON, GIE ; TEST if it is enabled. goto $-2 banksel PORTC movlw 0x00 ; start TMR2 with 0 movwf TMR2 movlw b'10001100' ; activate Halfbridge, 2LSB von 100 = 00, P1A active highe, P1B active high movwf CCP1CON movlw b'01100100' ; 8MSB of .400, 2LSB in CCP1CON 5-4, 400 = 0,5050505 dutycycle, 80µ on 78,4 off movwf CCPR1L movlw b'00000010' ;200ns Deadband delay movwf PWM1CON movlw .62 ; start TMR0 mit 65 movwf TMR0 ; 4 Prescaler and 20MHZ -> interrupt after 156,8µs movlw 0x00 movwf counter movlw 0x00 movwf counter1 ; TODO Step #5 - Insert Your Program Here MOVLW 0x55 ; your instructions GOTO $ ; loop forever END So the goal is to have 80µS on time, then after the 78µs off time, deactivate PWM, wait for a set ammount of time, Turn on PWM but in the direction as before, meaning, if PWM B was high before the break, turn it high again for 80µS. Rinse repeate. The times fit so far but the Spikes in the break area, shortly before PWM gets turned on again i can't understand and i can't get rid of. With experimenting i found out, that if i increase or decrease the value i write in TMR2 shortly before deactivating it has influence on the Spike duration, same for the TMR0 value, but with the set times this is the smallest i can get the spike. I hope someone might be able to tell me what i did wrong. Thanks alot! Edit forgott to add the Scope Pictures. Attached Image(s) |
|
相关推荐
12个回答
|
|
颠簸,只是人们看到这个消息,因为花了这么长时间才得到批准。
以上来自于百度翻译 以下为原文 Bump, just so people see this message as it took so long to get approved. |
|
|
|
嗨,还没有通过所有的代码发布,但不是清除CCP1CON,也许尝试使用外围设备中的关机控制机制:ECPAAS=0B100000;/*设置位7在ECPAAS寄存器中。*与此相关的选项很多,请参阅数据表。问候,Mysil。
以上来自于百度翻译 以下为原文 Hi, Haven't worked thru all the code posted, but instead of clearing the CCP1CON, maybe try to use the shutdown control mechanism in the peripheral: ECCPAS |= 0b10000000; /* Set bit 7 in ECCPAS register. */ There is a lot of options in connection with this, see the datasheet. Regards, Mysil |
|
|
|
当OP使用汇编程序时
以上来自于百度翻译 以下为原文 As the OP is using assembler, that would be BANKSEL ECCPAS BSF ECCPAS,ECCPASE |
|
|
|
嘿,首先谢谢大家的推送和反馈。我试图用ECCPAs禁用PWM,它也工作,但是在PWM恢复之前不久,尖峰仍然在信号上。我在ISR中改变了Dababeland Enabelin到这个:所以我禁用了ECPAs,然后等待暂停,改变PWM输出的极性并启用PWM。再次CCPA。我仍然不知道什么东西会产生PWM信号的尖峰,因为它应该被关闭。还是我错过了什么?
以上来自于百度翻译 以下为原文 Hey, first of all thanks for the push and the Feedback. I tried to disable PWM with the ECCPAS and it works too, but the Spike still are on the signal shortly before PWM gets turned back on. I changed the disabeling and enabeling in the ISR to this: banksel CCP1CON movlw b'10000000' ; deaktivate Halfbridge, ECCPAS,7 to high movwf ECCPAS ;movlw .198 ;movwf TMR2 movlw .50 movwf counter decfsz counter goto $-1 movlw .194 ; starte TMR2 mit 0 movwf TMR2 incf counter1 movlw b'10001111' ; activate Halfbridge, 2LSB from 100 = 00, P1A active high, P1B active low btfsc counter1,0 ; if counter uneven, P1A P1B active high movlw b'10001100' ; activate Halfbridge, 2LSB from 100 = 00, P1A active high, P1B active high movwf CCP1CON movlw b'00000000' movwf ECCPAS movlw .62 ; start TMR0 with decimal 65 movwf TMR0 ; with 4 Prescaler and 20MHZ interrupt after 156,8µs bcf INTCON, T0IF ; clear T0IF goto exit_ISR So i disable with ECCPAS, then wait the pause, change the polarity of the PWM outputs and enable PWM with ECCPAS again. I'm still not sure what could generate the spikes on the PWM Signal since it should be tourned off. Or do i miss something? |
|
|
|
一些外围设备控制TIS和端口引脚,并覆盖它们所设置的任何外围设备。但是当外围设备关闭时,TRIS和端口引脚恢复到外围设备控制之前的状态。我在PIC24部分注意到了这一点。也许这部分是这样做的。在启用外围设备之前,将TIS和端口设置为一些定义的状态。
以上来自于百度翻译 以下为原文 some peripherals take control of the tris and port pins and override whatever they have been set to make the peripheral work. but when the peripheral is turned off, the tris and port pins revert to what they were before the peripheral took control. I noticed this on PIC24 parts. perhaps this part does it as well. set the tris and ports to some defined state before enabling the peripheral. |
|
|
|
如果我能理解的话,肯定不会100%。这个想法是在停用PWM之前再次设置端口和TIS引脚。还是在再次启用它之前?一定会尝试的,谢谢!因此,我尝试设置TISISC、PORTC和安塞尔/ANSELH在停用PWM之前,在配置CCP1CON之后,在CCP1CON配置之后以及在ECPCAS中写入之前和之后,对PWM进行去激活,但结果基本相同。只有在ECPAS之后,它根本不起作用,而且不确定我把它放在哪里,我得到了2个尖峰而不是一个。但是,这与TMR设置相关,因为在TrPUT中改变TMRP0的值或TMR之前的TMR值得到类似的结果。
以上来自于百度翻译 以下为原文 Not 100% sure if i understood it corretly. The idea is to set the Port and Tris pins again before deactivating the PWM? Or before enabeling it again? Will try that for sure, thanks! So i tried to set the TRISC, PORTC and ANSEL / ANSELH before deactivating PWM, after deactivating PWM right before configuring CCP1CON again, right after CCP1CON configuration and before and after writing in the ECCPAS but the result where mostly the same. Only after the ECCPAS it didn't work at all and once, not sure where i placed it, i got 2 spikes instead of one. But that is correlated to the TMR settings since changing the value in TMR0 for the Interrput or the Value for TMR before stoping PWM gets a similar result. |
|
|
|
不,刚开始的时候,当你的外围设备被禁用时,你希望他们恢复状态。我怀疑你已经正确地设置了它们。
以上来自于百度翻译 以下为原文 No, just once at the start, to the state you want them to revert to when the peripheral is disabled. I suspect you were already setting them correctly. |
|
|
|
我在主程序开始时这样做,万一这是什么?
以上来自于百度翻译 以下为原文 ;******************************************************************************* ; INITIALISING PWM ;******************************************************************************* banksel TRISC clrf TRISC banksel PORTC clrf PORTC banksel ANSEL clrf ANSEL clrf ANSELH banksel T2CON movlw B'00000101' ; no Postscaler, Timer 2 on, Prescaler 4 movwf T2CON banksel PR2 movlw .197 ; .197 in Pr 2 register for 160µs Period. movwf PR2 I do this at the start of the main Programm, in case this is what was ment? |
|
|
|
是的。有没有其他代码运行,您没有告诉我们,访问PORTC?由于您使用的是缺少LAT寄存器的旧PIC,如果在同一端口上使用其他引脚的位集或位清除指令,则总是存在读取修改写入问题的机会。
以上来自于百度翻译 以下为原文 Yes. Is there any other code running that you have not shown us, that accesses PORTC ? As you are using an old PIC that lacks LAT registers, there is always a chance of Read-Modify-Write issues if you use bit set or bit clear instructions on other pins in the same port. |
|
|
|
第一个帖子中的代码是正在运行的整个代码。主要目标是只需要不需要任何其他东西就可以生成PWM。
以上来自于百度翻译 以下为原文 The code in the first Post is the whole code that is running. The main goal was just to generate the PWM needed without anything else. |
|
|
|
嗨,已经尝试过在消息“1”中显示的代码,看来你正在使用定时器0的中断来预测定时器2和CCP1何时起作用。为这两个定时器选择了预分频器4,所以应该可以预测定时。记住,有几个指令周期。从定时器转换中断中断直到输入中断,然后在中断Prolog、EXEOG和中断源测试中使用每个指令,在到达动作之前使用1个或2个指令周期。然后,我认为禁用中断处理程序中的ECP,然后初始化。在消息3中,我的建议是基于从ISR内部删除CCP的新初始化。如Qub所描述的:应用停机状态时要取的值,在ECPCAS寄存器中的其他位中指定,这些应该预先初始化。EN要继续操作,清除相同的比特,不要干扰CCP模块的其他设置。当计时器2返回到0时,CCP应该继续下一个周期循环。另一种暂停CCP信号的方式,可能会冻结定时器2MysIL。
以上来自于百度翻译 以下为原文 Hi, Have tried to step thru the code shown in message #1 Seems you are using interrupts from Timer 0 to predict when Timer 2 and the CCP1 are acting. There is prescaler 4 selected for both these timers, so it should be possible to predict the timing. Keep in mind that there is a few instruction cycles interrupt latency from timer transition until interrupt is entered, and then each instruction during interrupt prolog, epilog and testing for interrupt source, use 1 or 2 instruction cycles, before getting to the action. Then, I think disabling the ECCP inside interrupt handler, and then initializing it again, is a risky undertaking. My suggestion in message #3 was based on removing the new initialization of CCP from inside the ISR. As described by qub: banksel ECCPAS bsf ECCPAS, ECCPASE The values to be taken when Shutdown state is applied, is specified in other bits in ECCPAS register, these should be initialized beforehand.. Then to continue operation, clear the same bit, do not mess with other settings for the CCP module banksel ECCPAS bcf ECCPAS, ECCPASE The CCP should then continue with the next period cycle when Timer 2 go back to 0. Another way to pause the CCP signal, might to freeze the Timer 2 banksel T2CON bcf T2CON, TMR2ON // ... // And then to resume timer operation: bsf T2CON, TMR2ON Mysil |
|
|
|
嘿,很抱歉周末的回复,周末已经过去了。我试着用TMR2接口进行这项工作,但这并不适用于PWM发电机的工作方式。因此,从我理解它,PWM发生器试图完成它的当前PWM信号,以不产生未完成的波。因此,如果我在波浪结束之前到达代码的不可分割部分,这就足够了。我试图降低和增加TMR0启动时间,如果我中断之前,我仍然有相同的结果,而当我中断后,我得到了真正奇怪的混合。由于事实上,他想产生全波,这也是必要的设置TMR2不久之前完成,使启用是完成后,波完整性保持完整。关于禁用和启用,我不知道我是否理解你错了,或者如果不清楚我想做什么。我在附件中添加了一个PICUTUT,使它更直观地显示我想要生成什么样的PWM。因此,理论上,我需要80秒(160秒的160秒)重复最后一部分。在每个通道的78个部分之后,我需要增加一个5-10μs的中断,这两个通道都是关闭的。为了实现PWM,我希望将PWM发生器配置为80秒和78秒。现在,我开始PWM,并运行第一个周期正常,然后我中断后78秒。我计数我的计数器,以产生必要的休息,在这两个PWM关闭。然后,我相应地改变PWM的高电平和低电平设置,将PWM重新打开,使信号在中断之前或第二路的另一条路上再次接通。这就是为什么我重新初始化IpUPT中的CCP1CON的原因。他们之所以这么做,主要是因为,至少在目前,当我将PWM发生器设置为160个周期时,我不能可靠地触发78秒后的中断。希望这能使这个概念更清楚吗?再次感谢大家的反馈和帮助,我真的很感激。
以上来自于百度翻译 以下为原文 Hey, sorry for the late reply, was gone over the weekend. Regarding the interrupts. I tried to do it with the TMR2 interupts, but that didn't work witht he way the PWM Generator works. So from how i understand it, the PWM Generator tries to finish it's current pwm signal to not generate unfinished waves. Therefor it was apparently enough if i arrive at the dissable part of the code before the wave was finished. I treid to lower and increase the TMR0 start time and if i interrupted earlier i still had the same result, while when i interrupted later i got really strange mixes. Due to the fact that he wants to generate full waves it is also neccesary to set TMR2 shortly before finishing so that the enable is done cloes after and the wave integrity stays intact. Regarding the disable and enable, i'm not sure if i understood you wrong, or if it is not clear what i want to do. I added a Picuter in the attachment to make it more visual what kind of PWm i want to generate. So in theory i want 80µS on (160µs off 160µs on) repeat last part. after 78µs of the OFF part for each Channel, i need to add a break of 5-10µs were both channels are off. To Realize the pwm i want i configured the PWM generator to 80µS on and 78µs off. Now i start the PWM and run through the first cycle normaly, then i interrupt after the 78µs. i count my counter down to generate the needed break where both PWM is turned off. Then i change the high and low active settings for the PWM accordingly and turn the PWM back on so that the signal gets ON again if it was ON before the break or the other way arround for the 2nd channel. Thats why i reinitialize the CCP1CON in the interupt. They main reason i do it this way, is because, atleast for now, i can't reliably trigger a break after 78µS when i set the PWM generator to 160µS cycles. Hope this make the idea behind this more clear? Thanks everyone again for all the feedback and help, i really appreciate it. Attached Image(s) |
|
|
|
只有小组成员才能发言,加入小组>>
5166 浏览 9 评论
2000 浏览 8 评论
1929 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3175 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2227 浏览 5 评论
736浏览 1评论
619浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
507浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
633浏览 0评论
530浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 08:07 , Processed in 1.608207 second(s), Total 100, Slave 84 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号