TI MPS430 FR2311 - PWM

更新 發佈閱讀 10 分鐘
raw-image

---------------------------------------------------

IDE: TI CCS 20.3.0

--------------------------------------------------

PWM訊號用途蠻廣的 例如 調光 馬達控制

下面程式提供
一個標準的PWM功能(P2.0) 使用500Hz
跟一個用GPIO模擬PWM的功能(P1.0) 使用1.5kHz

主要是PWM功能要使用Timer
同一條Timer 需要一樣的頻率
若Timer與腳位對不起來
就可能要改慮使用GPIO加軟體的方式
去模擬PWM訊號

當然若是夠用就不要用模擬的


#include <msp430.h>
#include <stdint.h>

//Define++++++++++++++++++++++++++++++++++

//PWM Part
#define SMCLK_HZ   1000000UL
#define PWM_FREQ   1450UL    //1.5kHz
#define PERIOD_TCK (SMCLK_HZ / PWM_FREQ)
#define PWM_BIT    BIT0

//變數++++++++++++++++++++++++++++++++++
uint8_t i = 0;

//PWM Part 變數-----------------------------------------------------------------
//unsigned long MianFreq1=750;//1KHz
//unsigned long MianFreq1=1500;//700Hz
//unsigned long MianFreq1=1900;//550Hz
unsigned long MianFreq1=2100;//500Hz  P2.0用


static volatile uint16_t duty_ticks_p10 = PERIOD_TCK/2;  // P1.0用


//函式++++++++++++++++++++++++++++++++++
//延遲函式

void delay_ms(uint16_t ms)
{
    while (ms--) __delay_cycles(1000);   // 假設 1 MHz 時鐘
}


//PWMPart----------------------------------------------------------------------
// ===== PWM 初始化(P2.0)=====
void pwm_p20_init(void)
{
    // 設定 P2.0 為 Timer 輸出 (PWM)
    P2DIR  |= BIT0;       // 設置 P2.0 為輸出
    P2SEL0 |= BIT0;       // 選擇 P2.0 的 Timer 功能

    //P2.0
    // 設置 Timer_B1 以產生 PWM,並配置 CCR1
    TB1CCR0 = MianFreq1;
    // P2.0 使用 TB1.1 (CCR1) 輸出 PWM
    TB1CCTL1 = OUTMOD_7;  // 設定 CCR1 為 Reset/Set 模式
    //TB1CCR1 = 100;              

    TB1CTL = TBSSEL__SMCLK | MC__UP | TBCLR; // 使用 SMCLK,Up 模式運行,清除計數器
}



// ===== PWM 初始化(P1.0 軟體 PWM)=====
void pwm_p10_init(void)
{
    P1DIR  |= PWM_BIT;
    P1OUT  &= ~PWM_BIT;

    TB0CTL   = TBSSEL__SMCLK | MC__UP | TBCLR;
    TB0CCR0  = PERIOD_TCK - 1;
    TB0CCTL0 = CCIE;          // CCR0 中斷:週期開始
    TB0CCR1  = duty_ticks_p10;
    TB0CCTL1 = CCIE;          // CCR1 中斷:duty 結束

}



void pwm_init(void)
{
    pwm_p10_init();//1.5K Hz
    pwm_p20_init();//500 Hz
}

//  Timer ISR
// CCR0: 每個週期開始 → 拉高
#pragma vector = TIMER0_B0_VECTOR
__interrupt void TIMER0_B0_ISR(void)
{
    if (duty_ticks_p10 > 0)
        P1OUT |= PWM_BIT;
    else
        P1OUT &= ~PWM_BIT;
    TB0CCTL0 &= ~CCIFG;   // ★ 一定要清除 CCR0 中斷旗標!
}



