Easyelectronics.ru

Электроника для всех
Текущее время: 12 ноя 2018, 23:14

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



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 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
Сообщения: 616
Откуда: Челябинск
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
Сообщения: 2931
Откуда: КЧР, поселок Нижний Архыз
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
Сообщения: 5085
Вот чего вы экономили??
Чем кривее написан код, тем труднее компилятору его исправить.
IMHO.
Перепишите код как-то так:
Код:
do {
delayus = *(uint16_t*)(uint16_t)((uint16_t)TIM2_BaseAddress + 10);
  } while ( delayus < us );


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

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 5085
Теперь, почему это может не работать.
У вас число на проверку 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
Сообщения: 5085
Попробуйте с константой 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
Сообщения: 5085
Ну да, это была глупая идея.
Поставьте перед 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
Сообщения: 595
Откуда: Киев
Кто так пишет...
Неужели тяжело посмотреть в отладке режимы таймера и их сброс в прерывании. Задачка на пол часа.
Для простых процессоров пишите простым языком с обычным stm8s.h и некоторыми дефайнами, всё же будет проще для понимания, да и короче.


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

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


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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

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