在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32 uCOS_II 實(shí)踐 之 外部中斷事件 及 系統(tǒng)運(yùn)行過(guò)程

            STM32 uCOS_II 實(shí)踐 之 外部中斷事件 及 系統(tǒng)運(yùn)行過(guò)程

            作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò) 收藏
            在進(jìn)行uCOSII的程序之前先來(lái)復(fù)習(xí)下,裸機(jī)平臺(tái)下stm32的外部中斷的操作。

            大概可以分作4個(gè)步驟:1-配置相應(yīng)管腳為浮空輸入;2-配置相應(yīng)管腳為外部中斷口并設(shè)定其中斷屬性及參數(shù);3-配置NVIC相關(guān)寄存器,設(shè)定中斷優(yōu)先級(jí);4-編寫中斷服務(wù)函數(shù)。廢話不說(shuō)直接上代碼:

            本文引用地址:http://www.biyoush.com/article/201612/325150.htm

            第一步:配置相應(yīng)管腳為浮空輸入,來(lái)自文件Key.c

            voidKey_Port_Configuration(void)
            {
            GPIO_InitTypeDefGPIO_InitStructure_EXTI_KEY_PORTE;

            GPIO_InitStructure_EXTI_KEY_PORTE.GPIO_Pin=GPIO_Pin_4;// 端口4
            GPIO_InitStructure_EXTI_KEY_PORTE.GPIO_Mode=GPIO_Mode_IN_FLOATING;// 浮空輸入
            GPIO_InitStructure_EXTI_KEY_PORTE.GPIO_Speed=GPIO_Speed_50MHz;// 口線翻轉(zhuǎn)速度為50MHz
            GPIO_Init(GPIOE,&GPIO_InitStructure_EXTI_KEY_PORTE);// 端口初始化

            GPIO_InitStructure_EXTI_KEY_PORTE.GPIO_Pin=GPIO_Pin_3;// 端口3
            GPIO_InitStructure_EXTI_KEY_PORTE.GPIO_Mode=GPIO_Mode_IN_FLOATING;// 浮空輸入
            GPIO_InitStructure_EXTI_KEY_PORTE.GPIO_Speed=GPIO_Speed_50MHz;// 口線翻轉(zhuǎn)速度為50MHz
            GPIO_Init(GPIOE,&GPIO_InitStructure_EXTI_KEY_PORTE);// 端口初始化
            }

            第二步:配置相應(yīng)管腳為外部中斷口并且設(shè)定其中斷屬性及參數(shù),來(lái)自文件EXTIG.c

            voidEXTI_PORTE_Configuration(void)
            {
            EXTI_InitTypeDefEXTI_InitStructure_EXTI_LINE4;
            EXTI_InitTypeDefEXTI_InitStructure_EXTI_LINE3;

            /* Connect EXTI Line4,3 to PE4,PE3 */
            GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);// 配置 管腳PE4用作外部中斷線路
            GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);// 配置 管腳PE3用作外部中斷線路

            /* Configure EXTI Line4 to generate an interrupt on falling edge */
            EXTI_InitStructure_EXTI_LINE4.EXTI_Line=EXTI_Line4;//配置 使能或失能的外部線路
            EXTI_InitStructure_EXTI_LINE4.EXTI_Mode=EXTI_Mode_Interrupt;//配置 EXTI線路為中斷請(qǐng)求 (或者是事件請(qǐng)求)
            EXTI_InitStructure_EXTI_LINE4.EXTI_Trigger=EXTI_Trigger_Falling;//配置 使能線路的觸發(fā)邊沿 -- 下降沿觸發(fā)中斷
            EXTI_InitStructure_EXTI_LINE4.EXTI_LineCmd=ENABLE;//配置 狀態(tài)為使能
            EXTI_Init(&EXTI_InitStructure_EXTI_LINE4);// 初始化外部中斷線路4

            /* Configure EXTI Line3 to generate an interrupt on falling edge */
            EXTI_InitStructure_EXTI_LINE3.EXTI_Line=EXTI_Line3;//配置 使能或失能的外部線路
            EXTI_InitStructure_EXTI_LINE3.EXTI_Mode=EXTI_Mode_Interrupt;//配置 EXTI線路為中斷請(qǐng)求 (或者是事件請(qǐng)求)
            EXTI_InitStructure_EXTI_LINE3.EXTI_Trigger=EXTI_Trigger_Falling;//配置 使能線路的觸發(fā)邊沿 -- 下降沿觸發(fā)中斷
            EXTI_InitStructure_EXTI_LINE3.EXTI_LineCmd=ENABLE;//配置 狀態(tài)為使能
            EXTI_Init(&EXTI_InitStructure_EXTI_LINE3);// 初始化外部中斷線路3

            /* Generate software interrupt: simulate a falling edge applied on EXTI line 13 */
            EXTI_GenerateSWInterrupt(EXTI_Line4);//線路4產(chǎn)生一個(gè)軟件中斷
            EXTI_GenerateSWInterrupt(EXTI_Line3);//線路3產(chǎn)生一個(gè)軟件中斷
            }

            第三步:配置NVIC相關(guān)寄存器,設(shè)定中斷優(yōu)先級(jí),來(lái)自文件SysInit.c

            voidNVIC_Configuration(void)
            {
            NVIC_InitTypeDefNVIC_InitStructure_EXTI_LINE;

            /* ================ NVIC-EXTI-PORTE ================= */
            /* Configure one bit for preemption priority */
            NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);// 配置優(yōu)先級(jí)分組長(zhǎng)度

            /* Enable the EXTI15_10 Interrupt */
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannel=EXTI4_IRQn;// 配置使能指定的IRQ(Interrupt ReQuest中斷請(qǐng)求)通道
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannelPreemptionPriority=0;// 配置IRQ的 組 優(yōu)先級(jí)
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannelSubPriority=0;// 配置IRQ的 從 優(yōu)先級(jí)
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannelCmd=ENABLE;// 配置IRQ 使能
            NVIC_Init(&NVIC_InitStructure_EXTI_LINE);// 初始化 IRQ

            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannel=EXTI3_IRQn;// 配置使能指定的IRQ(Interrupt ReQuest中斷請(qǐng)求)通道
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannelPreemptionPriority=0;// 配置IRQ的 組 優(yōu)先級(jí)
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannelSubPriority=0;// 配置IRQ的 從 優(yōu)先級(jí)
            NVIC_InitStructure_EXTI_LINE.NVIC_IRQChannelCmd=ENABLE;// 配置IRQ 使能
            NVIC_Init(&NVIC_InitStructure_EXTI_LINE);// 初始化 IRQ
            }

            第四步:編寫中斷服務(wù)程序,來(lái)自文件stm32f10x_it.c

            voidEXTI3_IRQHandler(void)
            {
            if(EXTI_GetITStatus(EXTI_Line3)==SET)// 讀取中斷狀態(tài)
            {
            LED1_LOW;
            EXTI_ClearITPendingBit(EXTI_Line3);// 清除標(biāo)志位
            }
            }
            voidEXTI4_IRQHandler(void)
            {
            if(EXTI_GetITStatus(EXTI_Line4)==SET)// 讀取中斷狀態(tài)
            {
            LED1_HIGH;
            EXTI_ClearITPendingBit(EXTI_Line4);// 清除標(biāo)志位
            }
            }


            下面就要說(shuō)說(shuō)在uCOSII里的時(shí)候了。

            首先把上面所述步驟1,步驟2和步驟4的代碼放到KEY.C文件內(nèi),然后把步驟3的代碼加入SysInit.C文件內(nèi)的 NVIC_Configuration()函數(shù)。步驟1,步驟2,和步驟3與沒(méi)有操作系統(tǒng)的代碼一致,都是最底層的東西。步驟4需要符合ucos的代碼規(guī)范,也要用到ucos的系統(tǒng)函數(shù),如下面代碼:

            /*******************************************************************************
            * Function Name : Interrupt_Handle_KEY2
            * Description : 按鍵2中斷服務(wù)函數(shù)
            * Input : None
            * Output : None
            * Return : None
            *******************************************************************************/
            voidInterrupt_Handle_KEY2(void)
            {
            OSIntEnter();
            OSSemPost(Sem_Task_LED2);// 發(fā)送信號(hào)量,這個(gè)函數(shù)并不會(huì)引起系統(tǒng)調(diào)度,所以中斷服務(wù)函數(shù)一定要簡(jiǎn)潔。
            EXTI_ClearITPendingBit(EXTI_Line4);// 清除標(biāo)志位
            OSIntExit();
            }


            如代碼所示黃色高亮部分就是進(jìn)入中斷和出中斷的ucos部分的代碼,在出中斷的時(shí)候會(huì)引起系統(tǒng)調(diào)度,然后最高優(yōu)先級(jí)的任務(wù)會(huì)先執(zhí)行,保證了系統(tǒng)的實(shí)時(shí)性。

            步驟1~3的代碼和上面類似就不一一列舉,系統(tǒng)運(yùn)行過(guò)程如下:

            首先系統(tǒng)建立一個(gè)起始任務(wù)START,這個(gè)任務(wù)的優(yōu)先級(jí)最低為10,他主要是做系統(tǒng)心跳的顯示,另外把其他需要的任務(wù)初始化。在例程里有另外兩個(gè)任務(wù),分別是KEY1任務(wù)(優(yōu)先級(jí)為9)和LED2任務(wù)(優(yōu)先級(jí)為5)。先初始化KEY1任務(wù),初始化函數(shù)結(jié)束后就跳到KEY1任務(wù)代碼處執(zhí)行,當(dāng)遇到OSTimeDlyHMSM()函數(shù)時(shí),會(huì)引發(fā)系統(tǒng)調(diào)度,此時(shí)就兩個(gè)任務(wù),所以肯定會(huì)回到起始任務(wù)START,然后初始化LED2任務(wù),初始化函數(shù)結(jié)束后就跳到LED2任務(wù)代碼處執(zhí)行,在這個(gè)任務(wù)中有等待信號(hào)量的函數(shù),所以系統(tǒng)會(huì)自己掛起任務(wù),系統(tǒng)再進(jìn)行調(diào)度的時(shí)候也會(huì)執(zhí)行這個(gè)掛起任務(wù)里的代碼。這時(shí)候如果按下按鍵,就會(huì)觸發(fā)中斷,在中斷函數(shù)里會(huì)有信號(hào)量發(fā)出來(lái),在結(jié)束中斷的時(shí)候會(huì)有系統(tǒng)調(diào)度,此時(shí)系統(tǒng)會(huì)跳到請(qǐng)求信號(hào)量的斷點(diǎn)處去執(zhí)行代碼,這一點(diǎn)體現(xiàn)了ucos的搶占性的特點(diǎn),就是中斷的優(yōu)先級(jí)都是凌駕與非中斷任務(wù)的,所以中斷里發(fā)出的信號(hào)量一定是要先相應(yīng)的。然后系統(tǒng)就會(huì)遵循優(yōu)先級(jí)高低進(jìn)行系統(tǒng)調(diào)度。

            在這個(gè)例程里還有一個(gè)新的知識(shí)點(diǎn)就是計(jì)數(shù)信號(hào)量的使用。

            使用時(shí)分為4個(gè)步驟:

            1. 定義信號(hào)量指針void*Sem_Task_LED2;
            2. 創(chuàng)建信號(hào)量 Sem_Task_LED2 = OSSemCreate(0); // 函數(shù)里參數(shù)是指信號(hào)量的初始值
            3. 設(shè)置等待信號(hào)量 OSSemPend(Sem_Task_LED2,0,&err);
            4. 設(shè)置發(fā)送信號(hào)量OSSemPost(Sem_Task_LED2);

            這里創(chuàng)建信號(hào)量和設(shè)置等待信號(hào)量都是在任務(wù)LED2里,設(shè)置發(fā)送信號(hào)量在中斷服務(wù)函數(shù)里。見(jiàn)代碼:

            /*******************************************************************************
            * Function Name : Task_LED2
            * Description : LED2任務(wù)
            * Input : None
            * Output : None
            * Return : None
            *******************************************************************************/
            voidTask_LED2(void*p_arg)
            {
            (void)p_arg;
            Sem_Task_LED2=OSSemCreate(0);
            while(1)
            {
            OSSemPend(Sem_Task_LED2,0,&err);// 等待信號(hào)量
            LED2_HIGH;
            OSTimeDlyHMSM(0,0,1,0);
            LED2_LOW;
            OSTimeDlyHMSM(0,0,1,0);// 延時(shí),用來(lái)給其他任務(wù)留有運(yùn)行的時(shí)間
            }
            }

            這里要說(shuō)一下注意點(diǎn),首先定義的信號(hào)量指針是一個(gè)全局變量,需要在相應(yīng)的頭文件里進(jìn)行extern聲明,在這里是把他放在task.c文件里的。另外創(chuàng)建信號(hào)量和設(shè)置等待信號(hào)量函數(shù)都放在具體的任務(wù)中,因?yàn)樵谶壿嬌?,?chuàng)建信號(hào)量和等待信號(hào)量函數(shù)肯定要早與發(fā)送信號(hào)量函數(shù)執(zhí)行,因此在設(shè)置等待信號(hào)量之前去創(chuàng)建信號(hào)量是完全合適的,并且把創(chuàng)建信號(hào)量函數(shù)放在具體任務(wù)的while(1)上面,在創(chuàng)建函數(shù)的時(shí)候信號(hào)量就已經(jīng)被創(chuàng)建了,然后代碼執(zhí)行到等待信號(hào)量的時(shí)候任務(wù)就會(huì)被掛起,除非時(shí)間到或者有信號(hào)量來(lái)的話才會(huì)被執(zhí)行。最后設(shè)置發(fā)送信號(hào)量,在這里發(fā)送信號(hào)量函數(shù)是放在中斷服務(wù)程序里的,因?yàn)榘l(fā)送信號(hào)量函數(shù)的執(zhí)行并不會(huì)引起系統(tǒng)調(diào)度,只有在中斷服務(wù)函數(shù)執(zhí)行完畢,出中斷函數(shù)的執(zhí)行才會(huì)引發(fā)系統(tǒng)調(diào)度,所以中斷服務(wù)函數(shù)里的內(nèi)容一定要精簡(jiǎn),否則就會(huì)影響系統(tǒng)的實(shí)時(shí)性。



            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