// CCR1: duty 到點 → 拉低
#pragma vector = TIMER0_B1_VECTOR
__interrupt void TIMER0_B1_ISR(void)
{
    switch (__even_in_range(TB0IV, TB0IV_TBIFG)) {
    case TB0IV_TBCCR1:
        if (duty_ticks_p10 < PERIOD_TCK) P1OUT &= ~PWM_BIT;
        break;
    default: break;
    }
}



// ===== 設定 PWM duty(百分比 0~100)=====
// 設定 P2.0 (TB1.1) PWM Duty (0~100%)
void pwm_p20_set_duty(uint8_t percent)
{
    if (percent >= 100) {
        TB1CCR1 = TB1CCR0;      // 100% duty → 永遠高
    } else if (percent == 0) {
        TB1CCR1 = 0;            // 0% duty → 永遠低
    } else {
        // 四捨五入計算 TB1CCR1
        TB1CCR1 = (uint16_t)(((uint32_t)(TB1CCR0 + 1) * percent + 50) / 100);
    }
}



void pwm_p10_set_duty(uint8_t percent)
{
    if (percent >= 100) {
      duty_ticks_p10 = PERIOD_TCK;
    }else{
      duty_ticks_p10 = (uint16_t)((PERIOD_TCK * (uint32_t)percent + 50) / 100);
    }
    TB0CCR1 = (duty_ticks_p10 == 0) ? 1 : duty_ticks_p10;
}



int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;  // Stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;      // 解除高阻態,讓 GPIO 可用(即使本例沒用到腳位,建議保留)
   
//PWM Init
    pwm_init();

    __enable_interrupt();         // 開啟中斷

    //pwm_p10_set_duty(100);

    while(1){
        //漸亮
        for (i = 0; i <= 100; i++) {
            pwm_p10_set_duty(i);
            pwm_p20_set_duty(i);
            delay_ms(10);    // 改這裡控制呼吸速度
        }
        // 漸暗
        for (i = 100; i > 0; i--) {
            pwm_p10_set_duty(i);
            pwm_p20_set_duty(i);
            delay_ms(10);
        }
    }
}


PWM duty越低 在開發版上看到的亮度應該會越暗




有不清楚地可以在留言區留言

大家可以來討論

之後也會用 YT影片(@GGEggProgramming)的方式來說明內容及驗證

================

有其他MCU或是功能想知道怎麼開發

也可以留言讓G蛋知道

G蛋若能力能即盡量幫忙🤣







