- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi, i am using CY8C29466-24SXI kit, and i am trying to convert the RPM speed of motor to a frequency from the monitor "n", i have problem with the code, the output is constant and should change when i change the speed of motor
the equation should be : Freq(monitor) = [n ( speed[rpm]) * Zpol ( which is 😎 ] / 20
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When you do an ISR you have to modify boot.tpl in root project directory to add
the vector jump.
You have currently -
org 34h ;PSoC Block DBB11 Interrupt Vector
reti
This should be -
org 34h ;PSoC Block DBB11 Interrupt Vector
ljmp _ms_Timer_ISR_C
reti
Also you did not use the #pragma qualifier when declaring the C intterupt, look at Imagcraft manual.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note the interrupt vector comes from the last block in a timer or counter chain, in your case DBB11.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, forgot to add this -
#pragma interrupt_handler foo
void foo(void) {
..
..
}
Note "foo" is not used with an underscore in the declaration, just in boot.tpl.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dana,
i have the freqcode.asm, and tickhander.asm and called them in the h file. i am not sure if i have to use interupt for the timer because it should capture from the comparator. can you please be more clear what exactly i am doing wrong?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you have a schematic you can post ?
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dana, here is schematic for my project. basically, i want to take the frequency and put it in the RPM equation to measure RPM of the motor with the voltmeter ( manually ). the thing is the output from monitor is a digital signal (high/low) and is equivlant to a third of the commutation frequency.
the equation is: RPM = 2.5 * Freq (monitor)
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Basically to measure PW you use a timer, start it on positive edge of
input pulse, and either do a capture on 1 edge or an ISR on negative
edge. You could also use a counter to do this.
One simple method is use positive edge of pulse to start timer, and negative edge
to indicate end of pulse period,. That can be input pin set to ISR on negative edge.
Here is an ap note with several methods. Including an anlog method.
That works if freq is a constant.
http://www.psocdeveloper.com/docs/appnotes/an-mode/detail/an-pointer/an2103/an-file/119.html
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dana,
i tried to fix a project to have a function generator as input signal. and have compare out and terminal count out as outputs,, and connected LED on port 2-0 to check if it is working. for some reason when i connect the generator it doesnt want to compile, but once i take the generator out it compiles but cant test it beacuse of no signal in.
FYI, the link you sent earlier, i cant open any of these projects to look at it.
Thanks a lot for your time
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
it works, but the terminal count out i have nothing comes out, and compare out is same as signal i am putting in.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am at a remote site, do not have my cube with me for debugging, but here
is what I see -
1) boot.tpl. root directory you have to modify vector table to do the ISR vector to TachTimer16_MSB_ISR()
Edit boot.tpl vector table to reflect this change
org 24h ;PSoC Block DBB01 Interrupt Vector
reti
to
org 24h ;PSoC Block DBB01 Interrupt Vector
ljmp _TachTimer16_MSB_ISR
reti
2) In TachTimer16INT.asm I think the call name TachTimer16_MSB_ISR
must be changed to _TachTimer16_MSB_ISR, not 100% sure about this,
but I think that is the case.
3) The programming pins on the 29466 are Vdd, Vss, XRES, SCLK, and SDAT, so if you
are using any of these in design they have to be disconnected to program.
4) Function generator putting out 0 - 5 V, not some negative voltage to 5V ? You
have offset its output waveform, right ?
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some other observations -
1) Any reason for running the part not full speed at 24 Mhz ? Why waste MIPs (unless trying to save
power) available.
2) If you have a port with mixed I/O, you need to use shadow registers -
http://www.cypress.com/?id=4&rID=28251
http://www.planetpsoc.com/psoc1-articles-digital/13-basics-of-psoc-gpio.html?start=5
3) ISR notes -
http://www.cypress.com/?id=4&rID=36720
] http://www.planetpsoc.com/component/content/article/43-writing-a-c-isr.html
http://www.planetpsoc.com/psoc1-articles-digital/13-basics-of-psoc-gpio.html?start=7
4) I was wrong on call inside TachTimer16INT.asm, you do not need the underscore as
you are calling an asm(), not a C f().
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One last, I am so used to writing C interrupts that I forget when not to use
the _ preceding a call.
When I discussed boot.tpl, I indicated to put the underscore preceding that call,
but you are calling an asm function, so leave it off, should be -
ljmp TachTimer16_MSB_ISR
Bonehead I am.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dana,
i think i am too close now, i have it working but my output ( Compare out ) on PORT0-0 is always zero, it doesnt update with the frequency.
i wont be able to debuge it by LCD, however can i tested by Multimeter?
thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Maybe start at the basics for a moment.
1) To measure PW we use counter or timer.
2) Since all PSOC 1 counter/timers (C/T) are down counters, we load
them with a full scale value, in your case you have chosen 65000.
Normally for a 16 bit C/T you would use 65535.
Timer solution -
3) We start the Timer on the positive edge of the input signal whose
pulse width we want to measure. So we have the starting value of the
period register, which is 65000 in your case. We start it with an ISR
from the positive edge of the input signal (via pin configuration), and
read the timers count register in this ISR opr set a flag to do so.
Remember Timer runs continuously unless you stop it.
4) Timer continues to run, counts dropping in its counter register, then
input signal drops, triggering a capture event (another ISR). Now we read
timer count register giving us counts at end of its pulse. So we take start
counts and subtract capture counts. Note, there is a problem, if timer over-
flows, ie counts to 0 then next count starts back at full count (65000 in your
case) we have to take care of this subtraction problem.
Example, counter starts at 65000, counts down to 30000, PW = 35000. If
Clock to timer is 1 Mhz, 1 uS, then PW = 1 uS X 35000 = 35 mS.
The Compare register has no functionality in this solution.
Counter solution -
5) We load max period into period register, 65000 in your case.
6) Input signal goes to enable pin on counter.
7) Input goes high, counter starts counting down.
😎 We have the input pin configured for an interrupt on falling edge.
9) Input falls, ISR triggered, we read the counter register, not the
period register, and get the counts at the end of the pulse.
10) We subtract the ISR counts from the full scale counts we loaded (65000
in your case) and we have the PW counts. We get the PW time using same
calculation we did for timer case based on clock.
11) We stop and reload counter with 65000 in this ISR
12) We have to take care of the same “rollover” problem as the timer.
The Compare register has no functionality in this solution.
When to use the compare register. Say you want to know when the pulse has exceeded
3000 counts, in the case of a 1 Mhz clock, 3 mS width. Then you would set the compare
Register to 65000 – 3000 = 62000. When the C/T reaches 62000 the compare output
goes high. That can trigger an ISR to handle your pulse has exceeded 3 mS.
Hope this helps.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The reason your compare output never went high is the counts never dropped below
200, the value you wrote to the compare register.
As an aside, the core of all C/T blocks is a counter, counting clock inputs pulses.
The COMPARE and PERIOD register are separate registers from the core counter in the C/T.
The compare has logic, that looks at whats in the core counter, and compares its value against
whats in the compare register, generating a compare output and an ISR if you enable it.
The compare logic you select, < or <=.......
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------
#include
<m8c.h>#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma
interrupt_handler Tach16_MSB_ISR#pragma
WORD count=
WORD result=
WORD compare1=
WORD compare2=
interrupt_handler Tach16_LSB_ISR 0 ; 0 ; 0 ; 0 ;int
no_of_TimerPeriod= 0 ;int
no_of_TimerPeriod2= 0 ;int
flag= 0 ;void
{
count++;
Tach16_MSB_ISR ( void )
}
void
{
{compare1=TachTimer16_wReadCompareValue();
no_of_TimerPeriod=count;
flag=
}
Tach16_LSB_ISR ( void ) int pulse_width= 0 ; if (flag== 0 ) 1 ; else
{ flag=
compare2=TachTimer16_wReadCompareValue();
no_of_TimerPeriod2=count;
pulse_width=(compare1 +(no_of_TimerPeriod2 - no_of_TimerPeriod)*
}
0 ; 65000 + 65000 -compare2)/ 100 ; }void
{
main( void )int
TachTimer16_EnableInt();
TachTimer16_EnableTerminalInt();
TachTimer16_EnableCaptureInt();
TachTimer16_Start();
{
}
}
i; M8C_EnableGInt ; while ( 1 )- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Correction to my prior post. I forgot, frankly, the Timers do not have a separate capture register,
so was trying to advise you the compare register was pointless in the design to calc PW.
That being said I fooled around trying different approaches, looking at jitter, and seem to
think a slightly different approach produces a better result.
So I set up a timer, to capture on falling edge, and the input pin to the timer to ISR on rising edge.
In ISR for pin I simply read timer register. In capture ISR I do not read the compare register,
I execute again a simple read on timer register. So I have two values, and keep the timer running
continuously. Reason I did not read the capture register for second value is I felt that the machine
cycles, latency, is same for both ISR calls. So my observed jitter was better with this approach.
I worked with pulses up to 10 Khz with a 1 uS timer clock. And PW down to 30 uS in width,
where error seemed too high. I have not tried faster Timer clock, say 12 Mhz, to see what that will do.
I then tried using a counter solution, just one ISR on GPIO negative edge that feeds counter enable.
Pulse coming in goes high, starts counter counting. ISR stops counter, reads it, reloads it, restarts it.
Net result seemed I could handle much narrower pulses, 10 uS reading accurately.
Food for thought, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I omitted a couple of points.
1) Counter requires only 1 ISR.
2) Counter enable serves two purposes, going high we start
counter with a known value, going low ISR to indicate done counting.
3) For real accurate count one would look at read counter register
ASM listing and count instruction cycles to get latency.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Soime questions -
1) You are changing thePWM16 pulse width, not its frequency, with -
PWM16_WritePulseWidth(curr_rpm), is that what you intended ?
Most multimeters only measure frequnecy.
2) Your multimeter is measuring what, freq or PW ?
3) You have "freq = (float) 2400000/pulse_width;", this should be
"freq = (float) 24000000/pulse_width;"
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dana,
the curr_rpm is from the equation of the freq, so when i change the freq, it should change the rpm. and take that rpm value and measure thro the multimeter. as freq.
Mina
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dana,
thats what i am trying to do, take the freq from output and put it in the RPM equation and measure the freq that equivlant to RPM.
equation is RPM( freq) = 2.5 ( monitor freq)
so if i input freq 200HZ, i want to read on freqmeter 200*2.5= 500HZ
Can you advice me if my way is right or wrong ?
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1) You are changing thePWM16 pulse width, not its frequency, with -
PWM16_WritePulseWidth(curr_rpm), is that what you intended ?
3) You have "freq = (float) 2400000/pulse_width;", this should be
"freq = (float) 24000000/pulse_width;"
Did you fix those problems ? A PWM has two registers associated with it,
period, hence frequency, and pulse width, eg. duty cycle. I think you
were writing the wrong register.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi friends,
i have configured the UART module along with timer 16. My uart operating at 9600 bps. i have congigured the global resource as follows
Sysclk at 24 Mhz
VC1= 24Mhz /8
VC2 = VC1/ 3
VC3 = VC2/13
Now i need to operate my timer interrupt every 25 msec.
i just did like dis
Now my timer operating at VC2 i.e 1Mhz which is equal to 1micro sec.
Now i have given 65000 as period
40000 as compare value.
interrupt on compare true
compare value less than or equal to..
capture is low.
as i calculated the period value of 65000 gets decremented and when it reaches 40000 it generates an interrupt.
65000 (PERIOD)
40000 (-) (COMPARE VALUE)
-----------
25000 = 25000* 1micro sec = 25msec .
-----------
so as my calculation every 25 msec an interrupt should generate but im not getting the expecting output.. Tried checking the interrupt every sec but my expected value reaches only after 3 sec.
can u please help us in this. Is this the right way ....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Welcome in this forum and in the fascinating world of PSoCs!
You should set the period value to generate your wanted frequency, in your case to 25000-1 = 24999.
The compare value will change the duty-cycle of the compare output only, so you can set that to 25000/2 -1 = 12499 to have a 50% duty cycle.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The interrupt is going to occur at the period rate, unless in interrupt you reset
timer. So 25 mS = 40 Hz, therefore N = 1 Mhz / 40 = 25000. So set period to 24999,
then either set compare value to anything from 1 to 24998 (the extreme
gives very narrow pulses on compare out) or set interrupt type to terminal count,
compare value to 12499 (gives 50% duty cycle on compare out).
Note the compare interrupt occurs at the period rate, unless in ISR you terminate
timer by a reset, stop....or change the timer period.
Also don’t forget to modify boot.tpl for the interrupt vector.
http://www.cypress.com/?rID=91487 AN90833 - PSoC® 1 Interrupts
http://www.cypress.com/?rID=34189 AN47310 - PSoC® 1 Power Savings Using Sleep Mode
Lastly the way you had the timer set up it would have generated an ISR 25 mS
from the start of the timer, but then next interrupt would have occured 40,000 +
25,000 counts which would have been a little over 15 Hz rate. The counter counts
down from period value, hits the compare value (so its output goes true, continues
counting down to 0, and on rollover compare goes false, counter rolls over to period
value, and process repeats......
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A couple of other items -
1) You have CPU clock set to / 8 or 3 Mhz, if you want more performance
set it to /1. Note that would impact power.
2) If you have any analog coming out to a pin set in global properties
the OpAmp and Abuff power to high, otherwise impacts bandwidth and
CM range for analog signals.
3) In ISR mimimize code, like other f() calls, etcc. Reason is that creates a
lot of stack push and wastes MIPs. Generally speaking, wherever possible,
set a flag in ISR and exit, then process ISR from main(). Just good practice.
4) Ref material -
http://www.cypress.com/?rID=2638 AN2197 - Stepper Motor Driver for Smart Gauges
http://www.element14.com/community/docs/DOC-47984/l/cypress-an2229--application-note-on-psoc-1-motor... AN2229 Motor Control-Multi-Functional Stepping Motor Driver
http://www.element14.com/community/docs/DOC-47938/l/cypress-an41949--application-note-for-psoc-1-ste... AN41949 - Application Note for PSoC 1 Stepper Motor Controller
5) If your ISR rate is flexible you could always use the sleep timer, saves
digital blocks for use in something else. It has rates for ISR of -
Constant | Value | Interrupt rate |
---|---|---|
SleepTimer_1_HZ | 0x18 | 1 Hz |
SleepTimer_8_HZ | 0x10 | 8 Hz |
SleepTimer_64_HZ | 0x08 | 64 Hz |
SleepTimer_512_HZ | 0x00 | 512 Hz |
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am writing a code to measure the frequency and I am using CY8c28445-24PVXI chip. I have added FreqCode.h header file but when I compile it says cannot inlcude this header file. can you please help me.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Welcome in the forum.
A bit difficult to guess what the reason might be. Can be the wrong place where FreqCode.h and .c are stored. Are the files listed (added) to workspace explorer? Can you provide us with a project archive made from designer -> File ...
Bob