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

 
 
> STM32F100C6T6 и 1-wire, не отладить в IAR EWARM v6.30.4
ivainc1789
сообщение Jan 21 2012, 19:58
Сообщение #1


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

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



К STM32F100C6T6 подключен DS18B20. Со времен AVR есть отлаженные исходники для 1-wire bus. Думалось, что все будет просто при наладке портированных исходников, но затык случился конкретный: отладить и проверить работу подключенного DS18B20 практически не удалось. Разбор полетов указал на... странную работу портов и решения или ошибки что-то никак не увидел. Пришлось упростить до одного файла main.c, в котором приведены два упражнения (примера). Как вывести из IAR (Win7 64) с русскими комментами вместо крякозябр - не знаю, потому см. аттач.
Прикрепленный файл  main.pdf ( 26.04 килобайт ) Кол-во скачиваний: 603

Разочарований в STM32F100 два:
1. При частоте HCLK 24MHz максимальная частота ногодрыгания ~1.78Mhz. При макс оптимизации! Это катастрофа! Возможно, что-то сделано не так в системе тактирования? Неужели STM32 такие медленные?
2. Отладить простую процедуру сброса 1-wire не смог! Осциллом смотрю - все очень безоблачно: сначала вижу отриц импульс на 500us, потом проц освобождает шину, датчик ждет 35us и удерживает ее в нуле еще на 60-120us, т. е. с момента окончания отриц импульса до момента получения значения состояния шины я заложил 80us - вполне достаточно. Каково же было мое удивление, когда выяснилось, что проц читает это состояние как 1, хотя судя по осциллу явно должен быть 0. Проверил отладкой в EWARM через J-Link Ultra, что если вручную перед чтением установить на шине 0, то это состояние софтом читается правильно. Все дело в скорости чтения... Проц почему-то не может получить значение пина за несколько us. Стало ясно, почему и прочие процедуры чтения ключа и т. п. не работали... Попытки отключить USE_FULL_ASSERT, манипуляции оптимизацией ни к чему не привели, библиотечные функции проверены. Система тактирования проверена частично через вывод на пин MCO - Fhclk=24MHz. Нужна помощь...
Go to the top of the page
 
+Quote Post
3 страниц V  < 1 2 3  
Start new topic
Ответов (30 - 44)
shista
сообщение Jan 25 2012, 13:52
Сообщение #31





Группа: Участник
Сообщений: 12
Регистрация: 15-07-09
Пользователь №: 51 296



Цитата
Мое неудачное портирование исходников 1-wire на STM32F100 было связано с попыткой использования для счета задержек systick таймера ядра.

Пришел домой с работы. Модифицировал предыдущий код на работу с systick таймером. Проверил значение переменной в отладке. Менял температуру датчика. Опять работает... Что я делаю не так?
Сразу скажу, что кусок кода не мой, я брал из библиотеки Cox, жаль её перерабатывают, старые исходники снесли с сайта, а новых до сих пор не написали...

Цитата
Хотелось бы понять причину такого несоответствия...

А можно весь проект? Или хотя бы основной файл, чтобы не заниматься лишней работой по инициализации, а просто потестить хотя бы в том же отладчике...
Прикрепленные файлы
Прикрепленный файл  Blinky_4.rar ( 746.85 килобайт ) Кол-во скачиваний: 82
 
Go to the top of the page
 
+Quote Post
ivainc1789
сообщение Jan 25 2012, 17:27
Сообщение #32


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

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



Цитата
А можно весь проект?

Конечно. Все подготовил и перепроверил. Проблема описана в main.c и присутствует при отладке с любым уровнем оптимизации... Я бессилен... )))
Проект создан в IAR EWARM v6.30.4.

Прикрепленные файлы
Прикрепленный файл  main.c_functions.pdf ( 34.38 килобайт ) Кол-во скачиваний: 153
Прикрепленный файл  IAREWARM_v6.30.4_for_STM32F100_issue.rar ( 1.06 мегабайт ) Кол-во скачиваний: 48
 
Go to the top of the page
 
+Quote Post
shista
сообщение Jan 25 2012, 19:01
Сообщение #33





Группа: Участник
Сообщений: 12
Регистрация: 15-07-09
Пользователь №: 51 296



Посмотреть смогу не раньше пятницы, в четверг в командировке буду. Кстати, вышеприведённый келовский вариант с systick запускать не пробовали? У меня там всё ОК работает. Анализатором времянки не смотрел, но датчик стабильно выдаёт температуру.

Мельком глянул исходник и не увидел переключение направления работы пина (вход/выход). Т.е. вы устанавливаете пин в высокое состояние и после паузы не переключив направления работы пина пытаетесь с него прочитать. Ну тут начинается соперничество токов выхода порта контроллера и выхода датчика, думаю не в пользу последнего. Отсюда и пожизненная единица. Для начала сделайте переключение направления работы пина (регистры GPIOx_CRL). Можете глянуть как это сделано у меня (макросы T_SENS_DOWN, T_SENS_FREE).
Go to the top of the page
 
+Quote Post
ivainc1789
сообщение Jan 25 2012, 23:30
Сообщение #34


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

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



Цитата(shista @ Jan 25 2012, 23:01) *
Посмотреть смогу не раньше пятницы, в четверг в командировке буду. Кстати, вышеприведённый келовский вариант с systick запускать не пробовали? У меня там всё ОК работает. Анализатором времянки не смотрел, но датчик стабильно выдаёт температуру.

Обязательно попробую, но тоже не быстро...

Цитата
Мельком глянул исходник и не увидел переключение направления работы пина (вход/выход)

Я вроде выше цитировал ref manual. Если пин настроен на вывод, то сэмплирование его (через IDR регистр) на вход не отключается и доступно. Это же не AVR! Благодаря пулл-апу шина восстанавливается очень быстро. См. ниже вариант с задержкой 500/500 - там ведь пин нормально переключается?... Кроме того, если задержку заменить на чисто софтовую без systick'а - сразу все работает...
Go to the top of the page
 
+Quote Post
maksimp
сообщение Jan 26 2012, 05:28
Сообщение #35


Местный
***

Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023



Цитата(ivainc1789 @ Jan 25 2012, 11:05) *
Повторюсь, в чем проблема... После счета задержки на основе этого таймера состояние шины 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;// останов таймера
}

Замените SysTick->LOAD на SysTick->VAL.
SysTick->LOAD переписывается в SysTick->VAL доходит до 0. Когда задержка делается первый раз, то она заканчивается с SysTick->VAL равным SysTick->LOAD или немного меньше. Следующая задержка таким образом будет на столько тактов сколько в SysTick->VAL осталось с прошлго раза, то есть на величину предыдущей задержки.
Вероятно нужно так:
Код

__INLINE void Delay1wire(unsigned int Ticks){
  SysTick->VAL  =  Ticks - 1;// возможна подстройка для точности
  SysTick->CTRL  =  0x00000005;//  запуск  таймера
  while(!BITCHK(SysTick->CTRL,SysTick_CTRL_COUNTFLAG));// пока не установится COUNTFLAG
  SysTick->CTRL  =  0x00000004;// останов таймера
}

Go to the top of the page
 
+Quote Post
ivainc1789
сообщение Jan 26 2012, 07:17
Сообщение #36


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

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



Цитата(maksimp @ Jan 26 2012, 09:28) *
Замените SysTick->LOAD на SysTick->VAL.

maksimp, спасибо большое! Сення вечером исправлю, похоже здесь то собака и порылась... Глупая ошибка, ей Богу... beer.gif
Go to the top of the page
 
+Quote Post
ivainc1789
сообщение Jan 26 2012, 13:26
Сообщение #37


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

Группа: Свой
Сообщений: 1 175
Регистрация: 5-01-05
Пользователь №: 1 807



Ну и наконец, из-за особенностей регистра VAL SysTick таймера действительно работоспособный код будет такой:
Код
//  генератор  прецизионных  таймингов  для  1wire (Tmax[sec]=2^24/Fhclk)
static __INLINE void Delay1wire(unsigned int Ticks){
  SysTick->LOAD  =  Ticks - 1;  //  подстройка  для  точности
  SysTick->VAL  =  0;           //  загрузка  LOAD,  сброс  COUNTFLAG
  SysTick->CTRL  =  0x00000005; //  запуск  таймера
while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG));
  SysTick->CTRL  =  0x00000004; //  откл .  таймера
}
Go to the top of the page
 
