<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 牛人業(yè)話 > 關(guān)于STM8S ADC腳與其它功能復(fù)用時的問題

          關(guān)于STM8S ADC腳與其它功能復(fù)用時的問題

          作者: 時間:2016-09-21 來源:網(wǎng)絡(luò) 收藏

            之前寫過一篇關(guān)于芯片GPIO腳復(fù)用AD功能后無法回到GPIO狀態(tài)的小文,介紹芯片的應(yīng)用時相關(guān)施密特觸發(fā)器未適時開關(guān)而導(dǎo)致的問題。

          本文引用地址:http://www.ex-cimer.com/article/201609/310076.htm

            大致內(nèi)容就是某一GPIO口被復(fù)用為AD輸入腳做相關(guān)AD檢測。之后,把該腳AD功能禁用掉,再配置切換為帶下降沿觸發(fā)的外部中斷觸發(fā)腳,讓其作為芯片休眠喚醒腳。

            奇怪的是,那樣設(shè)置后根本沒法喚醒。即使不做休眠,做好切換配置后,直接查看該腳的IDR位的電平,不管外部輸入如何,發(fā)現(xiàn)對應(yīng)IDR位始終提示為0.

            后來找到原因是跟那個施密特觸發(fā)器的配置有關(guān)??赡苡腥擞X得該問題是鉆牛角尖,其實,也不盡然。畢竟應(yīng)用需求是五花八門的,遇到的問題往往也是五彩繽紛,問題不論大小折磨起人來也是不分男女老少的。

            這里再次分享個類似話題 ,希望能讓見到本文的人有所啟示。工程師反饋基本情況如下:

            使用芯片開發(fā)。因為TIM1/2都用做PWM了,所以用TIM4來做基本定時。TIM4正常中斷,UART1串口發(fā)送正常,就是串口接收中斷進不去。但只要把 TIM4_initialzation();屏蔽掉,串口馬上正常中斷接收,一旦打開TIM4,串口就接收不了,其它功能都正常。

            上面是該工程師對癥狀的基本描述和初步判斷?!井?dāng)然,調(diào)試遇到麻煩時候的判斷難免有偏差,偏差大小因人因景不同,有時甚至完全誤判。】

            下面是他的主循環(huán)代碼【為了排版和閱讀,做了些刪減】。

            int main( void )

            {

            CLK_DeInit(); //寄存器復(fù)位

            CLK_HSICmd(ENABLE); //內(nèi)部高速時鐘使能

            CLK_HSIPrescalerConfig( ); //分頻

            GPIO_initialzation();

            uart_initialzation();

            PWM1_initialzation();

            PWM2_initialzation();

            TIM4_initialzation(); //TIM4初始化

            enableInterrupts();//* 開啟總中斷 */

            Ts_cnt = 1000;

            Ls_cnt = 500;

            while(1)

            {

            PLED_flash(499); //LED 閃爍

            relay_control(); //繼電器控制

            CCT_calculate();//獲取相關(guān)AD值

            send_information();//輸出提示信息

            if(Flag_rec)

            {

            。。。。。?!韭浴?/p>

            }

            }

            }

            現(xiàn)在的情況是當(dāng)注釋掉上面的 TIM4_initialzation();語句后,UART-RX接收中斷就正常。

            TIM4只是做基本時鐘,不涉及外面其它硬件,最大可能是二者中斷優(yōu)先級有沖突導(dǎo)致UART-RX的正常接收。但當(dāng)把UART-RX中斷優(yōu)先級調(diào)高于TIM4的更新中斷時問題并無好轉(zhuǎn)。

            但事實又的確顯示出TIM4的中斷跟UART-RX接收有關(guān)系。

            TIM4、UART1初始化代碼只是些各種相關(guān)基本配置,不跟別的外設(shè)有關(guān)聯(lián)。不妨看看TIM4、UART1中斷服務(wù)程序里能否找到些蛛絲馬跡。

            INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler,23)

            {

            TIM4_ClearITPendingBit(TIM4_IT_UPDATE);

            ms_cnt++;//LED FLASH

            Ts_cnt++; //AD sample

            Ls_cnt++; //relay control

            uart_cnt++;//send information

            PWM2_duty_setting(Ts_cnt);

            pwm1_correct_cnt++;

            if(pwm1_correct_cnt > 100)

            {

            pwm1_correct_cnt = 0;

            if(pwm1_cnt > CCT_target)

            pwm1_cnt--;

            else

            pwm1_cnt++;

            PWM1_duty_setting(pwm1_cnt);

            }

            }

            INTERRUPT_HANDLER(UART1_RX_IRQHandler,18)

            {

            static uint8_t index = 0;

            UART1_ClearITPendingBit(UART1_IT_RXNE);

            recived_data[index] = UART1_ReceiveData8(); //讀數(shù)據(jù)

            if(recived_data[0] == 0x41)

            {

            index++;

            if((index > 7)&&(recived_data[7] == 0x0d))

            {

            index = 0;

            Flag_rec = 1;

            }

            }

            else

            {

            index = 0;

            recived_data[0] = 0;

            }

            }

            從TIM4的中斷服務(wù)程序里出現(xiàn)了好幾個全局變量,看看這些全局變量哪些函數(shù)會用到。因為TIM4的主要功能就是計數(shù)定時,下面幾個計時變量肯定是給別人用的。

            ms_cnt++;//LED FLASH

            Ts_cnt++; //AD sample

            Ls_cnt++; //relay control

            uart_cnt++;//send information

            問題到這里,繼續(xù)往下查就需要耐心了??蛻舸a不復(fù)雜,用到的外設(shè)模塊也不多,主循環(huán)里也就下面幾個函數(shù),一個個函數(shù)模塊進行排查。

            PLED_flash(499); //LED閃爍

            relay_control(); //繼電器控制

            CCT_calculate();//做AD轉(zhuǎn)換

            send_information();//輸出提示信息

            后來發(fā)現(xiàn)TIM4保持工作的同時屏蔽CCT_calculate();,UART-RX能正常接收??磥鞹IM4并非是影響UART接收的元兇。不過CCT_calculate()的運行還是跟TIM4中斷有關(guān),有個變量TS_CNT是在TIM4中斷里進行累加的。

            看看下面CCT_calculate()的代碼,里面有個條件判斷,即if(Ts_cnt > 1000)的判斷。

            voidCCT_calculate(void)

            {

            if(Ts_cnt> 1000)

            {

            Ts_cnt = 0;

            T_ad = Get_CH_Value(Ts_channel);

            T_degree = cal_temp(T_ad)-11;

            。。。。。

            }

            }

            如果TIM4被屏蔽不工作,TS_CNT就不會得到累加而大于1000然后往下執(zhí)行Get_CH_Value();函數(shù)。該Get_ADCCH_Value();函數(shù)對ADC做初始化之后執(zhí)行AD轉(zhuǎn)換并獲取相關(guān)AD值。

            正是在ADC初始化代碼里有對相關(guān)ADC通道對應(yīng)腳的施密特觸發(fā)器做了禁用配置。而且該ADC通道腳跟UART-RX腳又是復(fù)用的,麻煩就此產(chǎn)生了。

            

           

            在STM8MCU的GPIO 的各IO模塊里有個施密特觸發(fā)器,通過寄存器ADC_TDR控制其開和關(guān)。默認(rèn)情況下是打開的,IO腳的信號可以自由通過它進到輸入寄存器或其它外設(shè)模塊。

            如果某管腳做AD模擬輸入時,建議通過ADC_TDR將相應(yīng)的施密特觸發(fā)器關(guān)閉,目的是為了降低GPIO的功耗。如下圖所示,當(dāng)施密特觸發(fā)器被關(guān)閉后,不管外部引腳電平如何變化,它的輸出恒定為0。

            

           

            結(jié)合到本案例中的問題,因為他在AD轉(zhuǎn)換函數(shù)中初始化AD時關(guān)閉了該施密特觸發(fā)器,該腳又復(fù)用為UART-RX,此時RX信號根本進不到UART接收模塊中,不能產(chǎn)生UART接收中斷也就自然而然了。

            后來當(dāng)它打開施密特觸發(fā)器后,URAT-RX接收也就正常了。

            顯然,客戶最先認(rèn)為的TIM4影響UART-RX是個錯覺。因為它是每隔一定時間才去做AD轉(zhuǎn)換,同時做些AD初始化配置。如果TIM4關(guān)閉了,相應(yīng)的時間條件不成立也就不去做AD轉(zhuǎn)換,也就不會禁用施密特觸發(fā)器,進而就不會發(fā)生UART-RX失敗的情況。



          關(guān)鍵詞: STM8S ADC

          評論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();