Easyelectronics.ru

Электроника для всех
Текущее время: 22 янв 2019, 13:39

Часовой пояс: UTC + 5 часов




Начать новую тему Ответить на тему  [ Сообщений: 17 ] 
Автор Сообщение
 Заголовок сообщения: Непонятки с работой таймера
СообщениеДобавлено: 06 сен 2018, 21:36 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
Мучаю стм8с103
внешний кварц 16 мгц 1 кнопка 1 светодиод
делаю по прерывания опрос кнопка и моргание светодиодом

Код:
  CLK_DeInit();
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);           
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
  CLK_ClockSwitchCmd(ENABLE);
  CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
  while (CLK_GetSYSCLKSource() != CLK_SOURCE_HSE){};

// Delay
  TIM3_DeInit();
  TIM3_TimeBaseInit(TIM3_PRESCALER_16, 1000);
  TIM3_ClearFlag(TIM3_FLAG_UPDATE);
  TIM3_ITConfig(TIM3_IT_UPDATE, ENABLE);
  TIM3_Cmd(ENABLE);


это прерывание
Код:
  timer_cnt += 1000;

  if ( delay > 0 )
    delay--;

  led_cnt++;
  if ((led_cnt > led_const) && (led_const > 0)){
    GPIO_WriteReverse(GPIOB, GPIO_PIN_4);
    led_cnt = 0;
  }

  button_state = !BUT_PRESSED;
  if (GPIO_ReadInputPin(GPIOB, GPIO_PIN_2) == BUT_PRESSED) {
    button_cnt++;
    if(button_cnt > 1100){
      button_cnt = 1100 + 1;
      button_state = BUT_PRESSED;
    }
  } else {
    if(button_cnt > 100) {
      button1_state = BUT_PRESSED;
    }
    button_cnt = 0;
  }


