新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM8輸入捕獲

        STM8輸入捕獲

        作者: 時間:2016-11-19 來源:網絡 收藏
        最近在用STM8的過程中需要用到一個頻率檢測的功能,還好STM8S207的定時器中自帶有輸入捕獲功能,之前還想著用定時器計數方式來實現的,但既然人家提供了該功能,那就試試吧,由于硬件里面接的是PC1引腳就只看了Timer1,其他的定時器應該也是類似的,看了資料之后發(fā)現STM8的輸入捕獲其實與STC12C5A60S2中的PCA捕獲模式很類似,但是看資料沒有后者清晰易懂。。。

        本文引用地址:http://www.104case.com/article/201611/318491.htm

        在捕獲模式中,基本上只用到了讀進程,在STM8中有一個影子寄存器,但對于我們來說是看不到的,我們僅操作預裝載寄存器即可。而且需要注意的是無論是計數器還是捕獲/比較寄存器都是先讀/寫高8位,后讀/寫低8位數據。

        在文檔中給出了一個輸入捕獲模式的流程


        按著這個流程來就可以完成我們的輸入捕獲

        文檔中首先提到將TIM1_CCMR1寄存器的CC1S位寫01,將端口配置為輸入,但在TIM1_CCMR1的寄存器中有說明CC1S位的更改需在通道關閉時(TIM1_CCER1寄存器的CC1E=0)才可寫入,

        因此在配置中先將TIM1_CCER1寄存器的CC1E位寫0,然后將TIM1_CCMR1的CC1S位寫01,

        TIM1_CCER1 &= (unsigned char)~0x01;//清零TIM1_CCER1中的CC1E位,之后才可配置TIM1_CCMR1TIM1_CCMR1 = 0x01;//配置TIM1_CCMR1中的CC1S位為1,CC1通道配置為輸入,IC1映射到TI1FP1上//無濾波器、無預分頻器(捕獲輸入口上檢測到的每一個邊沿都觸發(fā)一次捕獲)

        TIM1_CCMR1寄存器有兩種功能,分別對應捕獲模式和比較模式,只需要捕獲模式即可


        濾波器是用來避免頻率波動的直接寫0即可,無濾波器,分頻器我們也寫00不用分頻器,當然也可以使用分頻器,提高準確率。

        接著是設置觸發(fā)方式,我們選擇上升沿觸發(fā)


        TIM1_CCER1 &= (unsigned char)~0x02;//上升沿或者高電平觸發(fā)

        最后使能捕獲功能,設置TIM1_CCER1寄存器的CC1E位=1,由于我們采用中斷方式因此也將TIM1_IER寄存器的CC1IE位置1,允許中斷請求。

        完整的初始化代碼如下

        void signal_capture_Init(void){TIM1_CNTRH = 0x00;//清零計數器高8位TIM1_CNTRL = 0x00;//清零計數器低8位TIM1_PSCRH = 0x00;//計數器時鐘分頻高8位TIM1_PSCRL = 0x10;//計數器時鐘分頻低8位16分頻TIM1_CCER1 &= (unsigned char)~0x01;//清零TIM1_CCER1中的CC1E位,之后才可配置TIM1_CCMR1TIM1_CCMR1 = 0x01;//配置TIM1_CCMR1中的CC1S位為1,CC1通道配置為輸入,IC1映射到TI1FP1上//無濾波器、無預分頻器(捕獲輸入口上檢測到的每一個邊沿都觸發(fā)一次捕獲)TIM1_CCER1 &= (unsigned char)~0x02;//上升沿或者高電平觸發(fā)TIM1_IER |= 0x02;//CC1IE=1,使能捕獲/比較1中斷TIM1_CCER1 |= 0x01;//捕獲使能TIM1_CR1 |= 0x01;//使能定時/計數器}

        當發(fā)生一個輸入捕獲時,計數器的值被傳送到TIM1_CCR1寄存器中,計時器的時鐘源在程序中我們設置為16分頻


        分頻過后計數器的頻率為1MHz,這里采用分頻主要是避免計數器溢出,這樣同時也降低了精度,同時設置計數器的初值為0,計數器默認計數方式是向上計數,計到最大值后又從0開始計數,

        中斷處理代碼如下

        @far @interrupt void signal_capture_irq (void){if(TIM1_SR1&0x02){TIM1_SR1 &= (unsigned char)~0x02;//清除CC1IF標志if(vsync_cap_data_old == 0x00){//第一次捕獲中斷來臨vsync_cap_data_old = TIM1_CCR1H;//先讀取高8位數據vsync_cap_data_old = (unsigned int)(vsync_cap_data_old<<8) + TIM1_CCR1L;//再讀取低8位數據}else{//第二次捕獲中斷來臨vsync_cap_data_new = TIM1_CCR1H;//先讀取高8位數據vsync_cap_data_new = (unsigned int)(vsync_cap_data_new<<8) + TIM1_CCR1L;//再讀取低8位數據TIM1_IER &= (unsigned char)~0x02;//禁止通道1捕獲/比較中斷TIM1_CR1 &= (unsigned char)~0x01;//停止計數器if(vsync_cap_data_new > vsync_cap_data_old)vsync_period = (vsync_cap_data_new - vsync_cap_data_old);elsevsync_period = 0xFFFF + vsync_cap_data_new - vsync_cap_data_old;vsync_cap_data_old = 0x00;isCaptureOver = 1;}}}

        我們捕獲兩次中斷計算時間差,

        if(isCaptureOver){//如果捕獲完成則對數據進行處理cmd_puts("period:");cmd_hex((unsigned char)(vsync_period>>8));cmd_hex((unsigned char)vsync_period);TIM1_CNTRH = 0x00;//清零計數器高8位TIM1_CNTRL = 0x00;//清零計數器低8位TIM1_IER |= 0x02;//CC1IE=1,使能捕獲/比較1中斷TIM1_CR1 |= 0x01;//使能定時/計數器isCaptureOver = 0;}
        這里只從串口輸出了周期,結果如下


        可以看到周期在一個范圍內波動我們取一個值0x79ED來計算,它所對應的頻率f=1000000/0x79ED=32.0379Hz還是比較接近我們的實際輸入頻率30Hz,誤差是大了些,可以通過代碼繼續(xù)改進



        關鍵詞: STM8輸入捕

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 云浮市| 通榆县| 哈巴河县| 班戈县| 岳普湖县| 平昌县| 徐州市| 武义县| 平乡县| 泰来县| 保康县| 白玉县| 正定县| 安化县| 大新县| 丹巴县| 迭部县| 德昌县| 灌阳县| 宁乡县| 汕尾市| 进贤县| 晋中市| 大名县| 乌鲁木齐县| 阿勒泰市| 丹寨县| 永仁县| 高邮市| 且末县| 乌什县| 贡嘎县| 遂昌县| 长顺县| 阿鲁科尔沁旗| 彩票| 冷水江市| 八宿县| 绥化市| 许昌县| 霍州市|