+Quote Post
EugenyAM
сообщение Jan 31 2012, 09:06
Сообщение #38


Участник
*

Группа: Свой
Сообщений: 73
Регистрация: 14-10-08
Из: Omsk
Пользователь №: 40 929



Когда-то делал на AVR асинхронный обмен по 1-wire через регистры сравнения таймера. Таймер тактировался частотой 1 МГц, что давало разрешение 1 мкс, в первый регистр сравнения записывалась длительность задержки в зависимости от того, что нужно было сделать - передать 0, 1 или прочитать шину, во второй - общая длительность бита. В обработчиках прерываний по совпадениям делались все ногодрыги и переключения режима пина ввод-вывод. Во втором обработчике производился также запуск следующего цикла. Алгоритм строился по принципу конечного автомата. В основной программе достаточно было запустить измерение и дождаться результата. Параллельно опрашивалось 4 датчика. Значения для таймера настроил по осциллографу с учетом времени входа в обработчик прерывания и выполнения команд в нем. Думаю, что для STM32 можно применить такой подход, несколько его модернизировав, в том числе, с использованием для передачи битов режим таймера с аппаратной генерацией ШИМ, или записав в 4 регистра сравнения фиксированные значения (t0, trd, t1, tbit), разрешать соответствующие прерывания в зависимости от состояния конечного автомата. Возможно, что скоро придется это сделать...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 31 2012, 11:01
Сообщение #39


Гуру
******

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



QUOTE (ivainc1789 @ Jan 26 2012, 15:26) *
Ну и наконец, из-за особенностей регистра VAL SysTick таймера действительно работоспособный код будет такой:
Как-то вы все усложняете. Запустите его считать один раз и навсегда. В начале задержки вычитывайте, добавляйте время задержки - получите время окончания. Далее в цикле вычитывайте VAL, вычитайте из времени окончания. Как только результат вычитания стал отрицательным - задержка окончилась. И все. Не нужно его останавливать/стартовать, можно одновременно использовать для отсчета нескольких задержек и т.д.
CODE
static __INLINE void Delay1wire(unsigned int Ticks){
  unsigned int Stop = SysTick->VAL + Ticks;
  while((int)(Stop - SysTick->VAL) > 0)
      ;
}


--------------------
На любой вопрос даю любой ответ
"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
maksimp
сообщение Jan 31 2012, 11:39
Сообщение #40


Местный
***

Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023



Цитата(Сергей Борщ @ Jan 31 2012, 14:01) *
Код
static __INLINE void Delay1wire(unsigned int Ticks){
  unsigned int Stop = SysTick->VAL + Ticks;
  while((int)(Stop - SysTick->VAL) > 0);
}

Неправильно. Во первых, он считает на уменьшение а не на увеличение. Поэтому не + Ticks а - Ticks. Во вторых, он не 32 разрядный а 24 разрядный. Как выполнить сравнение чтобы работало когда таймер в счёте переходит с 0 на 0xffffff я писал выше в теме.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 31 2012, 12:05
Сообщение #41


Гуру
******

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



