2020-03-03 11:54 PM
Hello community!
My mcu is STM32H743IIT6 tqsp176 from blue waveshare board. I create a new project from Cube with HAL. Then I make the simplest flashing cycle of the LED:
volatile unsigned long x = 0;
while (1)
{
while (x++ < 2000000) {}
x = 0;
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);
while (x++ < 2000000) {}
x = 0;
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
}
Any changes in code result in accidental change in frequency and DUTY CYCLE. For example:
1) When I make variable x global or local.
2) When i put beforce blink cycle this line HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);
3) When i add new variable such Y to cycle:
volatile unsigned long x = 0;
volatile unsigned long y = 0;
while (1)
{
while (x++ < 2000000) {}
y = x;
x = 0;
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);
while (x++ < 2000000) {}
y = x;
x = 0;
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
}
In this case frequesy change in random range. Can get X times higher, and can get X times lower. Duty cycle can become 10% / 90% or 30% / 70% and other.
4) When i put some code before this cycle frequency and duty cycle also change!!!
5) Even just when I move some code in places!!!
volatile unsigned long y = 0; // <<<<<<< declare first
volatile unsigned long x = 0;
while (1)
{
x = 0; // << move x here
while (x++ < 2000000) {}
y = x;
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_RESET);
x = 0; // << move x here
while (x++ < 2000000) {}
y = x;
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_0, GPIO_PIN_SET);
}
Absolutely any changes in code result in accidental change in frequency and DUTY CYCLE.
I try mcu work on HSE, PLL, HSI... there is no difference. I try keil compiler v5 & v6.. no difference. I try to create project without CUBE and HAL ... there is no difference. I try any dividers and clocks ... there is no difference.
MCU broken?
2020-03-04 08:39 AM
Today I run hardware PWM with TIMER3 CH1. It 's impossible, but the problem remains!
I excluded RCC config from system and now MCU work on HSI 64 MHz. Startup file from keil not modified. Are 2 running timers in system. TIM12 with interrupt and TIM3 without interrupt.
RCC->APB1LENR |= RCC_APB1LENR_TIM12EN;
TIM12->ARR = 10000;
TIM12->DIER |= TIM_DIER_UIE;
TIM12->PSC = 1000;
TIM12->CR1 |= TIM_CR1_URS;
TIM12->CR1 |= TIM_CR1_CEN;
RCC->APB1LENR |= RCC_APB1LENR_TIM3EN;
TIM3->ARR = 20000;
TIM3->PSC = 1000;
TIM3->CR1 |= TIM_CR1_URS;
TIM3->CR1 |= TIM_CR1_ARPE;
TIM3->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
TIM3->CCR1 = 10000;
TIM3->EGR |= TIM_EGR_UG;
TIM3->CCER |= TIM_CCER_CC1E;
TIM3->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
while (1) {}
And interrupt for TIM12
void TIM8_BRK_TIM12_IRQHandler (void)
{
if (TIM12->SR & 1UL)
{
TIM12->SR = 0;
if (flag)
{
LED_ON;
flag = 0;
}
else
{
LED_OFF;
flag = 1;
}
}
}
In global visibility area:
#define LED_ON GPIOI->BSRR |= (1UL << 16)
#define LED_OFF GPIOI->BSRR |= (1UL << 0)
volatile unsigned char flag = 0;
When i put LED_ON while (1) {} frequency and duty cycle are broken down.
2020-03-04 11:02 AM
> That 's the whole code. There is nothing any more.
Not quite true... There should be a startup file (.s). It can pull in SystemInit() etc.
How do you build and debug? Which IDE? Debugger?
-- pa
Updated:
Ah sorry, I see. It's Keil. Compiler v5 or v6?
2020-03-04 12:56 PM
PSC and ARR are programmed as N-1 for N states, zero thru N-1
TIM12->ARR = 10000 - 1;
TIM12->PSC = 1000 - 1;
Divide by 10,000,000
2020-03-04 02:37 PM
> When i put LED_ON while (1) {} frequency and duty cycle are broken down.
2020-03-04 10:58 PM
I tried both compilers (v5 v6).
2020-03-04 11:08 PM
1) 3.3V
2) 600 Ohm. But i used another pins without leds. They have exactly the same problem.
3) 4.347 MHz with prescaler /15
4) Right. It is waveshare blue core devboard.
5) Only one jumper set (VREF -> 3.3V)
2020-03-05 10:02 AM
4.347 MHz * 15 = 65.205, it looks quite bad. Datasheet says 63.7 to 64.3.
Tried your code with a few changes on a Nucleo-743ZI2 board. No clock setup, running on HSI. Much better results here.
Using timer channel 3 to blink the led on PB0, -1 from ARR and PSC as Clive1 suggested.
void led_red(int x) {
GPIOB->BSRR = x ? (1u << 14u) : (1u << 30u);
}
void led_yellow(int x) {
GPIOE->BSRR = x ? (1u << 1u) : (1u << 17u);
}
volatile int flag;
#define LED_ON led_yellow(1)
#define LED_OFF led_yellow(0)
void TIM8_BRK_TIM12_IRQHandler (void)
{
if (TIM12->SR & 1UL)
{
TIM12->SR = 0;
if(flag)
{
LED_ON;
flag = 0;
}
else
{
LED_OFF;
flag = 1;
}
}
}
int main() {
RCC->AHB4ENR |= RCC_AHB4ENR_GPIOBEN | RCC_AHB4ENR_GPIOEEN;
RCC->AHB4ENR;
RCC->APB1LENR |= RCC_APB1LENR_TIM12EN | RCC_APB1LENR_TIM3EN;
RCC->APB1LENR;
led_red(1);
GPIOB->AFR[0] = 2 << 0; // PB0 AF2 TIM3_CH3
GPIOB->MODER &= ~((2u << 28u) | (1u << 0u)); // red led output, green AF
GPIOE->MODER &= ~(2u << 2u); // yellow led output
TIM12->ARR = 10000-1;
TIM12->DIER |= TIM_DIER_UIE;
TIM12->PSC = 1000-1;
TIM12->CR1 |= TIM_CR1_URS;
TIM12->CR1 |= TIM_CR1_CEN;
TIM3->ARR = 20000-1;
TIM3->PSC = 1000-1;
TIM3->CR1 |= TIM_CR1_URS;
TIM3->CR1 |= TIM_CR1_ARPE;
// TIM3->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
// TIM3->CCR1 = 10000;
TIM3->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3PE;
TIM3->CCR3 = 10000-1;
TIM3->EGR |= TIM_EGR_UG;
// TIM3->CCER |= TIM_CCER_CC1E;
TIM3->CCER |= TIM_CCER_CC3E;
TIM3->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
while(1)
;
}
Frequency measured on both outputs: 3.209 - 3.211 Hz, period 311.4 - 311.6 ms.
Then played around a bit.
Setting the system clock to 480 MHz, timer clocks 240 MHz (clock setup in my answer here), still based on HSI:
Frequency measured on both outputs: 12.03 Hz, period 83.12 ms.
Setting system clock to 480 MHz based on HSI:
Frequency measured on both outputs: 11.95 Hz, period 83.68 ms. I might have overlooked something here.
2020-03-05 09:57 PM
My logic analyzer says than frequency between 4.16666 (62,4 MHz) and 4.347 (65,55 MHz). I dont have an oscilloscope.