i'm using winstar 16*2 char lcd for displaying volume byte on screen.this lcd is interfaced with MC9S08SE8 MCU.i'm controlling the volume by pt2258 .after running the asm program and increasing the volume by remote .it is displaying the correct sequence of volume bytes but when i continue to press the volume button it abruptly stops displaying the correct sequence and displays garbage characters and then the lcd display is turned off. plz help if somebody has any idea if someone has problem understanding the bug ,i can provide asm code.feel free to ask.actually its quite long and will take space.morover the code seems to work fine. i'm attaching the circuit diagram of lcd interface .i2c communication is used between pt2258 volume controller and microcontroller. |
Solved! Go to Solution.
Hello all,
the problem is finally solved.there was a small problem with the detect repeat pulse subroutine in my code.i was totally ignoring it .there was no problem with the circuit.there was no noise issue.it was a small n simple thing that was being ignored.all ur posts helped me learn alot of things.so im highly grateful to u.
thank u all ,
Hello, and welcome to the forum.
Keep in mind that, for the LCD display controller you are using, the character set includes many blank locations, and the upper page (bit-7 is set) also includes a group of Japanese style characters that might be interpreted as "garbage". I think that you will need to analyse what byte values are actually being sent to the display, using break point or single stepping debug techniques. This is likely to be a little more complicated because you are using 4-bit operating mode for the display.
Does the correct sequence always cease at the same point? If this is the case, I would suspect that your conversion algorithm to drive the display does not work for all volume values. Does the volume level still continue to increment after the displayed value goes haywire?
Regards,
Mac
I didn't even look at your circuit because if the LCD works OK for some numbers, it's very unlikely for this to be a hardware issue.
It would help if you provided some code, because without it one can only guess. And here's one such guess:
My guess is that your printing routine is incorrect (e.g., it converts binary to ASCII decimal incorrectly), and as the number increases it starts displaying 'funny' characters. Also, writing an 'infinite' string may end up clearing your display. I'm not saying this is what happens, I'm only guessing. Another possibility is that you have unbalanced stack operations some place, and they become evident after the routine has executed a few times.
thank u all for replying.i wasnt online to reply back.i forgot to mention one thing.the lcd screen gets blanked but it has a dc signal on its pin no 2 as in the image i have attached.this doesnt happen after a specific no. of volume button press.Also it happens anywhere in the sequence after a variable no. of button pressings.the volume control by pt2258 works correctly and provides correct change in volume as per code.morover the relay gets switched off but continues to have some dc on its pin.i'm providing the asm code .its long hence i was reluctant to upload.i have attached some part of it and i just hope it will b useful.the lcd display module no. is WH1602B.and the garbage its showing are in the following sequence..
k k ; + ; ;
[[ ;;
{ k k ; + ; ;
and then the screen gets blank with the sound of relay getting turned off.but there is still some dc signal on relay pins .
Hello,
Just recieved a delivery of Winstar WH1602D today!
Now that you say there is a relay involved, this vitually guarantees that you problem is noise like I hinted at before.
Presumably your back light glows so you have the backlight connected with the correct polarity.
Quite why you have the LCD power coming from a voltage divider off the 12v rather than connnected to the MPU's power supply is beyond me. I have found that the best protection from noise after you have done your best to eliminate it with snubbers and the like is to control the R/W line of the LCD so it is only write as long as it needs to be (a very short time).
Hello Peg,
When reading from the LCD display memory is not required, it is a very common practice to permanently tie the R/W line low for write only, primarily to minimize the number of interface connections required. My understanding is that only the Enable line is edge-sensitive, and therefore likely to be susceptable to noise impulses.
Since the schematic snippet of the OP does not show the relay driver circuit, we cannot be sure whether a commutating diode has been used across the relay coil. This method does slow the release of the relay, but should minimize any voltage impulse on the release of the relay, provided the diode is fast enough, and provided the relay supply line has sufficient bulk capacitance to absorb the return current pulse.
Perhaps the contact side of the relay could be more problematic if being used to switch a heavy inductive load, but I suspect this is probably not an issue for the application in question.
Regards,
Mac
bigmac wrote:Hello Peg,
When reading from the LCD display memory is not required, it is a very common practice to permanently tie the R/W line low for write only, primarily to minimize the number of interface connections required.
Yes, and if the topic of discussion was the how a HD44780 based LCD character module is typically interfaced (or the bleeding obvious) then this comment may even be relevant.
My understanding is that only the Enable line is edge-sensitive, and therefore likely to be susceptible to noise impulses.
Your understanding and what actually happens in a real world circuit is not necessarily one and the same!
Since the schematic snippet of the OP does not show the relay driver circuit, we cannot be sure whether a commutating diode has been used across the relay coil. This method does slow the release of the relay, but should minimize any voltage impulse on the release of the relay, provided the diode is fast enough, and provided the relay supply line has sufficient bulk capacitance to absorb the return current pulse.
Really!?
Perhaps the contact side of the relay could be more problematic if being used to switch a heavy inductive load, but I suspect this is probably not an issue for the application in question.
Well bugger me!
Regards,
Mac
hi MAC,
i have attacthed a modified ckt diagram with relay n/w in one of my later posts.i have used commutating diodes.the problem i'm facing is not the correct "switching off"of the relay .the problem is my lcd abruptly stop displaying after a variable no. button presses and the relay makes a sound of switching off but still has some dc on its pin .
Hello Amit,
The more information you add the more it reinforces my theory that your problem is with electrical noise corrupting the LCD module. I have seen this many times in the past and have dealt with it just in the last week with a 9S08GT8A controlled Winstar 1602D, very similar to yours.
You have variously described the problem as "goes blank" and "stop displaying". Which is it? Or is it both?
Can you temporarily remove the relay from circuit and remove any other potential noise sources and still try it?
Does it sometimes work correctly?
In my experience, once the module becomes corrupted by noise, this is what happens:
Subsequent writes still mostly display something on the screen but not as it should be.
Sometimes it is the correct character but in the wrong location
Mostly it is random characters written anywhere. (Semicolons seem to be popular here)
Usually this comes to a halt after some time and the display is frozen with whatever was displayed last.
Only occasionally will the display actually go completely blank
If you introduce a method where you can reinitialise the display with out resetting your whole programme then usually (but not always) you can restore correct operation.
The technique with the R/W line I described previously does a very good job or "covering up" this issue.
What I have done is a lot of other things to mitigate the noise actually occurring or affecting the circuit then added this afterwards as a belts and braces approach. However this takes time. So that is why I was suggesting to simply do the R/W change on its own and see if you notice a change as it is very simple/quick to do.
I have not tried to analyse your code.
Hello peg,
i also suspected the noise to be cause behind this bug.but i removed the relay n/w and powered the lcd using mcu pin no . 5.but its not helping.now i 'm sure that the problem is with the code.do u think u can help me with the code.
Hello Amit,
I am not saying it is noise, just that it is very likely.
Unfortunately I am struggling with a couple of project deadlines myself at the moment, so am unable to sepend time trawling through your code.
Perhaps you are running into timing issues with the LCD interface when you are doing the button repeat stuff.
I don't really know what happens when you do this as I am using LCD routines that I developed many years ago and so all of that just works for me. Any problems I had developing it are long forgotten.
I would suggest you cut down the code to a minimum to still have the issue. This may help you locate the problem yourself or if not, may produce an amount of code someone is willing to go through for you. Some more commenting would go along way to achieving this also.
THANX ALOT PEG.
Dear All,
My project is based on simple NEC protocol based remote control sensing. There is a separate remote control decoding section. There are two modes of operation for which I am CD4052B as switching IC. I am using PT2258 IC for volume operation.
As you can easily guess the MCU have to go to the repeat mode of operation when one is
pressing volume UP/DN key . So there are by pressing the key single time it will go into the relevant sub-routine once & for holding the key for long time it will go repeatedly executing the routine until any limit is reached.
As you can see the code is written is assembly level so is a bit lengthy. To make it easy I am separating it into several text files. It will make easier for you to encounter my problem.
One thing that I will like to add , by reading all of your comments I had just disconnected the lcd module & checked if my code section was OK. But the MCU is still resetting.
I don’t kno y???
I am not attaching the remote control decoding section. If any one wants then I will attach it as it is very lengthy. I am also requesting for any suggestion to simplify my remote control decoding section. At presently I am using the internal CLK of MC9S08SE8 is
5MHZ & creating several loops to match the delaying pulse of NEC protocol & it’s a very lengthy process. Can any one suggest any easier process by using the MC9S08SE8 MCU?????
Hello Amit,
Simply breaking up the previous code into several files does not help in making your code more understandable.
Assembly code is never "self-documenting". It generally needs copious comments within the code to understand its operation. This is in the context of what you are attempting to achieve, and the details of achieving this aim, rather than merely describing the operation of an instruction.
As a simple example, I would not expect that any RTS instruction would need a comment unless the sub-routine contained more than one RTS and a specific exit condition at this point was important to the operation of the calling code.
It should not be necessary to re-examine the datasheet for the MCU to derive the initialisation conditions for a peripheral register - an added comment should summarize the setting. An instruction like BSET 0,PTAD is meaningless withou a comment. Yes, we know that bit-0 of PTA output register is being set, but what does bit-0 do? Far more meaningful would be: BSET RLY,PTAD ; Activate relay
where RLY has previously been defined by an equate.
nova0809 wrote:One thing that I will like to add , by reading all of your comments I had just disconnected the lcd module & checked if my code section was OK. But the MCU is still resetting.
I don’t kno y???
I did not see within your code where you were clearing the COP timer, to prevent a COP reset. However, I could not specifically identify your main loop structure where it would usually be placed. Delay routines that may exceed the COP timeout period will also need to clear the COP timer. A macro is often used for this purpose.
nova0809 wrote:I am not attaching the remote control decoding section. If any one wants then I will attach it as it is very lengthy. I am also requesting for any suggestion to simplify my remote control decoding section. At presently I am using the internal CLK of MC9S08SE8 is 5MHZ & creating several loops to match the delaying pulse of NEC protocol & it’s a very lengthy process. Can any one suggest any easier process by using the MC9S08SE8 MCU?????
Using software delay loops for this type of application, as you seem to be suggesting, can work satisfactorily, and need not require lengthy code. The method is best suited to simple applications where the MCU is mainly idle until an IR transmission is received.
The process that I have used makes use of two very similar subroutines to analyse the incoming pulse train from the IR receiver module. Both provide a variable timeout period. The WAITHIGH routine waits until either a high input state, or timeout occurs. The exit condition will determine the next step for the decoding process. The second routine is WAITLOW, which waits until either a low input state, or timeout occurs. Both routines are also designed to ignore very short transient pulses, i.e. less than 100 us.
I have typically used an incremental delay value of 10-20 us, depending on the bus frequency, with the required delay determined by an 8-bit value. This gives a maximum delay value in the vicinity of 2500 - 5000 us. I would then call these routines using macros, so that the delay can be expressed directly in microseconds. The closest (rounded) 8-bit value for the required delay is calculated within the macro during the assembly process.
Actually this method may prove awkward because of a large disparity of timing periods within the NEC protocol, particularly with the start pulse period of 9000 us.
It should also be feasible to make use of a TPM channel operating with input capture mode. The use an interrupt will allow other tasks to occur during the IR receive process. Since the NEC protocol uses pulse-position modulation (PPM) following the start pulse and first gap, the pulse width is not really of interest, only the total period between successive pulses determines the current bit state. You will probably need a prescale division ration of 4, or more. A division ratio of 4 will give a timing resolution of 0.8 microseconds, which is more than adequate.
Regards,
Mac
Dear MAC,
In my program the COP watch dog timer was disabled by writing
0 on COPT [1:0] via command line LDA #$00, STA STOP1. If there is anything wrong with this process then please let me know. I am also disabled the interrupt. My main program continuously scans the input port for IR signal.
Please let me tell you one thing, all the things are working fine on normal operation.
It is even working fine when volume up / Dn key is pressed for a few times. No resetting is occurring or no hanging out.
I am very new in this field & so am not familiar with “MACRO” applications as such.
If you don’t have any problem then can you please provide me with the code that you were talking about in your last post?
I had also updated my program with things you were asking for. Please check!!!
Hello Amit,
nova0809 wrote:In my program the COP watch dog timer was disabled by writing
0 on COPT [1:0] via command line LDA #$00, STA STOP1. If there is anything wrong with this process then please let me know.
I presume that you actually mean the SOPT1 register.
nova0809 wrote:I am very new in this field & so am not familiar with “MACRO” applications as such.
If you don’t have any problem then can you please provide me with the code that you were talking about in your last post?
A macro definition consists of a series of instructions, and/or assembly directives. Each macro is given a label. Whenever a macro label is used within the code, and parameters may also be included, the instructions will be substituted into the code during assembly, in accordance with the macro definition. Parameters are identified by \1 for the first parameter, \2 for the second parameter, etc.
The use of macros can make the main code much easer to follow and understand because the "messy" details can be hidden within the macros. Do not confuse macros with sub-routines.
The code for the WAITLOW and WAITHIGH sub-routines is attached. These routines make extensive use of a macro to provide a various amounts of "padding" for accurate timing control. The sub-routines appear to be complex because I have made allowance to select one of two different ICS trim settings. Note that I have assumed use of the IRQ pin for the input signal. If a port pin was used, some of the padding values would need to be adjusted slightly to allow for the instructions BRSET and BRCLR in lieu of BIH and BIL instructions.
I have also attached some untested code to show how these sub-routines might be used for decoding the NEC IR sequence. The code is actually an ISR for the IRQ interrupt. It is somewhat unorthodox to used this type of code within an ISR because the ISR does not exit until the decoding process is complete. However, this decoding method does require that no other interrupt occur during decoding, as this would affect the timing. So it is convenient to make use of the interrupt.
Note that macros are also used within this code so that the delay parameters may be expressed directly in microseconds.
Regards,
Mac
Dear Mac,
Thanks a lot man 4 uploading your code. I was studying your code, but as a beginner have some queries. Hope you will find a little time to answer them.
1) About the IRQ pin configuration. Actually this project is just an up gradation of my previous project which was being developed with MC68HC705JP7 MCU. It was a simple MCU but was from remote past. I used the IRQ pin to wake my MCU & detect the NEC code, perform some operation & then going back to STOP mode again.
But when operating with MC9s08SE8, I am facing some difficulties in using this pin.
Can you tell me, how to initialize the IRQSC & other necessary regs to use the IRQ pin. One more thing, are you using IRQ pin as active high or active low? Is it possible to
use Stop mode3 with IRQ ??
2) Thanks a lot Bro, for writing something on MACRO operation.
In your previous post as you had mentioned ‘\1’ means 1st parameter for any MACRO.
I was looking into your MACRO definitions . Is it a common practice to write a MACRO definition …..
level: MACRO
…………
…………
…………
ENDM …………. like this??
Can u plz tell me LDA #((\1 – 10) /20) how this instruction works?
3) One more thing Bro,
BEQ *+5
Can you elaborate this operation? I had done only assembly level of MCU programming but haven’t come across some instaction like this.
4) COPRST..... in you program this function had been called after some specific interval?? Can you plz elaborate??
Hello Amit,
1. IRQ pin:
I assume that the IR decoder you are using provides a logic low output whenever the IR carrier is detected. On this basis the interrupt should occur on the first negative edge of the IR sequence, i.e the start pulse, and waking from Stop3 mode is feasible. I would also assume that you would use the trimmed internal reference oscillator of the ICS module for this application. It will provide fast oscillator startup after exiting stop mode.
The bit settings for the IRQSC register should be as follows:
IRQPDD Set this to 1 if you already have a pullup resistor wired at the output of the IR detector.
IRQEDG = 0 for negative edge
IRQPE = 1 will enable the IRQ pin
IRQF This is the read-only flag
IRQACK = 1 This will clear the flag, should it be set
IRQIE = 1 to enable IRQ interrupt
IRQMOD = 0 for edge-sensitive only
All bits may be written simultaneously, i.e. MOV #%01010110,IRQSC
2. Macros
This form of macro defininition pertains to the CW assembler. Other assemblers will likely have differing arrangements.
The instruction LDA #((\1 – 10)/20) within the macro definitions WAIT_HIGH and WAIT_LOW provides the required integer calculation so that the macro calls can be made with the wait delay expressed directly in microseconds. For example, the call WAIT_LOW 1000 would result in the instruction LDA #((1000-10)/20), which will further reduce to LDA #49.
You might notice that, within the code for the NEC decode process, I have allowed for timing errors within the incoming signal. In fact I have allowed for errors of up to 20 percent. from the nominal timing values. This may explain why I have chosen the specific delay values.
3. BRA *+5
For CW assembler, the asterisk symbol is shorthand to mean "the start address of the current instruction" (not the start of the next instruction). For example BRA * would result in a never ending loop. I would generally limit this usage to skipping a single instruction only.
For the instance that you queried, since the BRA instruction occupies two bytes, the length of the instruction(s) being skipped would occupy three bytes. The only reason to use this method is to avoid the need to define a label, and hopefully reduce the "cluttered" appearance of the code. But there are dangers if you miscalculate the number of bytes you require to skip. If in doubt, explicitly define a label.
4. COPRST macro:
This macro clears the COP timer (or watchdog), in the event that this is enabled, to prevent MCU reset by the COP under normal program flow. I have used the macro in a few places within the IR decode process, where otherwise the accumulated delay might extend beyond the COP timeout period. Provided you do not setup for "windowed" operation of the COP timer, the macro may be called as often as you think would be necessary, consistent with the timeout period that is selected.
Regards,
Mac
Continuing on point 3, the asterisk, I would suggest the only really useful/clear usage of this is something like:
BRCLR 1,BYTE,*
The effort used working out the offset is best applied to inventing/entering a label in my opinion.
Hello Peg,
At risk of being pedantic, perhaps it would have been least confusing if you had said
" * represents the value of the programme counter prior to the execution of the instruction"
In fact the particular usage was a "traditional' conditional jump construct. If it had been expressed as a macro (which it actually wasn't), the code would have been:
CW macro format:JNE: MACRO ; Jump to label if not equal BEQ *+5 ; Skip next if equal JMP \1 ENDM
I did not consider that this justified the inclusion of an extra label. Since this thread seems to have evolved into an assembler tutorial, here are some more examples that I often use.
; RAM registers: ORG Z_RAMStart ; Absolute assembly project; Allocate RAM variables here ...STKSIZE EQU RAMEnd+1-* ; Available space for stack
; Fetch serial data at pin PTA0 BRSET 0,PTAD,*+3 ; Set/clear CF ROLA
; Absolute assembly project; Note the two different uses for the asterisk. ORG (*/$200+1)*$200 ; Start new flash page
Regards,
Mac
bigmac wrote:
At risk of being pedantic, perhaps it would have been least confusing if you had said
" * represents the value of the programme counter prior to the execution of the instruction"
Hi Mac and Peg,
Traditionally, before pipelines, it was customary to refer to the asterisk as the program counter. I think it is time to change that, and refer to the asterisk as "the address of this instruction".
As Peg noted early on in this discussion, the Program Counter (the PC in the MCU) points to the next instruction. But the asterisk refers to the current instruction. If you examine the code generated by " bra * ", you will note that the assembler generated a negative offset to get to "*". So the asterisk is never really the program counter anymore.
Also, I have been boned by constructs like " bra *+5 ", since
1) you can't change code inside without recounting bytes,
2) it is often overlooked when you port the code, and
3) I can't count very high.
I prefer to use labels, except when I'm looping to the same instruction (like " brclr bit,byte,* "), which I almost never do. I mainly use the asterisk for this:
PacketSize equ *-PacketStart
That's my two cents (about all it is worth).