Maybe it is complaining that you have set your array to:
sineval var byte[72]
and then you go from 1 to 72.
You either need to change it to 0 to 71, or change your array size to 73
Maybe it is complaining that you have set your array to:
sineval var byte[72]
and then you go from 1 to 72.
You either need to change it to 0 to 71, or change your array size to 73
i have changed the number of array size together with other modifications but there is no change in the simulation result,it is still a line....
Code:define OSC 20 ;*****************VARIABLE DECLARATION****************************************** wsave VAR BYTE $70 SYSTEM ' alternate save location for W wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1 wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2 wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3 STEPCOUNT var byte 'Define stepcount as byte type variable stepcount = 256 ;**************SETTING THE REGISTERS WITH APPROPIATE BIT DEFINITION************* ADCON0 = %00000000 ADCON1 = %00000000 ;all anolog output trisb = %11111111 ;define porta as input trisc = %11111011 ;make ccp1/portc.2 an output pin trisa = %11111111 ;define porta as input TMR2 = 16 PR2 = 34 ;set for 36Khz HPWM(=72 steps*10 times*50hz) CCP1CON = %000001100 ;set to pwm mode T2CON=%00000110 ;enable timer2 and set timer2 prescaler value of 1:4 ;****************A sine lookup table in an array******************************** sineval var byte[73] sineval[1] = 128 ;0 degree sineval[2] = 137 ;5 degree sineval[3] = 146 sineval[4] = 154 sineval[5] = 163 sineval[6] = 171 sineval[7] = 179 sineval[8] = 187 sineval[9] = 194 sineval[10] = 200 sineval[11] = 206 sineval[12] = 212 sineval[13] = 216 sineval[14] = 220 sineval[15] = 224 sineval[16] = 227 sineval[17] = 228 sineval[18] = 229 sineval[19] = 230 ;90 degree sineval[20] = 229 sineval[21] = 228 sineval[22] = 227 sineval[23] = 224 sineval[24] = 220 sineval[25] = 216 sineval[26] = 212 sineval[27] = 206 sineval[28] = 200 sineval[29] = 194 sineval[30] = 187 sineval[31] = 179 sineval[32] = 171 sineval[33] = 163 sineval[34] = 154 sineval[35] = 146 sineval[36] = 137 sineval[37] = 128 ;180 degree sineval[38] = 119 sineval[39] = 110 sineval[40] = 102 sineval[41] = 93 sineval[42] = 85 sineval[43] = 77 sineval[44] = 69 sineval[45] = 62 sineval[46] = 56 sineval[47] = 50 sineval[48] = 44 sineval[49] = 40 sineval[50] = 36 sineval[51] = 32 sineval[52] = 29 sineval[53] = 28 sineval[54] = 26 sineval[55] = 26 sineval[56] = 26 sineval[57] = 28 sineval[58] = 29 sineval[59] = 32 sineval[60] = 36 sineval[61] = 40 sineval[62] = 44 sineval[63] = 50 sineval[64] = 56 sineval[65] = 62 sineval[66] = 69 sineval[67] = 77 sineval[68] = 85 sineval[69] = 93 sineval[70] = 102 sineval[71] = 110 sineval[72] =119 timerone var word INCLUDE "DT_INTS-14.bas" ; Base Interrupt System ;********Define INT_Handler as ISR********************************************** ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _sine, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM T1CON = $31 ; Prescaler = 8, TMR1ON TMR1L = 255 TMR1H = 254 @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts timerone = $EE16 ;gives about 50 hz sine Main: pause 5 'if timerone = $F9FF then timerone = $FF00 GOTO Main '---[TMR1_INT - interrupt handler]------------------------------------------ sine: TMR1L = timerone.byte0 TMR1H = timerone.byte1 CCPR1L = sineval[STEPCOUNT]>>1 stepcount = stepcount -1 if stepcount = 1 then stepcount = 73 @ INT_RETURN
Last edited by Ioannis; - 8th May 2011 at 15:37.
First thing I would do is make sure the ISR is working. Make an unused pin an output, then toggle it in the ISR. hook a scope to that and make sure it toggles. Also you can do the same in your main with another pin.
This way you will know some basic info like is my pic running, is my interrupt firing. do that and report back
-Bert
The glass is not half full or half empty, Its twice as big as needed for the job!
http://foamcasualty.com/ - Warbird R/C scratch building with foam!
hi,
i've managed to get the sinusoidal output sine wave although i'm getting frequency of 202Hz instead of 50Hz and peak voltage of 4.58v instead of 4.5v.Also the waveform is not smooth.Simulation results.docWhat should i do to acheave this parameters?
code:
Code:define OSC 4 ;*****************VARIABLE DECLARATION****************************************** wsave VAR BYTE $70 SYSTEM ' alternate save location for W wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1 wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2 wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3 ADCON0 = %00000000 ADCON1 = %00000000 trisb = %11111111 trisc = %11111011 trisa = %11111111 TMR2 = 16 PR2 = 15 ;set for 16Khz HPWM CCP1CON.3 = 1 ' set to pwm mode CCP1CON.2 = 1 T2CON.2=1 T2CON.0=1 STEPCOUNT var byte stepcount = 32 ; Set sine "table" in an array sineval var byte[32] sineval[1] = 128 sineval[2] = 148 sineval[3] = 167 sineval[4] = 185 sineval[5] = 200 sineval[6] = 213 sineval[7] = 222 sineval[8] = 228 sineval[9] = 230 sineval[10] = 228 sineval[11] = 222 sineval[12] = 213 sineval[13] = 200 sineval[14] = 185 sineval[15] = 167 sineval[16] = 148 sineval[17] = 128 sineval[18] = 108 sineval[19] = 89 sineval[20] = 71 sineval[21] = 56 sineval[22] = 43 sineval[23] = 34 sineval[24] = 28 sineval[25] = 26 sineval[26] = 28 sineval[27] = 34 sineval[28] = 43 sineval[29] = 56 sineval[30] = 71 sineval[31] = 89 sineval[32] = 108 timerone var word INCLUDE "DT_INTS-14.bas" ; Base Interrupt System ;include "ReEnterPBP-18.bas" ;not needed for ASM type interrupt service routines ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _sine, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM T1CON = $31 ; Prescaler = 8, TMR1ON TMR1L = 255 TMR1H = 254 @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts timerone = 65504 ;gives about 50 htz sine Main: pause 5 'timerone = timerone - 1 'uncomment to vary 60hz sine if timerone = $F9FF then timerone = $FF00 GOTO Main '---[TMR1_INT - interrupt handler]------------------------------------------ sine: TMR1L = timerone.byte0 TMR1H = timerone.byte1 CCPR1L = sineval[STEPCOUNT]>>1 stepcount = stepcount -1 if stepcount = 0 then stepcount = 32 @ INT_RETURN
Hi,
You're still off on the array.
This creates an array of 32 elements numbered 0-31 but you assign values to it starting at 1 and ending at 32 - not very good. There is no SineVal[32], when you read/write to that variable you're actually accessing the "next" RAM location, something I'm sure you don't want to do here.Code:Sinval VAR BYTE[32]
You can adjust the peak value by "scaling" the value in your sine-table but really, you're not even 2% off target.
Are you using a 4MHz x-tal like the code says or are you using something else?
If I'm not mistaken a reload value of 65505 with a prescaler of 1:8 running at 4Mhz gives an interrupt frequency of 4032Hz, you have 32 "steps" to your cycle so you "should" get around 126Hz....
For accuracy it's usually better to stop the timer and then ADD the preload value to the timers current value since this will take into account the interrupt latency etc. Stop it, copy it to a WORD, add the reload value, copy it back and restart the timer.
Any specific reason you're using a TMR1 prescaler of 8? Using a lower prescaler ratio will give you better "resolution" on the interrupt frequency.
/Henrik.
hellow Henrik,
thanx for the tips, i've re-worked my sine table,also i've include the code for accuracy although i'm not sure if i've place it in a right place!
For a 4MHz xtal and TMR1 prescaler of 1 i reload the T1 with the value 64980 to get 50Hz and it's what m getting on the scope.
Also TMR2 with prescaler of 4 is loaded with 117 for the interrupt to be generated every 556us(256-(556/(4*0.25*4))
But the problem is that the waveform i'm getting on the scope is not smooth at all....Simulation results..pdf
code:
where i'm wrong in the code? are the calculations above correct?Code:define OSC 4 ;*****************VARIABLE DECLARATION****************************************** wsave VAR BYTE $70 SYSTEM ' alternate save location for W wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1 wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2 wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3 STEPCOUNT var byte 'Define stepcount as byte type variable stepcount = 36 ;**************SETTING THE REGISTERS WITH APPROPIATE BIT DEFINITION************* ADCON0 = %00000000 ADCON1 = %00000000 ;all anolog output trisb = %11111111 ;define porta as input trisc = %11111011 ;make ccp1/portc.2 an output pin trisa = %11111111 ;define porta as input TMR2 = 117 PR2 = 13 ;set for 18Khz HPWM(=36 steps*10 times*50hz) CCP1CON = %000001100 ;set to pwm mode T2CON=%00000110 ;enable timer2 and set timer2 prescaler value of 1:4 ;****************A sine lookup table in an array******************************** sineval var byte[36] sineval[0] = 128 sineval[1] = 148 sineval[2] = 167 sineval[3] = 185 sineval[4] = 201 sineval[5] = 215 sineval[6] = 227 sineval[7] = 235 sineval[8] = 240 sineval[9] = 242 sineval[10] = 240 sineval[11] = 235 sineval[12] = 227 sineval[13] = 215 sineval[14] = 201 sineval[15] = 185 sineval[16] = 167 sineval[17] = 148 sineval[18] = 128 sineval[19] = 108 sineval[20] = 89 sineval[21] = 71 sineval[22] = 55 sineval[23] = 41 sineval[24] = 29 sineval[25] = 21 sineval[26] = 16 sineval[27] = 14 sineval[28] = 16 sineval[29] = 21 sineval[30] = 29 sineval[31] = 41 sineval[32] = 55 sineval[33] = 71 sineval[34] = 89 sineval[35] = 108 timerone var word INCLUDE "DT_INTS-14.bas" ; Base Interrupt System ;********Define INT_Handler as ISR********************************************** ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler TMR1_INT, _sine, ASM, yes endm INT_CREATE ; Creates the interrupt processor ENDASM T1CON = %000001 ; Prescaler = 1, TMR1ON TMR1L = 255 TMR1H = 254 @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts timerone = 64980 ;gives about 50 hz sine Main: pause 5 GOTO Main '---[TMR1_INT - interrupt handler]------------------------------------------ 'accuracy thing TimerShadow VAR WORD T1CON.0 = 0 'Stop TMR1 TimerShadow.HighByte = TMR1H TimerShadow.LowByte = TMR1L TimerShadow = TimerShadow + Timerone TMR1H = TimerShadow.HighByte TMR1L = TimerShadow.LowByte T1CON.0 = 1 'Restart TMR1 sine: TMR1L = timerone.byte0 TMR1H = timerone.byte1 CCPR1L = sineval[STEPCOUNT]>>1 stepcount = stepcount -1 if stepcount = 0 then stepcount = 36 @ INT_RETURN
Last edited by Ioannis; - 8th May 2011 at 15:38.
What are you using for a filter? You should have at least half of the below example to smooth out the signal. Also, it will never look too good on simulation. Might look better on actual hardware. Might be some issues with running it at 4 mhz. Is there a reason you don't want 20 mhz? Even AN655 's example showed 20 mhz.
Code:; Filter Diagram ; ; 2.7k 2.7k ; RC2 ___/\ /\ /\______/\ /\ /\________ Analog Output ; \/ \/ | \/ \/ | ; | | ; ----- 0.1uF ----- 0.1uF ; ----- ----- ; | | ; GND GND ; ;
Hi,
Several things.....
TMR2 is the timer used for the PWM generation. The fact that you initially load it with 117 doesn't matter for either the PWM frequency or your interrupt frequency since you're using TMR1 to generate the interrupts.
You have the prescaler for TMR2 set to 1:4 and PR2 set to 13 which indeed gives you ~18kHz PWM frequency but it'll only give you a give you 56 discrete dutycycles. Ie. the maximum value you can put in the dutycycle register is 56. The highest value in your sine table is 242 which you then shift right one time bofore putting in the CCP1L, so you're trying to put 121 in there when 56 is max.
Changing the prescaler to 1:1 and putting 55 in PR2 gives you the same PWM frequency but allows dutycycle values of 0-222.
TMR1 is now setup with a prescaler of 1:1 and you reload it with 64980 making it interrupt every 65536-64980=556us or at a frequency of 1798Hz, there's now 36 steps to your "cycle" so 1798/36=49.96Hz so it seems to be correct. I don't think you should expect to be able to run much faster than that at 4Mhz, the DT-ints takes quite afew cycles to save and restore all the system variables on each interrupt so you won't have much time left.
The "accuracy thing" needs to be performed on each reload or it won't have much effect. It should be in your ISR instead of the reload code you have there now.
/Henrik.
Bookmarks