SX/B, interrupts and serial output
I'm still trying to get my application to work with interrupts and serial output. I've programmed ISRs in assembly for PCs but I can't seem to get the hang of it on the SX.
Does anyone have an example, using SX/B that uses an interrupt while writing serial output? I'm using·9600 baud, single wire to a second SX. I'm using the interrupt as a timer, I need to write the time out to the second SX using a serial connection.
Thanks again,
Dan
·
Does anyone have an example, using SX/B that uses an interrupt while writing serial output? I'm using·9600 baud, single wire to a second SX. I'm using the interrupt as a timer, I need to write the time out to the second SX using a serial connection.
Thanks again,
Dan
·
Comments
No warranty expressed or implied -- this code works fine for me, your mileage may vary.
Post Edited (JonnyMac) : 6/30/2008 6:36:01 PM GMT
If you do a search in the SX forum for "Jon Williams" and buffered serial, you will also find examples of similar approaches for buffered serial comm, which might be useful as well.
[noparse][[/noparse]edit] -- then again, Jon might just post that very code while I was typing my initial response
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Thanks so much!
I had seen a similar application in SX/B help, but I wasn't able to get the timing down correctly when I added code. Basically, mine ended up sending garbage to the serial output, since my timing was off.
Was 9600B too fast for what I'm trying to do? I noticed you have your example set at 2400B to 38.4K. also looks like I need to use a 20Mhz resonator too.
Zoot, thanks for the tips. I actually subscribe to N&V now, and I can honestly say, it's so that I can read Jon's columns.
You all are awesome when it comes to helping people out,
Dan
In fact some of the really good SX programmers have put in pretty fast Baud speeds in their apps. You will need a 20MHZ or 50MHZ resonators to run such code (so that there is enough room for instructions in the ISR *and* so the mainline program is blasting through instructions without getting bogged down by frequent interrupts.
The general rule of thumb is -- if you need interrupts then you can't *also* use any high-level commands in the main program that depend on strict timing (e.g. SERIN, SEROUT, PULSIN, PULSOUT, RCTIME, ANALOGIN, etc). You would need to put that kind of code into the ISR itself, where strict time *is* maintained.
This is probably a matter of style, but I think the high-level commands are good for quasi-converting existing applications from the Basic Stamp, or quickly pulling together code for apps that don't require an ISR. Anything with real ISR work, I usually leave them behind. There are some methods and timing finesses you can do (like setting a flag to ensure that a high-level SEROUT only kicks in when the ISR has just finished, and knowing you have enough time *before* the next interrupt to send the byte).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
So, I need to write all of the high level routines using assembly and put them in the ISR code? Basically, I can't stick a SEROUT in the ISR code an expect it to work?
I don't have an issue with assembly language, I taught it for 9 years at college. I just haven't had the time to read all of the specs for SX assembly. I bought Gunther's book, and have been reading through it, but I haven't had a chance to try and write in it yet.
I had been using SX/B all of this time...yes, being lazy, until this current project hit. Now I'm paying for it....
Dan
Jonny's attached code IS like "serin/serout" but in assembly and in the ISR. A few regular SX/B functions allow the main program to queue and de-queue the sent/received bytes. You can use those routines in the ISR and the functions in your main program w/o change (except for pin assignments, perhaps).
Why don't you attach your current working code? If your ISR is slow enough, it may be just easy to slip serial comm. in between interrupts as move material into the ISR.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
I need to do a live clock, showing time remaining, using an LCD serial panel. I have a second SX chip handling the LCD interface. There is a single wire serial line from the first chip (timer) to the second chip (LCD control).
The code is stripped down to just the test pieces I'm trying to get to work. In this example, the SEROUT commands are not in the ISR. This was the point where I realized I had timing issues. Garbage started coming out of the serial line. I'm not sure if adjusting the ISR time would fix it.
I could insert Jon's code in the ISR, load up the queues·and see if it works. I'm worried that when I add the timing code in the ISR, it will throw off the timing. I could possibly keep a small footprint, by adding a counter, then checking the counter out side of the ISR to see how much time is remaining.
Hmmm......
Dan
Post Edited (DosManDan) : 6/30/2008 8:37:57 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Dan
Post your code
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Dan
You'll just need something larger to hold the count until the MS comes around:
P.S. -- there are more efficient ways to organize this kind of app, but this should be clear. Make sure the revision to your light ISR works at the faster interrupt rate required by the serial comms. THEN add in your serial code -- at least then you'll know if it "breaks" it was the addition of the serial code. Running this at 50mhz wouldn't hurt -- will help make sure the SX is blasting through instructions quickly enough that you won't get jitter in your controls or serial comms.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
1uffakind.com/robots/povBitMapBuilder.php
1uffakind.com/robots/resistorLadder.php
Post Edited (Zoot) : 6/30/2008 10:03:29 PM GMT
I'll give it a shot tonight and let you know how it goes. I can't thank you enough for your help. I have a 50MHZ Murata resonator, I'll swap it in and give it a shot.
Dan
The program uses a 16-bit counter (tix_LSB + tix_MSB) to count 15360 ISR cycles; this is 1/10th second. When this is reached the tix counter is reset and the timer updated, with cascading updates (if tenths rolls under, secs are decremented, and so forth). At the end of the timer section there is a test to see if all timer registers (tenths, secs, mins) are zero; when this happens the timer flag bit is cleared -- this makes testing for timer expiration easy (I left my test code in place so that you can see how I do it).
Have fun, Dan.
Jon
Post Edited (JonnyMac) : 6/30/2008 11:02:44 PM GMT
This was more than I could have hoped for. Thank you so much! Now I have to go over to EFX and buy a bunch of stuff to pay you back for the help
I was sitting here trying to figure out why this was giving me so much trouble. I think most of my issues were in not understanding how the actual timing values were calculated. I read, in your articles and in Gunther's book how to calculate them, but, in practice I wan't able to get them correct. The Assembly code you have is very clear, and I can see how and why you are doing it. I need to study what you did and then play with it to see if I can modify it and still get it to work. If I can do that, it will be a step in the right direction for me learning how to use interrupts on the SX.
Also, it looks like I would have been better off just doing it in Assembly rather than trying to easy way out with SX/B. Lesson learned. I need to spend some time learning the instruction sets for the chip.
I really do mean it, thank you very much. I hope to meet you in person sometime, I'll buy you lunch. I'm just down in Elk Grove, so when I'm up your way, I'll send you an e-mail.
Dan
I absolutely agree with your assertion that you should buy lots of EFX-TEK products -- everyone should!
I respectively disagree with your comment about SX/B. SX/B takes a lot of grunt work out of your programs versus using straight assembly, and as you've seen by my (and others') examples, adding assembly to an SX/B program is very easy -- to me, the best of both worlds. Take the ISR for example: by using the rate parameter of INTERRUPT you don't have to do any calculating to to get the RETURNINT or OPTION register values correct (this is especially handy when you start changing FREQ settings). SX/B is a great tool; don't give up on it too quickly.
You'll have to come down to Hollywood to buy me lunch, I live in the LaLaLand. If you make it down this way, give me a call (# is on EFX-TEK site).
I was trying to figure out why you didn't calc the RETURNINT values (I didn't realize it was going to do it for you). I didn't mean to imply I was going to give up on SX/B, but that I had avoided using the Assembly option. I should have just learned it and used it where appropriate.
I'll post the completed program so everyone can benefit from the solution. Also, this is the first time I've used two SX chips in a solution. I'm very impressed by what these chips can do. Using the SX chip as a virtual peripheral allowed me to replace an $8.00 LCD driver chip in the design. Once I have the whole design figured out, I plan on trying the SX-48 to see if I can reduce the chips to one.
Thanks again,
Dan
Dan
Where did the 153_600 come from in the interrupt? I ordered a 20MHz resonator, but it won't be here until Sat, due to the holiday. I do have a 50MHz resonator, but I'm not sure how to change the timing of the interrupt to work with it.
The instruction rate for 50MHz is 1/50000000 or 20us, for a 20MHz it would be 1/20000000 it should be 50us (if I'm understanding this correctly).
9600 baud is moving a bit every 104us. If we are sampling 4 times faster than the transfer rate, I'm assuming the target number we are trying to hit is 104/4 or 26us.
At 50 MHz, the RTCC should roll over: 0.020 * 256 = 5.12us
At 20 MHz it should roll at: 0.050 * 256 = 12.8us
This is the part were I get stuck. What do I change to get the right timing?
Dan
For serial UARTing you are better to sample an odd number of times during one bit period. Five is great (21 uSec at 9600), three (35 uSec) is workable.
Cheers,
Peter (pjv)
You want to sample an odd number of times so that you can sample in the middle of the bit period. That allows for the most jitter and/or timing error and still get the bits correctly.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Uhhhm, that was on fire when I got here...
www.iElectronicDesigns.com
·
The great thing about SX/B is that you can change the FREQ directive and the INTERRUPT section will correct itself (so long as the rate parameter parameter is specified -- in this program it is). All you have to do is change the FREQ directive and you'll be set. Until you're more comfortable with programming the SX I would suggest leaving [noparse][[/noparse]working] code as-is.
I was taught to use 4x sampling per bit, so that's where 153_600 comes from (1/4th the bit time at 38.4k baud).
So the 38.4K is really 9600Baud * 4
From that, I can now see how you get to 6.51us.
1/38.40= 0.02604 then divide by 4 to get· 0.00651 which converts to 6.51us
So how do you get the 153_600?
Dan
Post Edited (DosManDan) : 7/3/2008 6:13:04 PM GMT
If you've got a [noparse][[/noparse]1/x] key on your calculator this stuff is easy -- pop in your max baud rate, press 1/x, divide that by four, then press 1/x again.
This will give you the ISR rate for your maximum baud, assuming you're using 4x sampling. Per PJV and Bean, you may want to use 5. The only time I've not used 4 was for DMX input when running 50 MHz, and this was just to minimize timing in the ISR -- works fine, and I have projects running at a big amusement park in SoCal that are happily using that DMX code on Prop-SX controllers.
Post Edited (JonnyMac) : 7/3/2008 6:35:26 PM GMT
As always, I really appreciate your help. I learned how to calculate the interrupt time, and I hope others who have the same question now understand where the numbers come from.
Thanks!
Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Shawn Lowe
When all else fails.....procrastinate!
Jon wanted 4x oversampling 38400 baud, so the isr rate becomes 4*38400 = 153600
Using that rate, 9600 baud becomes 16x oversampled.
For 20MHz resonator the number of ISR cycles is 20_000_000/153600 = 130
There is only so much you can do in 130 cycles.
If 9600 baud is all you are interested in I suggest to use 12x oversampling.
rate = 12*9600 = 115200
ISR cycles = 20_000_000/115200 = 174
This gives you more cycles so you can do more inside the isr.
regards peter