Skip to content
Snippets Groups Projects
Commit ceacbbe2 authored by Eric Brombaugh's avatar Eric Brombaugh
Browse files

Added example demonstrating use of TIM1 for 2 channel PWM output

parent 133d7e98
No related branches found
No related tags found
No related merge requests found
TARGET:=tim1_pwm
all : flash
PREFIX:=riscv64-unknown-elf
GPIO_Toggle:=EXAM/GPIO/GPIO_Toggle/User
CH32V003FUN:=../../ch32v003fun
MINICHLINK:=../../minichlink
CFLAGS:= \
-g -Os -flto -ffunction-sections \
-static-libgcc -lgcc \
-march=rv32ec \
-mabi=ilp32e \
-I/usr/include/newlib \
-I$(CH32V003FUN) \
-nostdlib \
-I. -DSTDOUT_UART -Wall
LDFLAGS:=-T $(CH32V003FUN)/ch32v003fun.ld -Wl,--gc-sections
SYSTEM_C:=$(CH32V003FUN)/ch32v003fun.c
$(TARGET).elf : $(SYSTEM_C) $(TARGET).c
$(PREFIX)-gcc -o $@ $^ $(CFLAGS) $(LDFLAGS)
$(TARGET).bin : $(TARGET).elf
$(PREFIX)-size $^
$(PREFIX)-objdump -S $^ > $(TARGET).lst
$(PREFIX)-objdump -t $^ > $(TARGET).map
$(PREFIX)-objcopy -O binary $< $(TARGET).bin
$(PREFIX)-objcopy -O ihex $< $(TARGET).hex
flash : $(TARGET).bin
$(MINICHLINK)/minichlink -w $< flash -b
clean :
rm -rf $(TARGET).elf $(TARGET).bin $(TARGET).hex $(TARGET).lst $(TARGET).map $(TARGET).hex
/*
* Single-File-Header for using Advanced Control Timer (TIM1) for PWM generation
* 03-28-2023 E. Brombaugh
*/
#ifndef _T1PWM_H
#define _T1PWM_H
#include <stdint.h>
/*
* initialize act
*/
void t1pwm_init( void )
{
// Enable GPIOC, GPIOD and TIM1
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_TIM1;
// PD0 is T1CH1N, 50MHz Output PP CNF = 10: Mux PP, MODE = 11: Out 50MHz
GPIOD->CFGLR &= ~(GPIO_CFGLR_MODE0 | GPIO_CFGLR_CNF0);
GPIOD->CFGLR |= GPIO_CFGLR_CNF0_1 | GPIO_CFGLR_MODE0_0 | GPIO_CFGLR_MODE0_1;
// PC4 is T1CH4, 50MHz Output PP CNF = 10: Mux PP, MODE = 11: Out 50MHz
GPIOC->CFGLR &= ~(GPIO_CFGLR_MODE4 | GPIO_CFGLR_CNF4);
GPIOC->CFGLR |= GPIO_CFGLR_CNF4_1 | GPIO_CFGLR_MODE4_0 | GPIO_CFGLR_MODE4_1;
// Reset TIM1 to init all regs
RCC->APB2PRSTR |= RCC_APB2Periph_TIM1;
RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1;
// CTLR1: default is up, events generated, edge align
// SMCFGR: default clk input is CK_INT
// Prescaler
TIM1->PSC = 0x0000;
// Auto Reload - sets period
TIM1->ATRLR = 255;
// Reload immediately
TIM1->SWEVGR |= TIM_UG;
// Enable CH1N output, positive pol
TIM1->CCER |= TIM_CC1NE | TIM_CC1NP;
// Enable CH4 output, positive pol
TIM1->CCER |= TIM_CC4E | TIM_CC4P;
// CH1 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
TIM1->CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1;
// CH2 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
TIM1->CHCTLR2 |= TIM_OC4M_2 | TIM_OC4M_1;
// Set the Capture Compare Register value to 50% initially
TIM1->CH1CVR = 128;
TIM1->CH4CVR = 128;
// Enable TIM1 outputs
TIM1->BDTR |= TIM_MOE;
// Enable TIM1
TIM1->CTLR1 |= TIM_CEN;
}
/*
* set timer channel PW
*/
void t1pwm_setpw(uint8_t chl, uint16_t width)
{
switch(chl&3)
{
case 0: TIM1->CH1CVR = width; break;
case 1: TIM1->CH2CVR = width; break;
case 2: TIM1->CH3CVR = width; break;
case 3: TIM1->CH4CVR = width; break;
}
}
/*
* force output
*/
void t1pwm_force(uint8_t chl, uint8_t val)
{
uint16_t temp;
chl &= 3;
if(chl < 2)
{
temp = TIM1->CHCTLR1;
temp &= ~(TIM_OC1M<<(8*chl));
temp |= (TIM_OC1M_2 | (val?TIM_OC1M_0:0))<<(8*chl);
TIM1->CHCTLR1 = temp;
}
else
{
chl &= 1;
temp = TIM1->CHCTLR2;
temp &= ~(TIM_OC1M<<(8*chl));
temp |= (TIM_OC1M_2 | (val?TIM_OC1M_0:0))<<(8*chl);
TIM1->CHCTLR2 = temp;
}
}
#endif
/*
* Example for using Advanced Control Timer (TIM1) for PWM generation
* 03-28-2023 E. Brombaugh
*/
// Could be defined here, or in the processor defines.
#define SYSTEM_CORE_CLOCK 48000000
#define APB_CLOCK SYSTEM_CORE_CLOCK
#include "ch32v003fun.h"
#include <stdio.h>
#include "t1pwm.h"
int main()
{
uint32_t count = 0;
SystemInit48HSI();
// start serial @ default 115200bps
SetupUART( UART_BRR );
Delay_Ms( 100 );
printf("\r\r\n\ntim1_pwm example\n\r");
// init TIM1 for PWM
printf("initializing tim1...");
t1pwm_init();
printf("done.\n\r");
printf("looping...\n\r");
while(1)
{
t1pwm_setpw(0, count); // Chl 1
t1pwm_setpw(3, (count + 128)&255); // Chl 4
count++;
count &= 255;
Delay_Ms( 5 );
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment