在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用MM32F0270 定時器DMA方式輸出PWM

jf_pJlTbmA9 ? 來源:靈動MM32MCU ? 作者:靈動MM32MCU ? 2023-10-17 14:47 ? 次閱讀

對于控制步進電機來說,最重要的控制參數是脈沖的數量和頻率,兩者結合可以實現滿足要求的電機加減速曲線。在一些電機應用數量不多的場合,通常使用定時器中斷發送脈沖來控制步進電機,優點是原理簡單代碼易于實現。但是一旦控制的電機多起來,就會占用大量的MCU資源,這在大多數情況下是不可接受的,更不用說多軸聯動了。那么如何做到占用很少的MCU資源,又能實現脈沖發送的精確控制?

于是就想到了使用DMA功能更新PWM的輸出, DMA全稱Direct Memory Access,即直接存儲器訪問。DMA傳輸將數據從一個地址空間復制到另一個地址空間,提供在外設和存儲器之間或者存儲器和存儲器之間的高速數據傳輸。它允許不同速度的硬件裝置來溝通,而不需要依賴于MPU的大量中斷負載。

通過設置DMA傳輸數據的數量,可以控制發送的脈沖數。通過設置不同的裝載值和順序,可以使用不同頻率和脈寬。當需要發送較多數量的脈沖時,則可以使用DMA傳輸完成中斷中切換DMA傳輸的數據起始地址及發送數量,繼續發送。這個方法即方便,又減輕MPU的負擔,可以同時驅動多個電機工作,還可以根據電機的啟動、運行、停止使用不同的頻率。

定時器DMA模式

MM32F0270的定時器TIM1、TIM2、TIM3、TIM15、TIM16/17有DMA模式,能夠在發生單個事件時生成多個DMA 請求。主要目的是在沒有軟件開銷的情況下,多次重新編程定時器的一部分,也可以用于按周期讀取數個寄存器。下面以TIM1為例介紹:

TIM1_DCR 和 TIM1_DMAR 寄存器跟 DMA 模式相關。DMA 控制器的目標是唯一的,必須指向TIM1_DMAR 寄存器。開啟 DMA 使能后,在給定的 TIM1 事件發生時, TIM1 會給 DMA 發送請求。

對 TIM1_DMAR 寄存器的每次寫操作都被重定向到一個 TIM1 寄存器。TIM1_DCR寄存器的DBL位定義了DMA連續傳送的長度,即傳輸寄存器數量;當對TIM1_DMAR進行讀寫操作時,定時器識別 DBL,確定傳輸的寄存器數量。TIM1_DCR 寄存器的 DBA 位定義了DMA 傳輸的基地址, 定義從 TIM1_CR1 寄存器地址開始的偏移量(00000 為 TIM1_CR1;00001 為TIM1_CR2;……; 00110 為 TIM1_CCMR1 等)。

通過定時器的DMA模式來更新PWM,本文參官網例程“TIM1_DMA_UPData”進行說明具體實現方法。

實驗

本實驗使用TIM1的DMA模式,當更新事件發生時,更新 TIM1_CCR1、TIM1_CCR2 和 TIM1_CCR3 寄存器的內容。程序中配置TIM1的通道1、通道2、通道3輸出PWM,再通過DMA搬運數據來改變PWM的占空比。定時器每產生一個溢出事件(即計數完成),就發送DMA請求,根據數據在數組中的排列順序以生成所需要的時序。

程序部分

GPIO初始化

配置TIM1_CH1、TIM1_CH2 和 TIM1_CH3對應的GPIO。

void TIM1_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2);
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,  GPIO_InitStruct);
}

TIM1 DMA初始化

TIM1_CH3對應DMA1通道5,將data[]中的數據傳送到TIM1_DMAR寄存器,傳輸方向從存儲器到外設,數據寬度為半字,使能DMA傳輸完成中斷。

void TIM_DMA_Init(void)
{
    DMA_InitTypeDef  DMA_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1, ENABLE);

    DMA_DeInit(DMA1_Channel5);
    DMA_StructInit( DMA_InitStruct);
    //Transfer register address
    DMA_InitStruct.DMA_PeripheralBaseAddr    = (u32)   (TIM1->DMAR);
    //Transfer memory address
    DMA_InitStruct.DMA_MemoryBaseAddr        = (u32)data;
    //Transfer direction, from memory to register
    DMA_InitStruct.DMA_DIR                   = DMA_DIR_PeripheralDST;
    DMA_InitStruct.DMA_BufferSize            = 6;
    DMA_InitStruct.DMA_PeripheralInc         = DMA_PeripheralInc_Disable;
    //Transfer completed memory address increment
    DMA_InitStruct.DMA_MemoryInc             = DMA_MemoryInc_Enable;
    DMA_InitStruct.DMA_PeripheralDataSize    = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStruct.DMA_MemoryDataSize        = DMA_MemoryDataSize_HalfWord;
    DMA_InitStruct.DMA_Mode                  = DMA_Mode_Circular;
    DMA_InitStruct.DMA_Priority              = DMA_Priority_High;
    DMA_InitStruct.DMA_M2M                   = DMA_M2M_Disable;
    DMA_InitStruct.DMA_Auto_reload = DMA_Auto_Reload_Disable;
    DMA_Init(DMA1_Channel5,  DMA_InitStruct);

    DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

}

