Welcome to the VirtuQ Forums.
Results 1 to 70 of 70
  1. #1

    Keyboard Interfacing

    Hi,
    What does this much part of the code do?
    XSQR_TABLE:
    DB 0,1,4,9,16,25,36,49,64,81
    Q1.Does this creates a table in external RAM (lookup table) ?
    Q2. MOVC ; says gets the character form code space.
    What is this code space.?
    Q3. Say an instruction is written something like this:
    MOV A,@A+DPTR
    Please explain this.
    Q4. What is 'debouncing' related to keyboard programming.?

    Thanks,
    Anon10457
    Last edited by anon10457; 21-01-2013 at 01:53 AM.

  2. #2
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    What does this much part of the code do?
    XSQR_TABLE:
    DB 0,1,4,9,16,25,36,49,64,81
    Q1.Does this creates a table in external RAM (lookup table) ?
    In the above code, XQR_TABLE is just the label. DB means that put data bytes at memory location. Suppose you put 'ORG 200H' before this table, then all the data values after DB will be put starting at that address. This is the standard way to put a constant lookup table in the memory such as ROM. Usually the above of code is used to initialize some tables in on-chip ROM, however, I think that it should be possible to initialize external memory also with the above code. You may have to adjust starting memory address accordingly.

    MOVC ; says gets the character form code space.
    What is this code space.?
    Code space is the memory area where your program code resides. Usually this space is your on-chip-ROM. MOVC instruction is used to access ROM and move a byte from specified address into destination. You can read values in your lookup table through MOVC insturction.

    Say an instruction is written something like this:
    MOV A,@A+DPTR
    Please explain this.
    In the above code is A is accumulator and DPTR is data pointer register (typically used to hold the address corresponding to the data tables). The instruction means that move the byte at address A+DPTR into register A. Suppose value of A is 01H and DPTR is 300H, then byte stored at address 301H will be moved into register A.

    Q4. What is 'debouncing' related to keyboard programming.?
    When you press the key, due to the mechanical nature of the key, it may bounce a couple of times before the proper contact is established in the underlying switch. Hence, the usual practice is that, you first read the key value and then read it again after a small delay to make sure that you have sampled the right value. This technique is referred as key debouncing. I would encourage you to read more about it from wiki etc.

    -- Basant

  3. #3
    Hi,
    ORG 00H
    JMP MAIN
    DELAY:
    MOV TMOD,#01
    MOV TL0,#0B7H
    MOV TH0,#0FFH
    SETB TR0
    AGAIN: JNB TF0,AGAIN
    CLR TR0
    CLR TF0
    RET
    MAIN:
    MOV P2,#0FFH ;make P2 an input port
    K1: MOV P1,#0 ;ground all rows at once
    MOV A,P2 ;read all col
    ;(ensure keys open)
    ANL A,00001111B ;masked unused bits
    CJNE A,#00001111B,K1 ;till all keys release
    K2: ACALL DELAY ;call 20 msec delay
    MOV A,P2 ;see if any key is pressed
    ANL A,00001111B ;mask unused bits
    CJNE A,#00001111B,OVER;key pressed, find row
    SJMP K2 ;check till key pressed
    OVER: ACALL DELAY ;wait 20 msec debounce time
    MOV A,P2 ;check key closure
    ANL A,00001111B ;mask unused bits
    CJNE A,#00001111B,OVER1;key pressed, find row
    SJMP K2 ;if none, keep polling

    OVER1: MOV P1, #11111110B ;ground row 0
    MOV A,P2 ;read all columns
    ANL A,#00001111B ;mask unused bits
    CJNE A,#00001111B,ROW_0 ;key row 0, find col.
    MOV P1,#11111101B ;ground row 1
    MOV A,P2 ;read all columns
    ANL A,#00001111B ;mask unused bits
    CJNE A,#00001111B,ROW_1 ;key row 1, find col.
    MOV P1,#11111011B ;ground row 2
    MOV A,P2 ;read all columns
    ANL A,#00001111B ;mask unused bits
    CJNE A,#00001111B,ROW_2 ;key row 2, find col.
    MOV P1,#11110111B ;ground row 3
    MOV A,P2 ;read all columns
    ANL A,#00001111B ;mask unused bits
    CJNE A,#00001111B,ROW_3 ;key row 3, find col.
    LJMP K2 ;if none, false input,
    ;repeat

    ROW_0: MOV DPTR,#KCODE0 ;set DPTR=start of row 0
    SJMP FIND ;find col. Key belongs to
    ROW_1: MOV DPTR,#KCODE1 ;set DPTR=start of row
    SJMP FIND ;find col. Key belongs to
    ROW_2: MOV DPTR,#KCODE2 ;set DPTR=start of row 2
    SJMP FIND ;find col. Key belongs to
    ROW_3: MOV DPTR,#KCODE3 ;set DPTR=start of row 3
    FIND: RRC A ;see if any CY bit low
    JNC MATCH ;if zero, get ASCII code
    INC DPTR ;point to next col. addr
    SJMP FIND ;keep searching
    MATCH: CLR A ;set A=0 (match is found)
    MOVC A,@A+DPTR ;get ASCII from table
    MOV P0,A ;display pressed key
    LJMP K1
    ;ASCII LOOK-UP TABLE FOR EACH ROW
    ORG 300H
    KCODE0: DB '0','1','2','3'' ;ROW 0
    KCODE1: DB '4'','5'','6'','7'' ;ROW 1
    KCODE2: DB '8'','9'','A'','B'' ;ROW 2F
    KCODE3: DB 'C'','D','E'',''F' ;ROW 3
    END
    I found this code implementing keyboard interfacing.
    Now how to check which key is pressed.? Cos as I run the program it just runs. How to add that session so that it asks for an option to enter the pressed key,or press key now to detect? Something like that.

    Thanks
    Anon10457

  4. #4
    Hi,

    How to run it(the code above) in virtual hardware mode?

    Thanks,
    Anon10457

  5. #5
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    You need to connect different lines of keypad to various ports. When you select either Simple Keypad or Matrix Keypad from the virtual hardware, you would see that various lines need to be connected to different ports. Once you make the connection and have started the simulation, you can switch on a particular key by selecting them in the virtual hw in the regular way like you press a key in real system.

    -- Basant

  6. #6
    Hi,
    I did all to what you said. Still it keeps on rotating in the K1 loop only.
    I opened the matrix keypad, assigned Port 1 to all the rows with bit 0 and Port 2 to all the columns with bit 1 and pressed the key 5 (as shown in the screenshot attached).

    Why does it never comes out of ht K1 loop?

    Thanks,
    Anon10457
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	key.jpg 
Views:	298 
Size:	128.0 KB 
ID:	480  

  7. #7
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    We can't debug this program for you. You need to go about this in a more systematic way. The following approach would help.
    1. Pick up a good starting point. For keyboard interfacing, program from the reference textbook or similar sources would be good. Perhaps this is what you are doing.
    2. Identify well defined steps of your program.
    3. Make sure that each step is working correctly. Debugger tools will come very handy at this stage.
    4. Localize problems in each step if any and move only after making sure the correctness of individual step.

    Please note that debugging is a strong skill and it will come only after you practice it and follow systematic approach. If we do all the debugging for you, then you would loose the fun.

    -- Basant

  8. #8
    Hi,
    Steps I am taking:
    1. set matrix keypad.(as shown in screenshot)
    2. compile the code
    3. run the code
    4. while the code is running press any key of the keypad.

    But its just looping in K1 label.
    I wish to know
    Q1.as I press any key should the ports value from the keypad be copied to MCU.? Cos it does not for me here. As the value of P2 never changes so it is bound to be in the loop(label).
    Q2. As this is 4*4 matrix , I am just setting the 4 bits of port 2 and port 1 (0-4 bits) . Should not the value get copied to the ports in the code(if ports is used in the code) of its own to the code which is run very next after setting the lines?!?

    Thanks,
    Anon10457
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	matrix.jpg 
Views:	291 
Size:	125.4 KB 
ID:	481  
    Last edited by anon10457; 23-01-2013 at 12:45 AM.

  9. #9
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    When I referred to steps, I was talking about program steps. For examples:
    - Insertion of delay
    - Polling of port values
    - Reading lookup table values etc.
    Make sure that steps like above in your program are correct.

    Regarding values at the port, these will be available to the port, you need to sample them appropriately. It won't get copied automatically.

    -- Basant

  10. #10
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Loop K1 is very simple. You are just sending all 0s to port P1, sampling P2 and comparing P2 with 0FH.
    - Start with all keys open
    - Make sure that P1 is indeed an output port and P2 an input port
    - Step inside the loop a couple of times
    - Press one of the keys and check wherever you are sampling value of P2 that its value has indeed changed

    If you don't see any changes in the port value, then probably something is not right with port connection. In that case, just to make sure that your loop is correct, do a standalone testing.
    - Write separate program with just this loop and proper port configuration
    - Manually change values at port P2 and see whether you are able to sample new values
    - Once this is working fine, then you go back to your keypad program

    -- Basant

  11. #11
    Hi,
    Sampling is working fine now with the keypad. Its picking the values from keypad directly.
    In the sample below
    MOV A,#01010101B
    ANL A,11111111B
    END
    value of A comes out to be 01010101. Which is fine.
    But at the end of this another code:
    MOV A,#01010101B
    ANL A,00001111B
    END
    the value of A comes out to be 00000000.
    As per my calculation it should be 00000101 not 00000000.
    Why so?
    Please help to understand.
    Thanks,
    Anon10457

  12. #12
    Hi,
    In the sample below:
    ORG 300H
    KCODE0: DB '0','1','2','3'' ;ROW 0
    KCODE1: DB '4'','5'','6'','7'' ;ROW 1
    KCODE2: DB '8'','9'','A'','B'' ;ROW 2F
    KCODE3: DB 'C'','D','E'',''F' ;ROW 3
    END
    Q1.where can the see the values being updated to the lookup table in external ROM>?
    Q2. Additionally the code never compiles to the fullest. While single stepping it comes to END at once. why is this happening.?
    Thanks
    Anon10457

  13. #13
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    MOV A,#01010101B
    ANL A,00001111B
    END
    In the above code, you are not specifying second constant correctly. Check the correct syntax of passing an immediate value.

    -- Basant

  14. #14
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Q1.where can the see the values being updated to the lookup table in external ROM>?
    You can see the ROM area values through Virtual MCU -> Code Memory Area.

    Q2. Additionally the code never compiles to the fullest. While single stepping it comes to END at once. why is this happening.?
    Code does get compiled, but you cannot step into data area. Whatever you are writing as DB ..., is actually data. Simulator only executes instruction.

    -- Basant

  15. #15
    Hi,
    This is what I am keeping the memory code area
    ORG 200H
    KCODE0: DB '0''','1''','2''','3'' ;ROW 0
    KCODE1: DB '4'','5'','6'','7'' ;ROW 1
    KCODE2: DB '8'','9'','A'','B'' ;ROW 2
    KCODE3: DB 'C'','D','E'',''F' ;ROW 3
    END
    But in the code memory area the values it is showing is something else(I've attached the screenshot of it).

    Thanks,
    Anon10457
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	code memory area.jpg 
Views:	295 
Size:	129.2 KB 
ID:	485  

  16. #16
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    You will see the correct value in the code area when you have first compiled the code and then started the simulation. Further, syntax of your DB directive seems incorrect. Why have you put double quotes there?

    -- Basant

  17. #17
    Hi,
    Its working fine now.
    Q1.Where in the simulator I can find what is its crystal frequency?
    Q2. What is BIT addressable directive and byte addressable. ?
    Q3. Bit addressable RAM location, Byte addressable RAM location?
    Thanks
    Anon10457
    Last edited by anon10457; 26-01-2013 at 12:43 AM.

  18. #18
    Hi,
    In addition to the above post:
    Q4. Found instruction something like this:
    SW EQU P1.7
    MYDATA EQU P2
    What is EQU?
    What is MYDATA over there cos it does not even ends with ':' else would have been a label. What is it anyways?

    Thanks,
    Anon10457

  19. #19
    VirtuQ™ Moderator
    Join Date
    Jul 2011
    Location
    Bangalore, India
    Posts
    1,044
    Blog Entries
    2
    Anon10457,

    EQU is a compiler directive. Beyond this statement, MYDATA will refer to P2 and it can be used inter-changeably with P2.

    Thanks,

    Anup

  20. #20
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Quote Originally Posted by anon10457 View Post
    Q1.Where in the simulator I can find what is its crystal frequency?
    Q2. What is BIT addressable directive and byte addressable. ?
    Q3. Bit addressable RAM location, Byte addressable RAM location?
    Q1. When you try to edit the project, you can set clk frequency. There is no other place where you can set crystal frequency.

    Q2. There is no bit addressable directive. I guess what you want to ask is what are bit addressable instructions. As the name suggests, if you can directly refer a particular bit or a memory location or a register, it is termed as bit-addressable and instructions which allow to do that are bit-addressable instructions such as SETB. In 8051, data width is 1 bytes, hence by default everything is byte addressable as you can directly access any byte in the memory.

    So far bit addressable locations are concerned, the following RAM locations are bit addressable.
    - Address 20H -2FH
    - All memory locations corresponding to bit addressable registers such as P0, SCON etc.
    Within above memory range, specific bits will have different addresses. For example, the address of second bit at RAM location 21H has bit address 09H. You should refer to Section 5.3 of textbook or 8051 datasheet for complete bit address map.

    -- Basant

  21. #21
    Hi,
    Suppose instruction is :
    mydata BIT P2.3
    yourdata BIT P1.5
    Does this means from now on bit P2.3 will be referred to as mydata?

    Thanks,
    Anon10457

  22. #22
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    I guess so. However, I am not very sure about this directive. You will have to try to this out.

    -- Basant

  23. #23
    Hi,
    I require a small hint to put the code right.
    Say for example:
    Code1:
    JB SWOF, SUBRT
    In the above code I wish to call subroutine but calling as above does not solves my purpose cos SUBRT (which is a subroutine) needs to be called vis ACALL/LCALL else
    just next instructions address won't be kept on the stack.
    A little modified code :
    Code2:
    JB SWOF, L1
    L1: ACALL SUBRT
    solves the purpose upto a little extent but if the bit of SWOF is not 1 still it will call L1 to execute SUBRT.
    How to make a call so that there is no unnecessary calling of SUBRT ; and called only when the particular(SWOF) bit is set.?
    Thanks,
    Anon10457

  24. #24
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    You can use JNB as follows.

    JNB SWOF, L1
    ACALL SUBRT
    L1: ; <Rest of the code>

    -- Basant

  25. #25
    Hi,

    Code below is written to implement the Washing Machine:

    ORG 00H ; if particular bit is zero then LED is ON state on that bit & is working else OFF i.e OFF=1 n ON=0
    JMP MAIN
    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#93H
    MOV TL0,#0FEH
    SETB TR0
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ;default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    22.AGAIN3: JNB PAUSE ,AGAIN3 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON
    CLR RINSE
    DJNZ R2,L3
    25.AGAIN2: JNB PAUSE ,AGAIN2 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON
    CLR SPIN
    RET
    MAIN:
    SWOF EQU P2.7 ; PORT P2
    STRT EQU P2.6
    PAUSE EQU P2.5
    WASH EQU P2.4
    RINSE EQU P2.3
    SPIN EQU P2.2
    DONE EQU P2.1
    CLR SWOF ; TO RUN THE MACHINE SWOF NEEDS TO BE TURNED OFF BY CLEARING IT;LED ON;
    CLR STRT ; Experimenting here by switching on/off the keys as per the requirement
    CLR PAUSE
    JNB SWOF, L7 ; replace by L7 ;if switch off is set then it resets the state machine.
    ACALL SUBRT
    L7:
    JB STRT ,L5; replace by L5 ;if STRT is zero ;0=LED ON 1=LED OFF
    ACALL SUBRT3
    L5: CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    The issue is that PAUSE bit is clear i.e turned ON and it keeps on looping as shown on line no. 22 and 25. But what If I wish to STRT it again in between? In LED there is no such option to press the bit set as STRT in the middle so that it agains runs from PAUSE mode.

    How to make it run as set in PAUSE mode?

    Thanks,
    Anon10457
    Last edited by basant; 26-01-2013 at 08:02 PM. Reason: Fixed typos

  26. #26
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    I am unable to follow your state machine. First explain your high level program flow. Pseudo code will help. I can make any suggestions only after seeing your pseudo code.

    Thanks
    Basant

  27. #27
    Hi,
    6 states are there: STRT(start),PAUSE,WASH,RINSE,SPIN,DONE,SWITCHOFF(S WOF).

    If SWOF is set; i.e P2.7 is ON i.e P2.7=0; 7th Bit of LED is ON(Burning); Turn OFF rest of the states i.e OFF=1i.e LED of rest of bits is 1; not burning.

    1 ORG 00H ; if particular bit is zero then LED is ON state on that bit & is working else OFF i.e OFF=1 n ON=0
    3 JMP MAIN
    4 SUBRT: ;KEEP ALL OFF I.E STORE 1
    5 SETB STRT
    6 SETB PAUSE
    7 SETB WASH
    8 SETB RINSE
    9 SETB SPIN
    10 RET
    11 SUBRT3: ; section to run for 30msec
    12 MOV TMOD,#01H
    13 MOV TH0,#93H
    14 MOV TL0,#0FEH
    15 SETB TR0
    16 L1: ACALL SUBRT2 ; calls for WASH,RINSE,WASH,RINSE,SPINDRY
    17 AGAIN: JNB TF0, L1
    18 CLR TF0
    19 RET
    20 SUBRT2: ;default flow WASH RINSE WASH RINSE SPINDRY
    21 MOV R2 ,#02 ; WASH RINSE WASH RINSE is required twice so R2=2
    22 L3: CLR WASH
    23 AGAIN3: JNB PAUSE ,AGAIN3 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON
    24 CLR RINSE
    25 DJNZ R2,L3
    26 AGAIN2: JNB PAUSE ,AGAIN2 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON; P2.5 is 0 i.e 5th bit of LED is ON(burning)
    27 CLR SPIN ; SPIN after twice execution of WASH & RINSE
    28 RET
    29 MAIN:
    30 SWOF EQU P2.7 ; PORT P2
    31 STRT EQU P2.6
    32 PAUSE EQU P2.5
    33 WASH EQU P2.4
    34 RINSE EQU P2.3
    35 SPIN EQU P2.2
    36 DONE EQU P2.1
    37 CLR SWOF ; TO RUN THE MACHINE SWOF NEEDS TO BE TURNED OFF BY CLEARING IT; P2.7 is reset i.e P2.7 =0 burns LED's 7th bit ;
    38 CLR STRT ; Desired Operation instruction is kept here after line 37
    39 CLR PAUSE ; Desired Operation instruction is kept here after line 37
    40 JNB SWOF, L7 ;if switch off is set then it resets the state machine.
    41 ACALL SUBRT
    41.5 L7:
    42 JB STRT ,L5 ;if STRT is zero ;0=LED ON 1=LED OFF
    43 ACALL SUBRT3
    44 L5: CLR DONE ; set DONE bit after SPINDRY ; finish the process
    45 END
    whatever operation is to be done is written at line no. 38 ,39..{after line 37}.(Here Starting the machine and for checking the PAUSE function PAUSE is aslo cleared i.e 0 i.e ON i.e P2.6 & P2.5 bit is burning of LED).
    SUBRT3 runs machine for 30msec if STRT is reset(ON i.e P2.6 bit of LED is burning)

    Rest of the details are explained in comments of each line.

    Thanks,
    Anon10457

  28. #28
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    What you have shown is the commented code, your program flow is still not clear. What I had asked was pseudo code, something like as follows.

    1) Initialize the machine (all LEDs are off except SWOF)
    2) Pess START
    3) Go through the regular washing flow
    4) Come back to reset state

    Apart from the above, you also need to make provision for PAUSE interrupt. What you have shown is the connection to LEDs which just shows the status, but how would you take inputs like when to PAUSE, when to START etc.

    Next time when you show a code which is more that 20 lines, clearly write the program flow also. Unless we know what exactly you are trying to do, we can't make any suggestions.

    Thanks
    Basant

  29. #29
    Hi,

    1. Initialize the machine(Turning all LED's key off)
    2. Machine is turned ON by putting ON(CLR) the Switch Off button.
    3.Press Start.
    4.**Press the PAUSE state( just to check if its functioning or not)
    5.If switch off is set(ON) then turn off other states(calling SUBRT).
    6. If start is set (ON) then Initialize timer to run machine (general flow for 30msec):Subroutine2,subroutine3
    7. Once run for 30msec set DONE state ON.

    **
    Apart from the above, you also need to make provision for PAUSE interrupt. What you have shown is the connection to LEDs which just shows the status, but how would you take inputs like when to PAUSE, when to START etc.
    this is what my next doubt was(thats why shown in **).
    I mean in LED there is no such button pressing option (as was in keypad) so that if you press a particular key its starts responding accordingly.
    Moreover how to ask from the user(the one who uses the machine) to what function he needs to perform?

    Thanks,
    Anon10457

  30. #30
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    You will have to use simple keypad to take inputs. However, you can't keep on polling your inputs all the time. So, you will also require an external interrupt to tell that some relevant key has been switched on. Then in the ISR, you can check which key has been pressed to figure out what action to take.

    -- Basant

  31. #31
    Hi,
    The keys stored in code memory is in the form of 'char' (as per the code in post no. 3 ).
    Suppose 5 is pressed now how to store char value in any register or something. ?

    I've to take the inputs to set the state of machine consequently. But inputs come in the form of char.

    Thanks
    Anon10457

  32. #32
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Char size is one bye which can be stored anywhere in memory. I don't understand the confusion in storing this. Please explain more on what you are trying to do.

    - Basant

  33. #33
    Hi,
    As I pressed the key 9 which gets stored in accumulator (as per the code in post 3) .
    9 gets stored in A in the form of char not numeral. The numeral value in A is 57(Decimal), 39(Hex). (I've uploaded the screenshot)

    so, how to store the charracter to any register?
    Thanks,
    Anon10457
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	err.jpg 
Views:	286 
Size:	125.1 KB 
ID:	489  

  34. #34
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    The hardware (MCU in this case) understands only bits. Interpretation of this value is upto the user. Also to map a decimal value to a char, you need to refer to the ASCII table.

    In your application, you just need to find out whether START or some other key has been pressed or not. If a particular port say P2.3 is mapped to START key, just read this port and see whether it is 1 or 0. Why do you have to map this to a char or decimal?

    -- Basant

  35. #35
    Hi,
    Got it.
    I was thinking to map the char with the states(which now I feel was an dim step).
    Also in keypad we can at a time play with 4 bits of any port( as it is 4 * 4 matrix).
    But here we have six states .
    How to compensate this ?

    Thanks,
    Anon10457

  36. #36
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    I would suggest you to use simple keypad. That should take care of your requirements.

    -- Basant

  37. #37
    Hi,
    Here is the code for the machine:
    ORG 00H ; if particular bit is zero then LED is ON state on that bit & is working else OFF i.e OFF=1 n ON=0
    JMP MAIN
    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#93H
    MOV TL0,#0FEH
    SETB TR0
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ;default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    AGAIN3: JNB PAUSE ,AGAIN3 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON
    CLR RINSE
    DJNZ R2,L3
    AGAIN2: JNB PAUSE ,AGAIN2 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON
    CLR SPIN
    RET
    MAIN:
    SWOF EQU P2.7 ; PORT P2
    STRT EQU P2.6
    PAUSE EQU P2.5
    WASH EQU P2.4
    RINSE EQU P2.3
    SPIN EQU P2.2
    DONE EQU P2.1

    AGAIN4: JNB PAUSE ,AGAIN4 ; keep on jumping to AGAIN if PAUSE bit is 0 i.e LED IS ON
    JB SWOF, L7 ; replace by L7 ;if switch off is set then it resets the state machine.
    ACALL SUBRT
    L7:
    JB STRT ,L5; replace by L5 ;if STRT is zero ;0=LED ON 1=LED OFF
    ACALL SUBRT3
    L5: CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    Input is taken via simple keypad. Screenshot of it is attached.
    Is it fine?
    Please give suggestions to improve.


    Thanks,
    Anon10457
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	machine.jpg 
Views:	274 
Size:	128.6 KB 
ID:	490  

  38. #38
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    I think that your program will not work in the following scenarios.
    - Asynchronous PAUSE i.e. PAUSE can be pressed anytime during machine is running
    - Asynchronous RESUME i.e. machine can resume its operation anytime after PAUSE has been pressed and then RESUME is pressed

    I would suggest you that you should list down various test scenarios as above and make sure by doing simulation that all your tests pass.

    -- Basant

  39. #39
    Hi,
    Modified Code:
    ORG 00H ; if particular bit is zero then LED is ON state on that bit & is working else OFF i.e OFF=1 n ON=0
    JMP MAIN
    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#93H
    MOV TL0,#0FEH
    ;MOV TH1,#93H
    ;MOV TL1,#0FEH
    SETB TR0
    ;SETB TR1
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    LOOP1: JNB PAUSE,LOOP1
    L3: CLR WASH
    LOOP2: JNB PAUSE,LOOP2
    CLR RINSE
    LOOP4: JNB PAUSE,LOOP4
    DJNZ R2,L3
    LOOP3: JNB PAUSE,LOOP3
    CLR SPIN
    LOOP5: JNB PAUSE,LOOP5
    RET
    MAIN:
    SWOF EQU P2.7 ; PORT P2
    STRT EQU P2.6
    PAUSE EQU P2.5
    WASH EQU P2.4
    RINSE EQU P2.3
    SPIN EQU P2.2
    DONE EQU P2.1
    SETB IE.7;enabling EA
    SETB IE.0; enabling INT0
    SETB IP.0
    JB SWOF, L7 ; replace by L7 ;if switch off is set then it resets the state machine.
    ACALL SUBRT
    L7:
    JB STRT ,L5; replace by L5 ;if STRT is zero ;0=LED ON 1=LED OFF
    ACALL SUBRT3
    L5: CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    I've used 5 loops in SUBRT2 to solve the purpose of asynchronous PAUSE.
    Is it a little better now?
    From post #30
    So, you will also require an external interrupt to tell that some relevant key has been switched on. Then in the ISR, you can check which key has been pressed to figure out what action to take.
    In what reference you were mentioning about Interrupts?

    Thanks,
    Anon10457

  40. #40
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Quote Originally Posted by anon10457 View Post
    Hi,
    Modified Code:


    I've used 5 loops in SUBRT2 to solve the purpose of asynchronous PAUSE.
    Is it a little better now?
    From post #30

    In what reference you were mentioning about Interrupts?

    Thanks,
    Anon10457
    Consider the following scenarios.
    - Machine is running, then someone presses PAUSE. In this case, your MCU is already doing something, hence you can't poll for PAUSE. The only possibility is that you need to map it to an interrupt.
    - Machine is running, but power goes off. How would you handle this?

    Regarding your modified program, you would have to verify the correctness yourself. Why don't you list down various run scenarios and verify whether your program works in those cases.

    -- Basant

  41. #41
    Hi,
    ORG 00H ; if particular bit is zero then LED is ON state on that bit & is working else OFF i.e OFF=1 n ON=0
    JMP MAIN
    ORG 0003H ; START OF INT0 EXTERNAL INTERRUPT 0
    LJMP ISRT
    ISRT:
    LOOP1: JNB PAUSE,LOOP1
    RETI
    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#93H
    MOV TL0,#0FEH
    SETB TR0
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    CLR RINSE
    DJNZ R2,L3
    CLR SPIN
    RET
    MAIN:
    SWOF EQU P2.7 ; PORT P2
    STRT EQU P2.6
    PAUSE EQU P2.5
    WASH EQU P2.4
    RINSE EQU P2.3
    SPIN EQU P2.2
    DONE EQU P2.1
    SETB IE.7;enabling EA
    SETB IE.0; enabling INT0
    SETB IP.0
    JNB PAUSE,ISRT
    JB SWOF, L7 ; replace by L7 ;if switch off is set then it resets the state machine.
    ACALL SUBRT
    L7:
    JB STRT ,L5; replace by L5 ;if STRT is zero ;0=LED ON 1=LED OFF
    ACALL SUBRT3
    L5: CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    Used interrupt for PAUSE but does not solves the purpose much. Only if it is PAUSED in the beginning it performs else if in between it does not.
    What I wish to do is as a moment PAUSE is pressed it should jump to the Interrupt linked to it( No matter at what location of the code I am)
    Please give a little more hint to map PAUSE to interrupt.
    Interrupt should get the call (in the above case) once TF0 is set. But this does not happens. As set to PAUSE mode in the beginning it jumps to Interrupt but if kept in the pause for more than 30msec and then START it just finishes the code.
    Moreover, scenario such as if the user feels like just SPINDRY (say he handwashed the clothes and now just want to DRY via machine) needs to be taken into account or what?

    Thanks,
    Anon10457

  42. #42
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457

    Quote Originally Posted by anon10457 View Post
    Hi,


    Used interrupt for PAUSE but does not solves the purpose much. Only if it is PAUSED in the beginning it performs else if in between it does not.
    What I wish to do is as a moment PAUSE is pressed it should jump to the Interrupt linked to it( No matter at what location of the code I am)
    Please give a little more hint to map PAUSE to interrupt.
    Interrupt should get the call (in the above case) once TF0 is set. But this does not happens. As set to PAUSE mode in the beginning it jumps to Interrupt but if kept in the pause for more than 30msec and then START it just finishes the code.
    Moreover, scenario such as if the user feels like just SPINDRY (say he handwashed the clothes and now just want to DRY via machine) needs to be taken into account or what?

    Thanks,
    Anon10457
    What I had suggested was as follows.
    - Map all input buttons Start, Pause etc. to keypad
    - Use external interrupt to indicate that some button has been pressed
    - Poll in the ISR to figure out which button has been pressed

    I would suggest you that you should first try this out in a small program, understand the external interrupt. Then integrate this into your main program.

    -- Basant

  43. #43
    Hi,
    A sample program was written somewhere:
    Assuming that pin 3.3 (INT1) is connected to a pulse generator, write a program in which the falling edge of the pulse will send a high to PI.3, which is connected to an LED (or buzzer). In other words, the LED is turned on and off at the same rate as the pulses are applied to the INT1 pin. This is an edge-triggered version of Example 11-5.

    SOLUTION:
    ORG 0000H
    LJMP MAIN
    ;--ISR for hardware interrupt INT1 to turn on LED
    ORG 0013H ;INT1 ISR
    SETB P1.3 ;turn on LED
    MOV R3,#255
    BACK: DJNZ R3,BACK ;keep the buzzer on for a while
    CLR P1.3 ;turn off the buzzer
    RETI ;return from ISR
    ;------MAIN program for initialization
    ORG 30H
    MAIN: SETB TCON.2 ;make INT1 edge-triggered int.
    MOV IE,#10000100B ;enable External INT 1
    HERE: SJMP HERE ;stay here until get interrupted
    END
    First line of the question says Assume INTI is connected to pulse generator.

    How to make this assumption true?
    Is there any setting to be done to make it true?
    Cos when I compiled this program the timer just runs and nothing happens.


    Thanks,
    Anon10457
    Last edited by anon10457; 29-01-2013 at 11:29 PM.

  44. #44
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    It should be possible in the simulator to stop the program at a breakpoint and force values at pins or registers.
    - Check which ports are mapped for external interrupt
    - Set a breakpoint before the end of program
    - Start the simulator
    - When simulator reaches the breakpoint, force new value on the interrupt pin

    -- Basant

  45. #45
    Hi,
    Port 1 is connected the simple keypad(I've attached the screenshot. .
    So I guess Port1 is mapped to external interrupt. Right?

    Program never comes out of the HERE loop in the above code in port #43
    so there seems to be no point in setting the breakpoint at HERE loop's line.
    (Though I tried, as before it never comes out of it).

    Also while the program is running I am pressing the new/different keys on the keypad, still nothing seems to be happening.


    Please guide.
    Thanks,
    Anon10457

  46. #46
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    There is no screenshot attached.

    If I recall correctly, external interrupt pins are mapped to P3.2 and P3.3. Please check the references again for this. So you may have to use P3 pins instead of P1 for proper external interrupts. Also make sure that IE register is configured correctly.

    -- Basant

  47. #47
    Hi,
    Modified code:
    ORG 0000H
    LJMP MAIN
    ;--ISR for hardware interrupt INT1 to turn on LED
    ORG 0013H ;INT1 ISR
    JB STRT ,L5; replace by L5 ;if STRT is zero ;0=LED ON 1=LED OFF
    ACALL SUBRT3
    L5:
    JB SWOF , L8
    ACALL SUBRT
    L8:
    RETI ;return from ISR
    ;------MAIN program for initialization
    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#93H
    MOV TL0,#0FEH
    SETB TR0
    L1: ACALL SUBRT2
    ;LOOP2: JNB PAUSE,LOOP2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    CLR RINSE
    DJNZ R2,L3
    CLR SPIN
    RET
    ORG 30H
    MAIN:
    SWOF EQU P3.0 ; PORT P3
    STRT EQU P3.3
    PAUSE EQU P3.2
    WASH EQU P3.5
    RINSE EQU P3.4
    SPIN EQU P3.1
    DONE EQU P3.6
    SETB TCON.2 ;make INT1 edge-triggered int.----------------------------->46
    MOV IE,#10000100B ;enable External INT 1------------------------------->47
    HERE: SJMP HERE ;stay here until get interrupted------------------------->48
    CLR DONE ; set DONE bit after SPINDRY ; finish the process-------------->49
    END
    I am receiving this error while compilation:
    Compiling file: 16.2
    Initializing pre-processor ...
    Compilation error at 46 in 16.2: Unable to overwrite already reserved program memory at address 0x30 -- compilation failed
    Compilation error at 46 in 16.2: Unable to overwrite already reserved program memory at address 0x31 -- compilation failed
    Compilation error at 46 in 16.2: Unable to overwrite already reserved program memory at address 0x32 -- compilation failed
    Compilation error at 47 in 16.2: Unable to overwrite already reserved program memory at address 0x32 -- compilation failed
    Compilation error at 47 in 16.2: Unable to overwrite already reserved program memory at address 0x33 -- compilation failed
    Compilation error at 47 in 16.2: Unable to overwrite already reserved program memory at address 0x34 -- compilation failed
    Compilation error at 47 in 16.2: Unable to overwrite already reserved program memory at address 0x35 -- compilation failed
    Compilation error at 48 in 16.2: Unable to overwrite already reserved program memory at address 0x35 -- compilation failed
    Compilation error at 48 in 16.2: Unable to overwrite already reserved program memory at address 0x36 -- compilation failed
    Compilation error at 48 in 16.2: Unable to overwrite already reserved program memory at address 0x37 -- compilation failed
    Compilation error at 49 in 16.2: Unable to overwrite already reserved program memory at address 0x37 -- compilation failed
    Compilation error at 49 in 16.2: Unable to overwrite already reserved program memory at address 0x38 -- compilation failed
    Compilation error at 49 in 16.2: Unable to overwrite already reserved program memory at address 0x39 -- compilation failed
    Pre-processing FAILED !
    Creating code listing file ... -> "16.lst"
    13 errors, 0 warnings
    Please help to understand the fault.
    Neither of the key is pressed while compilation.
    Thanks,
    Anon10457
    Last edited by anon10457; 30-01-2013 at 09:58 PM.

  48. #48
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Please follow the errors.

    Your main program is starting at address 30H. It seems that rest of the program has already reached this address. That is why you are getting program memory related errors. To fix this issue, try putting your main code at some other location.

    -- Basant

  49. #49
    Hi,
    If one INT0 is running can't we call INT1 from INT0?
    Cos in this code I am unable to do the same:
    ORG 0000H
    LJMP MAIN
    ;--ISR for hardware interrupt INT0 to turn on LED
    ORG 0003H ; GETS CALLED ONCE PAUSE IS PRESSED P3.2 I.E INT0
    LOOP: SJMP LOOP
    RETI
    ;--ISR for hardware interrupt INT1 to turn on LED
    ORG 0013H ;INT1 ISR
    JB STRT ,L5; JUMP ON BIT 1 TO L5
    ACALL SUBRT3
    L5:
    JB SWOF , L8
    ACALL SUBRT
    L8:
    RETI ;return from ISR
    ;------MAIN program for initialization

    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#93H
    MOV TL0,#0FEH
    SETB TR0
    L1: ACALL SUBRT2
    ;LOOP2: JNB PAUSE,LOOP2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    CLR RINSE
    DJNZ R2,L3
    CLR SPIN
    RET
    ;ORG 30H
    MAIN:
    SWOF EQU P3.0 ; PORT P3
    STRT EQU P3.3 ; INT 1
    PAUSE EQU P3.2 ; INT0
    WASH EQU P3.5
    RINSE EQU P3.4
    SPIN EQU P3.1
    DONE EQU P3.6
    SETB TCON.2 ;make INT1 edge-triggered int.
    MOV IE,#10000101B ;enable External INT 1 AND INT0
    HERE: SJMP HERE ;stay here until get interrupted
    CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    Thanks,
    Anon10457

  50. #50
    Hi,
    As START is pressed INT1 executes. Fine. But in between as PAUSE is pressed i.e INT0 should not it keep the address of the current instruction to the Stack and jump to INT0 so that as it finishes the execution of INT0 it can resume back easily.?

    This is what I am trying to do but unable to achieve cos calling another interrupt i.e INT0 from INT1 is not happening.
    Please guide.

    Thanks,
    Anon10457
    Last edited by basant; 31-01-2013 at 07:32 AM.

  51. #51
    Hi,
    As posted in post #24
    You can use JNB as follows.

    JNB SWOF, L1
    ACALL SUBRT
    L1: ; <Rest of the code>
    Say SWOF is 0; L1 is executed i.e SUBRT does not. Fine.
    But say SWOF is 1; does not goes to L1(as per the demand); Fine; goes to just next line i.e ACALL SUBRT but Rule says as subroutine is called the address of the just next instruction gets saved onto the stack ; In this case loop L1 address gets saved onto the stack and later gets executed once subroutine is over (which I don't want to get executed as SWOF is 1).
    Purpose is not solved.

    I've tried the above concept in the code below which is to be run for 5msec and keeps togglling p0.1:
    ORG 00H
    LJMP MAIN
    SUBRT2:
    CPL P0.1
    RET
    MAIN:MOV TMOD,#01H
    MOV TH0,#0EDH
    MOV TL0,#0FFH
    SETB TR0
    AGAIN: JB TF0, L1
    ACALL SUBRT2
    L1:
    CLR TF0
    END
    It does not even runs for mor than 17micro sec.
    Please give some more hint.

    Thanks,
    Anon10457

  52. #52
    Hi,
    In addition to the post#49, after setting the priority to the PAUSE button solves the purpose a bit i.e can jump to another interrupt while one is executing .
    Snippet of code:
    ORG 0000H
    LJMP MAIN

    ;--ISR for hardware interrupt INT0 to turn on LED
    ORG 0003H ;INT0 ISR
    JB STRT ,L5; JUMP ON BIT 1 TO L5
    ACALL SUBRT3
    L5:
    JB SWOF , L8
    ACALL SUBRT
    L8:
    RETI ;return from ISR
    ;--ISR for hardware interrupt INT1 to turn on LED
    ORG 0013H ; GETS CALLED ONCE PAUSE IS PRESSED P3.3 I.E INT1
    ;LOOP: JB PAUSE,LOOP
    LOOP: JNB STRT,LOOP
    RETI
    ;------MAIN program for initialization
    SUBRT: ;KEEP ALL OFF I.E STORE 1
    SETB STRT
    SETB PAUSE
    SETB WASH
    SETB RINSE
    SETB SPIN
    RET
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#0EDH
    MOV TL0,#0FFH
    SETB TR0
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    CLR RINSE
    DJNZ R2,L3
    CLR SPIN
    RET
    MAIN:
    SWOF EQU P3.0 ; PORT P3
    PAUSE EQU P3.3 ; INT 1
    STRT EQU P3.2 ; INT0
    WASH EQU P3.5
    RINSE EQU P3.4
    SPIN EQU P3.1
    DONE EQU P3.6
    SETB TCON.3 ;make INT1 edge-triggered int.
    SETB TCON.1
    SETB IP.2 ;set PAUSE higher priority.
    MOV IE,#10000111B ;enable External INT 1 AND INT0 and timer 0
    HERE: SJMP HERE ;stay here until get interrupted
    CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    Is this code a little better than the previous ones?
    I understand still a lot modification is to be done in this.

    From post#40
    Consider the following scenarios:
    - Machine is running, but power goes off. How would you handle this?
    How to check power off state. I guess this is the highest of all the priorities. Right?

    Please guide.
    Thanks,
    Anon10457

  53. #53
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    What do you mean by calling INT1 from INT0? Do you want to call ISR of INT1 from ISR of INT0? If so, that would be a bad idea. You should not be mixing ISR's of different interrupts.

    Quote Originally Posted by anon10457 View Post
    Hi,
    If one INT0 is running can't we call INT1 from INT0?
    Cos in this code I am unable to do the same:


    Thanks,
    Anon10457
    -- Basant

  54. #54
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    I am not able to follow what you are trying to do here. Please elaborate your program flow.

    -- Basant

    Quote Originally Posted by anon10457 View Post
    Hi,
    As START is pressed INT1 executes. Fine. But in between as PAUSE is pressed i.e INT0 should not it keep the address of the current instruction to the Stack and jump to INT0 so that as it finishes the execution of INT0 it can resume back easily.?

    This is what I am trying to do but unable to achieve cos calling another interrupt i.e INT0 from INT1 is not happening.
    Please guide.

    Thanks,
    Anon10457

  55. #55
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    If you just need to keep toggling a port for some time, then you will have to do that in a loop which must be stopped once the timer gets over. You need something like as follows.

    In general, you should clearly describe your requirement while asking suggestion on code. We can make suggestion only based on information you provide.

    -- Basant

    Quote Originally Posted by anon10457 View Post
    Hi,
    As posted in post #24

    Say SWOF is 0; L1 is executed i.e SUBRT does not. Fine.
    But say SWOF is 1; does not goes to L1(as per the demand); Fine; goes to just next line i.e ACALL SUBRT but Rule says as subroutine is called the address of the just next instruction gets saved onto the stack ; In this case loop L1 address gets saved onto the stack and later gets executed once subroutine is over (which I don't want to get executed as SWOF is 1).
    Purpose is not solved.

    I've tried the above concept in the code below which is to be run for 5msec and keeps togglling p0.1:

    It does not even runs for mor than 17micro sec.
    Please give some more hint.

    Thanks,
    Anon10457

  56. #56
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    From post#40
    Consider the following scenarios:
    - Machine is running, but power goes off. How would you handle this?
    How to check power off state. I guess this is the highest of all the priorities. Right?
    I think that you can use SWOF for this purpose.

    -- Basant

  57. #57
    Hi,
    Ans 53: Yes, I meant calling of ISR INT1 from INT0.
    Ans 54: Actually what I was trying to do is that I had assigned PAUSE button to ISR INT0 and STRT to ISR INT1. So when machine is started and is running and say I press PAUSE button in between it should pause. And the very next moment if I press STRT again it should resume from the same location from where it had left to pause. To achieve this I assigned two different ISR to PAUSE and STRT buttons and kept priority of PAUSS higher.Its working upto certain extent now.

    Ans 55: From post #24
    You can use JNB as follows.
    JNB SWOF, L1
    ACALL SUBRT
    L1: ; <Rest of the code>
    which was actually written in response to post #23 what I wish to know is that
    say Say SWOF is 0; L1 is executed but SUBRT does not. I got till here.
    But say SWOF is 1 , so it should not execute L1 ; jumps to next line to call SUBRT but while returning from subroutine is calls L1 which in this case it should not as SWOF is 1.
    How to edit the code that it executes either L1 or SUBRT at a time depending on value of SWOF.
    Actual snippet of code where I want to implement the above logic is this:

    ---------------
    ---------------
    ORG 0003H ;INT0 ISR
    JB STRT ,L5; JUMP ON BIT 1 TO L5
    ACALL SUBRT3
    L5:
    ----------------
    ----------------
    RETI
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#0EDH
    MOV TL0,#0FFH
    SETB TR0
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    CLR RINSE
    DJNZ R2,L3
    CLR SPIN
    RET
    In this section of the code the timer runs forever even though the value of TF0 is set to 1 once from above logic.
    Please guide in this.

    Thanks,
    Anon10457
    Last edited by anon10457; 31-01-2013 at 09:11 PM.

  58. #58
    Hi,
    Modified code of washing machine:
    ORG 0000H
    LJMP MAIN

    ;--ISR for hardware interrupt INT0 to turn on LED
    ORG 0003H ;INT0 ISR
    JB STRT ,L5; JUMP ON BIT 1 TO L5
    ACALL SUBRT3
    L5:
    JB SWOF,L8
    SETB IE.7
    L8:
    RETI ;return from ISR
    ;--ISR for hardware interrupt INT1 to turn on LED
    ORG 0013H ; GETS CALLED ONCE PAUSE IS PRESSED P3.3 I.E INT1
    LOOP: JNB PAUSE,LOOP
    RETI
    ;------MAIN program for initialization

    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#0EDH
    MOV TL0,#0FFH
    SETB TR0
    L1: ACALL SUBRT2
    AGAIN: JNB TF0, L1
    CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    MOV R2 ,#02
    L3: CLR WASH
    CLR RINSE
    DJNZ R2,L3
    CLR SPIN
    RET
    MAIN:
    SWOF EQU P3.0 ; PORT P3
    PAUSE EQU P3.3 ; INT 1
    STRT EQU P3.2 ; INT0
    WASH EQU P3.5
    RINSE EQU P3.4
    SPIN EQU P3.1
    DONE EQU P3.6
    SETB TCON.3 ;make INT1 edge-triggered int.
    SETB TCON.1
    SETB IP.2 ;set PAUSE higher priority.
    MOV IE,#10000111B ;enable External INT 1 AND INT0 and timer 0
    HERE: SJMP HERE ;stay here until get interrupted
    CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    As there are just two External Interrupt both of which is utilized for PAUSE and STRT
    nothing is left for SWOF. So SWOF does not works upto its level in the middle of the code i.e when the program is running.

    Am I moving on the right track to implement the machine?
    Please give a hint to improve it.
    Thanks,
    Anon10457

  59. #59
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Ans 55: From post #24

    which was actually written in response to post #23 what I wish to know is that
    say Say SWOF is 0; L1 is executed but SUBRT does not. I got till here.
    But say SWOF is 1 , so it should not execute L1 ; jumps to next line to call SUBRT but while returning from subroutine is calls L1 which in this case it should not as SWOF is 1.
    How to edit the code that it executes either L1 or SUBRT at a time depending on value of SWOF.
    Actual snippet of code where I want to implement the above logic is this:
    The above requirement can be achieved with something like as follows.
    JNB SWOF, L1
    ACALL SUBRT
    JMP L2
    L1; <code of L1>
    JMP L3
    L2; <code of L2>
    L3; <rest of the code>
    -- Basant

  60. #60
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Quote Originally Posted by anon10457 View Post
    Hi,
    Modified code of washing machine:


    As there are just two External Interrupt both of which is utilized for PAUSE and STRT
    nothing is left for SWOF. So SWOF does not works upto its level in the middle of the code i.e when the program is running.

    Am I moving on the right track to implement the machine?
    Please give a hint to improve it.
    Thanks,
    Anon10457
    To solve multiple interrupt issue, you can take the following approach which is not exactly fully interrupt based, but allows to have more flexibility.
    - Use only one interrupt to indicate that some key has been pressed
    - Map your input keys onto some other port and poll inside ISR to see which key been pressed
    - Jump to respective subroutines to handle individual keys

    -- Basant

  61. #61
    Hi,
    - Use only one interrupt to indicate that some key has been pressed
    - Map your input keys onto some other port and poll inside ISR to see which key been pressed
    Suppose I am in ISR to detect which key has been pressed.
    Instruction comes like this in ISR:
    Junk Code:
    JB SWOF,L1
    ACALL SUBRT1
    L1:
    JB STRT, L2
    ACALL SUBRT2
    L2:
    ----------
    ----------
    In SUBRT2
    ------
    timer initialized
    Wash rinse Wash Rinse takes place
    ------
    Say SWOF was 0 then it jumps to L1; then say STRT is pressed i.e STRT=0 jumps to SUBRT2 and then timer starts and default function of the machine executes.
    My issue comes now, Say now somebody presses SWOF key, should not it resets every key then.? Which by the above method fails cos program is now in SUBRT2. So I require an interrupt to assign it to SWOF so that no matter wherever I am in the code; as SWOF key is pressed particular ISR is executed which resets every key.

    Already two external interrupts are utilised for STRT and PAUSE for asynchronous press and response


    I wish to know how else I can take care of asynchronous SWOF pressing.?

    Thanks,
    Anon10457

  62. #62
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Already two external interrupts are utilised for STRT and PAUSE for asynchronous press and response


    I wish to know how else I can take care of asynchronous SWOF pressing.?
    It seems that you didn't understand my last post. I suggested to use only one of the interrupt pins for START and PAUSE and identify which one has been pressed in the ISR. In this case, you would still have one interrupt free which you can use for SWOF.

    Finally, you need to find a workaround to solve problems with whatever resources you have in the MCU.

    -- Basant

  63. #63
    Hi,
    Just one interrupt for both STRTand PAUSE does not helps cos the equation is not balanced.

    If one interrupt is used for both the buttons how will the MCU will guess for which button the user has pressed it.?

    Thanks,
    Anon10457

  64. #64
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Quote Originally Posted by anon10457 View Post
    Hi,
    Just one interrupt for both STRTand PAUSE does not helps cos the equation is not balanced.

    If one interrupt is used for both the buttons how will the MCU will guess for which button the user has pressed it.?

    Thanks,
    Anon10457
    You can find out the pressed button by looking at the port/keypad value in the ISR.

    -- Basant

  65. #65
    Hi,
    I meant say P3.2 is set for both STRT and PAUSE. Now I pressed P3.2 with the intention of STRT but it takes me to PAUSE and vice versa could happen too.
    So how to get this straight.?

    Thanks
    Anon10457

  66. #66
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    You need to read hints for solutions carefully. You are missing the point.

    Suppose your interrupt is mapped to P3.2 and various buttons are mapped to various pins of port P1 through keypad. Say START is mapped to P1.0 and PAUSE is mapped to P1.1. When you get the interrupt, you can check values to P1.0 and P1.1 to figure out whether it is start or pause.

    -- Basant


    Quote Originally Posted by anon10457 View Post
    Hi,
    I meant say P3.2 is set for both STRT and PAUSE. Now I pressed P3.2 with the intention of STRT but it takes me to PAUSE and vice versa could happen too.
    So how to get this straight.?

    Thanks
    Anon10457

  67. #67
    Hi,
    Considering STRT and PAUSE is mapped to port P1. say P1.1 and P1.2.
    Say P3.2 is mapped to interrupt then as pressed takes to interrupt.
    Junk Code of Interrupt:
    ISR:
    JNB PAUSE,SUBRT1----line1
    JNB STRT,SUBRT2-----line2
    say STRT is pressed then , it takes to SUBRT2 where usual functioning takes place.

    Now while it is executing SUBRT2 a sudden PAUSE comes up how will it change to PAUSE mode then! Cos the PAUSE mode was checked in line1(earlier to it ;normal program flow). Asynchronous pressing of PAUSE will fail in this case. Remedy is to map interrupt to PAUSE to handle asynchronous press.

    As per post #38
    Asynchronous PAUSE i.e. PAUSE can be pressed anytime during machine is running
    Not mapping interrupt pins to STRT and PAUSE does not solves the purpose of 'asynchronous'.
    Thanks,
    Anon10457
    Last edited by anon10457; 01-02-2013 at 08:46 PM.

  68. #68
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457,

    Servicing interrupts cleanly will indeed remain a problem when you use the strategy of using one interrupt pin and then polling to take appropriate action. In this case, you can think about a strategy in which you slightly defer action for a button for some time. For example, in case of PAUSE, you need to remember the current state of the machine, hence if there was a PAUSE request, remember it in some register and poll it after every well defined state of the normal run of the machine to decide whether to pause it.

    -- Basant

  69. #69
    Hi,
    Updated Code:
    ORG 0000H
    LJMP MAIN
    ;--ISR for hardware interrupt INT0 to turn on LED
    ORG 0003H ;INT0 ISR
    JB STRT ,L5; JUMP ON BIT 1 TO L5
    ACALL SUBRT3
    L5: SJMP FINISH
    RETI ;return from ISR
    ;--ISR for hardware interrupt INT1 to turn on LED
    ORG 0013H ; GETS CALLED ONCE SWOF IS PRESSED P3.3 I.E INT1
    SETB IE.7
    RETI
    ;------MAIN program for initialization
    SUBRT3: ; section to run for 30msec
    MOV TMOD,#01H
    MOV TH0,#0EDH
    MOV TL0,#0FFH
    SETB TR0
    LOOP2: JNB PAUSE,LOOP2 ; TO CHECK IF PAUSE IS PRESSED
    AGAIN: JB TF0, L7
    L1:ACALL SUBRT2
    JMP L2
    L2:SJMP AGAIN
    L7: CLR TF0
    RET
    SUBRT2: ; Actual Machine Function default flow WASH RINSE WASH RINSE SPINDRY
    LOOP3: JNB PAUSE,LOOP3 ; TO CHECK IF PAUSE IS PRESSED
    MOV R2 ,#02
    LOOP4: JNB PAUSE,LOOP4 ; TO CHECK IF PAUSE IS PRESSED
    L3: CLR WASH
    LOOP5: JNB PAUSE,LOOP5 ; TO CHECK IF PAUSE IS PRESSED
    CLR RINSE
    LOOP6: JNB PAUSE,LOOP6 ; TO CHECK IF PAUSE IS PRESSED
    DJNZ R2,L3
    LOOP7: JNB PAUSE,LOOP7 ; TO CHECK IF PAUSE IS PRESSED
    CLR SPIN
    LOOP8: JNB PAUSE,LOOP8 ; TO CHECK IF PAUSE IS PRESSED
    RET
    MAIN:
    SWOF EQU P3.3 ; INT 1 PORT P3
    PAUSE EQU P3.0
    STRT EQU P3.2 ; INT0
    WASH EQU P3.5
    RINSE EQU P3.4
    SPIN EQU P3.1
    DONE EQU P3.6
    ;SETB TCON.3 ;make INT1 edge-triggered int.
    ;SETB TCON.1
    SETB IP.2 ;set SWOF higher priority.
    MOV IE,#10000111B ;enable External INT 1 AND INT0 and timer 0
    HERE: SJMP HERE ;stay here until get interrupted
    FINISH: CLR DONE ; set DONE bit after SPINDRY ; finish the process
    END
    I've attached the screenshot defining flow of program.

    Thanks,
    Anon10457
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	flow.png 
Views:	215 
Size:	45.7 KB 
ID:	491  

  70. #70
    VirtuQ Moderator
    Join Date
    Jun 2011
    Location
    Bangalore, India
    Posts
    310
    Blog Entries
    4
    Anon10457

    Quote Originally Posted by anon10457 View Post
    Hi,
    Updated Code:


    I've attached the screenshot defining flow of program.

    Thanks,
    Anon10457
    Your high level program flow looks fine with the given set of resources. I would futher suggest that to test out the entire program, first make sure that individual pieces are working correctly.

    -- Basant


 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •