|
|
View previous topic :: View next topic |
Author |
Message |
lindsay.wilson.88
Joined: 11 Sep 2024 Posts: 40
|
Accessing registers and bits directly - good idea? |
Posted: Thu Sep 12, 2024 4:30 pm |
|
|
I realise this has been asked and answered before (https://ccsinfo.com/forum/viewtopic.php?p=170258) but I'd like to elaborate a little.
In the previous software that I've been used to (mikroC and mikroBasic), I mostly interacted directly with registers - e.g. TRISB, PORTB, T2CON, all that stuff. I sort of like this because I know exactly what bits are being set (e.g. I can look up the datasheet, read about what's required, and then put it in code), but I do get the advantages of using higher-level functions instead - output_b(), enable_interrupts() and so on.
However, there's a few cases where I think it's still better to interact with registers. For example, at the moment I'm using Timer 2's interrupt to pulse a stepper motor (well, it's going to do a bit more than that eventually, but that's the basics 😁). The interrupt frequency is determined by the PR2 register value. The user is able to change the frequency by entering a new value over the serial port.
I can use setup_timer_2() each time to update it with the new value:
Code: | setup_timer_2(T2_DIV_BY_4,new_value,5); |
which is fine, but this might appear several times in the code and if I ever needed to tweak the pre or post scalers, I'd have to do it several places. Or have another couple of variables to hold them.
Instead, I could just write the new value directly to PR2 (assuming it's defined correctly with the getenv thing):
which is a lot simpler!
Similarly, if I want to start or stop the timer running, after it's been set up, all I need to do is set or clear the TMR2ON bit of T2CON.
Haven't actually asked a question yet 😁 I suppose it's, is there anything inherently bad about doing it this way? Are there any gotchas which are likely to crop up as a result of doing this? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Fri Sep 13, 2024 12:29 am |
|
|
Nothing at all, but the key is documentation.
With some registers there are other things that must be done, here the
built in functions take care of this for you. However on the basic timer
setting the PR2 register is easy to use as you show (though be aware
that since the prescaler and postscaler are cleared when you write this,
there will be a slight hiccup in the timing).
At the end of the day, the setup_timer command is telling you what it is
doing. the PR2= version does not. So you must make sure you document.
Add a comment to the line:
Code: |
PR2=new_value; //Set Timer2 division value register
|
Now the point is that if you come back in five years, or somebody else
works on the code, you/they get immediately told what you were doing.
Documentation, is always your friend.
When marking code, I used to have a thing that any code that did not
contain at least 75% comments, would get scored down massively, or
failed....
Try working on a project again years on, and you suddenly find why this
is so important. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Fri Sep 13, 2024 5:15 am |
|
|
re: Try working on a project again years on, and you suddenly find why this
is so important.
It doesn't need to take years......sigh.
Other day cutting some fun code(rainy day ..bored ), went to grab another cup of coffee, came back, STARED at screen for 10 minutes wondering WHAT is this 'code' supposed to do ?
So YES, add comments !! The more the merrier !!! Especially lines of code that are 'math',so 11 minutes from now,you'll KNOW what it's supposed to do.... |
|
|
lindsay.wilson.88
Joined: 11 Sep 2024 Posts: 40
|
|
Posted: Fri Sep 13, 2024 6:15 am |
|
|
Heh, like the time I forgot to set ANSEL and ANSELH and spent an afternoon trying to figure out why I couldn't output anything. When I look back at some of the stuff I wrote when I was learning (I think I first used QuickBasic), not a comment in sight!
Re your point about prescaler and postscaler being cleared when writing PR2, is that definitely the case? I had another look at the datasheet (I'm using a 16F887) and I can only see a paragraph about them being cleared when writing TMR2 or T2CON, nothing about PR2. It's important because I wouldn't want it generating two faster steps, which the motor might miss. Going slower for a time isn't a problem though.
[/img] |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Fri Sep 13, 2024 7:03 am |
|
|
No, on you chip it doesn't, but you then have the problem of a longer time,
if you set it to a new value below the current count...... |
|
|
lindsay.wilson.88
Joined: 11 Sep 2024 Posts: 40
|
|
Posted: Fri Sep 13, 2024 10:03 am |
|
|
That's true, but a longer time would be ok, the stepper would just have a "slow" step for that particular loop. I was mainly worried about it producing a shorter loop when the value is changed, but I don't think that should be possible. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Sat Sep 14, 2024 4:15 am |
|
|
You say a long pulse won't matter, but for a stepper running fast, it does.
You can get mis-step just as easily from a pulse that is too long as for
one that is too short. Could you use a PWM to generate the pulse train
for this?. Key is the PWM when you ask it to change speed does the
actual change when the pulse time reloads, to avoid any such glitch.
Otherwise use the timer interrupt and load the new period when the
timer resets. |
|
|
lindsay.wilson.88
Joined: 11 Sep 2024 Posts: 40
|
|
Posted: Sat Sep 14, 2024 11:03 am |
|
|
Excellent point about updating the period within the timer loop itself, thanks! That makes a lot more sense.
As for the effect for a long pulse, I see what you're saying, but I think it should still be ok. Normally, for any stepper-driven stuff, I'd ramp up the speed so it can reach a higher maximum speed that just going to full speed from stationary, and in that case I can see how a longer pulse would throw things off. However, in this application, I'm only pulsing the motor at the speed which it _can_ handle from a dead stop. For sake of argument, say 2000pps. I can hit the motor directly with a burst of pulses at 2000pps and it will respond happily. So even if there was a little delay somewhere in the middle, it would still be able to do the same number of pulses overall.
Hope that makes sense. I've got another Q coming up about hardware multipliers as well ;-) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sun Sep 15, 2024 6:46 am |
|
|
You'll have to consider more than just software to run the stepper.
There's a LOT of hardware to consider that can affect your performance goal.
'Slop' in the drive train, unbalanced driven mass, gear to gear fit, belt tension, fwd vs rev motion characteristics, actual sensor used for position (obviously you can't just 'count 1234 pulses and I'm there' ).
Also the power interface 'driver' has several requirements and needs to be matched to the stepper motor.
Don't forget about the 'heat factor', not only ambient temperature, but stepper motor and driver as well. |
|
|
lindsay.wilson.88
Joined: 11 Sep 2024 Posts: 40
|
|
Posted: Sun Sep 15, 2024 7:05 am |
|
|
@temtronic Thanks - all valid points, but not really an issue here. I'm using the Sherline CNC rotary table from my milling machine (link https://www.sherline.com/product/8730-cnc-rotary-table-with-stepper-motor/). It's worm-gear driven, and the amount of backlash is tiny - I forget offhand, but something like 0.01mm on a 20mm part diameter. In the final application, it's only going to be driven in the one direction when doing the "important" stuff, so backlash isn't a concern. As for the driver, I've got that pretty well matched - I've used an A4988 with it in the past and it works well. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|