I'm using the s08SH32 , I have a program I wrote to display temperature from a DS1820 one wire thermo on a 20x2 character display. It works well using a standard asm subroutine for the short delays needed in my "one_wire.c) section :-
void delay_2us(unsigned int n)
{
asm {
LDHX (n)
LOOP1: AIX #-1 ;[2]
// NOP ;[1]
CPHX #0 ;[3]
BNE LOOP1 ;[3]
}
}
However I've tried to modify the program to write to a graphics display ( Nokia 5110 and that's working well ) the delays for the one wire routine go adrift , instead of getting approx 500uS from a "delay_2uS (250) " call I get about 1.6 mS and changing the value of n makes no difference , If I change LDHX (n) to LDHX #2, LDHX #2 etc I get the expected result , so it appears that the value "n" is not being transferred to the routine .
I'm far more at hime with assembly than "C" , but I'm trying to get up to speed with "C" so I'd appreciate any ( non obscene ) suggestions , I'm obviously doing something pretty basically wrong , but I'm confused as to why changing a display routine should screw up what was a working one wire routine !!
解決済! 解決策の投稿を見る。
Hello,
I presume that your display delays are non-critical in that only a minimum delay is required. Obviously the one-wire delays are much more critical.
Do you globally disable interrupts for the whole time critical portion of the one-wire protocol? This is necessary because the occurrence of any interrupt will increase the delay timing by the ISR servicing period, and this may well be happening in your case if interrupts are still operative.
I would use the following macros to disable interrupts, and to restore the previous interrupt state when the time critical part is completed.
#ifndef critical// Macros to globally disable and restore interrupts:#define critical __asm tpa; __asm psha; __asm sei#define critical_restore __asm pula; __asm tap#endif
Another consideration is whether it is possible for COP timout to occur during the delay routine. This is probably not happening in your case with relatively short delays, but there may be the potential for this to occur towards the upper limit of your delay parameter. For the 'SH8, the inclusion of __RESET_WATCHDOG; within the loop will more than double the loop cycles, so should probably be avoided. But you may wish to include prior to the delay loop, and/or following the delay loop.
I assume that you are not calling the delay function within an ISR - this would indeed be potentially problematic.
If there are issues associated with the global disabling of interrupts for the period required, you might consider using a TPM channel to provided the necessary one-wire timing. This may require a combination of output compare and input capture interrupts, and would utilize the channel pin.
Regards,
Mac
Hello,
I presume that your display delays are non-critical in that only a minimum delay is required. Obviously the one-wire delays are much more critical.
Do you globally disable interrupts for the whole time critical portion of the one-wire protocol? This is necessary because the occurrence of any interrupt will increase the delay timing by the ISR servicing period, and this may well be happening in your case if interrupts are still operative.
I would use the following macros to disable interrupts, and to restore the previous interrupt state when the time critical part is completed.
#ifndef critical// Macros to globally disable and restore interrupts:#define critical __asm tpa; __asm psha; __asm sei#define critical_restore __asm pula; __asm tap#endif
Another consideration is whether it is possible for COP timout to occur during the delay routine. This is probably not happening in your case with relatively short delays, but there may be the potential for this to occur towards the upper limit of your delay parameter. For the 'SH8, the inclusion of __RESET_WATCHDOG; within the loop will more than double the loop cycles, so should probably be avoided. But you may wish to include prior to the delay loop, and/or following the delay loop.
I assume that you are not calling the delay function within an ISR - this would indeed be potentially problematic.
If there are issues associated with the global disabling of interrupts for the period required, you might consider using a TPM channel to provided the necessary one-wire timing. This may require a combination of output compare and input capture interrupts, and would utilize the channel pin.
Regards,
Mac