Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using RD16 16BIT PIC register write in Oshonsoft

camerart

Well-Known Member
Hi,
Has anyone used the RD16BIT (write to 2x BYTES to registers in one WORD) in Oshonsoft? I'm using an 18F4431 PIC.

It needs a write to a pair of registers, and so far I've not got very far.
Camerart.
 
What are you trying to read/write?, I presume you are aware it's a specific hardware function?, specifically for TMR1 - so you can read it as a single 16 bit read instead of two 8 bit reads. You have to configure a bit in TMR1 to enable it.
 
What are you trying to read/write?, I presume you are aware it's a specific hardware function?, specifically for TMR1 - so you can read it as a single 16 bit read instead of two 8 bit reads. You have to configure a bit in TMR1 to enable it.
Hi N,
I have a SERVO control program, where I need to write to registers. So far I've done 2x BYTES, but the RD16 section says, that this can cause errors, hence the RD16 question.
I have the T1CON BIT set, now I need to write to them.
C
 

Attachments

  • RD16.jpg
    RD16.jpg
    386.8 KB · Views: 50
I think what you saw is a function of Oshonsoft. Years ago, I tried in Assembly to write to TMR1L with multiple addwf's to see whether TMR1H would catch the overflow, and it didn't. Of course, you can write to both registers separately or threat them in the usual 8-bit H/L register way. I then tried counting down from TMR1L, and again, it did not automatically handle the borrow like TMR1 does when counting down.

If you decompile your code, I'll bet it's at least 4 lines of code: e.g., movlw high(1000), movwf TMR1H; movlw low(1000), movwf TMR1L. I agree with Nigel. It's a special function, and you cannot divert it to another use like you show. Of course, it is a 16-bit counter/timer when using the correct gate source.
 
I think what you saw is a function of Oshonsoft. Years ago, I tried in Assembly to write to TMR1L with multiple addwf's to see whether TMR1H would catch the overflow, and it didn't. Of course, you can write to both registers separately or threat them in the usual 8-bit H/L register way. I then tried counting down from TMR1L, and again, it did not automatically handle the borrow like TMR1 does when counting down.

If you decompile your code, I'll bet it's at least 4 lines of code: e.g., movlw high(1000), movwf TMR1H; movlw low(1000), movwf TMR1L. I agree with Nigel. It's a special function, and you cannot divert it to another use like you show. Of course, it is a 16-bit counter/timer when using the correct gate source.
Hi J,
I didn't consider Oshonsoft, only the D/S from where the section in #3 came from.
Here is the OSH ASM for that section:
TMR1HL = 0x03e8
MOVLW 0xE8
MOVWF TMR1L
MOVLW 0x03
MOVWF TMR1H
This shows in the Simulator TMR1 BYTEs, but from what you say this won't work.
If not, then following the RD16 section in the D/S, how do I implement it?
C
 
It depends on what you r mean by "work." They will work like ordinary 8-bit registers, not like a 16-bit register as they do when working as TMR1. Pre-loading those registers is a common way to get specific time intervals.
 
Hi J,
I didn't consider Oshonsoft, only the D/S from where the section in #3 came from.
Here is the OSH ASM for that section:
TMR1HL = 0x03e8
MOVLW 0xE8
MOVWF TMR1L
MOVLW 0x03
MOVWF TMR1H
This shows in the Simulator TMR1 BYTEs, but from what you say this won't work.
If not, then following the RD16 section in the D/S, how do I implement it?
C

You don't, it's an 8 bit processor, you can only do 8 bit reads or writes - if you read the datasheet it explains what RD16 actually means.
 
Hi J and N,
I did read the D/S, but couldn't understand it, so I just pressed buttons, and saw that the Time went into the correct registers.
If it works, then is it ok?
C
 
The only thing you can do is make your life easier by using functions to hide the reading of the two registers.

'Read Tmr1
Function RTMR1() As Word
RTMR1.LB = TMR1L
RTMR1.HB = TMR1H
End Function
'Write Tmr1
Function WTMR1(RegTmr1 As Word) As Bit
TMR1H = RegTmr1.HB
TMR1L = RegTmr1.LB
End Function
 
The code I wrote and what you got from your compiler are identical (I used an assembler directive that produced exactly the same code as what you got.). Except when used as one of the defined TMR1 functions, TMR1H/L are identical to any other pair of 8-bit read/write registers. I am not sure what chip you are using. If you take an enhanced mid-range, e.g., PIC16F1829, you will find TMR1H/L in Bank0. If your are not in Bank0 when you write to them, you may get some very unexpected results. For example IOCBF (Bank7) shares the same offset as TMR1L. Writing what you think is to TMR1L when you are in Bank7 may give you an unexpected result if IOC interrupts are enabled.

In sum, TMR1H/L just happen to be the names of two, ordinary read/write 8-bit registers, unless used with TMR1 functions.. You are much safer using 0x20 and 0x21, named whatever you want, even TIMR1L and TIMR1H, at those respective locations. (I would not advise doing that. It is just an example.) They will work the SAME. Sixteen bit operations will require multiple steps as shown, even though Oshonsoft may not require you to write them that way. (I know nothing about Oshonsoft.)
 
Writes to the high byte are to a buffer and get transferred to the actual register when the low byte is written.
Reads of the low byte transfer the high byte to the buffer. This ensures that the 16 bit value is valid.

So, if reading, read the low byte first.
If writing, write the high byte first.

Mike.
 
Hi N, D, J and M,
Thanks for your replies, some were a bit on the difficult to understand pile, but I get the idea.
Using example #4, this appears to work ok, but as I now realise, that writing the 2x BYTES in sequence, won't affect the timng of what I'm doing, as it will be in time passing section, and will only 'waste' uS.
I don't need to read these BYTEs, where timing could be an issue, as they are COMPARE times..
Cheers, C.
 
I think you're missing the point.

If you have the RD16 bit set then you have to read and write the TMR1L and TMR1H registers in a particular sequence (see posts #11 and #13).

If you use 'TMR1HL = 0x03e8' it doesn't use the correct sequence. That would be ok if you had RD16=0, but not with RD16=1. If the simulator seems to be showing it working then the simulator is wrong, and when you run it on real hardware it won't work the same.
 
I think you're missing the point.

If you have the RD16 bit set then you have to read and write the TMR1L and TMR1H registers in a particular sequence (see posts #11 and #13).

If you use 'TMR1HL = 0x03e8' it doesn't use the correct sequence. That would be ok if you had RD16=0, but not with RD16=1. If the simulator seems to be showing it working then the simulator is wrong, and when you run it on real hardware it won't work the same.
Hi T,
Ok, I may have missed the point.
I could revert back to the RD16 tests, and see if the SIM result is the same as 'live' if anyone wants me to try, but as mentioned, I'm now not using RD16, as it's not important for what I'm doing. Previously, I thought it may be an advantage.
C
 

Latest threads

New Articles From Microcontroller Tips

Back
Top