QUOTE (maksimp @ Jan 31 2012, 13:39) *
Неправильно. Во первых, он считает на уменьшение а не на увеличение. Поэтому не + Ticks а - Ticks. Во вторых, он не 32 разрядный а 24 разрядный. Как выполнить сравнение чтобы работало когда таймер в счёте переходит с 0 на 0xffffff я писал выше в теме.
Ну, бывает, ошибся. Тогда можно так
CODE
static __INLINE void Delay1wire(unsigned int Ticks){
  unsigned int Stop = (SysTick->VAL - Ticks) << 8;
  while((int)(Stop - (SysTick->VAL << 8)) < 0)
     ;
}
Итого, все тело цикла выливается в три команды:
CODE
  12:main.cpp      ****   unsigned int Stop = (SysTick->VAL - Ticks) << 8;
  82                      .loc 1 12 0
  83 0000 044B             ldr    r3, .L3    @ tmp142,
  84 0002 9A68             ldr    r2, [r3, #8]    @ tmp143,
  85 0004 101A             subs    r0, r2, r0    @ tmp144, tmp143, Ticks
  86                  .LVL1:
  87 0006 0002             lsls    r0, r0, #8    @ Stop, tmp144,
  88                  .LVL2:
  89                  .L2:
  13:main.cpp      ****   while((int)(Stop - (SysTick->VAL << 8)) < 0)
  90                      .loc 1 13 0 discriminator 1
  91 0008 9A68             ldr    r2, [r3, #8]    @ tmp146,
  92 000a B0EB0222         subs    r2, r0, r2, lsl #8    @, Stop, tmp146,
  93 000e FBD4             bmi    .L2    @,


maksimp, у вас - четыре yeah.gif
CODE
  19:main.cpp      ****  unsigned int x = SysTick->VAL - Ticks; // конечное значение таймера
119                      .loc 1 19 0
120 0000 034B             ldr    r3, .L7    @ tmp140,
121 0002 9A68             ldr    r2, [r3, #8]    @ tmp141,
122 0004 101A             subs    r0, r2, r0    @ x, tmp141, Ticks
123                  .LVL4:
124                  .L6:
  20:main.cpp      ****  while((x - SysTick->VAL)&0x800000); // пока текущее не уменьшится до конечного
125                      .loc 1 20 0 discriminator 1
126 0006 9A68             ldr    r2, [r3, #8]    @ tmp143,
127 0008 821A             subs    r2, r0, r2    @ tmp144, x, tmp143
128 000a 1202             lsls    r2, r2, #8    @, tmp144,
129 000c FBD4             bmi    .L6    @,


--------------------
На любой вопрос даю любой ответ
"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
iPKM
сообщение Feb 2 2012, 10:15
Сообщение #42





Группа: Участник
Сообщений: 11
Регистрация: 19-08-11
Пользователь №: 66 793



При копировании функции _delay_loop из архива Blink_3, который был приложен ранее, и компилировании её в IAR 6.21. вылетает куча ошибок
CODE
__asm void _delay_loop(uint32_t __count)
{
loop SUBS r0,r0,#1
BNE loop
BX lr
}

Ошибки:
CODE
Error[Pe130]: expected a "{" D:\Документы\IAR Project\DTH-11 ARM\delay.h 11
Error[Pe040]: expected an identifier D:\Документы\IAR Project\DTH-11 ARM\delay.h 36
Error[Pe260]: explicit type is missing ("int" assumed) D:\Документы\IAR Project\DTH-11 ARM\delay.h 36
Error[Pe020]: identifier "loop" is undefined D:\Документы\IAR Project\DTH-11 ARM\delay.h 38
Error[Pe065]: expected a ";" D:\Документы\IAR Project\DTH-11 ARM\delay.h 38
Error[Pe010]: "#" not expected here D:\Документы\IAR Project\DTH-11 ARM\delay.h 38
Error while running C/C++ Compiler


Если привести код как написано в документации к IAR:
CODE
void _delay_loop(uint32_t __count)
{
asm("loop: \n");
asm("SUBS r0,r0,#1 \n");
asm("BNE loop \n");
asm("BX lr");
}

Ругается так:

Error[Og010]: Inline assembler instruction does not have a unique size: "BNE loop "

Как быть? может что настроить нужно в IDE?

Сообщение отредактировал iPKM - Feb 2 2012, 10:16
Go to the top of the page
 
+Quote Post
shista
сообщение Feb 2 2012, 14:47
Сообщение #43





Группа: Участник
Сообщений: 12
Регистрация: 15-07-09
Пользователь №: 51 296



Замените
Код
asm("BNE loop \n");

на
Код
asm("BNE.N loop \n");


Код
asm("BX lr");
в данном случае лишняя строчка

Сообщение отредактировал shista - Feb 2 2012, 14:59
Go to the top of the page
 
+Quote Post
toweroff
сообщение Feb 2 2012, 17:01
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Я делал 1-wire на lpc2103 через SSP с длиной, помнится, 16 бит (UARTы все были заняты)
нормально работало, но, конечно, SSP был свободен для этого
Go to the top of the page
 
+Quote Post
smk
сообщение Feb 3 2012, 06:25
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



У STM есть особенность настройки выводов портов, ограничивающая скорость нарастания/спада напряжения. При ее включении частота на ноге не превысит 2 МГц. Может в этом дело?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
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 Текстовая версия Сейчас: 19th July 2025 - 10:35
Рейтинг@Mail.ru


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