留言
avatar-img
留言分享你的想法!
avatar-img
臭G蛋的馬蹄刃
2會員
31內容數
一個路過的代碼騎士,穿梭在各個世界學習。 另外 分享自我學習的心得, 分享主要工作中關於 物聯網、專案管理、綠能、碳排放 相關知識與心得與可實踐的專業內容。 持續學習,也持續分享。
你可能也想看
Thumbnail
嶄新的台灣獨立調香師品牌Sunkronizo ,這個名稱源自希臘語「同步」的意思。讓香氛不單純只是氣味調製,更是個人風格的展現與靈魂意志延伸的一種溝通語言。 很適合接下來年底聖誕佳節送禮的試香組,以一星期中的日子來為全系列香氛產品命名, 是品牌創立後首個推出全系列概念作品...
Thumbnail
嶄新的台灣獨立調香師品牌Sunkronizo ,這個名稱源自希臘語「同步」的意思。讓香氛不單純只是氣味調製,更是個人風格的展現與靈魂意志延伸的一種溝通語言。 很適合接下來年底聖誕佳節送禮的試香組,以一星期中的日子來為全系列香氛產品命名, 是品牌創立後首個推出全系列概念作品...
Thumbnail
根據美國電影協會(MPA)主辦的「串流服務如何推動臺灣創意經濟」論壇內容,深入探討串流平臺對臺灣影視產業的影響、數據分析、政府政策建議、內容國際化策略,以及臺灣與「韓流」的差距。文章提出 awwrated 在串流生態系中的潛在角色,強調數據、策略與自信是臺灣影視產業發展的關鍵。
Thumbnail
根據美國電影協會(MPA)主辦的「串流服務如何推動臺灣創意經濟」論壇內容,深入探討串流平臺對臺灣影視產業的影響、數據分析、政府政策建議、內容國際化策略,以及臺灣與「韓流」的差距。文章提出 awwrated 在串流生態系中的潛在角色,強調數據、策略與自信是臺灣影視產業發展的關鍵。
Thumbnail
本文探討串流平臺(VOD)如何徹底改變好萊塢和臺灣影視產業的生態。從美國電影協會(MPA)的數據報告,揭示串流服務在臺灣的驚人普及率與在地內容的消費趨勢。文章分析國際作品如何透過在地化元素開拓新市場。同時,作者也擔憂政府過度監管可能扼殺臺灣影視創新自由,以越南為鑑,呼籲以開放態度擁抱串流時代的新機遇
Thumbnail
本文探討串流平臺(VOD)如何徹底改變好萊塢和臺灣影視產業的生態。從美國電影協會(MPA)的數據報告,揭示串流服務在臺灣的驚人普及率與在地內容的消費趨勢。文章分析國際作品如何透過在地化元素開拓新市場。同時,作者也擔憂政府過度監管可能扼殺臺灣影視創新自由,以越南為鑑,呼籲以開放態度擁抱串流時代的新機遇
Thumbnail
本週報告有聊到MCU公司,所以把舊報告搬到這邊,並做部份開放供參考~
Thumbnail
本週報告有聊到MCU公司,所以把舊報告搬到這邊,並做部份開放供參考~
Thumbnail
券商報告-1/4閱讀重點整理,今天花時間整理新唐這檔個股,希望大家多多支持!Cheers!
Thumbnail
券商報告-1/4閱讀重點整理,今天花時間整理新唐這檔個股,希望大家多多支持!Cheers!
Thumbnail
電子產業_半導體_IC設計_MCU微控制器_有發行可轉債
Thumbnail
電子產業_半導體_IC設計_MCU微控制器_有發行可轉債
Thumbnail
眾所皆知,蜘蛛人新宇宙是一個講述多元平行宇宙的故事,裡面參與的宇宙除了故事裡的原創宇宙,更連結了猛毒宇宙、樂高宇宙,甚至提到了前兩代蜘蛛人電影、漫畫正史事件,蜘蛛人2099也親切的「問候」了荷蘭弟蜘蛛人,那麼問題來了,這些都可以視為該電影的正史嗎?又或反過來問,這部電影也算作那些作品的正史嗎? 網
Thumbnail
眾所皆知,蜘蛛人新宇宙是一個講述多元平行宇宙的故事,裡面參與的宇宙除了故事裡的原創宇宙,更連結了猛毒宇宙、樂高宇宙,甚至提到了前兩代蜘蛛人電影、漫畫正史事件,蜘蛛人2099也親切的「問候」了荷蘭弟蜘蛛人,那麼問題來了,這些都可以視為該電影的正史嗎?又或反過來問,這部電影也算作那些作品的正史嗎? 網
Thumbnail
公司介紹 新唐科技成立於2008年4月,從華邦電子邏輯IC部門分割出來為獨立公司,主要產品為32位元ARM SoC平台開發。公司目前已開發出一系列32位元完整ARM7和ARM9系列控制晶片,是大中華區以ARM處理器為基礎之系統單晶片(SoC)的供應商。 2022年第四季,產品應用方面,電腦占14%、
Thumbnail
公司介紹 新唐科技成立於2008年4月,從華邦電子邏輯IC部門分割出來為獨立公司,主要產品為32位元ARM SoC平台開發。公司目前已開發出一系列32位元完整ARM7和ARM9系列控制晶片,是大中華區以ARM處理器為基礎之系統單晶片(SoC)的供應商。 2022年第四季,產品應用方面,電腦占14%、
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News