新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32單片機學習---PWM輸出

        STM32單片機學習---PWM輸出

        作者: 時間:2016-11-27 來源:網絡 收藏
        上午花了半天時間熟悉了stm32的PWM模塊。中午利用午飯時間把PWM功能調試成功。當然,很簡單的東西,也許很多前輩估計都不屑一顧的東西。

        今天最大的感嘆就是網絡資源實在是個巨大的寶庫,真的很慶幸,在這個復雜的社會環境里,在一個到處充斥著私心、私利的時代,各個網站,各個論壇上的眾多網友都時刻保持著開源的氛圍。學習一定要和他人交流,而網絡提供了這么一個極好的平臺。

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

        廢話少說,言歸正傳。

        實現功能:采用定時器2的通道2,使PA1輸出頻率1K,占空比40的PWM波形,用PA8隨意延時取反led燈,指示程序運行。

        首先熟悉一下定時器的PWM相關部分。看圖最明白

        其實PWM就是定時器的一個比較功能而已。

        CNT里的值不斷++,一旦加到與CCRX寄存器值相等,那么就產生相應的動作。這點和AVR單片機很類似。既然這樣,我們要產生需要的PWM信號,就需要設定PWM的頻率和PWM的占空比。

        首先說頻率的確定。由于通用定時器的時鐘來源是PCLK1,而我又喜歡用固件庫的默認設置,那么定時器的時鐘頻率就這樣來確定了,如下:

        AHB(72MHz)→APB1分頻器(默認2)→APB1時鐘信號(36MHz)→倍頻器(*2倍)→通用定時器時鐘信號(72MHz)。

        這里為什么是這樣,在RCC模塊學習記錄里有詳細記載,不多說。

        因此圖中的CK_PSC就是72MHz了。

        下面的資料也是網上一搜一大把,我就羅列了:

        STM32的PWM輸出有兩種模式,模式1(PWM1)和模式2(PWM2),由TIMx_CCMRx寄存器中的OCxM位確定的(“110”為模式1,“111”為模式2)。模式1和模式2的區別如下:

        110:PWM模式1-在向上計數時,一旦TIMx_CNT=TIMx_CCR1時通道1為無效電平(OC1REF=0),否則為有效電平(OC1REF=1)。

        111:PWM模式2-在向上計數時,一旦TIMx_CNT=TIMx_CCR1時通道1為有效電平,否則為無效電平。

        由此看來,模式1和模式2正好互補,互為相反,所以在運用起來差別也并不太大。我用的是模式一,因此后面的設定都是按照模式一來設定的。

        PWM的周期是就是由定時器的自動重裝值和CNT計數頻率決定的。而CNT的計數時鐘是CK_PSC經分頻器PSC得到,因此CNT的時鐘就是CK_PSC/分頻系數。這個分頻系數在TIM_TimeBaseStructure.TIM_Prescaler確定。我設置的值是72,因此CNT的計數頻率也就是CK_CNT的頻率為1MHz。

        下一步就是確定定時器自動重裝值。因為CNT每自加到ARR寄存器的值時就會自動清零,當然前提是設定為為向上計數模式,而就是根據這個溢出事件來改變PWM的周期。所以PWM信號的頻率由ARR的值來確定。我設置的值是1000-1,即TIM_TimeBaseStructure.TIM_Period = 1000-1;因此PWM的周期是1MHz/1000=1KHz。

        接下來就要確定PWM的占空比了。因為CNT在自加到ARR值的過程中會不斷和CRRX的值相比較,一旦二者相等就產生匹配事件,但要注意CNT不會理會這件事,它會繼續++直到等于ARR。而CRRX的值我設定為400-1,那么占空比就隨之確定為40%。

        好了,下面就是庫函數的配置了。

        TIMER輸出PWM實現步驟

        1.設置RCC時鐘;

        2.設置GPIO;

        3.設置TIMx定時器的相關寄存器;

        4.設置TIMx定時器的PWM相關寄存器。

        首先是main函數和全局變量申明,很簡單,不作說明


        GPIO_InitTypeDef GPIO_InitStructure;

        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

        TIM_OCInitTypeDef TimOCInitStructure;

        int main(void)
        {

        rcc_cfg();
        gpio_cfg();
        tim2_cfg();
        pwm_cfg();
        //
        while (1)
        {

        GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);

        delay();


        GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);

        delay();
        }
        }

        下面是IO口的配置:

        void gpio_cfg()
        {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        }

        此處要注意的是PWM輸出口要配置為復用推挽輸出,原因我也不知道,反正照搬就是了。


        上一頁 1 2 下一頁

        關鍵詞: STM32單片機PWM輸

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 姚安县| 武山县| 克什克腾旗| 芜湖市| 峨山| 牡丹江市| 通海县| 静乐县| 丹棱县| 栖霞市| 昌宁县| 宁海县| 资兴市| 桃江县| 阿拉尔市| 临武县| 新密市| 美姑县| 和静县| 剑川县| 商河县| 洛宁县| 安新县| 靖边县| 贺州市| 云霄县| 邯郸市| 施秉县| 瑞安市| 綦江县| 喀喇沁旗| 那坡县| 文水县| 雷波县| 阿巴嘎旗| 大名县| 邳州市| 古田县| 蓬溪县| 炉霍县| 墨玉县|