Программирование STM8

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

Вот заспорили)
У меня вот заработало, некий барьер понимания преодолен и по мне уже большой разницы в том чей хидер использовать нет
Куда более важнее теперь вникнуть в остальную переферию читая rm016
Еще бы привыкнуть к тому, что выводы все "корявые" ;) то есть подтяжка, то нет

Кстати что iar, что stvd такие простенькие. После них теперь атмел студия кажется верхом совершенства ;)
Сложно отвыкнуть от привычных удобств
Автоподстановка в iar - если сравнить с атмелом то считай и нет никакой автоподстановки
Ident совершенно кривой
Иерархии кода нет, да что уж там...;)
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 952
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

Re: Программирование STM8

Сообщение GARMIN »

Отступы настраиваются в настройках редактора очень просто.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

У меня вот заработало

с транзисторами али без. Яркость нормальная?
Еще бы привыкнуть к тому, что выводы все "корявые"

теперь можно и на STM32 переходить - там с выводами получше и индикацию динамическую на дма можно сделать... :)
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

GARMIN писал(а):Отступы настраиваются.

настройку отступов я видел, но там нет выключателя кривизны)
по сравнению с атмелом работает все через одно место
там целый букет неудобств, придется мириться

без транзисторов, крутил вертел CD4511 - BCD дешивратор, а то валяется без дела, но потом не стал
для первого устройства простота не порок
яркость нормальная, но без запаса

stm32 в плане, его рассматриваю для чего-то тяжеловесного
даже поморгал светодиодом на кейле, вот теперь видимо надо будет на иаре моргать, чтобы полный зоопарк не плодить
robot
Родился
Сообщения: 6
Зарегистрирован: Ср ноя 25, 2009 22:52:00
Откуда: Тольятти

Re: Программирование STM8

Сообщение robot »

народ подскажите,
как у STM8S в IARe переключится в WAIT режим и обратно?
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

если использовать хидер от производителя:
wfi(); /* Wait For Interrupt */
выход по прерыванию

можно еще так:
__wait_for_interrupt();

если вы не пользуетесь сим замечательным хидером, то можно так:
asm("wfi");
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

oleg110592 писал(а):Где вектора EXTI и пр.?

забавно, но у меня тоже не обнаружилось описание EXTI векторов
читал перечитывал RM0016
так и не вкурил как мне настроить прерывание на PA3
с чего начать?

настроил CR2 на порту и EXTI_CR1_bit.PAIS = 3;
этого достаточно?

как мне теперь описать обработчик?
a5021
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Re: Программирование STM8

Сообщение a5021 »

Взято отсюда.

Спойлер

Код: Выделить всё

#include <intrinsics.h>
#include <iostm8s103f3.h>

//
//  Process the interrupt generated by the pressing of the button on PD4.
//
#pragma vector = 8
__interrupt void EXTI_PORTD_IRQHandler(void)
{
    PD_ODR_ODR3 = !PD_ODR_ODR3;     //  Toggle Port D, pin 3.
}

//
//  Main program loop.
//
void main()
{
    //
    //  Initialise the system.
    //
    __disable_interrupt();
    PD_ODR = 0;             //  All pins are turned off.
    PD_DDR = 0xff;          //  All pins are outputs.
    PD_CR1 = 0xff;          //  Push-Pull outputs.
    PD_CR2 = 0xff;          //  Output speeds up to 10 MHz.
    //
    //  Now configure the input pin.
    //
    PD_DDR_DDR4 = 0;        //  PD4 is input.
    PD_CR1_C14 = 0;         //  PD4 is floating input.
    //
    //  Set up the interrupt.
    //
    EXTI_CR1_PDIS = 2;      //  Interrupt on falling edge.
    EXTI_CR2_TLIS = 0;      //  Falling edge only.
    __enable_interrupt();

    while (1)
    {
        __wait_for_interrupt();
    }
}
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

спасибо
заработало
на кофейной гуще угадал таки правильный номер вектора для пора А - вектор 5
вот только из даташита это ни разу не следует
или я не туда смотрю?
в даташите указан номер прерывания - 3
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

в хидере stm8s.h:

Код: Выделить всё

 #define INTERRUPT_HANDLER( a, b )  \
 _Pragma( VECTOR_ID( (b)+2 ) )        \
 __interrupt void (a)( void )

можно спокойно писать вектор из даташита:

Код: Выделить всё

INTERRUPT_HANDLER(TIM2_UPD_OVF_IRQHandler, 13)
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

Теперь то я понимаю что нужно 2 прибавлять, вот только где об этом написано в документах ST или IAR?
Что то такой запутанности я у атмела не встречал

