Hi,
yes, i set all the pin state 1st but outside the main loop, i simulate it and my switching and my 3 phases channel all works ok.
i will test it in the real physical PIC tmrw and see the results, then feed back to you again.
photoelectric
Hi,
yes, i set all the pin state 1st but outside the main loop, i simulate it and my switching and my 3 phases channel all works ok.
i will test it in the real physical PIC tmrw and see the results, then feed back to you again.
photoelectric
Hi,
ive just test it on real physical PIC and found out that phase 1 and phase 2 works fine but phase 3 wont work very well.
As you can see from the attached named Phase 1 shows the correct generated pwm, same as phase 2.
However, file Phase 3 show that the signal from portb.3 always high as a result generating wrong pwm switching.
ive recheck the circuit but nothing wrong with it.
i also simulate the program using real PIC simulation and nothing was wrong.
So, i guess maybe the code got something problem.
below is my complete coding:
please help to advice.Code:DEFINE OSC 20 Phase VAR BYTE[3] ' Array used as pointers into lookuptable. DutyCycle VAR WORD[3] ' Array storing the dutycycles retreived from the table Temp VAR WORD ' Temporary variable to avoid hard to understand array indexing i VAR BYTE ' General purpose counter TRISC.2 = 0 ' Set PORTC.2 (CCP1) to output TRISC.1 = 0 TRISB.5 = 0 CCP1CON = %00001100 ' Set CCP1 to PWM CCP2CON = %00001100 CCP3CON = %00001100 T2CON = %00000101 ' Turn on Timer2, Prescale=4 PR2 = 249 ' Set PR2 to get 5KHz out ' The lookup table has 186 entries long, to get 120° phase shift we need to ' "start" the second phase at 1/3 of the cycle and the third phase at 2/3 ' of the table. 186/3=62 so first phase starts at 0, second phase at 62 ' and third phase at 123. ' Initilise pointers. Phase[0] = 0 : Phase[1] = 15 : Phase[2] = 30 High PORTC.3 'Set the initial state for portc.3 Low PORTC.0 'Same High PORTC.6 'Same Low PORTC.5 'Same High PORTB.4 'Same Low PORTB.3 'Same Main: GoSub GetDuty ' Retrieve the dutycycle values for all three phases GoSub SetDutyCycle ' Set the three PWM modules accordingly ' Now increment the individual table pointers and make sure they wrap ' around to zero when they reach the end of the table. That way they ' will always stay 62 "steps" (120°) from each other. For i = 0 TO 2 Phase[i] = Phase[i] + 1 IF Phase[i] > 46 Then Phase[i] = 0 'When pointer is > 185 we need to wrap around to 0. GoSub ChangeBridgeDrive 'One phase is starting over, go change the outputs. EndIF Next PauseUs 300 GoTo Main SetDutyCycle: ' Get value from the array of dutycycles and put it in the dutycycle ' registers of the 3 PWM modules. We could have used the array directly ' but this way (using a Temp variable) is easier to understand. Temp = DutyCycle[0] ' Get dutycyle for phase 1 from the array and store in temp. CCP1CON.4 = Temp.0 ' Set the LSB's CCP1CON.5 = Temp.1 CCPR1L = Temp >> 2 ' Set the 8 high bits Temp = DutyCycle[1] ' Same procedure. CCP2CON.4 = Temp.0 CCP2CON.5 = Temp.1 CCPR2L = Temp >> 2 Temp = DutyCycle[2] ' Same procedure. CCP3CON.4 = Temp.0 CCP3CON.5 = Temp.1 CCPR3L = Temp >> 2 Return ' ------------------------------------------------------------------------------ ' ---- Subroutine to retreive the three dutycycle values from the table. ' ---- Values will be stored in the DutyCycle array. ' ------------------------------------------------------------------------------ GetDuty: ' This For-Next loop runs three times. Each time it gets the value from the lookuptable ' that Phase[i] is pointing at. The Phase array pointers are incremented in the main loop ' and are always 62 "steps" appart so that a 120° phase shift is preserved. For i = 0 TO 2 LookUp2 Phase[i], [0,0,70,137,208,275,341,408,470,529,588,643,694,745,788,827,866,898,925,_ 953,968,984,996,1000,996,984,968,953,925,898,866,827,788,745,_ 694,643,588,529,470,408,341,275,208,137,70,0,0],Temp ' Lookup2 can't handle an array as the designator so we need to ' put the value in a temporary variable first and then move ' it to the array of dutycycles. DutyCycle[i] = Temp Next Return ChangeBridgeDrive: ' When we come here the value i contains the phase counter that just got reset so we ' can use that to determine for which phase we should switch the outputs. Select Case i Case 0 ' It was Phase 1 that rolled over Toggle PORTC.3 ' Invert the state of the pin Toggle PORTC.0 ' Invert the state of the pin Case 1 ' It was Phase 2 that rolled over Toggle PORTC.5 ' Invert the state of the pin Toggle PORTC.6 ' Invert the state of the pin Case 2 ' It was Phase 1 that rolled over Toggle PORTB.4 ' Invert the state of the pin Toggle PORTB.3 ' Invert the state of the pin End Select Return End
thanks
Hi,
OK, so you're saying that it works in the simulator but not in the real world? Or does it not work in the simularor either?
What do YOU think might be the problem and what have YOU tried in order to figure it out?
Have you:
A) Checked the datasheet to see if there's anything specific with PortB.3?
B) Tried another pin, just as an experiment, to see if the logic of the code works?
C) Connect a LED to PortB.3 and write code to turn that on and off so you KNOW that the pin actually works and is configured properly
D) Disconnect the external logic and measured on the pin directly.
E) Anything else?
Let me know what you've tried and what the results are.
Hi,
its works on simulator for all phases but in real world only phase 3 as i mention before.
i think its the pin portb.4 and portb.3 on the PIC16F737 but im not sure.
A) yes, i have check the function of portb.3 and portb.4 -
based on the datasheet
portb.3:
-Digital I/O.
-CCP2 capture input, compare output, PWM output.
-Analog input channel 9.
portb.4:
-Digital I/O.
-Analog input channel 11.
since i declare portb.5 as the ccp3, should be no problem for portb.3.
portb.4 same function as i use for phase 1 and 2
B)i tried another pin which is portb.2 and portb.3, still not function well (seem like it wont toggle properly)
C)havent done it yet. will test using it next week and feedback to you again.
D)Yes, i measure part A and B directly to the pin PIC
btw, i test it on the breadboard. havent change the breadboard yet but i dont think its the reason.
i will test it again friday next week and feedback to you.
if u have any more idea on testing error please let me know
photoelectric
Hi,
So it says that PortB.3 can be the output of CCP2 but that's likely not the problem because you get the PWM from CCP2 on PortC.1, correct?
It also says that it (and PortB.4) can be an analog input. Have you investigated that part? Usually when the PIC starts up it defaults to analog inputs. In order to make them work as digital outputs you need to turn the analog functions off.
If you look at the PortB section of the datasheet you'll see in table 5-4 that they mention the ADCON1-register. You'll also see that it defaults to all zeros on startup. If you then turn to the Analog-to-digital converter section of the datasheet and look at the ADCON1 register you'll see that all zeros mean that AN0-AN11 are configured as analog inputs. This needs to be changed in order for the pin to function as a digital pin.
The other pins you're using (PortC.0, PortC.3, PortC.5 and PortC.6) doesn't have any analog circuitry so they work out of the box but PortB.3 and PortB.4 (as well as PortB.2 that you tried) DO have analog circuitry which is most likely the reason for them not to work as you expect.
The fact that it works in the simulator only illustrates that the simulator isn't doing what the real PIC does....
/Henrik.
hi,
im back
tq for your advice. i change the port b to digital by just adding:
adcon1 = 7
then it works fine. Actually, i only follow the example in the PBP book and i dint really understand the definition of it, how the PIC change the analog port to digital port and so on.
Can you help explain about the ADCON1 command and what if i want to chnge ONLY portb.4 and portb.3 to digital??
what should i do??
thanks
Hi,
ADCON1 is not a command, it's register in the PIC which is used to control the ADC. When you do ADCON1 = 7 you set that register to 7 (which for the 16F737 sets AN8-13 to digital and leaves the rest as analog).
As I tried to tell you in my previous response you need to open up the datasheet for the PIC and look at the ADC section in general and specifically the description of the ADCON1 register. You'll find that setting just PortB.3 and PortB.4 to digital isn't possible.
Bookmarks