. 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