日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

【.Net Micro Framework PortingKit - 08】GPIO驱动

發(fā)布時(shí)間:2025/1/21 asp.net 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【.Net Micro Framework PortingKit - 08】GPIO驱动 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

要點(diǎn)亮LED燈或獲得輸入IO的狀態(tài)應(yīng)該是比較容易的,打開(kāi)端口時(shí)鐘,然后讀寫(xiě)相關(guān)的GPIO寄存器就可以了,但是要實(shí)現(xiàn)一個(gè)輸入中斷,就要費(fèi)些周折了。

對(duì)STM32(Cortex-M3)的芯片,要實(shí)現(xiàn)一個(gè)GPIO中斷一般需要如下幾步:

1、? 配置時(shí)鐘控制器寄存器(RCC)的APB2RSTR,確保對(duì)應(yīng)的GPIOA ~ GPIOG時(shí)鐘使能。

2、? 對(duì)GPIO寄存器的CRL(或CRH)要設(shè)置正確的輸入模式,如浮空輸入模式(對(duì)接收IO中斷來(lái)說(shuō),當(dāng)然要設(shè)置成輸入模式)。

3、? 要通過(guò)AFIO寄存器配置中斷的輸入來(lái)源,對(duì)STM32芯片來(lái)說(shuō),具有19路EXTI中斷線,其中3路分別連接PVD輸出、RTC鬧鐘事件及USB喚醒事件,剩下的對(duì)GPIOA ~ GPIOG 7*16=112個(gè)IO點(diǎn)來(lái)說(shuō),同時(shí)只能配置16路IO輸入中斷。

4、? 接下來(lái)要配置EXIT寄存器,根據(jù)需要來(lái)配置是上升沿觸發(fā)中斷、還是下降沿觸發(fā)中斷或兩者都觸發(fā)。

5、? 而后比較重要的是, 要配置NVIC的SETENA寄存器,讓對(duì)應(yīng)的EXTI0、EXTI1、EXTI2、EXTI3、EXTI4、EXTI9_5或EXTI15_10中斷位使能,此外還要配置各中斷的優(yōu)先級(jí)(前提是中斷優(yōu)先級(jí)分組寄存器已配置完畢)。

6、? 最后我們要設(shè)置中斷向量表(該向量表要重定位到內(nèi)存中,以便于動(dòng)態(tài)修改),在EXTI0、EXTI1、EXTI2、EXTI3、EXTI4、EXTI9_5或EXTI15_10對(duì)應(yīng)的位置,放入我們的中斷函數(shù)的入口地址。

?

和PC平臺(tái)程序開(kāi)發(fā)不同,基本上你每做一步,都可以很直觀的看到你的進(jìn)展和成果,但對(duì)嵌入式開(kāi)發(fā)來(lái)說(shuō),如果上述幾步有任何一個(gè)環(huán)節(jié)出了問(wèn)題,你的進(jìn)展都是零,有時(shí)候你會(huì)花上一天的時(shí)間去反復(fù)核實(shí)每個(gè)寄存器的值是否正確,以期獲得你希望的結(jié)果。所以說(shuō)嵌入式開(kāi)發(fā)是驚喜的型的,要么成,要么不成,一線之隔!

