2015-10-19 08:13 PM
Hi,
I am new to this forum, new to ST world. Where I should start to look into programming 1 wire GPIO, generating bursts with custom widths 100 .. 300 micro-seconds for STBC02 chip. For example to turn one of the power switched ON/OFF I have to buzz a pin: (1 is 100 us, start/stop bit is 300us)OFF: ..00000111010111000000000.. 1. Should I go with PWM, brute GPIO pull/up down or timers ? Thank you.
2015-10-20 01:08 AM
Marius,
you can use both methods, they all are valid. To help you to take a decision you need to consider other requirements of your project: are there others functions to run into the MCU ? simultaneously ? are you in a hurry ? do you want to simply make it working, or do you want to implement an elegant solution ? Well. Go with GPIO, it is fast, easy to code and debug. The timing of waveforms will probably not be perfect, but the end device might already manage large margin, and all should work anyway. Or, go with timers. This should increase the difficulty (starting condition of timer outputs are sometime not easy to manage, timer documentation is well known to be unfriendly ) and the precision of timings as well. Do not forget an alternative architecture: a timer triggers a DMA to update regularly GPIO output register. Note that this does not work when GPIO is located in (what ST call) IOPORT, which is the case for STM32L0.2015-10-23 01:34 PM
Hi,
Thank you. I went with timers and looks pretty good. For whom might be interested.Prerequisites:
Board: NUCLEOSTM32F411
compatible SDK: STM32Cube_FW_F4_V1.5.0static int Toggles;
static int Startseq; static TIM_HandleTypeDef TimHandle; void Turn_SW1_OA(BOOL on) { Toggles = 4 + (on * 2); Startseq = 3; tim_work(); } // 10 Khz clock void tim_work(void) { uint32_t sysclock = SystemCoreClock; uint32_t uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1; // 10 Khz /// test 1 Hz with a LED Set_gpio(FALSE); // should be 0, but anyway #ifdef TIMER_LED_TEST_1HZ uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10) - 1; HAL_Delay(3000); //stop to see the LED #endif __TIM4_CLK_ENABLE(); /// 10 Khz 100us clock period = T_SYS_CLOCK/(prescaler+1)*(period+1) TimHandle.Instance = TIM4; TimHandle.Init.Period = 10000 - 1; TimHandle.Init.Prescaler = uwPrescalerValue; TimHandle.Init.ClockDivision = 0; TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK) { printf(''Err HAL_TIM_Base_Init\r\n''); return; } if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK) { HAL_TIM_Base_DeInit(&TimHandle); printf(''Err HAL_TIM_Base_Init\r\n''); return; } HAL_NVIC_SetPriority(TIM4_IRQn, 0, 1); HAL_NVIC_EnableIRQ(TIM4_IRQn); while(_toggles>=0) { HAL_Delay(1); }; #ifdef TIMER_LED_TEST_1HZ HAL_Delay(3000); //stop see the LED #endif HAL_Delay(1); //more than 500us, stop LEVEL Set_gpio(FALSE); // end STOP sequence started in IRQ last toggle HAL_NVIC_DisableIRQ(TIM4_IRQn); HAL_TIM_Base_Stop_IT(&TimHandle); HAL_TIM_Base_DeInit(&TimHandle); __TIM4_CLK_DISABLE(); } void TIM4_IRQHandler(void) { __HAL_TIM_CLEAR_FLAG(&TimHandle, TIM_FLAG_UPDATE); if(_startseq-->0) { Set_gpio(1); return; } if(--_toggles>0) { Toggle_gpio(); } else { Set_gpio(1); // put it up for STOP, (main will put it down) } }