--- In , "CW" <cheol1217@y...> wrote: > Hi, I managed to get input from three different switches and > control the LEDS without using interrupt. When I run this program > step by step there is no problem, however if I run the program > automatically I can press a switch only in the first time and > programme just ends somehow. I think I need some kind of time > control using time interrupts, but it seems so hard understand. > Can you plz give me some hints how to do it. I have taken a look at the code you posted, and have noted a few problems. Some of the 'problems' I discuss here are merely matters of style; but there are also some bonafide bugs that I have found as well. - Near label "LOOP" you have a LDAA #%11111000 / STAA DDRA,X sequence. Are you sure that your HC11 variant has a DDRA? The HC11 A and E series parts do NOT provide a DDRA register; the direction of most Port A bits is fixed (excepting PA3 and PA7, which are controlled via the PACTL register). - Near label "START" you initialize the RTI pseudo-vector. For sake of completeness, and to allow your program to run in debug environments other than BUFFALO, it is 'good practice' to initialize the JMP instruction opcode as well. You should add a LDAA #$7E / STAA $00EB sequence to your init code. Also, as a matter of style, you should declare a symbol that contains the location of the RTI pseudo-vector, and use it instead of a literal constant, like this: RTIVEC EQU $00EB ;RTI pseudo-vector ... LDAA #$7E ;JMP instruction opcode STAA RTIVEC ;Place in RTI pseudo-vector location LDD #RTI ;Address of RTI ISR STD RTIVEC+1 ;Copy to RTI pseudo-vector - It appears as if you are attempting to use Port A to both read your switches and control LEDs. This would be OK if you had only buttons attached to PA0-PA2, and LEDs only attached to PA3-PA7. Based on what I see in your code, it appears as if you have both LEDs and switches attached to PA0-PA2, which is not a Good Thing. Also, unless you happen to be using a 'HC11F1 device, PA0-PA2 are input-only (see comment regarding DDRA above). If you ARE using a F1, when you configure DDRA to set PA0-PA7 as outputs, your button (s), if pressed, will attempt to force a OUTPUT line to a fixed state - you could damage the pin drivers for those ports if the output level (as set by PORTA) conflicts with the level that the switches are trying to assert when they are pressed. It would be much better if you moved your pushbutton switches to a different port, say, Port E (any port capable of being configured as an input port will do). - Near label "T1" you initialize the X register to $00FF and use it as a delay counter. After the delay is complete, you jump to LOOP, which contains code that assumes that X is equal to REGBAS. You should make sure you re-initialize X to REGBAS following your delay routine. Better yet, add a LDX #REGBS instruction at the start of the LOOP routine. In this same block of code, you check for the end-of-table condition using 'CPY #$3008'. It would be better (as a matter of good style) to change this to 'CPY #LIST+8' - or, better yet, declare your table like this: LIST FCB $9E,$9D,$9B,$97,$8F,$BF,$DF,$1F ENDLIST EQU * and change the CPY end-of-table check to 'CPY #ENDLIST'. This way, if you decide to change the length of the table, your code will 'automagically' adjust the address that the CPY instruction checks for. You can use this same 'trick' for your tables LIST1 and LIST2 - add symbols such as 'ENDLIST1' and 'ENDLIST2', declared as shown above for 'ENDLIST'. - In various sections of your code, I note that you sometimes perform a 'LDX #$1000' instead of a 'LDX #REGBS'. As a matter of good style, you should always use the symbolic constant REGBS when you want X to point to the register page. - In your 'RTI' ISR, you use the instruction BSET TFLG2,X,%01000000 to clear the RTIF bit. This instruction WILL clear the RTIF, but as a side-effect of the read-modify-write mechanisim used by the BSET instruction, you will wind up clearing any other flag bit that is set in TFLG2. The BSET instruction works internally like this: the location specified by the first operand (TFLG2 in this case) is read, the value read is ORed with the mask operand you specify, and the result of the OR operation is written back to the same address (TFLG2). If you think this through, and recognize that bits in TFLG2 are RESET when a 1-bit is written to them, you will come to see that any bit set in TFLG2 will be cleared after the BSET instruction is executed. Since you are only using the RTI interrupt, the BSET as you have coded it will not have any adverse effects, but if you later decide to utilize the other interrupt sources that TFLG2 annunciates, the BSET in your RTI routine is going to cause intermittent, difficult-to-track problems. The solution to this problem is quite simple. Replace the BSET instruction with 'BCLR TFLG2,X,%10111111'. This at first glance appears to be a bit odd, but again, if you consider how the BCLR instruction works internally, and the nature of the clearing mechanisim used by TFLG2, the BCLR instruction I show above does the job. Here's how it works: Upon entry to the 'RTI' ISR, bit 6 of TFLG2 (RTIF) will be set. When the BCLR instruction is executed, TFLG2 is read (the value will be %x1xxxxxx x=unknown). The value read from TFLG2 is ANDed with the 1's compliment (inverted) value of the mask you specify - in this case, %10111111 inverted is % 01000000. The result of this AND operation will be %01000000, assuming RTIF is set. This value is then written to TFLG2, which has the result of clearing RTIF but leaving all the other bits unchanged. If, by some odd chance RTIF was not set, the result of the AND operation will be %00000000, which will leave TFLG2 unchanged. Using BSET instead of BCLR to clear flag-register bits is a common mistake made by beginning HC11 programmers. - The SEI instruction at the start of your 'RTI' ISR is unnecessary - the HC11 interrupt service logic automatically sets the interrupt- disable bit when an interrupt is serviced. The I-flag in the status register will be restored to its original state when it is popped off the stack by the RTI instruction. - If I understand what you are trying to do in your RTI routine correctly, it appears as if you wish to iterate through a LED control table, loading one element from the table and storing it to the LED control port every time RTICNT counts down to 0. In this routine, you make numerous references to non-symbolic addresses and constants - this is not very good practice. You could make your RTI LED-control routine truly flexible by making a few simple changes. First, declare these variables at the start of your code: LISTST EQU $3500 ;Start of active LED control table LISTEND EQU $3502 ;End of active LED control table +1 LISTPTR EQU $3504 ;Current location in control table RTICNT EQU $3506 ;RTI delay counter; LED pacing In your main code, initialize these variables to the start and end of the LED control table you want to use: LDD #LIST ;Set start-of-table address STD LISTST STD LISTPTR ;Also init table pointer LDD #LISTEND ;Set end-of-table address STD LISTEND When you wish to 'activate' a different LED control table, say, when a different button is pressed, all you have to do is repeat the code above, substituting the appropriate start and end of table addresses for the ones shown above (e.g. LIST1/LIST1END, LIST2/LIST2END, etc.) In your RTI ISR, iterate through the active LED control table like this: RTI LDX #REGBS ;Point to control registers BCLR TFLG2,X,%10111111 ;Clear RTIF DEC RTICNT ;Decrement delay BNE RTIX ;Exit if delay not complete LDY LISTPTR ;Get current list pointer INY ;Point to next element CPY LISTEND ;End of list ? BLO RTI1 ; No, continue LDY LISTST ; Yes, reset to start of list RTI1 STY LISTPTR ;Save updated list pointer LDAA 0,Y ;Get control byte from list STAA PORTA,X ;Write to LED control port LDAA #80 ;Reset delay count STAA RTICNT ; RTIX RTI ;Exit - One last note. It appears as if the code starting at label 'CONT' up through to the start of your RTI ISR is not used for anything - it is never referenced. I assume this is an alternative test routine you wrote - Am I correct? Hope this helps you out. -- Mark |