How to get SPI speed 12.5khz on CH32V003 - Page 1
Forum section: electronics / general

author: kgavionics
author_rank: Regular Contributor
timestamp: March 12, 2025, 01:10:52 am
content: HelloI'm working on project where I need an SPI speed of 12.5 KHZ.I'm using a CH32av003@48MHZ on internal oscillator.I think my only choice is an external quartz @3.2 MHZ with prescalar of 256,but it would be very slow running my application.Is there any other way to get 12.5khz SPI without loosing the HSI speed of 48MHZ?Than you in advance

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 12, 2025, 01:38:30 am
content: The SPI peripheral can divide HCLK by up to 256 *and* HCLK can be prescaled by up to 256 as well from SYSCLK (HPRE bits in RCC_CFGR0).These are only powers of two so you can't get 12.5 kHz from 48 MHz. Closest would be ~ 11.7 kHz with SPI BR = 1/256 and HPRE = 1/16.

author: brucehoult
author_rank: Super Contributor
timestamp: March 12, 2025, 04:14:05 am
content: That slow a speed you can easily bit-bang with a timer and interrupt once every 3840 clock cycles = 256 * 15.

author: HwAoRrDk
author_rank: Super Contributor
timestamp: March 12, 2025, 10:08:28 am
content: How about using the USART in synchronous mode - i.e. with clock output?The USART has a fractional baud rate generator, so you can easily do 12.5 kHz with that when you have HCLK of 48 MHz. You would just need to set a divider of 240 in USART_BRR. The baud is set by HCLK/(16*USARTDIV), so 48000000/(16*240) = 12500.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 12, 2025, 10:21:09 am
content: bit-bang it with a timer. If you're concerned about jitter, generate the clock with a timer compare and use an interrupt off that to update the data.

author: kgavionics
author_rank: Regular Contributor
timestamp: March 12, 2025, 06:25:16 pm
content: Thank you guys for all your inputs, it's very much appreciated!I'm going to elaborate what I'm trying to achieve, maybe you guys are going to point me in the right direction.I'm working on an Arinc 429 Transmitter using the IC HOLT 8586 (see scheamtic). So basically, I'm trying to send 32 bit Arinc429 word on the MOSI line and Nand it with the inverted clock signal and send both signal to the HOLT 8586 chip.What would be the best solution without hardware SPI?TIA

