日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

[筆記](méi).菜農(nóng)M0助學(xué)板之GPIO按鍵之邊沿檢測(cè)小練(寄存器操作方式)

 戴維圖書(shū)館 2013-10-25

[筆記](méi).菜農(nóng)M0助學(xué)板之GPIO按鍵之邊沿檢測(cè)小練(寄存器操作方式)

已發(fā)貼至:http://bbs.21ic.com/viewthread.php?tid=233787

現(xiàn)象解釋:
  KED1雙邊沿控制LED1:按下亮松開(kāi)滅
  KEY2下降沿控制LED2 第一次按下即亮,第二次按下滅
  KEY2上升沿控制LED3:第一次松開(kāi)即亮,第二次松開(kāi)即滅


這個(gè)比較簡(jiǎn)單,直接貼出代碼,大家可以驗(yàn)證一下。


main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "nuc1xx.h"
#include "DrvSYS.h"
/**********************************************************
* 宏定義
**********************************************************/
typedef enum{NO=0, YES=!NO}BOOL_T;
/* GPIO宏定義參考 */
// GPIO功能寄存器宏定義
//typedef struct
//{
//    __IO uint32_t PMD0:2;
//    __IO uint32_t PMD1:2;
//    __IO uint32_t PMD2:2;
//    __IO uint32_t PMD3:2;
//    __IO uint32_t PMD4:2;
//    __IO uint32_t PMD5:2;
//    __IO uint32_t PMD6:2;
//    __IO uint32_t PMD7:2;
//    __IO uint32_t PMD8:2;
//    __IO uint32_t PMD9:2;
//    __IO uint32_t PMD10:2;
//    __IO uint32_t PMD11:2;
//    __IO uint32_t PMD12:2;
//    __IO uint32_t PMD13:2;
//    __IO uint32_t PMD14:2;
//    __IO uint32_t PMD15:2;
//} GPIO_PMD_T;
// PMD[1:0] = 0; // 輸入
//            1; // 輸出
//            2; // 開(kāi)漏
//            3; // 準(zhǔn)雙向
// GPIO輸出寄存器宏定義
//typedef __IO uint32_t GPIO_DOUT_T;
// GPIO輸入寄存器宏定義
//typedef __IO uint32_t GPIO_PIN_T;
/* 設(shè)置所用GPIO */
// GPIO方向
#define BEEP_OE     GPIOB->PMD.PMD10 = 1 // BEEP輸出
#define KEY_IE      (*(uint32_t *)&GPIOB->PMD) &= 0x0FFFFFFF 
//#define KEY_IE      GPIOB->PMD.PMD15 = 0; \
//                    GPIOB->PMD.PMD14 = 0   
#define LED_OE      (*(uint32_t *)&GPIOA->PMD) |= 0x00000150
//#define LED_OE      GPIOA->PMD.PMD2 = 1; \
//                    GPIOA->PMD.PMD3 = 1; \
//                    GPIOA->PMD.PMD4 = 1;     
// GPIOIO電平
#define Close_BEEP  GPIOB->DOUT&=~(1<<10)
#define Open_BEEP   GPIOB->DOUT|=1<<10  
#define Close_LED1  GPIOA->DOUT|=1<<2
#define Open_LED1   GPIOA->DOUT&=~(1<<2)
#define Close_LED2  GPIOA->DOUT|=1<<3
#define Open_LED2   GPIOA->DOUT&=~(1<<3)
#define Close_LED3  GPIOA->DOUT|=1<<4
#define Open_LED3   GPIOA->DOUT&=~(1<<4)
#define Read_KEY1   (GPIOB->PIN>>15)&0x1
#define Read_KEY2   (GPIOB->PIN>>14)&0x1      
/**********************************************************
* 函數(shù)及變量申明
**********************************************************/
void MAIN_INIT(void);
void TMR0_IRQHandler(void) __irq;
BOOL_T Flag_tmr0_20ms = NO;
/**********************************************************
* 系統(tǒng)上電初始化
**********************************************************/
void MAIN_INIT(void)
{
    UNLOCKREG();
    {   /* 配置系統(tǒng)時(shí)鐘 */
        SYSCLK->PWRCON.XTL12M_EN = 1; //  設(shè)定12M外部晶振
        DrvSYS_Delay(5000); // 等待時(shí)鐘就緒
        DrvSYS_SelectPLLSource(E_SYS_EXTERNAL_12M); // 選擇12MHz為PLL輸入
        DrvSYS_Open(50000000); // 打開(kāi)50MHz
    }      
    {   /* 配置GPIO */
        BEEP_OE; Close_BEEP;
        LED_OE; Close_LED1; Close_LED2;
        KEY_IE;         
    }
    {   /* 配置TMR0 */
        NVIC_DisableIRQ(TMR0_IRQn);
        // 第一步 使能和選擇定時(shí)器時(shí)鐘源及使能定時(shí)器模塊          
        SYSCLK->CLKSEL1.TMR0_S = 0; // 選擇12Mhz作為定時(shí)器時(shí)鐘源 
        SYSCLK->APBCLK.TMR0_EN =1;  // 使能定時(shí)器0
        TIMER0->TCSR.CEN = 1;       // 使能定時(shí)器模塊
        // 第二步 選擇操作模式    
        TIMER0->TCSR.MODE = 1; // 選擇周期模式
        TIMER0->TCSR.CRST = 1; // 清加1計(jì)數(shù)器    
        // 第三步 輸出時(shí)鐘周期 = 定時(shí)器時(shí)鐘源周期*(8位預(yù)分頻因子 + 1) * (24位比較因子TCMP)
        TIMER0->TCSR.PRESCALE = 11; // 12分頻
        TIMER0->TCMPR = 5000; // 12M/12/20000, 20ms
        // 第四步 使能中斷
        TIMER0->TISR.TIF = 1; // 清中斷  
        TIMER0->TCSR.IE = 1; // 使能中斷 
        NVIC_EnableIRQ(TMR0_IRQn);  // 使能TMR0中斷
        // 第五步 使能定時(shí)器模塊
        TIMER0->TCSR.CRST = 1; // 復(fù)位向上計(jì)數(shù)器
        TIMER0->TCSR.CEN = 1; // 使能TMR0
        //TIMER0->TCSR.TDR_EN=1; // 無(wú)需讀取加1計(jì)數(shù)器值
    }
    LOCKREG();
}
/**********************************************************
* TMR0 ISR
**********************************************************/
void TMR0_IRQHandler(void) __irq
{   // 注意:ISR內(nèi)必須清中斷
    TIMER0->TISR.TIF = 1; // 清中斷  
  
    Flag_tmr0_20ms = YES;   
}
/**********************************************************
* 主函數(shù)
**********************************************************/
int main(void)
{
    uint8_t KEY_OldVal[2] = {1,1}; // 按鍵之舊值,次態(tài)值
    uint8_t KEY_NewVal[2] = {1,1}; // 按鍵之新值,現(xiàn)態(tài)值
    uint8_t LED_Val[3] = {1,1,1}; // LED值
    MAIN_INIT(); // 上電初始化系統(tǒng)
  
    while(1) {
        if(Flag_tmr0_20ms != NO) {
            Flag_tmr0_20ms = NO;
  
            KEY_NewVal[0] = Read_KEY2;
            KEY_NewVal[1] = Read_KEY1;
  
            /* KEY2雙邊沿控制LED1 */
            if(KEY_NewVal[0] ^ KEY_OldVal[0]) {
                // 先鎖存舊值
                KEY_OldVal[0] = KEY_NewVal[0]; 
                // 雙邊沿采樣
                LED_Val[0] = KEY_OldVal[0];                             
            }
  
            /* KEY1單邊沿控制LED2、LED3 */
            if(KEY_NewVal[1] ^ KEY_OldVal[1]) {
                // 下降沿控制LED2
                if(KEY_OldVal[1]/* && (~KEY_NewVal[1])*/
                    LED_Val[1] = LED_Val[1] ? 0 : 1; 
                // 上升沿采樣LED3 
                if(/*(~KEY_OldVal[1]) && */KEY_NewVal[1]) 
                    LED_Val[2] = LED_Val[2] ? 0 : 1;
                // 后鎖存舊值
                KEY_OldVal[1] = KEY_NewVal[1];                              
            }
  
  
            /* 響應(yīng)雙邊沿控制 */
            // 按下亮松開(kāi)滅
            if(!LED_Val[0]) Open_LED1;
            else Close_LED1;
              
            /* 響應(yīng)下降沿控制 */
            // 第一次按下即亮,第二次按下滅
            if(!LED_Val[1]) Open_LED2;
            else Close_LED2;  
              
            /* 響應(yīng)上升沿控制 */
            // 第一次松開(kāi)即亮,第二次松開(kāi)即滅
            if(!LED_Val[2]) Open_LED3;
            else Close_LED3;           
           }
  
        if(0) break; // 跳出大循環(huán)
    }
    return 0;
}

Snap1

下面給出Multisim之硬件仿真圖示范

邊沿檢測(cè) 

雙邊沿檢測(cè)

雙邊沿檢測(cè)

上升沿檢測(cè)

上升沿檢測(cè)

下降沿檢測(cè)

下降沿檢測(cè)

 .COM 缺氧? / CC BY 2.5     

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多