[Iot smart gateway-05] scan keyboard Programming Design

Source: Internet
Author: User

. The net micro framework simulator provides five simulated buttons (top, bottom, left, right, and confirmation buttons. the net MF Development Board only needs to provide five buttons, and these five keys are directly connected to the CPU pin, you can use the Input Functions of gpio to perform operations.

However, for some special applications, such as some. Net micro Framework Education boxes or some industrial systems, five buttons are obviously too few. However, if you need more than a dozen buttons, If you directly connect to the pin of the chip, it will obviously occupy a lot of resources, and other functions will become unusable. In this case, the most common thing is to scan the keyboard.

 

The schematic diagram of the above scan keyboard should be the simplest one. It is a little more complicated. In a row or column, a VCC is connected through an upper-tension resistor. In this way, we only need 8 pin feet to get the information of 16 buttons.

The general idea of implementation is also relatively simple: The line (or column) is connected to the chip output pin, and the column (or row) is connected to the chip Input Pin pin, the output pin step outputs Low (or high in turn, depending on the pull-up or drop-down resistance in the circuit) levels, and then checks the level changes of the input pin. If there are any changes, the keys for this column and this row are pressed.

This judgment is often placed in the while loop or thread, and is constantly running. For some monolithic systems, if the single function is implemented, this is understandable. However, for a system platform, if this is also done, it is clear that the system resources are still quite occupied.

Therefore, the best way is to use the interrupt method. In normal times, we do not judge whether the interruption is triggered. Once the interruption is triggered, we start another round of judgment to determine which button is pressed.

1. Scan Mode for key acquisition

 Public   Class  Scankeypad { Public   Event  Nativeeventhandler oninterrupt; outputport [] rows = Null  ; Inputport [] Cols = Null  ;  Public  Scankeypad (CPU. Pin [] output_pins, CPU. Pin [] input_pins) {rows = New Outputport [] { New Outputport (output_pins [ 0 ],False ), New Outputport (output_pins [ 1 ], False ), New Outputport (output_pins [ 2 ], False ), New Outputport (output_pins [ 3 ], False  )}; Cols = New Inputport [] { New Inputport (input_pins [ 0 ], True , Port. resistormode. pullup ), New Inputport (input_pins [ 1 ], True , Port. resistormode. pullup ), New Inputport (input_pins [ 2 ], True , Port. resistormode. pullup ), New Inputport (input_pins [ 3 ], True , Port. resistormode. pullup)}; thread threadkeypad = New Thread ( New  Threadstart (keypadscan); threadkeypad. Start ();}  Void  Keypadscan (){  Int Key =- 1 , Oldkey =- 1  ;  While ( True ) {Key =- 1  ;  For ( Int I = 0 ; I <rows. length; I ++ ) {Rows [I]. Write (  False  );  For ( Int J = 0 ; J <cols. length; j ++){  If (! Cols [J]. Read () {key = I * Rows. Length + J;  Break  ;} Rows [I]. Write (  True  );  If (Key>- 1 ) Break ;}  If (Key>- 1 & Key! = Oldkey ){  If (Oninterrupt! = Null ) Oninterrupt (( Uint ) Key, 1  , Datetime. Now); oldkey = Key ;}  Else   If (Oldkey>-1 & Key =- 1  ){  If (Oninterrupt! = Null ) Oninterrupt (( Uint ) Oldkey, 0  , Datetime. Now); oldkey =- 1  ;} Thread. Sleep (  100  );}}} 

 

2. access keys in the interrupt mode

Public   Class  Interruptkeypad {  Public   Event  Nativeeventhandler oninterrupt; outputport [] rows = Null  ; Interruptport [] Cols = Null  ; CPU. Pin [] pins = Null  ;  Uint Key = 0 ;  Public  Interruptkeypad (CPU. Pin [] output_pins, CPU. Pin [] input_pins) {rows = New Outputport [] { New Outputport (output_pins [ 0 ], False ), New Outputport (output_pins [ 1 ], False ), New Outputport (output_pins [ 2 ],False ), New Outputport (output_pins [ 3 ], False  )}; Cols = New  Interruptport [input_pins.length]; pins = Input_pins;  For ( Int I = 0 ; I <input_pins.length; I ++ ) {Cols [I] =New Interruptport (input_pins [I], True  , Port. resistormode. pullup, port. interruptmode. interruptedgeboth); Cols [I]. oninterrupt + = New  Nativeeventhandler (interruptkeypad_oninterrupt );}}  Private   Uint Getpinindex ( Uint  PIN ){  For ( Uint I = 0 ; I <pins. length; I ++ ){  If (PIN = ( Uint ) Pins [I]) Return  I ;}  Return   0  ;}  Void Interruptkeypad_oninterrupt ( Uint Data1, Uint  Data2, datetime time ){  If (Data2 =1  ){  For ( Int I = 0 ; I <cols. length; I ++ ) {Cols [I]. oninterrupt -= New  Nativeeventhandler (interruptkeypad_oninterrupt );}  //  --                  Uint Col = Getpinindex (data1 ); For ( Int I = 0 ; I <rows. length; I ++ ) {Rows [I]. Write (  True  );  If  (Cols [col]. Read () {key = ( Uint ) (I * Rows. Length + COL); thread threadkeypad = New Thread ( New Threadstart (keypadrun); threadkeypad. Start ();  Break  ;}}  //  --                  For ( Int I = 0 ; I <rows. length; I ++) rows [I]. Write ( False  );  For ( Int I = 0 ; I <cols. length; I ++ ) {Cols [I]. oninterrupt + = New  Nativeeventhandler (interruptkeypad_oninterrupt );}}}  Void  Keypadrun () {oninterrupt (key,  1  , Datetime. Now); oninterrupt (key,  0  , Datetime. Now );}} 

 

Note: In the interrupt mode, the trigger event must be executed in the thread; otherwise, there may be problems (if used in winform, it is best to use the timer provided by winfrom instead of the thread, otherwise, the UI cannot be operated directly, so you must use the delegate method, similar to programming on Windows ).

Problem 1:Since the keyboard we use does not have a pull (or drop-down) resistor circuit, we initially did thisProgramInputport (input_pins [1], true, port. resistormode. pullup), the bottom layer of the last parameter does not implement internal pull-up, drop-down, and suspension functions, so the settings are invalid. This leads to the fact that when the button is not pressed, the status of the pin is unknown, sometimes 1, sometimes 0, and the program cannot run correctly.

In addition, the gpio registers of stm32f103 and stm32f207 differ greatly, and the internal implementation of the pull-up and drop-down settings are also different. After implementation, it is found that the internal pull is normal, the setting of the drop-down effect is not obvious, and the pin status is unknown. So all the programs we implement are set to pull up.

Problem 2:Scan the keyboard in interrupt modeCodeWhen pb6, pc0, and PB1 pin are found to trigger interruption exceptions, but nativesample is normal. No special issues have been found for these three pin pins. This issue will be investigated later. Therefore, if the interrupt mode is used, these three pin pins cannot be used.

The above two methods are implemented at the application level. In fact, if the pin of the scan keyboard is fixed, a better way is to use C ++ at the underlying layer, in addition, you can Virtualize 8 Physical pin feet to 16. The usage is exactly the same as that of physical pin.

The official simplewpfapplication example is a typical WPF application, but it requires five buttons to operate. Our Wisteria 207 system only provides one physical button, so it cannot be operated. After the scan keyboard is connected, we may demonstrate this example completely. However, because we use a scan keyboard, the original program cannot be used. You must make the following modifications.

  Public  Sealed   Class  Gpiobuttoninputprovider {  Public   Readonly  Dispatcher dispatcher;  Private  Dispatcheroperationcallback callback;  Private  Inputprovidersite site;  Private  Presentationsource source;  Public Gpiobuttoninputprovider (presentationsource source ){  This . Source = Source; Site = Inputmanager. currentinputmanager. registerinputprovider ( This  ); Callback = New Dispatcheroperationcallback ( Delegate ( Object  Report) {inputreportargs ARGs = (Inputreportargs) report;  Return Site. reportinput (ARGs. device, argS. Report) ;}); dispatcher = Dispatcher. currentdispatcher; CPU. Pin [] output_pins = {(CPU. Pin) gpio_names.pc8, (CPU. Pin) gpio_names.pc9, (CPU. Pin) gpio_names.pb7, (CPU. Pin) gpio_names.pc2}; CPU. Pin [] input_pins = {(CPU. Pin) gpio_names.pc3, (CPU. Pin) gpio_names.pa0, (CPU. Pin) gpio_names.pa5, (CPU. Pin) gpio_names.pa5}; interruptkeypad key = New  Interruptkeypad (output_pins, input_pins); key. oninterrupt + = New Nativeeventhandler (key_oninterrupt );}  Void Key_oninterrupt ( Uint Data1, Uint  Data2, datetime time) {rawbuttonactions action = (Data2! = 0 )? Rawbuttonactions. buttonup: rawbuttonactions. buttondown; rawbuttoninputreport report = New  Rawbuttoninputreport (source, time, getbutton (data1), Action); dispatcher. begininvoke (callback,  New Inputreportargs (inputmanager. currentinputmanager. buttondevice, report);} button getbutton (  Uint  Data ){  Switch  (Data ){  Case   2  :  Return  Button. vk_up;  Case   5  :  Return Button. vk_left;  Case   6  :  Return  Button. vk_select;  Case   10  :  Return  Button. vk_down;  Case   7  :  Return Button. vk_right ;}  Return  Button. None ;}} 

 

After modifying the program in gpiobuttoninputprovider. CS, you can use it.

As follows:

The actual running video link is as follows:

Http://v.youku.com/v_show/id_XNDI3ODU4OTg4.html

 

From the video, we can see that the running of the WPF program on the stm32f207 platform is still quite smooth.

-------------------------------------------------------------------------------

:Http://www.sky-walker.com.cn/MFRelease/Sample/ScanKey_WPFTest.rar

MfIntroduction:Http://blog.csdn.net/yefanqiu/article/details/5711770

MfMATERIALS:Http://www.sky-walker.com.cn/News.asp? Id = 25

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.