Кстати по поводу хидеров IAR и спора выше, у меня вот тоже в его хидерах эти вектора отсутствуют. Что я нетак делаю?
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

там вначале еще два вектора RESET и TRAP, начали нумерацию с TLI, потому и 2 добавлять. Хидер от производителя об этом знает.
Версия иара какая? В версии 2.10.3 плохие хидеры, в самой свежей 2.10.4 вектора появились, но не известно все ли еще там в порядке.
Вы не первый об этот кактус колетесь:
http://caxapa.ru/505737.html?todo=full

О! Из примера что немного выше:

Код: Выделить всё

//  Set up the interrupt.
//
    EXTI_CR1_PDIS = 2;      //  Interrupt on falling edge.

все таки получатся можно в битовые переменные 100500 писать.
имхо нагляднее:

Код: Выделить всё

EXTI->CR1 |= EXTI_CR1_PDIS;
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

буду признателен за критику по коду
это будет дисплей текущего инструмента для ЧПУ
на борту две семисегментные цифры (точки не подключены)
пищалка
и один вход с активным нулем на PA3 и внешней подтажкой с питанием 5В

суть простая - ловим нули на входе и если поймали ноль длительностью более 100мсек, то увеличиваем счетчик
как только между нулями возникла пауза более 1 сек - значение счетчика копируем на дисплей и выдаем звуковой сигнал

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

Спойлер

Код: Выделить всё

#include <intrinsics.h>
#include <iostm8s103f3.h>      // подключение заголовочного файла с объявлениями регистров, масок и битов

typedef unsigned char uint8;

typedef enum {
  segNone = 0,
  segA = (1 << 0),
  segB = (1 << 1),
  segC = (1 << 2),
  segD = (1 << 3),
  segE = (1 << 4),
  segF = (1 << 5),
  segG = (1 << 6),
  segDB = (1 << 7)
} enum_segment;

#define DISPLAY_CHAR_BLANK  10
#define DISPLAY_CHAR_MINUS  11

const uint8 bcd_map[] = {
  segA | segB | segC | segD | segE | segF,         // 0
  segB | segC,                              // 1
  segA | segB | segD | segE | segG,               // 2
  segA | segB | segC | segD | segG,               // 3
  segB | segC | segF | segG,                  // 4
  segA | segC | segD | segF | segG,               // 5
  segA | segC | segD | segE | segF | segG,         // 6
  segA | segB | segC,                        // 7
  segA | segB | segC | segD | segE | segF | segG,   // 8
  segA | segB | segC | segD | segF | segG,         // 9
  0,                                                // blank
  segG                                              // -
};

struct {
  volatile uint8      tool_number;
  volatile uint8      tool_cnt;
  struct {
   volatile uint8   prescaler;
    volatile uint8  prescaler2;
   volatile uint8   cnt_down;
   volatile uint8   cnt_pause;
    volatile uint8  beep;
  } timer;
} var;

struct {
  volatile uint8        digits[2];
  volatile uint8        cur_digit;
  volatile enum_segment cur_segment;
} display;

void mcu_init();
void delay();

void display_init();
void display_digit(uint8 d, uint8 );
void display_segment(enum_segment s, uint8 v);
void display_update();
void display_set(uint8 digit, uint8 v);

void beep(uint8 d);

int main( void )
{
   mcu_init();
   display_init();

    display_set(0, DISPLAY_CHAR_MINUS);
    display_set(1, DISPLAY_CHAR_MINUS);
   __enable_interrupt();

   beep(1);

    while(1) {
      __wait_for_interrupt();
     }
}

