Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help PWM using A/D PIC18F2431

Status
Not open for further replies.

trr85

New Member
Hi guys Im EE student Im doing a project where I need 2 PWM signals: 1 fixed PWM and 1 variable PWM using A/D module.
Im using POWER CONTROL PWM MODULE.

I did fixed PWM and it worked perfect, I tested with some PWM frequencys and some duty cycles, here I dont have troubles.

Variable PWM my analog input is a rectified sinusoidal wave at 60 Hz, Im using AN0, Im working in this project since April and I have troubles here, my output isnt working in the correct way. I was using 8 MHz cristal with HSPLL enabled so Fosc = 32 MHz, I had FPWM = 100 KHz at 8 bits PWM resolution, I was loading the 8 MSB to Duty Cycle register... but I cant get the correctly output, so the last Wednesday I get a 10 MHz cristal now I have Fosc = 40 MHz, and 10 PWM resolution bits at FPWM = 39 KHz.. I loaded the 10 A/D result bits to the 10 PWM duty cycle bits and I still having troubles, the PWM output is working bad, some times the output go to 5 Volts (100% duty cycle) or go to 0 Volts (0 % duty cycle) or stay freeze in a low duty cycle, some times didnt stop.

About my A/D configuration, Im using single shot, Im trigering A/D convertion by software, A/D interrupt disable, my TAD is Fosc/32, and my TACQT = 2TAD, I have followed the A/D configuration steps from datasheet.
Im using PWM free-running mode.
To read the A/D result Im using a PWM interrupt each time that interrupt is active Im reading the A/D result and loading to Duty Cycle registers.

I hope somebody can help me please I need finish it, this project is my thesis from university, its a led ballast, the variable PWM signal will be used for a CD-CD converter Boost to made a PFC, the fixed PWM will be used for a CD-CD converter Buck, Im in darkness in variable PWM since April I dont know what can be the trouble I read my code, read datasheet, Im going to be crazy =P

I show You my hardware connection and my variable PWM output in a video.
I have attached my code.

**broken link removed**
>>> Hardware connection

**broken link removed**
>>> Analog input

**broken link removed**
>>> Variable PWM output video

Note: please copy and paste the url-links to your web browser.

Thank You for Your time.
Regards.
Tom.
 

Attachments

  • code.asm
    5.5 KB · Views: 268
Last edited:
Mybe the other way round

I am currently working just with the PC PWM module of the 18F4431.

I did not mess with AD conversions yet.

It looks like you are launching every conversion INSIDE the ISR and staying there, waiting to complete.

As a first test, I would not even use interrupts; I would just do the same start, wait for completion, pass values to PWM module in a simple loop.

Would you try that and tell the outcome?
 
ttr,
Trouble shooting!
Look at pin 2 of the micro to see if the op-amps are doing their job. Maybe there is oscillation. Use an O-scope.
Many people do not understand the registers on the PWM. Some people have problems with 10bit ADC but do not have problems with 8 bit.
I think you should remove the signal from pin2 and connect a pot. Set the pot for 0.1 volt and look at the PWM. Then set the pot for 0.2 volts and look at the PWM. (repeat) I think you will find a very strange relationship between input and output.
 
It looks like you are launching every conversion INSIDE the ISR and staying there, waiting to complete.
As a first test, I would not even use interrupts; I would just do the same start, wait for completion, pass values to PWM module in a simple loop.
Would you try that and tell the outcome?

I will test your suggestion, thank You soon I will reply.

ttr,
Trouble shooting!
Look at pin 2 of the micro to see if the op-amps are doing their job. Maybe there is oscillation. Use an O-scope.
Many people do not understand the registers on the PWM. Some people have problems with 10bit ADC but do not have problems with 8 bit.
I think you should remove the signal from pin2 and connect a pot. Set the pot for 0.1 volt and look at the PWM. Then set the pot for 0.2 volts and look at the PWM. (repeat) I think you will find a very strange relationship between input and output.

The output signal from opamps is correctly, I use scope to watch it in school laboratory.
I need use this analog input, because my project need be connected in AC input, here we have 127 V(AC) at 60 Hz.
input = 127 Volts -> Voltage complete wawe rectifier -> Voltage divisor -> output = rectified sinusoidal wave, 60 Hz, 5 Volts.
At the moment Im using signal generator to get the analog input and a complete wave precision rectifier.
I did think test it using pot but my real needed is using this variable signal.
Thank You.
 