TIM1 PWM初始化

TIM1輸出PWM,配置時鐘分頻系數和預裝載值,遞增計數,使用PWM模式1,輸出高電平有效,分別對TIM1_CH1、TIM1_CH2、TIM1_CH3指定要加載到捕獲比較寄存器中的脈沖值為arr/2、arr/4、arr/6,使能TIM1的DMA模式,起始地址為TIM1_CCR1,傳輸長度為3。

void TIM1_PWM_Init(u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
    TIM_OCInitTypeDef  TIM_OCInitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1, ENABLE);

    TIM_TimeBaseStructInit( TIM_TimeBaseStruct);
    TIM_TimeBaseStruct.TIM_Period = arr;
    TIM_TimeBaseStruct.TIM_Prescaler = psc;
    //Setting Clock Segmentation
    TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
    ///TIM Upward Counting Mode
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1,  TIM_TimeBaseStruct);

    TIM_OCStructInit( TIM_OCInitStruct);
    //Select Timer Mode: TIM Pulse Width Modulation Mode 2
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;

    //Setting the Pulse Value of the Capture Comparison Register to be Loaded
    TIM_OCInitStruct.TIM_Pulse = arr / 2;
    TIM_OC1Init(TIM1,  TIM_OCInitStruct);
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OCInitStruct.TIM_Pulse = arr / 4;
    TIM_OC2Init(TIM1,  TIM_OCInitStruct);
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_OCInitStruct.TIM_Pulse = arr / 6;
    TIM_OC3Init(TIM1,  TIM_OCInitStruct);
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

    TIM_ARRPreloadConfig(TIM1, ENABLE);

    TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_3Bytes);
    TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
    TIM_CtrlPWMOutputs(TIM1, ENABLE);

    TIM_Cmd(TIM1, ENABLE);
}

使能DMA1通道5

DMA_Cmd(DMA1_Channel5, ENABLE);

配置NVIC

NVIC_Configure(DMA1_Channel4_5_6_7_IRQn, 1, 1);

DMA1中斷服務子程序

void DMA1_Channel4_5_6_7_IRQHandler()
{
    if (DMA_GetITStatus(DMA1_IT_TC5)) {
        //clear IRQ flag
        DMA_ClearITPendingBit(DMA1_IT_TC5);
    }
}

定義數組data[]

static u16 data[] = {2000, 3000, 4000, 8000, 7000, 6000};

Main()函數

s32 main(void)
{
    TIM1_GPIO_Init();
    TIM1_PWM_Init(10000, 0);
    TIM_DMA_Init();
    NVIC_Configure(DMA1_Channel4_5_6_7_IRQn, 1, 1);
    DMA_Cmd(DMA1_Channel5, ENABLE);
    while (1) {
    }
}

演示

下載程序到目標板。連接邏輯分析儀測試PA8、PA9、PA10的輸出,打開對應上位機軟件啟動采樣,運行程序,各通道的PWM輸出情況如下:

wKgaomUD772AHrmCAACIeLDRj7Q290.png

截取其中1個周期觀察:

wKgZomUD776ADUH5AADZEUJrwpQ251.png

TIM1_CH1輸出PWM占空比為20%和80%, TIM1_CH1輸出PWM占空比為30%和70%, TIM1_CH1輸出PWM占空比為40%和60%,運行結果和預期一致。

實驗簡單演示了MM32F0270的定時器TIM1的DMA方式更新PWM,通過該方案可以實現多路、不同頻率、不同脈寬、數量精確可控的PWM波。

工程路徑如下:

~ MM32FMM32F0270_Lib_SamplesMM32F0270_SamplesLibSamplesTIMTIM1_DMA_UPData。

來源:靈動MM32MCU
免責聲明:本文為轉載文章,轉載此文目的在于傳遞更多信息,版權歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權問題,請聯系小編進行處理

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • PWM
    PWM
    +關注

    關注

    114

    文章

    5186

    瀏覽量

    213957
  • 定時器
    +關注

    關注

    23

    文章

    3248

    瀏覽量

    114819
  • dma
    dma
    +關注

    關注

    3

    文章

    561

    瀏覽量

    100587
