蔡逢煌, 王 武
(福州大學(xué) 電氣工程與自動(dòng)化學(xué)院, 福建 福州 350116)
我院在“單片機(jī)原理與應(yīng)用”這門課程的教學(xué)上逐步形成了具有自己特點(diǎn)的教學(xué)模式,我們把該課程的教學(xué)分成七大模塊:GPIO模塊、中斷模塊、定時(shí)器模塊、PWM 模塊、捕獲模塊、AD模塊和通信模塊,把各個(gè)模塊之間通過(guò)案例聯(lián)系起來(lái),使各個(gè)模塊的教學(xué)即相對(duì)獨(dú)立又前后聯(lián)系。
其中,定時(shí)器模塊、捕獲模塊、PWM模塊都是與時(shí)間有關(guān)系的,其處理本質(zhì)上都是通過(guò)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的。定時(shí)器是通過(guò)計(jì)數(shù)來(lái)實(shí)現(xiàn)計(jì)時(shí)的;PWM模塊在計(jì)數(shù)的基礎(chǔ)上,實(shí)現(xiàn)特定時(shí)刻對(duì)引腳輸出狀態(tài)的控制;捕獲模塊則是把引腳輸出狀態(tài)改變的那個(gè)時(shí)刻對(duì)應(yīng)的計(jì)數(shù)值記錄下來(lái)。
在先前的教學(xué)中,這三個(gè)模塊是相對(duì)獨(dú)立講授的,沒(méi)有把它們之間的內(nèi)在聯(lián)系介紹給學(xué)生。因此,學(xué)生學(xué)完后,只懂得單個(gè)模塊的應(yīng)用。由于沒(méi)有實(shí)際工程經(jīng)驗(yàn),不懂得如何把它們聯(lián)系起來(lái)應(yīng)用。在新教學(xué)安排上,我們采用循序漸進(jìn)的方法,結(jié)合案例引入解決了這一問(wèn)題。首先學(xué)習(xí)定時(shí)器模塊,然后學(xué)習(xí)PWM模塊,最后學(xué)習(xí)捕獲模塊。在教學(xué)案例的設(shè)計(jì)上特別關(guān)注這些模塊之間的內(nèi)在聯(lián)系,逐漸深入,最后接近于工程實(shí)際。
教學(xué)案例的設(shè)計(jì)是依托硬件平臺(tái)實(shí)現(xiàn)的。硬件平臺(tái)采用價(jià)格低廉、攜帶方便和功能強(qiáng)大的“ 口袋實(shí)驗(yàn)室”,也就是TI公司的C2000 Piccolo TMS320F28027 LaunchPad最小系統(tǒng)板。該板通過(guò)USB接口與電腦連接,利用CCS軟件開(kāi)發(fā)平臺(tái)進(jìn)行程序的編寫(xiě)、調(diào)試和燒寫(xiě)。“口袋實(shí)驗(yàn)室”使學(xué)生能超越課堂的空間和時(shí)間的限制,完成應(yīng)用程序的設(shè)計(jì)和理論算法的實(shí)踐,從而減輕了學(xué)生與教師的壓力[1-3]。
該板上有1個(gè)按鍵和4個(gè)LED燈。案例的設(shè)計(jì)是基于按鍵和LED以及編制程序?qū)崿F(xiàn)的。程序代碼要求可移植,也就是后面的案例可以在前面案例的基礎(chǔ)上完成,代碼有繼承性。
通過(guò)這幾年的教學(xué)實(shí)踐,我們?cè)O(shè)計(jì)和這些模塊相關(guān)的案例如下。
設(shè)計(jì)一個(gè)按鍵控制顯示模式的工程案例,要求:
(1) 按鍵有:短按、長(zhǎng)按、雙擊三種功能;
(2) 顯示模式:跑馬燈顯示;顯示間隔時(shí)間由定時(shí)器計(jì)量。
(3) 按鍵控制功能:短按減少跑馬燈的顯示間隔時(shí)間;長(zhǎng)按增加跑馬燈的顯示間隔時(shí)間;雙擊恢復(fù)跑馬燈的顯示間隔時(shí)間為初始時(shí)間。
(1) 按鍵有:短按、長(zhǎng)按、雙擊三種種功能(可直接移植定時(shí)器案例的按鍵處理程序);
(2) 顯示模式:跑馬燈模式或者呼吸燈模式。呼吸燈模式是利用PWM控制LED的顯示亮度,從暗逐漸到亮。全亮后再逐漸變暗,全暗后,重復(fù)進(jìn)行。跑馬燈模式繼承1.1的案例。
(3) 按鍵控制功能:短按減少顯示間隔的周期;長(zhǎng)按增加顯示間隔的周期;雙擊進(jìn)行顯示模式的切換。
(1) 繼承之前案例的按鍵處理功能和呼吸燈顯示功能。
(2) 顯示模式:雙擊進(jìn)行顯示切換----呼吸燈模式和捕獲值顯示模式。
(3) 呼吸燈模式------LED1慢慢亮,到最亮的時(shí)候保持住,然后LED2開(kāi)始慢慢變亮,到最亮的時(shí)候保持住,依次四個(gè)LED燈完全亮,保持一秒鐘,LED4慢慢暗,到熄滅后,LED3開(kāi)始慢慢變暗,依次四個(gè)LED燈完全暗。熄滅一秒鐘,再重復(fù)。(可移植案例1.2的呼吸燈顯示代碼進(jìn)行修改)。
(4) 按捕獲值控制LED顯示亮度--------對(duì)PWM輸出進(jìn)行捕獲(把PWM3A引腳接到捕獲口),根據(jù)捕獲的占空比值控制LED顯示亮度。
0--25%: LED1(由PWM1A控制)亮度根據(jù)占空比按比例調(diào)節(jié);
25%--50%: LED1全亮、LED2(由PWM1B控制)亮度根據(jù)占空比(0-25%)按比例調(diào)節(jié);
50%--75%: LED1、LED2全亮, LED3(由PWM2A控制)亮度根據(jù)占空比(0-25%)按比例調(diào)節(jié);
75%--100%: LED1、LED2、 LED3全亮,LED4(由PWM2B控制)亮度根據(jù)占空比(0-25%)按比例調(diào)節(jié);
(5) 按鍵控制功能:短按-----PWM3A輸出占空比減小;長(zhǎng)按-----PWM3A輸出占空比增大;雙擊-----切換顯示模式。
1.1節(jié)的定時(shí)器案例涉及到“單片機(jī)原理與應(yīng)用”課程GPIO模塊、定時(shí)器模塊、中斷模塊的應(yīng)用。寄存器的操作調(diào)用TI提供的底層驅(qū)動(dòng)庫(kù)函數(shù)。部分代碼如下:
/*定時(shí)器中斷周期1ms*/
interrupt void myTimer_CpuTimer0_isr(void)
{
msecond_key_counter++; //按鍵識(shí)別用
display_delay++; //跑馬燈顯示間隔時(shí)間
PIE_clearInt(myPie, PIE_GroupNumber_1);
//中斷應(yīng)答標(biāo)志位清零
}
說(shuō)明:定時(shí)器模塊提供授時(shí)服務(wù)。通過(guò)相關(guān)變量把時(shí)間傳遞給按鍵識(shí)別模塊和跑馬燈控制模塊。
學(xué)生在這部分容易出現(xiàn)的問(wèn)題:在定時(shí)器函數(shù)里面實(shí)現(xiàn)按鍵識(shí)別和跑馬燈控制,程序功能沒(méi)有按模塊化編程,各個(gè)功能融合一起時(shí),程序可讀性差,可移植性差。
/*跑馬燈程序*/
void LED_Display(void)
{
if(display_delay > time_display_delay)
//time_display_delay為按鍵更改的時(shí)間延時(shí)
{
LED_off(LED[LED_Count]); //熄滅當(dāng)前LED
LED_Count++; //指向下一個(gè)LED
if(LED_Count >=4) LED_Count=0;
LED_on(LED[LED_Count]); //LED點(diǎn)亮
PIE_clearInt(myPie, PIE_GroupNumber_1);
//中斷應(yīng)答標(biāo)志位清零
}
}
按鍵對(duì)應(yīng)的IO口為外部中斷的輸入源。按鍵按下為高電平,按鍵放開(kāi)為低電平。上升沿和下降沿都可以觸發(fā)外部中斷。一個(gè)按鍵要識(shí)別成三個(gè)不同的功能:短按、長(zhǎng)按、雙擊。按鍵的算法思路為:上升沿中斷時(shí)判斷是否雙擊,并清零相關(guān)時(shí)間變量。下降沿時(shí)判斷長(zhǎng)按、短按。
學(xué)生在這部分功能實(shí)現(xiàn)上存在困難,主要是對(duì)算法的分析能力比較薄弱。特別是對(duì)雙擊的處理。程序編制方式雖然多樣,但是總體上不夠優(yōu)化。
/*按鍵中斷程序*/
interrupt void KEY_XINT1_isr3(void)
{
if(msecond_key_counter < 10) //兩次進(jìn)入中斷的時(shí)間小于10ms,判斷為抖動(dòng)
{
PIE_clearInt(myPie, PIE_GroupNumber_1);
return; //為按鍵抖動(dòng),退出中斷
}
//上升沿
if(KEYPRESSED == GetKeyStatus(KEY1))
{
if(msecond_key_counter <250) //距上次按鍵放開(kāi)時(shí)間小于250ms,判斷為雙擊 {
Flag_KEY_PRESS_TWICE = 1; //雙擊標(biāo)志位,等待按鍵釋放后再處理 }
else key_status = 0;
msecond_key_counter = 0; //清計(jì)時(shí)
}
//下降沿時(shí)對(duì)應(yīng)按鍵放開(kāi),進(jìn)行按鍵動(dòng)作的確認(rèn)
else if(KEYPRESSED != getKeyStatus(KEY1))
{
if(Flag_KEY_PRESS_TWICE == 1)
{
key_status = KEY_PRESS_TWICE; //雙擊
Flag_KEY_PRESS_TWICE = 0;
}
else if(msecond_key_counter > 350)
{
key_status = KEY_PRESS_LONG; //長(zhǎng)按
}
else if(msecond_key_counter > 100)
{
key_status = KEY_PRESS_SHORT; //短按
}
msecond_key_counter = 0; //清計(jì)時(shí)
}
PIE_clearInt(myPie, PIE_GroupNumber_1);
}
/*按鍵短按、長(zhǎng)按、雙擊處理*/
void KEY_MODE(void)
{
if(msecond_key_counter > 500)
{ switch(key_status)
{
case 1: time_dispaly_delay=time_dispaly_delay-200;
// 案例1
// mypwm_period = mypwm_period - 200; //案例2
// myCmp3A=myCmp3A-3000; //案例3
key_status = KEY_PRESS_NO;
break;
case 2: time_dispaly_delay=time_dispaly_delay+200;
// 案例1
// mypwm_period = mypwm_period + 200; //案例2
// myCmp3A=myCmp3A+3000; //案例3
key_status = KEY_PRESS_NO;
break;
case 3:
// time_dispaly_delay = TIME_INITIAL;
// 恢復(fù)初始值
display_mode=!display_mode; //顯示模式切換
key_status = KEY_PRESS_NO;
break;
default: break;
}
}
}
三個(gè)案例的按鍵程序基本一樣,可以直接進(jìn)行移植,在按鍵處理程序里面針對(duì)功能的不同可做部分修改。
學(xué)生容易出現(xiàn)的問(wèn)題是:程序沒(méi)有按模塊化編程,各個(gè)模塊的程序代碼嵌套在一起,可移植性差。
/*pwm中斷函數(shù)*/
interrupt void LED_EPWM3_isr(void)
{
PWM_huxideng1(); //呼吸燈改變占空比
PWM_capture(); //捕獲反饋模式改變占空比
if(pwm_mode == 0) //呼吸燈顯示模式
{
PWM_setCmpA(myPwm1,myCmp1A_huxi);
PWM_setCmpB(myPwm1,myCmp1B_huxi);
PWM_setCmpA(myPwm2,myCmp2A_huxi);
PWM_setCmpB(myPwm2,myCmp2B_huxi);
}
if(pwm_mode == 1) //捕獲顯示模式
{
PWM_setCmpA(myPwm1,myCmp1A_cap);
PWM_setCmpB(myPwm1,myCmp1B_cap);
PWM_setCmpA(myPwm2,myCmp2A_cap);
PWM_setCmpB(myPwm2,myCmp2B_cap);
}
PWM_setCmpA(myPwm3,myCmp3A);
//PWM3A輸出
PWM_clearIntFlag(myPwm3); //清中斷標(biāo)志位
PIE_clearInt(myPie, PIE_GroupNumber_3);
}
PWM_huxideng1()函數(shù)對(duì)應(yīng)呼吸燈模式改變占空比,PWM_capture()函數(shù)對(duì)捕獲反饋模式改變占空比,兩種方式相對(duì)獨(dú)立運(yùn)行, 按鍵切換顯示方式。當(dāng)一種顯示模式工作時(shí),另一種仍然在后臺(tái)運(yùn)行。
學(xué)生容易產(chǎn)生的問(wèn)題是:兩種顯示模式互相影響,即當(dāng)一種模式運(yùn)行時(shí),另一種就停止運(yùn)行。這些問(wèn)題都是對(duì)軟件的模塊化思想不熟悉導(dǎo)致的。
由于篇幅限制,對(duì)其他軟件代碼感興趣者可以跟筆者聯(lián)系獲得。
從以上的案例設(shè)計(jì)來(lái)看,由于前后模塊有繼承性,通過(guò)這種訓(xùn)練培養(yǎng)學(xué)生對(duì)軟件工程的模塊化思維。從近三年的教學(xué)效果來(lái)看,學(xué)生在學(xué)完這些模塊后,對(duì)知識(shí)的理解和接受程度上出現(xiàn)明顯的分化,有的學(xué)生邏輯思維能力和編程能力比較強(qiáng),能順利地完成課堂布置的作業(yè)(根據(jù)統(tǒng)計(jì),這部分學(xué)生只占10%左右);其他的大部分學(xué)生,完成相關(guān)的課堂作業(yè)有困難,主要體現(xiàn)在:①對(duì)模塊的工作原理較難理解;②對(duì)模塊大概理解了,但是不知道怎么轉(zhuǎn)換為程序代碼;③對(duì)模塊理解了,也能轉(zhuǎn)換為程序代碼,但是如何完成工程實(shí)現(xiàn)存在困難;④可以完成功能實(shí)現(xiàn),但是整個(gè)程序結(jié)構(gòu)混亂,程序可讀性差。
導(dǎo)致產(chǎn)生這些問(wèn)題的原因是:①基礎(chǔ)比較薄弱,“電路”和“數(shù)字電子技術(shù)”課程的知識(shí)點(diǎn)沒(méi)掌握好;②計(jì)算機(jī)的相關(guān)概念沒(méi)有理解,對(duì)軟件控制硬件的原理理解不清楚;還有C語(yǔ)言的基礎(chǔ)較薄弱;③對(duì)模塊之間的聯(lián)系缺乏整體概念,不善于從系統(tǒng)的層面來(lái)分析問(wèn)題;④缺少軟件工程的思維,程序的結(jié)構(gòu)化、標(biāo)準(zhǔn)化理解不透徹,軟件代碼質(zhì)量低。
針對(duì)上述存在的問(wèn)題,在后續(xù)的教學(xué)過(guò)程中,我們打算努力做到:學(xué)生首先獨(dú)立完成案例,然后教師對(duì)每個(gè)學(xué)生的軟件進(jìn)行檢測(cè),針對(duì)學(xué)生學(xué)習(xí)過(guò)程中存在的典型問(wèn)題進(jìn)行分析講解,然后學(xué)生對(duì)自己編寫(xiě)的程序再次進(jìn)行改進(jìn),逐步完善,達(dá)到程序的標(biāo)準(zhǔn)化和規(guī)范化。
定時(shí)器模塊、PWM模塊、捕獲模塊是單片機(jī)的重要組成部分,它們都與時(shí)間有關(guān)。通過(guò)案例的設(shè)計(jì),既讓學(xué)生懂得單個(gè)模塊的使用,更懂得如何綜合應(yīng)用各個(gè)模塊完成一項(xiàng)工程,滿足軟件的模塊化、規(guī)范化和可移植性。實(shí)踐證明,引入工程案例和任務(wù)驅(qū)動(dòng)法開(kāi)展課堂和實(shí)驗(yàn)實(shí)踐教學(xué),能激發(fā)學(xué)生學(xué)習(xí)興趣,培養(yǎng)學(xué)生工程素養(yǎng)。
[1] 張江印.高校單片機(jī)教學(xué)模式的研究[J].上海:實(shí)驗(yàn)室研究與探索,2011,30(9):103-106.(蔡逢煌等文)
[2] 蔡逢煌,王武. 嵌入式類課程教學(xué)的思考和實(shí)踐[J],南京:電氣電子教學(xué)學(xué)報(bào),2015,37(1):24-25.
[3] 曹靜,江世明.模塊化單片機(jī)實(shí)驗(yàn)平臺(tái)的設(shè)計(jì)[J].邵陽(yáng):邵陽(yáng)學(xué)院學(xué)報(bào)(自然科學(xué)版),2011,08(3):23-25.