|
Проблема с функцией задержки., STM32F107 |
|
|
|
Jun 27 2016, 09:05
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Какая то ну очень странная проблема. Я сделал функцию задержки так. Код void Delay_us(uint32_t us) { uint32_t ticks = 72 * us; SysTick->LOAD = ticks; SysTick->CTRL |= 0x01; //enable while (!(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk)); SysTick->CTRL &= ~0x01; //disable } Проверяю Код PIN_OUT_PP(One_Wire_Pin); while (1) { PIN_ON(One_Wire_Pin); Delay_us(500); PIN_OFF(One_Wire_Pin); Delay_us(500); } Вижу хороший сигнал 500 микросек. Никаких проблем. А вот в этой функции Код unsigned int One_Wire_Reset(GPIO_TypeDef * GPIOx, uint16_t PINx) { unsigned int tmp; PIN_IN(GPIOx, PINx); if ((PIN_SYG(GPIOx, PINx))==0) return One_Wire_Bus_Low_Error;
PIN_OUT_PP(GPIOx, PINx); PIN_OFF(GPIOx, PINx); Delay_us(480); PIN_ON(GPIOx, PINx); PIN_IN(GPIOx, PINx); Delay_us(60);
if ((PIN_SYG(GPIOx, PINx))==0) tmp=One_Wire_Success; else tmp=One_Wire_Error_No_Echo; Delay_us(Time_After_Reset); return tmp; } я вижу сигнал идет вниз на 350 микро (вместо 480). Кручу и так и этак, ума не приложу в чем проблема
Сообщение отредактировал Jenya7 - Jun 27 2016, 09:06
|
|
|
|
|
Jun 27 2016, 11:35
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Jenya7 @ Jun 27 2016, 10:05)  Какая то ну очень странная проблема. Я сделал функцию задержки так. Уже неоднократно обсуждалось и предлагалось, как тут.
|
|
|
|
|
Jun 27 2016, 12:45
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Извиняюсь, что не про задержку: QUOTE (Jenya7 @ Jun 27 2016, 12:05)  CODE unsigned int One_Wire_Reset(GPIO_TypeDef * GPIOx, uint16_t PINx) { ... PIN_OUT_PP(GPIOx, PINx); ... Вы хорошо подумали?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 27 2016, 13:23
|
Местный
  
Группа: Участник
Сообщений: 328
Регистрация: 1-06-06
Из: USA
Пользователь №: 17 672

|
Цитата(Jenya7 @ Jun 27 2016, 05:38)  Я не хочу чтоб он все время тикал, будет генерироваться интерапт который не нужен (SysTick_Handler). А так открыл, отсчитал, закрыл. STM32F4xx Код #define DWT_CYCCNT *(volatile uint32_t *)0xE0001004 #define DWT_CONTROL *(volatile uint32_t *)0xE0001000 #define SCB_DEMCR *(volatile uint32_t *)0xE000EDFC #ifndef HCLK #define HCLK 168000000 #endif
#define dwt_ena() (SCB_DEMCR |= CoreDebug_DEMCR_TRCENA_Msk) #define dwt_dis() (SCB_DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk) #define dwt_rst() DWT_CYCCNT = 0 #define dwt_start() (DWT_CONTROL |= DWT_CTRL_CYCCNTENA_Msk) #define dwt_cnt() DWT_CYCCNT
void delay_1us (void) { uint32_t start, end; start = dwt_cnt(); end = start + HCLK/1000000; if (end < start) while (dwt_cnt() > start); while (end >= dwt_cnt()); }
void delay_1ms (void) { uint32_t start, end; start = dwt_cnt(); end = start + HCLK/1000; if (end < start) while (dwt_cnt() > start); while (end >= dwt_cnt()); Идея, надеюсь, понятна...
--------------------
|
|
|
|
|
Jun 27 2016, 13:28
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Jun 27 2016, 18:23)  Вы уверены, что он должен передавать именно в этом режиме? Сергей что вы такой загадочный.  А в каком же еще режиме ему передавать? У меня внешняя подтяжка. Цитата(pitt @ Jun 27 2016, 18:23)  Идея, надеюсь, понятна... Спасибо. Сделаю на DWT.
|
|
|
|
|
Jun 27 2016, 13:44
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Jenya7 @ Jun 27 2016, 15:05)  Какая то ну очень странная проблема. SysTick->LOAD = ticks; SysTick->CTRL |= 0x01; //enable while (!(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk)); SysTick->CTRL &= ~0x01; //disable Хотя-бы откройте даташит с описанием Systick! Почему SysTick->CTRL |= 0x01 ??? Почему текущее значение не сбрасываете? Почему флаг предварительно не чистите? .... А что у Вас в остальных битах? А бит 1? Может у вас там ISR вызывается? А бит 2? Какой частотой тактируется Systick? Что за магическое число 72? Если хотите тактироваться частотой ядра, то нужно: Код SysTick->CTRL = 1 << 2; u32 j = SysTick->CTRL; SysTick->LOAD = SysTick->CURRENT = ticks; SysTick->CTRL = 1 | 1 << 2; while (!(SysTick->CTRL & 1 << 16)); SysTick->CTRL = 1 << 2; //disable
|
|
|
|
|
Jun 27 2016, 13:46
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Jenya7 @ Jun 27 2016, 16:28)  Сергей что вы такой загадочный.  А в каком же еще режиме ему передавать? У меня внешняя подтяжка. Точно в таком же, как и в I2C - в режиме открытого коллектора. Во-первых, на шине не будет конфликта уровней, когда датчик уже начал отвечать, а вы еще не начали его слушать. Во-вторых, не нужно будет вообще менять режим ноги, потому что ногу в режиме открытого коллектора можно читать не меняя режима (отключив нижний транзистор, т.е. выдав единицу).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 27 2016, 13:54
|
Профессионал
    
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075

|
Цитата(Сергей Борщ @ Jun 27 2016, 18:46)  Точно в таком же, как и в I2C - в режиме открытого коллектора. Во-первых, на шине не будет конфликта уровней, когда датчик уже начал отвечать, а вы еще не начали его слушать. Во-вторых, не нужно будет вообще менять режим ноги, потому что ногу в режиме открытого коллектора можно читать не меняя режима (отключив нижний транзистор, т.е. выдав единицу). Спасибо. Не знал. Последнее я не понял. Что значит выдав единицу? Это на выход? Цитата(jcxz @ Jun 27 2016, 18:44)  Хотя-бы откройте даташит с описанием Systick! Почему SysTick->CTRL |= 0x01 ??? Почему текущее значение не сбрасываете? Почему флаг предварительно не чистите? .... А что у Вас в остальных битах? А бит 1? Может у вас там ISR вызывается? А бит 2? Какой частотой тактируется Systick? Что за магическое число 72? Если хотите тактироваться частотой ядра, то нужно: Код SysTick->CTRL = 1 << 2; u32 j = SysTick->CTRL; SysTick->LOAD = SysTick->CURRENT = ticks; SysTick->CTRL = 1 | 1 << 2; while (!(SysTick->CTRL & 1 << 16)); SysTick->CTRL = 1 << 2; //disable Мда...Точно. Спасибо. Вообще то это не disable SysTick->CTRL = 1 << 2; а выбор источника тактирования...ну и disable тоже.
Сообщение отредактировал Jenya7 - Jun 27 2016, 14:39
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|