Last edited:
Hi I tested changing the analog input to a 10 Kohm pot 5 Volts Vcc, I modified the code removing PWM interrup but now allowing ADC interrup each convertion ADC module stoped until I read the ADC result value and load to PWM duty cycle registers... but its not working correctly, because if I put 5 Volts I must get 100% duty cycle and I didnt get it, if I put 2.5 Volts I must get 50% duty cycle and I get less than it... I think that exist some trouble in the moment to work together ADC result with PWM duty cycle registers but I dont undestand what can be the trouble, hope someone have some suggestion, I attached a video and asm code.

Regards.
Tom.
 

Attachments

  • Video using modified code.zip
    3.8 MB · Views: 177
  • code.asm
    5.9 KB · Views: 201
Step by step

if I put 5 Volts I must get 100% duty cycle and I didnt get it, if I put 2.5 Volts I must get 50% duty cycle ...

Things would not happen merely because you want it.

PLease do this (always using short sentences):

Say what you would like the micro to do.

Show pseudocode to explain it.

Show the calculation you applied to get that relationship (and explain how you implemented it).

And finally, what you actually get.

While all the above could seem excessive to you, it should be more than easy to say if you have a clear idea of how to solve the problem. Your first attempt didn't show that.
 
Hi after some test in university Im back, The A/D module is working fine I tested it loading the ADC result to a port C and A from pic, I used a led bar (10 leds) to check it, when I tested in PWM it work fine load the correctly value to duty cycle register, if I load 2.5 Volts in analog input, I get 50% from duty cycle in PWM output signal, my trouble now is that my signal is flickering a lot, some times stay some value for some seconds and after load other value, I think that FIFO buffer from ADC is doing wrong some thing, I changed my code today, Im using PWM interrup each time that PTMR match PTPER start the Hight priority interrupt routine service, in this interrupt service Im reading and loading the ADC result to duty cycle registers, I have attached my new code here, I have disallowed ADC interrupt, Im working in Continuous Loop mode in ADC module.

Regards.
Tom.
 

Attachments

  • code.asm
    5.9 KB · Views: 198
Too long

Tomasito,

Podrías usar "punto y aparte" de vez en cuando?

I will noth bother to read sentences that long!

Follow my suggestions, brief and clear please.
 
Lo siento :D Atferrari pero me emociono detallando.

I need get this PWM output:
**broken link removed**

Im using POWER CONTROL PWM MODULE and 10-BIT HIGH-SPEED ANALOG-TO-DIGITAL CONVERTER (A/D) MODULE.

If I configure POWER CONTROL PWM MODULE to work with a fixed PWM I dont have any trouble.

To get Variable Duty Cycle PWM output using 10-BIT HIGH-SPEED ANALOG-TO-DIGITAL CONVERTER (A/D) MODULE, Im using a pot 10 Kohms, 5 Volts as max voltage, so If I put 2.5 Volts in ADC input I must to get 50% duty cycle in PWM output.
Im using PWM interrupt, in the interrupt routine service Im loading the 10 bits from ADC result to the 10 bits from PWM duty cycle.

I get the correct PWM output respect the ADC input signal, If I load 0.5 Volts in analog input I get 10% duty cycle in PWM output, If I load 2.5 Volts in analog input I get 50% duty cycle in PWM output, etc.

The trouble is that my signal is flickering a lot (the output works 3 - 5 seconds and after down to 0% duty cycle for other 3 seconds and after come back the correct signal and after go down, etc).

I think that my trouble is with ADC module but I dont undestand what can be the trouble because I have followed the A/D MODULE INITIALIZATION STEPS.

Regards.
Tom.
 

Attachments

  • code.asm
    5.9 KB · Views: 166
ADC module initialization

I think that your problem resides somewhere in the settings of ADCON1 and ADCON2 but not sure where.

Are you enabling the FIFO scheme? If so, for what?

Check those registers bit by bit and get used to do as explained here below. It pays in the long term.

Just two details:

a) to show the settings of every register clearly, so you (or anyone else for the case) could revise them EASILY, do something like this (examples from my own code):
Code:
  LOADREG PTCON0,B'00000000'  ;PWM time base is off
  ;                0.......
  ;                .0......
  ;                ..0.....
  ;                ...0....   ;0000 =1:1 postscale
  ;                ....0...
  ;                .....0..   ;00 =1:1 prescale
  ;                ......0.
  ;                .......0   ;PWM time base in free running mode
 
 
  LOADREG PTCON1,B'00000000'  ;
  ;                0.......   ;PWM time base is off - PC PWM module stopped.
  ;                .0......   ;read only bit
  ;                ..0.....   ;not implemented
  ;                ...0....   ;not implemented
  ;                ....0...   ;not implemented
  ;                .....0..   ;not implemented
  ;                ......0.   ;not implemented
  ;                .......0   ;not implemented
 
  LOADREG PWMCON0,B'00100111'
  ;                 0.......  ;not implemented
  ;                 .0......
  ;                 ..1.....  
  ;                 ...0....  ;010 =enable pins PWM0 and PWM1 for PWM output
  ;                 ....0...  ;= pair PWM1:0 in complementary mode
  ;                 .....1..  ;= pair PWM3:2 in independent mode
  ;                 ......1.  ;= pair PWM5:4 in independent mode
  ;                 .......1  ;= pair PWM7:6 in independent mode

