реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Проблема с функцией задержки., STM32F107
Jenya7
сообщение Jun 27 2016, 09:05
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 27 2016, 09:16
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



А я вот так сделал:
CODE
#include "systick.h"
#include "stm32f0xx.h"

void
systick_init(void)
{
SysTick->CTRL &= SysTick_CTRL_ENABLE_Msk; // stop SysTick timer
SysTick->LOAD = 0x00FFFFFF;
SysTick->VAL = 0x00FFFFFF;
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; // start SysTick timer
}

int
systick_ticks(void)
{
return SysTick->VAL;
}

int
systick_diff(int from, int to)
{
return (from - to) & 0x00FFFFFF;
}

void
systick_delay(int ticks)
{
int start = systick_ticks();
while (systick_diff(start, systick_ticks()) < ticks) ;
}
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 27 2016, 09:38
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(scifi @ Jun 27 2016, 14:16) *
А я вот так сделал:

Я не хочу чтоб он все время тикал, будет генерироваться интерапт который не нужен (SysTick_Handler). А так открыл, отсчитал, закрыл.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 27 2016, 11:09
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Jenya7 @ Jun 27 2016, 12:38) *
Я не хочу чтоб он все время тикал, будет генерироваться интерапт который не нужен (SysTick_Handler).

Не пойму, кому это может помешать. Можно подумать, кто-то держит у виска пистолет и заставляет обрабатывать все запросы на прерывание.
Впрочем, хозяин - барин.
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Jun 27 2016, 11:35
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



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

Уже неоднократно обсуждалось и предлагалось, как тут.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 27 2016, 12:01
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(KnightIgor @ Jun 27 2016, 16:35) *
Уже неоднократно обсуждалось и предлагалось, как тут.

спасибо поробую с DWT. В EFM32 я делал на нем задержки все работало хорошо. Что интересно - сделал задержку на таймере и вышеуказанная функция заработала. Вижу ожидаемые 480 микро. Интересно почему SysTick так себя ведет.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 27 2016, 12:45
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 27 2016, 13:18
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Jun 27 2016, 17:45) *
Извиняюсь, что не про задержку:
Вы хорошо подумали?

Пин работает в двух режимах - выход пуш-пул на передачу и вход на прием.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 27 2016, 13:23
Сообщение #9


Гуру
******

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



QUOTE (Jenya7 @ Jun 27 2016, 16:18) *
выход пуш-пул на передачу
Вы уверены, что он должен передавать именно в этом режиме?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
pitt
сообщение Jun 27 2016, 13:23
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 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());


Идея, надеюсь, понятна...


--------------------
Прокричал немой глухому:"...Спасибо за внимание!"
http://www.youtube.com/watch?v=3Nnj4ky4Z_g
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 27 2016, 13:28
Сообщение #11


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(Сергей Борщ @ Jun 27 2016, 18:23) *
Вы уверены, что он должен передавать именно в этом режиме?

Сергей что вы такой загадочный. sm.gif А в каком же еще режиме ему передавать? У меня внешняя подтяжка.

Цитата(pitt @ Jun 27 2016, 18:23) *
Идея, надеюсь, понятна...

Спасибо. Сделаю на DWT.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 27 2016, 13:44
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 27 2016, 13:46
Сообщение #13


Гуру
******

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



QUOTE (Jenya7 @ Jun 27 2016, 16:28) *
Сергей что вы такой загадочный. sm.gif А в каком же еще режиме ему передавать? У меня внешняя подтяжка.
Точно в таком же, как и в I2C - в режиме открытого коллектора. Во-первых, на шине не будет конфликта уровней, когда датчик уже начал отвечать, а вы еще не начали его слушать. Во-вторых, не нужно будет вообще менять режим ноги, потому что ногу в режиме открытого коллектора можно читать не меняя режима (отключив нижний транзистор, т.е. выдав единицу).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jun 27 2016, 13:54
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 27 2016, 16:13
Сообщение #15


Гуру
******

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



QUOTE (Jenya7 @ Jun 27 2016, 16:54) *
Последнее я не понял. Что значит выдав единицу? Это на выход?
Ну да. Верхний транзистор при настройке выхода в режим открытого стока отключается совсем. При выводе нуля включается нижний транзистор, на выходе появляется ноль. При выводе единицы нижний транзистор отключается, выход оказывается в третьем состоянии и притягивается к единице внешним резистором. Вот в это время ногу и можно читать - если никто другой не притянул ее к земле своим открытым стоком/коллектором, то с нее прочитается единица. Если притянул - соответственно, ноль.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 3rd July 2025 - 09:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01508 секунд с 7
ELECTRONIX ©2004-2016