收藏 人收藏

    評論

    相關推薦

    靈動微課堂 (第196講) | 使用MM32F0270 LPTIM從STOP模式喚醒

    LED燈。01 MM32F0270 LPTIM的簡要介紹LPTIM即低功耗定時器,得益于其定時器的低功耗。由于 LPTIM 的時鐘源具有多樣性,因此 LPTIM 能夠在所有電源模式(待機模式除外)下保持
    發表于 01-10 11:38

    靈動微課堂 (第197講) | MM32F0270 UART空閑中斷 + DMA接收不定長數據

    )UART DMA方式MM32F0270 UART使用DMA方式接收數據可以減小CPU的開銷。對于接收定長數據,可以將
    發表于 01-10 11:42

    靈動微課堂 (第198講) | 使用MM32F0270 LPUART從低功耗模式喚醒

    在許多的工業與消費類應用中,越來越多的需要使用低功耗功能,使用外部串口數據通信發送命令來喚醒MCU。靈動微電子推出的MM32F0270系列,支持多種靈活的低功耗模式,支持LPUART的外設。本文介紹
    發表于 01-17 13:24

    靈動微課堂 (第200講) | 使用MM32F0270 定時器DMA方式輸出PWM

    %, TIM1_CH1輸出PWM占空比為40%和60%,運行結果和預期一致。實驗簡單演示了MM32F0270定時器TIM1的DMA
    發表于 02-18 13:36

    靈動微課堂 (第200講) | 使用MM32F0270 定時器DMA方式輸出PWM

    PWM占空比為20%和80%, TIM1_CH1輸出PWM占空比為30%和70%, TIM1_CH1輸出PWM占空比為40%和60%,運行結
    發表于 03-17 17:26

    STM32F030的定時器PWM使用設置與ADC的dma代碼

    里面是STM32F030的定時器PWM使用設置與ADC的dma代碼
    發表于 03-21 15:29 ?152次下載

    MM32F0140定時器模塊計數定時功能

    本篇筆記主要探討 MM32F0140 定時器模塊的框圖結構、定時器提供的計數定時等功能以及配置定時器的流程,并以 pokt-
    的頭像 發表于 04-07 16:31 ?2775次閱讀
    <b class='flag-5'>MM32F</b>0140<b class='flag-5'>定時器</b>模塊計數<b class='flag-5'>定時</b>功能

    MM32F0270 產品手冊(中文版)

    MM32F0270 產品手冊(中文版)
    發表于 02-23 18:36 ?0次下載
    <b class='flag-5'>MM32F0270</b> 產品手冊(中文版)

    MM32F0270 產品手冊(英文版)

    MM32F0270 產品手冊(英文版)
    發表于 02-23 18:37 ?0次下載
    <b class='flag-5'>MM32F0270</b> 產品手冊(英文版)

    MM32F0270 用戶手冊(中文版)

    MM32F0270 用戶手冊(中文版)
    發表于 02-23 18:37 ?0次下載
    <b class='flag-5'>MM32F0270</b> 用戶手冊(中文版)

    MM32F0270 用戶手冊(英文版)

    MM32F0270 用戶手冊(英文版)
    發表于 02-23 18:38 ?0次下載
    <b class='flag-5'>MM32F0270</b> 用戶手冊(英文版)

    MM32F0270 勘誤表(中文版)

    MM32F0270 勘誤表(中文版)
    發表于 02-23 18:38 ?0次下載
    <b class='flag-5'>MM32F0270</b> 勘誤表(中文版)

    MM32F0270 勘誤表(英文版)

    MM32F0270 勘誤表(英文版)
    發表于 02-23 18:39 ?0次下載
    <b class='flag-5'>MM32F0270</b> 勘誤表(英文版)

    使用MM32F0270 USB從Suspend模式喚醒

    使用MM32F0270 USB從Suspend模式喚醒
    的頭像 發表于 09-26 16:39 ?962次閱讀
    使用<b class='flag-5'>MM32F0270</b> USB從Suspend模式喚醒

    使用MM32F0270 LPTIM從STOP模式喚醒

    使用MM32F0270 LPTIM從STOP模式喚醒
    的頭像 發表于 10-26 16:46 ?1006次閱讀
    使用<b class='flag-5'>MM32F0270</b> LPTIM從STOP模式喚醒
    主站蜘蛛池模板: 波多久久夜色精品国产| www.色.con| 狠狠狠狠狠狠| 国内精品免费视频精选在线观看| 国产一区高清| 久久久久久天天夜夜天天| 国产成人综合自拍| 91大神在线免费观看| 久久久久国产精品免费网站| 最好看的最新中文字幕2018免费视频 | 天堂在线www| 日本三级网站在线观看| 靠比久久| 91老色批网站免费看| 免费观看美女被cao视频| 日本肥妇| 资源种子在线观看| 精品色| 天天干天天天天| 在线看黄网| 张柏芝三级无删减在线观看| 色在线视频播放| 韩国r天堂| av天天看| 一区二区三区精品国产欧美| 欧美色图亚洲激情| free欧美| 一区二区三区在线观看免费| 羞羞爱爱| 久久精品亚洲精品国产欧美| 午夜久久久久久网站| 日本69式xxx视频| 日韩欧美亚洲综合久久影院d3| 国产成人91青青草原精品 | 久久久久大香线焦| 男女午夜特黄毛片免费 | 美女淫| 天天干天天上| 一级毛片不收费| 久久精品人| 在线免费视频网站|