Who would like to verify, every time, what is the meaning of H'AE'? Let's admit that is far from intuitive or just easy!

b) Take advantage of the instructions of this family: you could write the ISR like this:
Code:
   [COLOR=red]MOVFF ADRESL,PDC0L[/COLOR]
[COLOR=red]   MOVFF ADRESH,PDC0H[/COLOR]
   BCF  PIR3, PTIF
   BSF  ADCON0, GO    ; GO/DONE: A/D Conversion Status bit
   retfie FAST
While the datasheet says not to use MOVFF inside the ISR, it is only when the registers are involved in the control of the interrupt (which is not the case here).
 
Hi atferrari, I did a video from my variable PWM to show u how its working:
**broken link removed**

I think that my trouble is in ADCON1, with FIFO Buffer, Im using FIFO buffer because Im using Continious loop mode, so many values will be entering to the fifo.

I tryied work with Single shot mode ADC and the adc module wasnt doing good the work, was just varing the pwm from 0 to 25% aprox.

REGISTER 20-2: ADCON1: A/D CONTROL REGISTER 1

ADCON1 = 0x10 = 0b00010000

bit 7-6 VCFG<1:0>: A/D VREF+ and A/D VREF- Source Selection bits
00 = VREF+ = AVDD, VREF- = AVSS

bit 5 Unimplemented: Read as 0’

bit 4 FIFOEN: FIFO Buffer Enable bit
1 = FIFO is enabled

bit 3 BFEMT: Buffer Empty bit
0 = FIFO is not empty (at least one of four locations has unread A/D result data)

bit 2 BFOVFL: Buffer Overflow bit
0 = A/D result has not overflowed

bit 1-0 ADPNT<1:0>: Buffer Read Pointer Location bits
Designates the location to be read next.
00 = Buffer address 0
 
I insist on my orginal idea

You are having zero Duty Cycle for long periods, right? That suggests that "0" is being passed repeatedly to the PWM module because the FIFO buffer has nothing else to pass :confused:. Do you agree?

Added /Or are you reading it in a wrong way? Just guessing here... /Added

I insist on you trying what I told you in a previous post: start, wait for completion, pass values to PWM module in a simple loop. For the moment, no interrupts.

(If timing allows, to make it faster, start next conversion and then read.)

An educated guess says that the loop would be much faster than the conversion thus no one would be missed out.

Do you actually know the time elpased between the start of two consecutive conversions?
 
Last edited:
Hi atferrari, today I will test ur suggestion, aprox I can do 2 conversions in 1 PWM period, I think too about FIFO buffer is loading a old value so is because I get some times "0" for long time... later show u my result, thank You.

Regards.
Tom.
 
Also consider this

Maybe your buffer is just empty so no value to be passed to the PWM module. While waiting for the doctor I spend my time reading the ADC part and it seems that you should take advantage of both buffer-associated flags (overflow and empty)

Later, not at this stage, you may consider as well the function triggered by the postivie edge of the PWM signal.

Yes it is all in the datasheet.
 
I did a new code using ADC Continious Loop mode without interrupt, PWM output was better than the older signals, I need test some details with buffer-associated flags (overflow and empty).

I have used ADC triggered by PWM rising edge some time ago, the trouble using it is a significant disadvantage because the PWM frequency be reduced at half, my output frequency now is 39 KHz if I use PWM rising edge as triggered I will have 19.5 KHz PWM frequency and it will be a low swtching frequency for use in CD - CD converters.

Tomorrow I will do some test to my new code and I will show u my new video.

Thank you for ur time in this =)

Regards.
Tom.
 
Finally...!

I did a new code using ADC Continious Loop mode without interrupt, PWM output was better than the older signals, I need test some details with buffer-associated flags (overflow and empty).
Good to hear that! Before moving to interrupts and good use of buffer, make sure that you get the best from a continuous loop.

I have used ADC triggered by PWM rising edge some time ago, the trouble using it is a significant disadvantage because the PWM frequency be reduced at half, my output frequency now is 39 KHz if I use PWM rising edge as triggered I will have 19.5 KHz PWM frequency and it will be a low swtching frequency for use in CD - CD converters.

Yes, it seems to be rather limitated if using the raising edge.:(

I think I would put the burden of getting new values for the PWM module, on the ADC itself.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top