void mcu_init() {
     CLK_CKDIVR = 0;

   // input
   PA_CR1 = MASK_PA_CR1_C13;   // подтяжка
   PA_CR2 = MASK_PA_CR2_C23;   // разрешаем прерывани

     //PB_DDR = MASK_PD_DDR_DDR4 | MASK_PD_DDR_DDR5;
     //PB_CR2 = MASK_PB_CR2_C24 | MASK_PB_CR2_C25;

   // outpur
     PD_DDR = MASK_PD_DDR_DDR2 | MASK_PD_DDR_DDR3 | MASK_PD_DDR_DDR4 | MASK_PD_DDR_DDR5 | MASK_PD_DDR_DDR6;
     PD_CR1 = MASK_PD_CR1_C12 | MASK_PD_CR1_C13 | MASK_PD_CR1_C14 | MASK_PD_CR1_C16;
     PD_CR2 = MASK_PD_CR2_C22 | MASK_PD_CR2_C23 | MASK_PD_CR2_C24 | MASK_PD_CR2_C25 | MASK_PD_CR2_C26;

     PC_DDR = MASK_PD_DDR_DDR3 | MASK_PD_DDR_DDR4 | MASK_PD_DDR_DDR5 | MASK_PD_DDR_DDR6 | MASK_PD_DDR_DDR7;
     PC_CR1 = MASK_PC_CR1_C13 | MASK_PC_CR1_C14 | MASK_PC_CR1_C15 | MASK_PC_CR1_C16 | MASK_PC_CR1_C17;
     PC_CR2 = MASK_PC_CR2_C23 | MASK_PC_CR2_C24 | MASK_PC_CR2_C25 | MASK_PC_CR2_C26 | MASK_PC_CR2_C27;

     // timer
     TIM2_PSCR = 0;         // предделитель 1(16 - значение 4)
     TIM2_CNTRH = 0;         // счетчик = 0
     TIM2_CNTRL = 0;
     TIM2_ARRH = 0x3E;
     TIM2_ARRL = 0x80;        // потолок счета 16000
     TIM2_IER = MASK_TIM2_IER_UIE;  // разрешение прерывания по переполнению
     TIM2_CR1 = MASK_TIM2_CR1_URS | MASK_TIM2_CR1_CEN; // счет вверх, прерывание по переполнению, старт таймера

   // beep
     BEEP_CSR_bit.BEEPSEL = 1;
   BEEP_CSR_bit.BEEPDIV = 0x1E;

   // внешние прерывания
   EXTI_CR1_bit.PAIS = 3;   // срабатывать по фронту и спаду
   //ITC_SPR1.VECT3SPR = 0;
}

#pragma vector = TIM2_OVR_UIF_vector
__interrupt void TIM2_OVR_UIF_handler(void)
{
  TIM2_SR1_UIF = 0;                 // очистка флага прерывания

  display_update();

  if(++var.timer.prescaler == 10) {
   var.timer.prescaler = 0;
   // 100 раз в секунду

    if(var.timer.cnt_down && !--var.timer.cnt_down) var.tool_cnt++;
    if(var.timer.cnt_pause && !--var.timer.cnt_pause) {
        if(var.tool_cnt < 100) {
          var.tool_number = var.tool_cnt;
          var.tool_cnt = 0;
          display_set(0, var.tool_number / 10);
          display_set(1, var.tool_number % 10);
          beep(5);
        } else {
          var.tool_cnt = 0;
          var.tool_number = 0;
          beep(50);
        }
    }
    if(var.timer.beep && !--var.timer.beep) BEEP_CSR_bit.BEEPEN = 0;

    if(++var.timer.prescaler2 == 10) {
         var.timer.prescaler2 = 0;
         // 10 раз в секунду
    }
  }
}


#define EXTI0_vector 5
#pragma vector = EXTI0_vector
__interrupt void Input_interrupt(void) {
  if(PA_IDR_bit.IDR3 == 0) {
      // failing edge
      var.timer.cnt_down = 10;  // 1 = 10msec, отсчет длительности импульса
      var.timer.cnt_pause = 0;  // сброс ожидания окончания счета
  } else {
      // raising edge
      var.timer.cnt_down = 0;       // сброс отсчета длительности импульса
      var.timer.cnt_pause = 100;    // ожидание окончания счета
  }
}

void display_init() {
  display.cur_digit = 255;
  display.cur_segment = segA;
  display.digits[0] = 0;
  display.digits[1] = 1;
  display_digit(0, 0);
  display_digit(1, 0);
}

void display_set(uint8 d, uint8 v) {
  if(d <2 && v < 12) {
   display.digits[d] = bcd_map[v];
  }
}

void display_update() {
     display_digit(display.cur_digit, 0);         // выключаем предыдущую цифру
     display_segment(display.cur_segment, 0);     // выключаем предыдущий сегмент

     // следующий сегмент
   switch(display.cur_segment) {
   case segA:
     display.cur_segment = segB;
     break;
   case segB:
     display.cur_segment = segC;
     break;
   case segC:
     display.cur_segment = segD;
     break;
   case segD:
     display.cur_segment = segE;
     break;
   case segE:
     display.cur_segment = segF;
     break;
   case segF:
     display.cur_segment = segG;
     break;
   case segG:
     display.cur_segment = segA;
     if(++display.cur_digit > 1) display.cur_digit = 0;
     break;
   }

     display_digit(display.cur_digit, 1);         // выключаем цифру
    uint8 ch = display.digits[display.cur_digit];
   if(ch & display.cur_segment) {
      display_segment(display.cur_segment, 1);     // выключаем сегмент
   }
}