основная прога
Код:
  while(TRUE){
    if ( GPIO_ReadInputPin(GPIOB, GPIO_PIN_2) == BUT_PRESSED )
      GPIO_WriteHigh(GPIOB, GPIO_PIN_4);
    else
      GPIO_WriteLow(GPIOB, GPIO_PIN_4);

    if(button_state == BUT_PRESSED){
      led_const = 500;
      while( GPIO_ReadInputPin(GPIOB, GPIO_PIN_2) == BUT_PRESSED){ ;}

#if DEBUG == 1
      printf("Button pressed \r\n");
#endif

      delay = 30000;  // TimeOut Prog Mode 30 sec
      while(true) {
   if ( delay == 0 ) {

#if DEBUG == 1
  printf("TimeOut\r\n");
#endif

          break;
        }
        if ( button_state == BUT_PRESSED ) {
          led_const = 100;
          while( GPIO_ReadInputPin(GPIOB, GPIO_PIN_2) == BUT_PRESSED){ ;}

#if DEBUG == 1
  printf("Clear EEPROM\r\n");
#endif
          Clear();
          break;
        }
        if ( button1_state == BUT_PRESSED ) {
          button1_state = !BUT_PRESSED;

#if DEBUG == 1
  printf("Exit\r\n");
#endif
          break;
        }
      }


вроде все нормально - частота 16 мгц ( вижу по регистрам ), HSE включен (вижу по регистрам)
и тут вылез глюк
delay выставлен на 30 секунд (30000 милисекунд) - светодиод моргает 30 раз
если включен режим вывода отладочной инфы (debug = 1) все работает как положенно, а вот если debug = 0 то фигвам - delay отсчитывает только 6 секунд - светик моргает 6 раз

не могу понять в чем проблема


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 07 сен 2018, 07:39 
Старожил

Зарегистрирован: 06 фев 2011, 15:16
Сообщения: 617
Откуда: Челябинск
imsushka писал(а):
Show
delay как у вас объявлена?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 07 сен 2018, 16:14 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
uint32 delay;

я не могу понять причем тут printf
если он есть все работает
если нету - не работает


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 07 сен 2018, 20:28 
Старожил

Зарегистрирован: 26 ноя 2012, 10:28
Сообщения: 3383
Откуда: КЧР, поселок Нижний Архыз
delay точно как volatile объявлена? Если нет, то все понятно.
И да, пользоваться SPL и printf на STM8 — жесть какая-то!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 07 сен 2018, 21:11 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
не, не волачила

но по листингу смотрю - вроде ничего в регистрах нету
и не понятно причем тут printf

дурацкий иар, включал разную оптимизацию и смотрел получившийся код
ОТВРАТНО во всех случаях

я к CCS привык - хороший компилятор, всегда можно построить код так что б было на асм похоже


почему printf жесть ???
нормальная отладка, все видно
флеша все равно валом

и ваще, зачем нужна volatile?? я сам контролирую использование переменных


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 07 сен 2018, 21:16 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
поменял на volatile - точно также не работает


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 08 сен 2018, 15:36 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
выключил всю оптимизацию - та же фигня !?!?!?!?!

в чем я не прав


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 20:28 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
а-а-а-а-а-а-а

у меня вынос мозга случился

Код:
volatile uint16 delay, delayus;
uint32 clkk;
uint8 clks;

void DelayUs(uint16 us) {
  delayus = us;
  TIM2->CNTRH = 0;
  TIM2->CNTRL = 0;
  do {
  } while ( *(uint16_t*)(uint16_t)((uint16_t)TIM2_BaseAddress + 10) < delayus );
}


//--- Main function block begin ------------------------------------------------

int main() {
 
//--- CPU init -----------------------------------------------------------------
  CLK_DeInit();
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);           
  CLK_ClockSwitchCmd(ENABLE);
  CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
  while (CLK_GetSYSCLKSource() != CLK_SOURCE_HSE){};
   
  TIM2_DeInit();
  TIM2->PSCR = TIM2_PRESCALER_16;
  TIM2->ARRH = 255;
  TIM2->ARRL = 255;
 
  TIM2->SR1 = (uint8_t)(~((uint8_t)(TIM2_FLAG_UPDATE)));
  TIM2->SR2 = (uint8_t)(~((uint8_t)((uint16_t)TIM2_FLAG_UPDATE >> 8)));
  TIM2->IER |= (uint8_t)TIM2_IT_UPDATE;
  TIM2->CR1 |= (uint8_t)TIM2_CR1_CEN;

  GPIO_Init(GPIOD, GPIO_PIN_5, GPIO_MODE_OUT_PP_HIGH_FAST); // uart2 tx
  GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST); // led
  GPIO_Init(GPIOB, GPIO_PIN_2, GPIO_MODE_IN_PU_NO_IT); // button
  UART2_DeInit();
  UART2_Init( (uint32_t)9600, UART2_WORDLENGTH_8D, UART2_STOPBITS_1, UART2_PARITY_NO, UART2_SYNCMODE_CLOCK_DISABLE, UART2_MODE_TXRX_ENABLE);
  UART2_Cmd(ENABLE);

  enableInterrupts();
//--- -------- -----------------------------------------------------------------
   
#if DEBUG == 1
CLK_Source_TypeDef clks;
  clks = CLK_GetSYSCLKSource();
  clkk = CLK_GetClockFreq();
  printf("\n\rIR Transiver\n\rCPU Freq = %lu (%x)\r\n", clkk, clks);
#endif

  for (cnt = 0; cnt < 10; cnt++) {
    GPIOB->ODR &= (uint8_t)(~GPIO_PIN_4);
//    GPIO_WriteLow(GPIOB, GPIO_PIN_4);
    DelayUs(65000);
//    GPIO_WriteHigh(GPIOB, GPIO_PIN_4);
    GPIOB->ODR |= (uint8_t)GPIO_PIN_4;
    DelayUs(65000);
  }

  while(TRUE){}


все что оставил от программы
если есть printf все работает нормально - светик моргает с периодом 130 мсек
если нету принта то не моргает савсЭм

если принтф поставить после цикла моргания - тоже не моргает


???????????????????????????????????


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 20:39 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 5370
Вот чего вы экономили??
Чем кривее написан код, тем труднее компилятору его исправить.
IMHO.
Перепишите код как-то так:
Код:
do {
delayus = *(uint16_t*)(uint16_t)((uint16_t)TIM2_BaseAddress + 10);
  } while ( delayus < us );


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 20:42 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 5370
Теперь, почему это может не работать.
У вас число на проверку 65000. Условие станет ложным только тогда, когда таймер будет больше 65000. Для word это числа 65001-65535. Т.е. если кто-то где-то займет процессор и счетчик успеет натикать 535 раз, то ваш delay провалится до следующего цикла.
Это хороший стиль программирования?....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 21:13 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
хай ладно допустим

НО!, почему все работает если есть printf ???????


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 21:16 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
    61 void DelayUs(uint16 us) {
    62 delayus = us;
    \ _Z7DelayUst:
    \ 000000 CF .... LDW L:delayus, X
    63 TIM2->CNTRH = 0;
    \ 000003 725F 530A CLR L:0x530a
    64 TIM2->CNTRL = 0;
    \ 000007 725F 530B CLR L:0x530b
    65 do {
    66 // t.lo = TIM2->CNTRL;
    67 // t.hi = TIM2->CNTRH;
    68 } while ( *(uint16_t*)(uint16_t)((uint16_t)TIM2_BaseAddress + 10) < delayus );
    \ ??DelayUs_0:
    \ 00000B CE 530A LDW X, L:0x530a
    \ 00000E C3 .... CPW X, L:delayus
    \ 000011 25 F8 JRC L:??DelayUs_0
    69 }
    \ 000013 87 RETF

так что я написал практически на асме
а на асме = оптимально

правда я тут заметил 1 проблемку (я правда не знаток стм)
но при заходе в прерывании регистр X не сохраняется, но это иар так дедает


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 21:25 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 5370
Попробуйте с константой 30000 вместо 65000.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 21:29 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
не моргает

535 тиков таймера = 500 мксек - это ж до ....

у меня прерывания по таймеру 50 мксекунд - все нормально отрабатывает ( если есть printf )


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 21:39 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 5370
Ну да, это была глупая идея.
Поставьте перед for вызов "DelayUs(30000);"
В процедуру printf не лазили? ... может остались выдачи через GPIO.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 10 сен 2018, 21:46 
Только пришел

Зарегистрирован: 07 апр 2013, 18:53
Сообщения: 13
не в printf не полезу там 3 кило кода

я не могу понять причем тут printf ????



самое интерестное что проект сдал заказчику, все работает, проблем нет, оставил включенным вывод отладочной информации
НО мне уже самому интерестно разобрацца в чем проблема


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Непонятки с работой таймера
СообщениеДобавлено: 11 сен 2018, 19:30 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 596
Откуда: Киев
Кто так пишет...
Неужели тяжело посмотреть в отладке режимы таймера и их сброс в прерывании. Задачка на пол часа.
Для простых процессоров пишите простым языком с обычным stm8s.h и некоторыми дефайнами, всё же будет проще для понимания, да и короче.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 17 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: john1770


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB