How do you generate complementary PWM Outputs?

I would like to generate complementary PWM Outputs with adjustable dead time.

According to the STM32F401RE Microcontroller datasheet

http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1810/PF258797,

this is possible with Timer 1 (TIM1).

So far I have attempted to configure the timer myself using information available from the TIM HAL Driver from ST:

http://developer.mbed.org/users/dreschpe/code/mbed-F401/docs/4e95b79aa640/stm32f4xx__hal__tim__ex_8c.html

and looking through an example of someone using the driver:

https://petoknm.wordpress.com/2015/01/05/rotary-encoder-and-stm32/.

Obviously, I do not want to use a HAL sensor, but this is the closest example I can get to someone using the advanced features of the timers.

Thanks!

Damien

Edit: Here is the code I went with in the end:

void ConfigurePWM(float duty_us, float period_us){
unsigned int value;
float newVal; // Ensure power is turned on
// Grabbed from lines 54-57 of analogin_api.h, modified for PWM
// This turns on the clock to Ports A, B, and C
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
// This turns on the clock to the Time 1:
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Set the GPIO Ports properly:
// PWM1 is connected to PA_8
// PWM1N is connected to PA_7 // Set the PWM outputs to general output pins:
// This sets the PA_7 and PA_8 pins to Alternate Function Pins
value = 0x8000 + 0x20000;
GPIOA->MODER |= value; // Set the PWM outputs to high speed:
value = 0xC000 + 0x30000;
GPIOA->OSPEEDR |= value; // Set PWM as outputs to the pins:
value = GPIOA->AFR[];
// Reset the lowest four bits:
value &= 0xFFFFFFF0;
// Configure PA_8 to AF:
value |= 0x1;
GPIOA->AFR[] = value; value = GPIOA->AFR[];
// Reset the the 4 MSB:
value &= 0x0FFFFFFF;
// Configure PA_7 to AF:
value |= 0x10000000;
GPIOA->AFR[] = value; // Set pull down resistors to PWM outputs:
value = GPIOA->PUPDR;
// Clear the bits:
value &= ~(GPIO_PUPDR_PUPDR7 | GPIO_PUPDR_PUPDR8);
// Set to pull down:
value |= GPIO_PUPDR_PUPDR7_1 | GPIO_PUPDR_PUPDR8_1;
// Set the register:
GPIOA ->PUPDR = value; // Set the prescale value to 1:
TIM1->PSC = ; // *** TIM1 control register 1: TIMx_CR1 ***
value = ;
// [9:8] Set CKD bits to zero for clock division of 1
// [7] TIMx_ARR register is buffered, set the ARPE bit to 1:
// value |= 0x80;
// [6:5] Set CMS bits to zero for edge aligned mode
// [6:5] Set CMS bits to 10 for Center Aligned mode 2, up down mode with flags set when counter reaches the top.
//value |= TIM_CR1_CMS_1;
// [4] Set DIR bit to zero for upcounting
// [3] Set OPM bit to zero so that the counter is not stopped at update event
// [2] Set URS bit to zero so that anything can create an interrupt
// [1] Set UDIS bit to zero to generate an update event
// [0] Set the CEN bit to zero to disable the counter
// * Set the TIMx_CR1 Register: *
TIM1->CR1 |= value; // *** TIM1 control register 2: TIMx_CR2 ***
value = ;
// [14] Set OIS4 bit to zero, the idle state of OC4 output
// [13] Set OIS3N bit to zero, the idle state of OC3N output
// [12] Set OIS3 bit to zero, the idle state of OC3 output
// [11] Set OIS2N bit to zero, the idle state of OC2N output
// [10] Set OIS2 bit to zero, the idle state of OC2 output
// [9] Set OIS1N bit to zero, the idle state of OC1N output
// [8] Set OIS1 bit to zero, the idle state of OC1 output
// [7] Set TI1S bit to zero, connecting only CH1 pin to TI1 input
// [6:4] Set to 111: The OC4REF signal is used as trigger output (TRGO)
// value |= TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0;
// value |= TIM_CR2_MMS_1 | TIM_CR2_MMS_0;
// [3] Set CCDS bit to zero, request sent when CCx event occurs
// [2] Set CCUS bit to 1, capture/compare control bits are updated by setting the COMG bit or when a rising edge occurs on TRGI
// value |= 0x4;
// [0] Set CCPC bit to 1, CCxE, CCxNE and OCxM are update on a commutation event, or rising edge on TRGI
// value |= 0x1;
// * Set the TIMx_CR2 Register: *
TIM1->CR2 = value; // *** TIM1 Auto Reload Register: ARR ***
value = ;
// [15:0] Set ARR bits to the frequency to be loaded in:
newVal = ceil(period_us/PWMSTEP_US);
value = (unsigned int) newVal;
// * Set the TIMx_ARR Register:
TIM1->ARR = value; // *** TIM1 capture/compare register 1: CCR1 ***
value = ;
// [15:0] Set the capture compare value to the duty cycle:
newVal = ceil(duty_us/PWMSTEP_US);
value = (unsigned int) newVal;
// * Set the TIMx_CCR1 Register:
TIM1->CCR1 = value; // *** TIM1 capture/compare register 4: CCR4 ***
value = ;
// [15:0] Set the capture compare value to the duty cycle:
newVal = ceil(duty_us/2.0f/PWMSTEP_US);
value = (unsigned int) newVal;
// * Set the TIMx_CCR1 Register:
TIM1->CCR4 = TIM1->ARR - CH4SHIFT; // *** TIM1 capture/compare mode register 2: CCMR2
value = ;
// [15] Set OC4CE bit to 0, OC4Ref is not affected by the ETRF input
// [14-12] Set the OC4M bits to '110', PWM mode 1, which is what we want I think.
value |= TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;
// [11] Set the OC4PE bit to 1, meaning read/write operations to the preload event require an update event.
value |= 0x800;
// [10] Set the OC4FE bit to 0, the output compare fast enable is disabled
// [9:8] Set the CC4S bits to 0, the channel is configured as an output.
// * Set the TIMx_CCMR2 Register: *
TIM1->CCMR2 = value; // *** TIM1 capture/compare mode register 1: CCMR1
value = ;
// [7] Set OC1CE bit to 0, OC1Ref is not affected by the ETRF input
// [6-4] Set the OC1M bits to '110', PWM mode 1, which is what we want I think.
value |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
// [3] Set the OC1PE bit to 1, meaning read/write operations to the preload event require an update event.
value |= 0x8;
// [2] Set the OC1FE bit to 0, the output compare fast enable is disabled
// [1:0] Set the CC1S bits to 0, the channel is configured as an output.
// * Set the TIMx_CCMR1 Register: *
TIM1->CCMR1 = value; // *** TIM1 capture/compare enable register: CCER
value = ;
// [15:4] - Don't care:
// [3] Set CC1NP bit to zero for active high.
// [2] Set CC1NE bit to 0, to de-activate the OC1N signal
// value |= 0x4;
// [1] Set the CC1P bit to zero for active high.
// [0] Set the CC1E bit to 1, to de-activate the OC1 signal
// value |= 0x1;
// * Set the TIM1_CCER Register: *
TIM1->CCER = value; // *** TIM1 break and dead-time register: BDTR
value = ;
// [15] Set MOE bit to 1 to enable the OC and OCN outputs
value |= 0x8000;
// [11] Set the OSSR bit such that the ouputs are forced to their idle mode when not running
//value |= TIM_BDTR_OSSR;
// [10] Set OSSI bit such that the outputs are forced to their idle mode when MOE = 0
value |= TIM_BDTR_OSSI;
// * Set the TIM1_BDTR register:
TIM1->BDTR = value; // *** TIM1 DMA/Interrupt enable register: DIER
value = ;
// [2] Set the CC1IE bit to 1, to trigger an interrupt when counter 1 has a match - which should be half way through the duty cycle.
value |= TIM_DIER_CC4IE;
// Set the TIM1_DIER register:
TIM1->DIER |= value; // Set the UG bit in the EGR register to kick things off:
value = ;
TIM1->EGR = value; // Configure the interrupt:
NVIC_SetVector(TIM1_CC_IRQn, (uint32_t)&TIM1_CC_IRQHandler);
NVIC_EnableIRQ(TIM1_CC_IRQn); return; }

STM32F4 How do you generate complementary PWM Outputs?的更多相关文章

  1. Generate stabilized PWM signals

    A standard technique for generating analog voltages using µCs is to use a PWM output and filter the ...

  2. Two PWM outputs from MCU combine to form a monotonic 16-bits DAC

    http://www.edn.com/design/analog/4329365/Combine-two-8-bit-outputs-to-make-one-16-bit-DAC

  3. Renesas M16C/6X -- Simple PWM Signal Generation Using DMA

    1. Requirements To generate a PWM output, we need to create a train of pulses with constant period a ...

  4. how to generate an analog output from a in-built pwm of Atmega 32AVR microcontrloller?

    how to generate an analog output from a in-built pwm of Atmega 32AVR microcontrloller? you need a re ...

  5. M451 PWM对照数据手册分析

    PWM_T Struct Reference Control Register » Pulse Width Modulation Controller(PWM)   typedef struct { ...

  6. 说说M451例程之PWM的寄存器讲解

    M451提供了两路PWM发生器.每路PWM支持6通道PWM输出或输入捕捉.有一个12位的预分频器把时钟源分频后输入给16位的计数器,另外还有一个16位的比较器.PWM计数器支持向上,向下,上下计数方式 ...

  7. STM32 Timer : Base Timer, Input Capture, PWM, Output Compare

    http://www.cs.indiana.edu/~geobrown/book.pdf An example of a basic timer is illustrated in Figure 10 ...

  8. STM32F4 -- How to use the DMA burst feature

    Bits 15:13 Reserved, must be kept at reset value. Bits 12:8 DBL[4:0]: DMA burst length This 5-bit ve ...

  9. STM32学习日志--使用DMA功能自动更新PWM的输出

    /******************************************************************************* 编译环境: EWARM V5.30 硬 ...

随机推荐

  1. iOS8 自定义navigationbar 以及 UIBarButtonItem 边距问题

    一.自定义navigationbar - (void)initNavigationBar{ [self.navigationController setNavigationBarHidden:YES] ...

  2. Linux - sed 常用操作

    sed 文本常用操作方式 sed 10q # 显示文件中的前10行 (模拟"head") sed -n '$=' # 计算行数(模拟 "wc -l") sed ...

  3. [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)

    [BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...

  4. Python 装饰器入门(上)

    翻译前想说的话: 这是一篇介绍python装饰器的文章,对比之前看到的类似介绍装饰器的文章,个人认为无人可出其右,文章由浅到深,由函数介绍到装饰器的高级应用,每个介绍必有例子说明.文章太长,看完原文后 ...

  5. springboot整合rabbitmq客户端连接报超时异常问题解决:An unexpected connection driver error occured java.net.SocketException: Socket Closed,java.util.concurrent.TimeoutException

    我用的是springboot2.0.6版本,对应的ampq也是2.0.6版本,然后启动一直报: 还有java.util.concurrent.TimeoutException, 用户授权什么的都对,很 ...

  6. Linux使用一个定时器实现设置任意数量定时器功能【转】

    转自:https://www.jb51.net/article/120748.htm 为什么需要这个功能,因为大多数计算机软件时钟系统通常只能有一个时钟触发一次中断.当运行多个任务时,我们会想要多个定 ...

  7. http和socket之长连接和短连接区别【转】

    转自:https://blog.csdn.net/mengyafei43/article/details/25195445 TCP/IP TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层 ...

  8. H2内嵌数据库使用步骤

    1.找到h2数据库的jar包 D:\repositories\com\h2database\h2\1.4.187\h2-1.4.187.jar 2.双击jar包,配置连接信息 Driver Class ...

  9. [Android]Eclipse 安装 ADT[Android Development Tooling] 失败的两种解决办法

    原因 最近想在新装的 Win7 里搭建一下 Android 的开发环境,虽然现在有 Android Studio 了,不过还是习惯 Eclipse 一点.众所周知的原因,Eclipse 直接安装 AD ...

  10. 探秘Java类加载

    Java是一门面向对象的编程语言. 面向对象以抽象为基础,有封装.继承.多态三大特性. 宇宙万物,经过抽象,均可归入相应的种类.不同种类之间,有着相对井然的分别. Java中的类,便是基于现实世界中的 ...