Да чего вы кинулись код то кидать?
Eddy_Em писал(а):
VladislavS, так ведь и подход абсолютно разный: на аврке нет DMA, там реализовать 1-wire можно только двумя способами: таймер+прерывание или UART. А на STM32 можно таймер с DMA, можно USART с DMA…
А кто-нибудь может выложить код для STM32 где реализован 1-wire способом: таймер+прерывание?
А то сижу изобретаю велосипед.
USART не хочу использовать, к тому же не хочу подключать несколько DS18B20 на одну линию, хочу каждый датчики на отдельную ногу STM32, тут ни каких USART не хватит.
Пытался сам переписать свой старый код от AVR с delay() на использование таймера, но не пойму как в STM32 таймер работает, можно ли внутри прерывания таймера поменять значение перезагрузки (TIM_Period)?
Т.е. я хотел в начале слота сначала выдать на 1-wire 0, настроить таймер на 1мкс, запустить таймер, потом внутри прерывания таймера например, выдать на 1-wire 1 и перенастроить таймер например на 60мкс (окончание слота). Вот у меня такое впечатление, что внутри прерывания не перенастраивается таймер, может я вообще как-то неправильно таймер настроил. Может кто подскажет, что как то по другому нужно делать 1-wire на таймере.
Вот кусок моего кода работы с таймером (только не смейтесь, микроконтроллерами не занимаюсь, так только, разовую самоделку нужно сделать):
void TIM3_Set_Period(uint32_t a_us)
{
TIM_TimeBaseInitTypeDef TIMER_InitStructure;
TIM_TimeBaseStructInit(&TIMER_InitStructure);
TIMER_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIMER_InitStructure.TIM_Prescaler = 71; //1 мкс
TIMER_InitStructure.TIM_Period = a_us;
TIM_TimeBaseInit(TIM3, &TIMER_InitStructure);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
// TIM_Cmd(TIM3, ENABLE);
}
void TIM3_init(void)
{
// TIMER3
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM3_Set_Period(2); // по умолчанию прерывание через 2 мкс
/* NVIC Configuration */
/* Enable the TIM4_IRQn Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
/* Даём знать, что обработали прерывание */
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
TIM_Cmd(TIM3, DISABLE);
switch(OneWire_step)
{
case Read_init:
OneWire_writePinHIGH();
TIM3_Set_Period(200); //
здесь должно быть <15 мкс, а тут хоть 200 ставлю все равно температуру считывает, будь то и не меняет TIM_Period OneWire_step = Read_Bit;
break;
case Read_Bit:
// - Read bit
OneWire_Bit = OneWire_readPin();
TIM3_Set_Period(60); // временной слот минимум 60 мкс
OneWire_step = End_slot;
break;
case End_slot:
OneWire_step = 0;
OneWire_done = 1;
break;
}; // end switch
if ( !OneWire_done ) {
TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE);
}
}
}
uint8_t OneWire_readBit(void){
OneWire_done = 0;
// - Drop line
OneWire_writePinLOW();
TIM3_Set_Period(1); // низкий уровень не менее 1us
OneWire_step = Read_init;
TIM_SetCounter(TIM3, 0);
TIM_Cmd(TIM3, ENABLE);
delay_us( 100 ); //
чтоб работало пока пришлось такой костыль подставить, пока не разобрался с настройкой таймера в прерывании uint8_t Bit = OneWire_Bit;
return Bit;
}