author: aeg
author_rank: Regular Contributor
timestamp: March 13, 2025, 01:13:41 am
content: OK, so my understanding is that during the first half of each bit cell, you want TX1IN/TX0IN to be 10 or 01 depending on bit value, and then during the second half you want TX1IN/TX0IN to be 00 or 11 (doesn't matter which).I would probably use two channels of the timer, in PWM mode, with a period of 40us (one cycle per half bit cell), to directly generate TX1IN/TX0IN without using U1. You might be looking for a less tricky solution, though.

author: kgavionics
author_rank: Regular Contributor
timestamp: March 14, 2025, 04:11:31 pm
content: Hello againI went with the timer output/compare for the clock and I got the signal I'm looking for, but now I can't get the timer2 interrupt to execute for a stupid reason that I can't find!Can someone look what I'm missing to make the global interrupt work?TIACode:volatile uint8_t tim2_intrp=0;int main(void){PIN_alternate_PP(CLOCK); // set CLOCK pin as output__enable_irq();NVIC_EnableIRQ(TIM2_IRQn);RCC->APB1PCENR |= RCC_TIM2EN; // enable timer 2 clockTIM2->CTLR1 &= ~TIM_CEN; //Disable timer counterTIM2->CTLR1 |=TIM_ARPE; //autoload of the ATRLR register enabledTIM2->PSC = (uint16_t) 0;TIM2->ATRLR = (uint16_t)1940; //12.5khzTIM2->CHCTLR2 |=TIM_OC3M_0 | TIM_OC3M_1 ;//TOGGLE 0C1REF TOGGLES WHEN TIM2_CNT=TIM2_CCR1TIM2->CCER |=TIM_CC3E; // COMPARE CAPTURE CHANNEL IS CONFIGURED AS OUTPUTTIM2->CTLR1 |=TIM_CEN; //ENABLE TIMER 2}void TIM2_IRQHandler(void)__attribute__((interrupt));void TIM2_IRQHandler(void){tim2_intrp=1;//interrupt flagTIM2->INTFR &=~TIM_CC3IF;//clear pending interrupt}

author: brucehoult
author_rank: Super Contributor
timestamp: March 14, 2025, 09:30:21 pm
content: Some suggestions that I 100% didn't come up with by myself and may or may not be useful:Summary of Likely Issues- Missing TIM_CC3IE: You didn’t enable the CC3 interrupt in TIM2->DIER.- Uninitialized CCR3: The compare value wasn’t set, so the event might not trigger.- Flag Clearing: The method to clear TIM_CC3IF might be incorrect.Interrupt Flag Clearing IssueIn your handler, you clear the interrupt flag like this:TIM2->INTFR &= ~TIM_CC3IF; // Clear pending interruptHowever, for CH32V timers (and most MCU timers), the interrupt flag is typically cleared by writing a 0 to the specific bit or, in some cases, by reading the status register followed by a write. The correct way to clear the flag is usually:TIM2->INTFR = ~TIM_CC3IF; // Write 0 to clear CC3 interrupt flagThe difference is subtle:&= ~TIM_CC3IF performs a read-modify-write operation, which might not properly clear the flag if other flags are set or if the hardware requires a direct write.= ~TIM_CC3IF ensures only the CC3IF bit is cleared while leaving other bits unchanged.Check the CH32V003 reference manual for the exact behavior of TIM2->INTFR (Interrupt Flag Register), but this is a common pitfall.https://x.com/i/grok?conversation=1900658773573730503

author: kgavionics
author_rank: Regular Contributor
timestamp: March 15, 2025, 12:13:11 am
content: Quote from: brucehoult on March 14, 2025, 09:30:21 pmThank you brucehoult for the reply, you mentioned TIM2->DIER, but there is no such register in the CH32V003 it's only part of the stm32f4 family.

author: brucehoult
author_rank: Super Contributor
timestamp: March 15, 2025, 12:29:16 am
content: DIER (DMA/Interrupt Enable Register) is at offset 0xC in STM32. Looks like WCH are using a different name for it ... DMAINTENR (DMA/interrupt enable register) in your screenshot, at the same offset and I imagine the same functionality.My apologies for any confusion from the LLM.

author: kgavionics
author_rank: Regular Contributor
timestamp: March 15, 2025, 01:04:20 pm
content: Quote from: brucehoult on March 15, 2025, 12:29:16 amI got the timer interrupt working by enabling it in the DIER (DMAINTENR) register.Thank you again for Brucehoult

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 15, 2025, 01:12:26 pm
content: The CH32V003 is a great little MCU, but relatively limited, I'm just wondering why you'd want to use such a limited MCU to control avionics (which is what ARINC 429 is for). For the challenge, I suppose?

author: kgavionics
author_rank: Regular Contributor
timestamp: March 15, 2025, 01:20:14 pm
content: Quote from: SiliconWizard on March 15, 2025, 01:12:26 pmI'm just experimenting, but the project is going to use an STM32F411 for sure!

author: peter-h
author_rank: Super Contributor
timestamp: March 16, 2025, 07:03:22 pm
content: Anything with ARINC429 has 1 or 2 extra zeroes on the priceso why not use something better like HI3593, which is what I am using. That has a simple selector register bit for slow or fast 429. Then you can use a CPU at a proper speed, with other stuff potentially doable e.g. ETH, USB, etc.

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 16, 2025, 07:36:43 pm
content: It's very easy to implement efficiently on a RP2040 or RP2350 with its PIO, for those who want something cheap, and with the RP2350 with its 2 M33 cores and PIO, you'll get something that's much more capable than a STM32F411 on which you'd have to somewhat bit-bang it or use an output compare but still with more "manual" handling (SPI peripherals rarely have a "baudrate" generator that can do more than divide the peripheral clock by powers of 2, but the PIO on RP2040/2350 can be clocked at a "fine-tuned" frequency, it has a fractional divider.)

author: peter-h
author_rank: Super Contributor
timestamp: March 16, 2025, 07:54:59 pm
content: Bit banging ARINC429 is easy (at both high and low speeds; 100k and 12.5k respectively) for areceiver, and lots of people do that if they want say 10 receivers, which would be a lot of $$$ in 429 chips, which tend to be expensive but also "dual use" (not quite ITAR) and the distis get you to sign stupid forms before you can buy them.But atransmitterneeds special wave shaping, which is conceptually easy but you end up with a fair number of components.