Reading a Keypad and displaying it using Microprocessor

不羁的心 提交于 2019-12-23 04:46:01

问题


MTS-88.C and I/O BOARD -08 has 8 (Eight) 7-segment displays and 20 key-pads on board. The displays are numbered from 7-SEG.1 to 7-SEG.8 and are connected to Port B’s PB7 to PB0 lines respectively. To display a character on a 7-segment display a byte has to be written to port B. The MSB 4 bits are the address of the 7-segment display and LSB 4 bits are the data. So if we write 58 H to port B then the 6th 7-segment display will show data 8.

20 key-pads are numbered from P01 to P20 and are arranged in 5 columns and 4 rows. Rightmost column is connected to PB0 while leftmost column is connected to PB4. Topmost row is connected to PA0 while bottom-most row is connected to PA3. For detecting a key press, first a column must be activated by writing a byte to port B. Next, port A should be read. The valid values are 1, 2, 4 and 8 for row 1, 2, 3 and 4 respectively.

The experiment is to read the keypad and display the pressed key id on the specified 7-segment display. In this experiment, I haven't understood some lines in the assembly code I have shown below. I have made comments beside those lines which I haven't understood.

MEMORY ADDRESS   ASSEMBLY CODE    
0000:0476        MOV AL,90
0000:0478        OUT 13,AL
0000:047A        MOV DL,00
0000:047C        MOV CX,0004H  //why storing 4 here
0000:047F        MOV AL,0F
0000:0481        MOV BL,CL
0000:0483        SHL BL,01  //why left shift for 4 times
0000:0485        SHL BL,01   
0000:0487        SHL BL,01
0000:0489        SHL BL,01
0000:048B        OR AL,BL  //why doing OR operation here
0000:048D        OUT 11,AL
0000:048F        IN AL,10
0000:0491        MOV BL,01
0000:0493        TEST AL,BL  //what is testing here
0000:0495        JE O4A7     //when we are jumping(what is the condition)
0000:0497        INC DL   // what are we storing in DL
0000:0499        CMP DL,09
0000:049C        JG  047A  //why are we comparing DL with 9
0000:049E        SHL BL,01
0000:04A0        TEST BL,10  //what is being tested here
0000:04A3        JE 0493
0000:04A5        LOOP O47F
0000:04A7        MOV AL,DL
0000:04A9        OUT 11,AL
0000:04AB        PUSH CX
0000:04AC        MOV CX,500
0000:04AF        NOP   //why is this operation needed
0000:04B0        LOOP 04AF
0000:04B2        POP CX
0000:04B3        JMP 047A

What is actually being done with those lines I have marked above?


回答1:


I am puzzled how both the display and the keyboard uses port B. I guess there is some logic which detects the low 4 bits being 1 which would be invalid for a digit to display and then it switches into keyboard mode.

TEST AL,BL //what is testing here

It's testing through the 4 low bits of PA0-PA3 to see which one is set. This is the row number of the key pressed. Note that BL has been initialized to 1 at line 0491 and it is shifted left on line 049E in a loop. So it goes through 1, 2, 4 and 8 as required.

JE O4A7 //when we are jumping(what is the condition)

Apparently the keys use negative logic, that is you will get a 0 bit if a key is pressed. So the condition is looking for that 0 bit.

NOP //why is this operation needed

That's just part of a delay loop to make it longer.

INC DL // what are we storing in DL

JG 047A //why are we comparing DL with 9

I think the code only works for keys 0-9 because those can be represented by a single digit. So DL is the digit counter and the JG is for the end condition.

Update: given the new information, I can also say:

MOV CX,0004H //why storing 4 here

CX is the column counter, it is counting down from 4 to 0.

//why left shift for 4 times

Since the diagram shows you need the column index in the top 4 bits, this does that.

OR AL,BL //why doing OR operation here

You need to output 4F, 3F, 2F, 1F, 0F to port B. The top 4 bits are already set to the correct column index, what's left is to set the low 4 bits to 1. Since AL has been loaded with 0F, this achieves that.

The algorithm is as follows:

start:
    key = 0;
    for(column = 4; column != 0; column--)
    {
        portB = (column << 4) | 0x0f;
        in = portA;
        for(row = 1; row != 0x10; row <<= 1)
        {
            if ((in & row) == 0)
            {
                portB = key;
                goto start;
            }
            if (++key == 10) goto start;
        }
    }
    goto start;


来源:https://stackoverflow.com/questions/33502350/reading-a-keypad-and-displaying-it-using-microprocessor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!