接下來(lái)我們說(shuō)一下GPIO實(shí)現(xiàn)的詳細(xì)步驟,首先在CortexM3.h頭文件中添加GPIO相關(guān)的寄存器描述:

  • struct?CortexM3_GPIO ?
  • ?
  • { ?
  • ?
  • ??static?const?UINT32?c_Base?=?0x40010800; ?
  • ?
  • ??static?const?UINT32?A?=?0; ?
  • ?
  • ??static?const?UINT32?B?=?1; ?
  • ?
  • ??static?const?UINT32?C?=?2; ?
  • ?
  • ??static?const?UINT32?D?=?3; ?
  • ?
  • ??static?const?UINT32?E?=?4; ?
  • ?
  • ??static?const?UINT32?F?=?5;? ?
  • ?
  • ??static?const?UINT32?G?=?6;? ?
  • ?
  • ??static?const?UINT32?GPIO_Mode_NULL?=?0x00; ?
  • ?
  • ??static?const?UINT32?GPIO_Mode_Speed_10MHz?=?0x01; ?
  • ?
  • ??static?const?UINT32?GPIO_Mode_Speed_2MHz?=?0x02; ?
  • ?
  • ??static?const?UINT32?GPIO_Mode_Speed_50MHz?=?0x03; ?
  • ?
  • ??static?const?UINT32?GPIO_Mode_IN_FLOATING?=?0x04; ?
  • ?
  • ????/****/?volatile?UINT32???CRL;??//配置寄存器 ?
  • ?
  • ??/****/?volatile?UINT32???CRH; ?
  • ?
  • ??/****/?volatile?UINT32???IDR;??//數(shù)據(jù)寄存器 ?
  • ?
  • ??/****/?volatile?UINT32???ODR; ?
  • ?
  • ??/****/?volatile?UINT32???BSRR;?//置位復(fù)位寄存器 ?
  • ?
  • ??/****/?volatile?UINT32???BRR;??//復(fù)位寄存器 ?
  • ?
  • ??/****/?volatile?UINT32???LCKR;?//鎖定寄存器 ?
  • ?
  • }; ?
  • ?
  • struct?CortexM3_EXTI ?
  • ?
  • { ?
  • ?
  • ??static?const?UINT32?c_Base?=?0x40010400; ?
  • ?
  • ??/****/?volatile?UINT32??IMR; ?
  • ?
  • ??/****/?volatile?UINT32??EMR; ?
  • ?
  • ??/****/?volatile?UINT32??RTSR; ?
  • ?
  • ??/****/?volatile?UINT32??FTSR; ?
  • ?
  • ??/****/?volatile?UINT32??SWIER; ?
  • ?
  • ??/****/?volatile?UINT32??PR; ?
  • ?
  • }; ?
  • ?
  • struct?CortexM3_AFIO ?
  • ?
  • { ?
  • ?
  • ??static?const?UINT32?c_Base?=?0x40010000;?? ?
  • ?
  • ??/****/?volatile?UINT32?EVCR; ?
  • ?
  • ??/****/?volatile?UINT32?MAPR; ?
  • ?
  • ??/****/?volatile?UINT32?EXTICR[4]; ?
  • ?
  • }; ?
  • ?
  • 由于NVIC相關(guān)的代碼我們已經(jīng)在《NVIC中斷處理》說(shuō)過(guò)了,這里就不重復(fù)了。

    對(duì).Net Micro Framework的架構(gòu)來(lái)說(shuō),要實(shí)現(xiàn)如下幾個(gè)接口:

    1、CPU_GPIO_Initialize

    2、CPU_GPIO_Uninitialize

    3、CPU_GPIO_Attributes

    4、CPU_GPIO_DisablePin

    5、CPU_GPIO_EnableOutputPin

    6、CPU_GPIO_EnableInputPin

    7、CPU_GPIO_EnableInputPin2

    8、CPU_GPIO_GetPinState

    9、CPU_GPIO_SetPinState

    10、CPU_GPIO_GetPinCount

    11、CPU_GPIO_GetPinsMap

    12、CPU_GPIO_GetSupportedResistorModes

    13、CPU_GPIO_GetSupportedInterruptModes

    14、CPU_GPIO_PinIsBusy

    15、CPU_GPIO_ReservePin

    16、CPU_GPIO_GetDebounce

    17、CPU_GPIO_SetDebounce

    考慮到難易程度和篇幅,我們只介紹CPU_GPIO_Initialize、CPU_GPIO_EnableOutputPin、 CPU_GPIO_EnableInputPin和EXTI_IRQHandler 中斷函數(shù)的具體實(shí)現(xiàn)。

  • BOOL?GPIO_Driver::Initialize() ?
  • ?
  • { ?
  • ?
  • ?????????CortexM3_AFIO?&AFIO?=?CortexM3::AFIO(); ?
  • ?
  • ????for(int?i=0;i<4;i++)? ?
  • ?
  • ????{ ?
  • ?
  • ???????AFIO.EXTICR[i]=0x0000; ?
  • ?
  • ????}???????? ?
  • ?
  • CortexM3_EXTI?&EXTI=?CortexM3::EXTI();???? ?
  • ?
  • ????EXTI.IMR?=?0x00000000; ?
  • ?
  • ????EXTI.EMR?=?0x00000000; ?
  • ?
  • ????EXTI.RTSR?=?0x00000000;? ?
  • ?
  • ????EXTI.FTSR?=?0x00000000;? ?
  • ?
  • ????EXTI.PR?=?0x0007FFFF; ?
  • ?
  • ????//NVIC? ?
  • ?
  • ????if(!CPU_INTC_ActivateInterruptEx(CortexM3_NVIC::c_IRQ_Index_EXTI0,(UINT32)(void?*)EXTI_IRQHandler?))???return?FALSE; ?
  • ?
  • ?????????//略 ?
  • ?
  • ????return?TRUE; ?
  • ?
  • } ?
  • ?
  • 其中比較重要的是CPU_INTC_ActivateInterruptEx函數(shù),它可動(dòng)態(tài)設(shè)置c_IRQ_Index_EXTI0中斷所對(duì)應(yīng)的中斷函數(shù)的入口地址。

  • void?GPIO_Driver::EnableOutputPin(GPIO_PIN?pin,?BOOL?initialState) ?
  • ?
  • { ?
  • ?
  • ????ASSERT(pin?<?c_MaxPins);???????? ?
  • ?
  • ????UINT32?port?=?PinToPort(pin);? ?
  • ?
  • ?????????UINT32?bit?=?PinToBit(pin); ?
  • ?
  • ????UINT32?pos?=?(bit?%?8)<<2; ?
  • ?
  • ?????????CortexM3_GPIO?&GPIO=?CortexM3::GPIO(port);???? ?
  • ?
  • ????//通用推挽輸出模式 ?
  • ?
  • ????if(bit<8) ?
  • ?
  • ????{???????? ?
  • ?
  • ???????GPIO.CRL?=?(GPIO.CRL?&?~(0x0F?<<?pos))?|?(CortexM3_GPIO::GPIO_Mode_Speed_50MHz?<<?pos); ?
  • ?
  • ????} ?
  • ?
  • ?????????else?
  • ?
  • ?????????{ ?
  • ?
  • ????????????GPIO.CRH?=?(GPIO.CRH?&?~(0x0F?<<?pos))?|?(CortexM3_GPIO::GPIO_Mode_Speed_50MHz?<<?pos); ?
  • ?
  • ?????????} ?
  • ?
  • ? ?
  • ?
  • ????//初值 ?
  • ?
  • ????if(initialState)?GPIO.BSRR?=?0x1?<<?bit; ?
  • ?
  • ????else?GPIO.BRR?=?0x1?<<?bit; ?
  • ?
  • } ?
  • ?
  • 輸出默認(rèn)為通用推挽輸出模式,你也可以根據(jù)實(shí)際需要進(jìn)行必要的調(diào)整。

  • BOOL?GPIO_Driver::EnableInputPin(GPIO_PIN?pin,?BOOL?GlitchFilterEnable,?GPIO_INTERRUPT_SERVICE_ROUTINE?ISR,?void?*pinIsrParam,?GPIO_INT_EDGE?intEdge,?GPIO_RESISTOR?resistorState) ?
  • ?
  • { ?
  • ?
  • ????ASSERT(pin?<?c_MaxPins);???????? ?
  • ?
  • ????UINT32?port?=?PinToPort(pin);? ?
  • ?
  • ?????????UINT32?bit?=?PinToBit(pin); ?
  • ?
  • ????UINT32?pos?=?(bit?%?8)<<2; ?
  • ?
  • ?????????CortexM3_GPIO?&GPIO=?CortexM3::GPIO(port);???? ?
  • ?
  • ????//浮空輸入 ?
  • ?
  • ????if(bit<8) ?
  • ?
  • ????{???????? ?
  • ?
  • ???????GPIO.CRL?=?(GPIO.CRL?&?~(0x0F?<<?pos))|?(CortexM3_GPIO::GPIO_Mode_IN_FLOATING?<<?pos); ?
  • ?
  • ????} ?
  • ?
  • ?????????else ?
  • ?
  • ?????????{ ?
  • ?
  • ????????????GPIO.CRH?=?(GPIO.CRH?&?~(0x0F?<<?pos))|?(CortexM3_GPIO::GPIO_Mode_IN_FLOATING?<<?pos); ?
  • ?
  • ?????????} ?
  • ?
  • ????//中斷輸入源配置(AFIO) ?
  • ?
  • ????CortexM3_AFIO?&AFIO?=?CortexM3::AFIO(); ?
  • ?
  • ????AFIO.EXTICR[bit?>>?2]?&=?~(0x0F?<<?(0x04?*?(bit?&?0x03))); ?
  • ?
  • ????AFIO.EXTICR[bit?>>?2]?|=?port?<<?(0x04?*?(bit?&?0x03)); ?
  • ?
  • ?????????CortexM3_EXTI?&EXTI=CortexM3::EXTI(); ?
  • ?
  • ????if(ISR) ?
  • ?
  • ????{ ?
  • ?
  • ????????switch(intEdge) ?
  • ?
  • ????????{ ?
  • ?
  • ????????????case?GPIO_INT_NONE:???//無(wú)中斷 ?
  • ?
  • ????????????????EXTI.IMR?&=?~(0x1<<bit);???????????????????????????????????? ?
  • ?
  • ????????????????return?FALSE; ?
  • ?
  • ????????????case?GPIO_INT_EDGE_LOW:???//下降沿中斷 ?
  • ?
  • ????????????case?GPIO_INT_LEVEL_LOW: ?
  • ?
  • ????????????????EXTI.IMR?|=?0x1<<bit;????? ?
  • ?
  • ?????????????????????????????????????EXTI.FTSR?|=?0x1<<bit;????????//下降沿有效 ?
  • ?
  • ?????????????????????????????????????EXTI.RTSR?&=?~(0x1<<bit);??//上升沿?zé)o效 ?
  • ?
  • ????????????????break; ?
  • ?
  • ????????????//略 ?
  • ?
  • ????????????default: ?
  • ?
  • ????????????????ASSERT(0); ?
  • ?
  • ????????????????return?FALSE; ?
  • ?
  • ????????} ?
  • ?
  • ????}????????????????? ?
  • ?
  • ??????????????????? ?
  • ?
  • ????return?TRUE; ?
  • ?
  • } ?
  • ?
  • GPIO輸入的實(shí)現(xiàn)比較繁瑣一些,可以根據(jù)需要僅把端口配置成輸入模式,而不配置相應(yīng)的中斷參數(shù)。這樣可以通過(guò)不斷掃描的方式獲得輸入信號(hào)。

  • void?GPIO_Driver::ISR(void?*Param) ?
  • ?
  • { ?
  • ?
  • ?????????CortexM3_EXTI?&EXTI=CortexM3::EXTI(); ?
  • ?
  • ????UINT32?interruptsActive?=?EXTI.PR; ?
  • ?
  • ????UINT32?bitMask??=?0x1,?bitIndex?=?0; ?
  • ?
  • ?????????while(interruptsActive) ?
  • ?
  • ????{ ?
  • ?
  • ????????while((interruptsActive?&?bitMask)?==?0) ?
  • ?
  • ????????{ ?
  • ?
  • ????????????bitMask??<<=?1; ?
  • ?
  • ????????????++bitIndex; ?
  • ?
  • ????????} ?
  • ?
  • ????????CortexM3_AFIO?&AFIO?=?CortexM3::AFIO(); ?
  • ?
  • ????????UINT32?port?=?(AFIO.EXTICR[bitIndex?>>?2]>>(0x04?*?(bitIndex?&?0x03)))?&?0xF; ?
  • ?
  • ????????GPIO_PIN?pin?=?BitToPin(?bitIndex,?port); ?
  • ?
  • ????????PIN_ISR_DESCRIPTOR&?pinIsr?=?g_GPIO_Driver.m_PinIsr[?pin?]; ?
  • ?
  • ????????pinIsr.Fire(?(void*)&pinIsr?); ?
  • ?
  • ????????interruptsActive?^=?bitMask; ?
  • ?
  • ???????????????????EXTI.PR?|=?bitMask; ?
  • ?
  • ????}? ?
  • ?
  • } ?
  • ?
  • 在中斷函數(shù)中,根據(jù)相關(guān)寄存器的值來(lái)判斷哪一個(gè)(或同時(shí)哪一些)GPIO發(fā)生的中斷,并由此執(zhí)行業(yè)已配置好的異步中斷處理函數(shù)。

    好了,寫(xiě)完了GPIO驅(qū)動(dòng)程序,我們就可以漂漂亮亮的在NativeSample中寫(xiě)我們的測(cè)試程序了:

  • void?ISR(?GPIO_PIN?Pin,?BOOL?PinState,?void*?Param?) ?
  • ?
  • { ?
  • ?
  • ????if(PinState)????//?released,?up ?
  • ?
  • ????{ ?
  • ?
  • ??????CPU_GPIO_SetPinState(GPIO_Driver::PF7,0x0); ?
  • ?
  • ????} ?
  • ?
  • ????else????????????//?pressed,?down ?
  • ?
  • ????{ ?
  • ?
  • ???????CPU_GPIO_SetPinState(GPIO_Driver::PF7,0x1); ?
  • ?
  • ????} ?
  • ?
  • } ?
  • ?
  • ? ?
  • ?
  • void?ApplicationEntryPoint() ?
  • ?
  • {??? ?
  • ?
  • ????//LED?D1?D2?D3?D4??? ?
  • ?
  • ????CPU_GPIO_EnableOutputPin(GPIO_Driver::PF7,FALSE); ?
  • ?
  • ?????????CPU_GPIO_EnableOutputPin(GPIO_Driver::PF8,FALSE); ?
  • ?
  • ? ?
  • ?
  • ?????????//user按鈕?=?0x1 ?
  • ?
  • ?????????CPU_GPIO_EnableInputPin(GPIO_Driver::PG8,FALSE,ISR,GPIO_INT_EDGE_BOTH,RESISTOR_PULLDOWN);???????????????????? ?
  • ?
  • ????while(TRUE)????? ?
  • ?
  • ????{??? ?
  • ?
  • ???????????CPU_GPIO_SetPinState(GPIO_Driver::PF8,!CPU_GPIO_GetPinState(GPIO_Driver::PF8)); ?
  • ?
  • ???????????Events_WaitForEvents(?0,?1000?);??????? ?
  • ?
  • ?????????} ?
  • ?
  • } ?
  • ?
  • 上面的程序比我們最初在《調(diào)試初步:點(diǎn)亮LED燈》中提到的代碼清爽多了,把程序下載到開(kāi)發(fā)板上運(yùn)行,你會(huì)發(fā)現(xiàn)D3 LED燈以一秒為周期不斷地閃爍,而D2 LED燈則在user按鈕按下時(shí)才亮,放開(kāi)時(shí)則滅。

    只要細(xì)心 + 耐心,其實(shí)嵌入式開(kāi)發(fā)還是比較容易的,并且功能實(shí)現(xiàn)那一刻喜悅的“強(qiáng)度”,是作為PC平臺(tái)軟件開(kāi)發(fā)者所難以企及的

    ?

    轉(zhuǎn)載于:https://blog.51cto.com/yfsoft/321228

    總結(jié)

    以上是生活随笔為你收集整理的【.Net Micro Framework PortingKit - 08】GPIO驱动的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。