基於迴圈DMA PWM實現正玄波

2021-09-25 04:42:56 字數 4126 閱讀 6249

最近看群裡大家在討論pwm,想起以前寫的pwm模擬正玄波的**,拿出來分享下。

其實也很簡單,我就把我做的思路講解下,期望能幫助到用到的人吧。

首先說下要求:

1、16點的正玄波,當然這個是不是重點;

2、正玄波週期可調;

3、正玄波幅度可調;

實現思路:

一、利用matlab**,計算出16點的正玄波基礎資料

static  const   float   c_fsinstandardvalue=;
這16個資料點適合週期無關的。

二、怎麼顯示負半波

由於我們的板子沒有負壓,因此我要想實現輸出負壓,只能提供直流分量,因此我在演算法裡面把直流分量

提高到了1.65v。

三、根據使用者輸入頻率和幅度計算週期和占空比

static  bool    calculate_pwm_ratio(uint16_t    hwselectsinv_mv,uint32_t    wselectsinf_hz)

hwpwmt = timx_clk/(wselectsinf_hz*dma_buffer_size);

for(i=0;ihwpwmt)

if(s_hwdmabuffer[i])

}return true;

}

四、就是底層硬體驅動了

dma驅動:

static  bool    pwm_dma(uint8_t  chselectchannel)

tdma_initlstructure.dma_memorybaseaddr = (uint32_t)s_hwdmabuffer;

tdma_initlstructure.dma_dir = dma_dir_peripheraldst;

tdma_initlstructure.dma_buffersize = dma_buffer_size;

tdma_initlstructure.dma_peripheralinc = dma_peripheralinc_disable;

tdma_initlstructure.dma_memoryinc = dma_memoryinc_enable;

tdma_initlstructure.dma_peripheraldatasize = dma_peripheraldatasize_halfword;

tdma_initlstructure.dma_memorydatasize = dma_memorydatasize_halfword;

tdma_initlstructure.dma_mode = dma_mode_circular;

tdma_initlstructure.dma_priority = dma_priority_high;

tdma_initlstructure.dma_m2m = dma_m2m_disable;

dma_clearflag( dma1_it_tc7 );

dma_init(dma1_channel7, &tdma_initlstructure);

}while(0);

dma_cmd(dma1_channel7,enable);

return true;

}

io口驅動:

void    user_pwm_init(void)

; gpio_init(gpiob, (gpio_inittypedef*)&c_tgpio_initstructure);

}while(0);

//nvic_setpriority(dma1_channel5_irqn, 0);

//nvic_enableirq(dma1_channel5_irqn);

}

pwm驅動:

bool    user_pwm_cfg(uint16_t   hwsetv_mv,uint16_t   hwsetf_hz,uint8_t  chselectchannel)

if(!pwm_dma(chselectchannel))

if(!calculate_pwm_ratio(hwsetv_mv,hwsetf_hz))

/* 第1步:開啟gpiob rcc_apb2periph_afio 的時鐘 */

//rcc_apb2periphclockcmd(rcc_apb2periph_gpiob | rcc_apb2periph_afio, enable);

/*do;

gpio_init(gpiob, (gpio_inittypedef*)&c_tgpio_initstructure);

gpio_resetbits(gpiob, gpio_pin_6);

gpio_resetbits(gpiob, gpio_pin_7);

}while(0);

*//* 配置gpio為復用推挽輸出模式 */

/*do;

gpio_init(gpiob, (gpio_inittypedef*)&c_tgpio_initstructure);

}while(0);

*//* 使能tim4的時鐘 */

//rcc_apb1periphclockcmd(rcc_apb1periph_tim4, enable);

dotim_timebasestructure.tim_period = hwsetf_hz - 1; /* tim_period = tim3 arr register */

tim_timebasestructure.tim_prescaler = 0;

tim_timebasestructure.tim_clockdivision = 0;

tim_timebasestructure.tim_countermode = tim_countermode_up;

tim_timebaseinit(tim4, &tim_timebasestructure);

}while(0);

/* pwm1 mode configuration: channel1 */

do;tim_oc1init(tim4, (tim_ocinittypedef*)&ttim_ocinitstructure);

tim_oc1preloadconfig(tim4, tim_ocpreload_disable);

tim_oc2init(tim4, (tim_ocinittypedef*)&ttim_ocinitstructure);

tim_oc2preloadconfig(tim4, tim_ocpreload_disable);

tim_oc3init(tim4, (tim_ocinittypedef*)&ttim_ocinitstructure);

tim_oc3preloadconfig(tim4, tim_ocpreload_disable);

tim_oc4init(tim4, (tim_ocinittypedef*)&ttim_ocinitstructure);

tim_oc4preloadconfig(tim4, tim_ocpreload_disable);

switch(chselectchannel)

//tim_oc4init(tim4, (tim_ocinittypedef*)&ttim_ocinitstructure);

//tim_oc4preloadconfig(tim4, tim_ocpreload_disable);

}while(0);

tim_arrpreloadconfig(tim4, enable);

//dma

dowhile(0);

//dma_cmd(dma1_channel5,enable);

/* tim4 enable counter */

tim_cmd(tim4, enable);

tim_ctrlpwmoutputs(tim4, enable);

return true;

}

輸出波形,經過乙個低通濾波器後,輸出了正玄波。

for迴圈實現正等腰三角形

層數i 星星數 空格數 迴圈層i 1 1 8 2 3 6 3 5 4 4 7 2 5 9 0 星星數 2 i 1 空格數 2 n 1 2 i 1 2 n i n 5 for i 1 i n i for j 1 j 2 i 1 j echo n 每層輸出完後換行 如果出現三角形斜曲了,這個是字型的原因...

佇列 基於迴圈陣列的實現

description 請完成以下佇列類的實現 請注意陣列實現應該為迴圈陣列 enum errorcode success,underflow,overflow const int maxqueue 100 template class myqueue public myqueue bool emp...

裴波那契數列(迴圈實現遞迴)

裴波那契 fibonacci 數列 f n 0,1 f n 1 f n 2 n 0n 1n 1 求裴波那契數列的第n項。題目來自劍指offer 1.遞迴解法,效率很低的解法,不用 一看到這個題,我們就很容易竊喜的想到這種解法 很多f i 進行了重複計算,隨著n的增大,計算量急劇增加,時間複雜度以n的...