CH32V003 Timer Issue

Ch32V003 Timer code is not working

`void initializeTimer(uint16_t prsc, uint16_t arr);
void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {
        GPIO_WriteBit(GPIOC, GPIO_Pin_0, (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_0) == Bit_SET) ? Bit_RESET : Bit_SET);
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

void setup()
{
      initializeTimer(47999, 999);
}
void loop()
{
}

void initializeTimer(uint16_t prsc, uint16_t arr)
{
       TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = {0};
       NVIC_InitTypeDef NVIC_InitStructure = {0};
       GPIO_InitTypeDef GPIO_InitStructure = {0};

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOC, &GPIO_InitStructure);

       TIM_TimeBaseStructure.TIM_Period = arr;
       TIM_TimeBaseStructure.TIM_Prescaler = prsc;
       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
       TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

       TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

       NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       NVIC_Init(&NVIC_InitStructure);

       TIM_Cmd(TIM2, ENABLE);
}`

I moved your topic to an appropriate forum category @satishmunot.

In the future, when creating a topic please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

some time since I looked at the CH32V003

tried your timer code and as stated it locks up
added some print statements and it appears to fail when configuring the Nested Vectored Interrupt Controller (NVIC)

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  Serial.println("\ncalling NVIC_Init()");
  NVIC_Init(&NVIC_InitStructure);
  Serial.println("\nNVIC_Init() returned");

  TIM_Cmd(TIM2, ENABLE);

the serial monitor displays

calling NVIC_Init()

but not "\nNVIC_Init() returned"

I assume the attempt to configure the CH32 NVIC is clashing with the Arduino CH32 setup

have a look at Arduino Timer Interrupts for the CH32V003 WCH MCU which uses the CH32 HardwareTimer library function
however the document states
Board Manager version 1.0.4 will not work with this sketch because it requires the HardwareTimer function.

this is a verion of the example with minor modifications (change the LED GPIO pin to PD4 and printing an * in loop() when in timer interrupt occurs)
also some documentation on how to install the HardwareTimer function.


// CH32V003 HardwareTimer.h library test

// original code from https://www.instructables.com/Arduino-Timer-Interrupts-for-the-CH32V003-WCH-MCU/

// NOTE: CH32 1.0.4 board manager does not include "HardwareTimer.h" 
// 1. download https://github.com/openwch/arduino_core_ch32 and unzip
// 2. open C:\Users\<username>\AppData\Local\Arduino15\packages\WCH\hardware\ch32v\1.0.4 and delete contents
// 3: copy contents of C:\Users\<username>\Downloads\arduino_core_ch32-main\arduino_core_ch32-main

/* e.g. should look like
PS C:\Users\xx> cd C:\Users\xx\AppData\Local\Arduino15\packages\WCH\hardware\ch32v\1.0.4
PS C:\Users\xx\AppData\Local\Arduino15\packages\WCH\hardware\ch32v\1.0.4> dir

    Directory: C:\Users\xx\AppData\Local\Arduino15\packages\WCH\hardware\ch32v\1.0.4

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        10/02/2026     07:34                cores
d-----        10/02/2026     07:34                libraries
d-----        10/02/2026     07:34                system
d-----        10/02/2026     07:34                tools
d-----        10/02/2026     07:34                variants
-a----        10/02/2026     05:33              7 .gitignore
-a----        10/02/2026     05:33            156 .gitmodules
-a----        10/02/2026     05:33          43574 boards.txt
-a----        10/02/2026     05:33            202 package.json
-a----        10/02/2026     05:33           9206 platform.txt
-a----        10/02/2026     05:33              0 programmers.txt
-a----        10/02/2026     05:33           4564 README.md
*/

// (c) 2024 Pablo Montoreano
/*******************************************************
  simple Blink sketch using a timer
  for WCH CH32V003
  compile selecting CH32V00x board
  to compile this sketch you will need a Board Manager version that includes 
  HardwareTimer (as of today 30/Sep/24 unpublished, I had to force install it from github)
  no 3rd party libraries used
*********************************************************/

#include "HardwareTimer.h"

HardwareTimer myTimer(TIM2);
static const unsigned int myPort= PD4;  // output port (this is the onboard LED port)
static volatile int myLED;
static bool interrupted=false;          // flag set true on interrupt
// timer interrupt routine
void timerHandler(void) {
  myTimer.pause();
  myLED= (myLED == HIGH) ? LOW : HIGH;  // blink LED
  digitalWrite(myPort, myLED);
  myTimer.setOverflow(1000000, MICROSEC_FORMAT);
  myTimer.resume();
  interrupted=true;                     // flag indicates interrupt
}

void setup() {
  Serial.begin(115200);
  delay(2000);
  Serial.println("\n\nCH32V003 HardwareTimer.h library test");
  pinMode(myPort, OUTPUT);
  myLED= LOW;
  digitalWrite(myPort, myLED); // start pulse for channel sep
  myTimer.setOverflow(1000000, MICROSEC_FORMAT);  // interrupt every second
  myTimer.attachInterrupt(timerHandler);
  myTimer.resume();
}

// on timer interrupt print *
void loop() {
  if(interrupted) {
    interrupted=false;
    Serial.print('*');
  }
}

LED blinks and Serial monitor outputs

CH32V003 HardwareTimer.h library test
******************************************

the CH32 is an interesting device but is lacking documentation and the CH32 MCU EVT Boards V1.0.4 is missing some functions