Код
Почитал дискусиию и решил проверить действительно ли такие траблы...
Если вы внимательно читали, то понимаете, что суть темы не в том, чтобы подключить датчик DS18B20 к STM32F100 как таковой - он у меня уже давно работает именно на софтовых задержках, реализации которых в принципе достаточно для большинства проектов. Я бы даже сказал, что нет необходимости эту реализацию задержек как-то переделывать, т. к. на время работы с шиной 1-wire все равно придется приостанавливать большинство других софтверных задач, т. к. времянка слишком жесткая...
Мое неудачное портирование исходников 1-wire на STM32F100 было связано с попыткой использования для счета задержек systick таймера ядра. Опять же, я осознаю, что это излишне и не нужно - по сути ничего не дает, но поведение этого таймера на счете "мелких" задержек вызвало мое непонимание его работы. Вот это и напрягает... Я был бы признателен тому, кто смог бы выделить время и проверить, в чем тут может быть проблема...
Повторюсь, в чем проблема... После счета задержки на основе этого таймера состояние шины 1-wire не может быть достоверно прочитано в рамках, например, сброса/проверки этой шины:
Код
// генератор прецизионных таймингов для 1wire (Tmax[sec]=2^24/Fhclk)
__INLINE void Delay1wire(unsigned int Ticks){
SysTick->LOAD = Ticks - 1;// возможна подстройка для точности
SysTick->CTRL = 0x00000005;// запуск таймера
while(!BITCHK(SysTick->CTRL,SysTick_CTRL_COUNTFLAG));// пока не установится COUNTFLAG
SysTick->CTRL = 0x00000004;// останов таймера
}
// пин C15 настроен как GPIO_Mode_Out_OD ( эмуляция 1-wire)
// к пину C15 припаян внешний pull-up 5k с датчиком DS18B20
// пин A11 тестовый , настроен как GPIO_Mode_Out_PP
Work:
GPIOC->BRR=GPIO_BRR_BR15;// сбросить С15 (шина в состояние "0")
Delay1wire(500*us);
__istate_t s = __get_interrupt_state();
__disable_interrupt();
GPIOC->BSRR=GPIO_BSRR_BS15;// установить C15 (шина в состояние "1")
Delay1wire(80*us);
tmp=(GPIOC->IDR >> 15)&1;// получить текущее состояние шины(должен быть "0" при испр датчике
__set_interrupt_state(s);
GPIOA->BSRR=tmp?GPIO_BSRR_BS11:GPIO_BSRR_BR11;// тестовый пин(при подкл исправном датчике) всегда = 1 = ошибка !!!!!!
Delay1wire(420*us);
goto Work;
В вышеприведенном коде не удается правильно прочитать состояние шины. Далее, для поиска возможной ошибки, я упростил процедуру максимально:
Код
// пин C15 настроен как GPIO_Mode_Out_OD ( эмуляция 1-wire)
// к пину C15 припаян внешний pull-up 5k с датчиком DS18B20
Work:
GPIOC->BRR=GPIO_BRR_BR15;// сбросить С15
Delay1wire(500*us);
GPIOC->BSRR=GPIO_BSRR_BS15;// установить C15
Delay1wire(80*us);
Delay1wire(420*us);
goto Work;
По идее, этот код должен давать на С15 сигнал импульс/пауза 500us/500us. У меня он почему-то дает 600us/400us. Естественно все прерывания запрещены.
Хотелось бы понять причину такого несоответствия... Возможно, это поможет понять почему исходно не читается правильно состояние шины...