2014-03-04 12:40 AM
Hi, I need to generate some pulses on a pin with a timer.
Pin is normally high, it have to stay low for a precise time, then high for at least another time.I tried with one-pulse mode, but it works conversely: it wait, then it do pulse.Someone has an idea? Please not with software timers...Thanks2014-03-04 07:41 AM
Well there's PWM mode, where the pulse width and period can be modified, and can be always ON or OFF. There's timers with N channels, and polarity settings?
2014-03-04 08:14 AM
I have to communicate with a DS2431, it's a 1-wire EEPROM.
It has strictly timings, I wrote code with software timing already, but sometimes it fails I think because of RTOS interrupts.When I have to write a bit in, I have to send a pulse short or long respectively if 1 or 0, then to wait the end of the fixed time slot. This is the only condition must be respected.STM32 timers' one pulse mode is the opposite: delay before and then pulse.Is it possible to do it with a single timer or I have to cascade two of them?2014-03-04 08:23 AM
If I were modifying a single parameter DMAing that from a table of sequences would work quite effectively. For two parameters, I'd probably opt for a similar arrangement but use the TIM Update interrupt to modify those parameters at each step.
2014-03-26 03:31 AM
I've found the solution: TIM3 generates pulses and at same time it measures pulse width on same pin.
TIM3 is controlled by TIM9 which starts and stops it when needed.Both timers are initialized to be clocked at 8MHz.The memory is connected to PC8, which is initialized as open drain, and with AF=3 that is TIM3_CH3.PC8 has a 1,8kΩ resistor to VDD to let pin high when not asserted.This is the function to check if a device is connected:_bool OWConnected(){ TIM9->ARR=7040; TIM9->CNT=1; TIM9->SMCR=0; TIM9->CR1=TIM_OPMode_Single; TIM9->CR2=TIM_TRGOSource_Enable; TIM3->CCMR2=(TIM3->CCMR2&~(TIM_CCMR2_OC3M|TIM_CCMR2_CC3S|TIM_CCMR2_OC4M|TIM_CCMR2_CC4S))|TIM_OCMode_Timing|(TIM_OCMode_Timing<<8); TIM3->ARR=7050; //higher than TIM9->ARR TIM3->CNT=4479; //setting it at CCR3+1 pulse is generated immediately TIM3->CCR3=4478; TIM3->CR1=TIM_CounterMode_Down; TIM3->SMCR=TIM_SlaveMode_Gated|TIM_TS_ITR0; TIM3->CR2=0; TIM3->CCMR2=(TIM3->CCMR2&~(TIM_CCMR2_OC3M|TIM_CCMR2_CC3S|TIM_CCMR2_IC4F|TIM_CCMR2_IC4PSC|TIM_CCMR2_OC4M|TIM_CCMR2_CC4S))|TIM_OCMode_PWM2|(TIM_ICSelection_IndirectTI<<8); TIM3->CCER=(TIM3->CCER&~(TIM_CCER_CC3P|TIM_CCER_CC4P|TIM_CCER_CC4NP))|((TIM_OutputState_Enable|TIM_OCPolarity_High)<<8)|((TIM_CCx_Enable)<<12); OWPORT->MODER=(OWPORT->MODER&~(3<<(OWPIN*2)))|(2<<(OWPIN*2)); TIM3->SR&=~TIM_FLAG_Update; TIM9->SR&=~TIM_FLAG_Update; TIM3->CR1|=TIM_CR1_CEN; TIM9->CR1|=TIM_CR1_CEN; //start both timers while((TIM9->SR&TIM_FLAG_Update)==0); //wait finish TIM3->CR1&=~TIM_CR1_CEN; return (TIM3->CCR4<6421)?1:0; //if connected a device generate a pulse}To write a byte is like Morse code: short and long pulses means respectively 1 and 0:void OWWrite_bit(U8 v){ TIM3->SR&=~TIM_FLAG_Update; TIM9->SR&=~TIM_FLAG_Update; if(v) { TIM3->CCR3=80; TIM3->CNT=81; } else { TIM3->CNT=721; TIM3->CCR3=720; } TIM3->CR1|=TIM_CR1_CEN; TIM9->CR1|=TIM_CR1_CEN; while((TIM9->SR&TIM_FLAG_Update)==0);}void OWWrite(U8 v){U8 bitMask; TIM9->ARR=800; TIM9->CNT=1; TIM3->CCMR2=(TIM3->CCMR2&~(TIM_CCMR2_OC3M|TIM_CCMR2_CC3S))|TIM_OCMode_Timing; TIM3->ARR=800; TIM3->CNT=799; TIM3->CCR3=0; TIM3->CR1|=TIM_OPMode_Single|TIM_CounterMode_Down; TIM3->CCMR2=(TIM3->CCMR2&~(TIM_CCMR2_OC3M|TIM_CCMR2_CC3S))|TIM_OCMode_PWM2; TIM3->CCER=(TIM3->CCER&~TIM_CCER_CC3P)|((TIM_OutputState_Enable|TIM_OCPolarity_High)<<8); for (bitMask = 0x01; bitMask; bitMask <<= 1) OWWrite_bit(bitMask & v);}To read, after a pulse, device replies not asserting pin if bit is 1, asserting it for a while if 0:U8 OWRead_bit(){ TIM3->CNT=79; TIM3->CCR3=78; TIM3->SR&=~TIM_FLAG_Update; TIM9->SR&=~TIM_FLAG_Update; TIM3->CR1|=TIM_CR1_CEN; TIM9->CR1|=TIM_CR1_CEN; while((TIM9->SR&TIM_FLAG_Update)==0); TIM3->CR1&=~TIM_CR1_CEN; return (TIM3->CCR4>662)?1:0;}U8 OWRead(){U8 bitMask;U8 r = 0; TIM9->ARR=640; TIM9->CNT=1; TIM3->CCMR2=(TIM3->CCMR2&~(TIM_CCMR2_OC3M|TIM_CCMR2_CC3S|TIM_CCMR2_OC4M|TIM_CCMR2_CC4S))|TIM_OCMode_Timing|(TIM_OCMode_Timing<<8); TIM3->ARR=800; TIM3->CNT=79; TIM3->CCR3=78; TIM3->CR1=TIM_CounterMode_Down; TIM3->CCMR2=(TIM3->CCMR2&~(TIM_CCMR2_OC3M|TIM_CCMR2_CC3S|TIM_CCMR2_IC4F|TIM_CCMR2_IC4PSC|TIM_CCMR2_OC4M|TIM_CCMR2_CC4S))|TIM_OCMode_PWM2|(TIM_ICSelection_IndirectTI<<8); TIM3->CCER=(TIM3->CCER&~(TIM_CCER_CC3P|TIM_CCER_CC4P|TIM_CCER_CC4NP))|((TIM_OutputState_Enable|TIM_OCPolarity_High)<<8)|((TIM_CCx_Enable)<<12); for (bitMask = 0x01; bitMask; bitMask <<= 1) if (OWRead_bit()) r |= bitMask; return r;}That's all folks!2014-03-26 06:05 AM
Just a note, you don't need to RMW on TIM->SR, so
TIM3->SR &= ~TIM_FLAG_Update; Just needs to be, also removes a race conditionTIM3->SR = ~TIM_FLAG_Update;