void display_digit(uint8 d, uint8 v) {
  switch(d) {
  case 0:
    PD_ODR_bit.ODR5 = (v)?0:1;
    break;
  case 1:
    PC_ODR_bit.ODR4 = (v)?0:1;
    break;
  }
}

void display_segment(enum_segment s, uint8 v) {
  switch(s) {
  case segA:
    PD_ODR_bit.ODR3 = v;
    break;
  case segB:
    PC_ODR_bit.ODR3 = v;
    break;
  case segC:
    PC_ODR_bit.ODR5 = v;
    break;
  case segD:
    PC_ODR_bit.ODR7 = v;
    break;
  case segE:
    PC_ODR_bit.ODR6 = v;
    break;
  case segF:
    PD_ODR_bit.ODR2 = v;
    break;
  case segG:
    PD_ODR_bit.ODR6 = v;
    break;
  }
}

void beep(uint8 d) {
     BEEP_CSR_bit.BEEPEN = 1;
    var.timer.beep = d;
}


Изображение
вот так вышло с питанием от 24В для станка

IMG_2464.JPG
(112.24 КБ) 1375 скачиваний
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

ничо так - сильно не углублялся (не любимый хидер) , C13 C24 конечно колет глаза. Индикация разве посегментная? Ну прям слепит глаза - надо срочно светофильтр. :))
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Программирование STM8

Сообщение ChipKiller »

axillent писал(а):буду признателен за критику по коду
замените switch выборкой из таблицы - будет работать быстрей и "сожрет" меньше памяти...
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

в самом плюгавом стм8 8К флэша - экономить как в авр не надо, важнее наглядность
axillent
Электрический кот
Сообщения: 1040
Зарегистрирован: Вс сен 25, 2011 19:09:33

Re: Программирование STM8

Сообщение axillent »

oleg110592 писал(а):Индикация разве посегментная? Ну прям слепит глаза - надо срочно светофильтр. :))

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

ChipKiller писал(а):замените switch выборкой из таблицы

какой именно?
тот который со ссылками на порты таблицу придется строить со ссылками на функции - получится более громоздко
а тот где идет определение следующего сегмента в принципе там можно заменить на битовый сдвиг (если посмотреть на enum), но наглядность явно сильно пострадает

oleg110592 писал(а):в самом плюгавом стм8 8К флэша

в природе вроде как есть F2 с 4к, нет?)

863 bytes of readonly code memory
148 bytes of readonly data memory
279 bytes of readwrite data memory (+ 22 absolute)


правильно понимаю, что мой код сейчас занимает 863+148 байт флэша?
279 это RAM? почему так много? в AVR такая программа заняла бы не больше 20-30 байт
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: Программирование STM8

Сообщение oleg110592 »

на картинках F2 был, но в products пока нету, неужто, если появится, цена будет меньше чем 0.285$
RAM прерывания вроде забирают, в опциях проекта, в линкере можно включить генерацию map файла - там видно что куда ушло
Последний раз редактировалось oleg110592 Ср май 20, 2015 12:03:24, всего редактировалось 2 раза.
a5021
Друг Кота
Сообщения: 6452
Зарегистрирован: Пт сен 13, 2013 13:11:31

Re: Программирование STM8

Сообщение a5021 »

oleg110592 писал(а):
О! Из примера что немного выше:

Код: Выделить всё

//  Set up the interrupt.
//
    EXTI_CR1_PDIS = 2;      //  Interrupt on falling edge.

все таки получатся можно в битовые переменные 100500 писать.

PDIS имеет длину два бита, т.ч. абсолютно корректная запись. В восьмибитную переменную можно тоже сдуру 100500 записать, но это почему-то никого не возбуждает.

имхо нагляднее:

Код: Выделить всё

EXTI->CR1 |= EXTI_CR1_PDIS;

Так писать нельзя. Это ошибка. Вы, похоже, не понимаете смысл битовых полей, а беретесь судить.
Последний раз редактировалось a5021 Ср май 20, 2015 11:24:25, всего редактировалось 1 раз.
Аватара пользователя
Psych
Опытный кот
Сообщения: 848
Зарегистрирован: Ср мар 02, 2011 07:47:39
Откуда: Уфа

Re: Программирование STM8

Сообщение Psych »

axillent писал(а):+148 байт флэша

Почему то эта цифра тоже очень велика, ведь у вас const data занимает всего 12 байт.
axillent писал(а):279 это RAM? почему так много? в AVR такая программа заняла бы не больше 20-30 байт

Попробуйте включить оптимизацию или убрать volatile(одно из двух :) ).
Ответить

Вернуться в «Разные вопросы по МК»