Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

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

Пт май 13, 2022 09:26:00

Коллеги, приветствую!
Поделитесь установщиком программы stm8 st visual develop ide.
STM не хочет делиться.
Спасибо

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

Пт май 13, 2022 18:45:24

Коллеги, приветствую!
Поделитесь установщиком программы stm8 st visual develop ide.

Скачивал 1.03.2022, обновлял лицензию
https://disk.yandex.ru/d/1eq_QJid_5Jw5Q

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

Вт авг 16, 2022 17:45:53

Добрый день. Решил помигать светодиодиком на STM8. В Platformio установил соответствующий пакет, и выбрал пример native-blink (пока пробую без библиотек). В коде примера смотрю на настройку пина, и вижу следующее (привожу лишь необходимые на мой взгляд куски:
Код:
#include "STM8S103F3.h"

#define LED_PORT   sfr_PORTB
#define LED_PIN    PIN5

// configure LED pin as output
  LED_PORT.DDR.byte = LED_PIN;    // input(=0) or output(=1)
  LED_PORT.CR1.byte = LED_PIN;    // input: 0=float, 1=pull-up; output: 0=open-drain, 1=push-pull
  LED_PORT.CR2.byte = LED_PIN;    // input: 0=no exint, 1=exint; output: 0=2MHz slope, 1=10MHz slope

То есть, для настройки пина на выход пуш-пулл с быстрыми фронтами, надо выставить соответвующий бит (5 по счету) в 3-х регистрах. И это делается этой хитрой конструкцией. Почему она для меня хитрая ? Потому что в AVR и PIC я привык выставлять биты конструкцией вида DDRB |= 1<<5;
Ну и сбрасывать соответственно похожим образом: DDRB &= ~(1<<5);
Залез в хидер, нашёл там union, внутри которого структура с битовыми полями.

но как сбрасывать, так и не понял.
Как с помощью этой конструкции сбросить бит в регистре ?

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

Вт авг 16, 2022 18:31:53

LED_PORT.DDR.byte - это обращение ко всем битам, то есть к
/// bytewise access to DDR
uint8_t byte;
И можете работать с ним как раньше.

Union объединяет эти определения или делает эквивалентным их или проецирует этот байт на структуру и обратно (не знаю, как лучше сказать...)
то есть, к биту можно обратиться как LED_PORT.DDR.DDR0 = 0

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

Вт авг 16, 2022 18:46:54

...к биту можно обратиться как LED_PORT.DDR.DDR0 = 0

Вот, такое обращение с использованием битовых полей для меня логично и понятно)) Ранее с обьединениями дела не имел, лишь вскользь читал в Кернигане и Ричи.
То есть, для сброса бита при обращении к структуре объединения как к целому байту мне необходимо писать LED_PORT.DDR.byte &= ~(LED_PIN); ?
И правильно ли я понял, что установку битов лучше производить конструкцией типа LED_PORT.DDR.byte |= LED_PIN, иначе если делать как в примере, то все остальные биты регистра будут сбрасываться ?

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

Вт авг 16, 2022 19:28:29

То есть, для сброса бита при обращении к структуре объединения как к целому байту мне необходимо писать LED_PORT.DDR.byte &= ~(LED_PIN); ?
да, но только со сдвигом единички, то есть, (1 << LED_PIN)

установку битов лучше производить конструкцией типа LED_PORT.DDR.byte |= LED_PIN
не знаю, как лучше с точки зрения языка. Конструкция в любом случае будет красивше, так как займёт одну строку, вместо восьми. Однако, возможно, есть алгоритм, где краисвше обратиться в цикле к каждому биту. Ещё может быть разница с точки зрения компилятора.

то все остальные биты регистра будут сбрасываться?
обращаясь к .byte Вы обращаетесь ко всем битам,, соответсвенно. либо сбросятся, либо установятся. Обращаясь к .DDR0 - обращаетесь только к этому биту, никакие другие не будут затронуты,

Вообще, это очень удобно.
Например, можете сделать такую структуру:

Код:
/** Port A data direction register (DDR at 0x5002) */
  union {

  .....

    /// bitwise access to register DDR
    struct {
      BITFIELD_UINT   DDR03      : 4;      // bit 0...bit 3
      BITFIELD_UINT   DDR47      : 4;      // bit 4...bit 7
    };  // DDR bitfield

    /// register _PORT_DDR reset value
    #define sfr_PORT_DDR_RESET_VALUE   ((uint8_t) 0x00)

  } DDR;

и в итоге получить обращение к младшему и старшему 4-битным словам. И если вся логика построена на таких словах, это будет удобно.

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

Вт авг 16, 2022 19:50:30

... да, но только со сдвигом единички, то есть, (1 <<LED_PIN).

Ну, учитывая, что в хидере пины представлены битовыми масками, а не порядковыми номерами битов, то наверное все таки без единичек))
Код:
/*----------
  FOR CONVENIENT PIN ACCESS
----------*/

#define PIN0     0x01
#define PIN1     0x02
#define PIN2     0x04
#define PIN3     0x08
#define PIN4     0x10
#define PIN5     0x20
#define PIN6     0x40
#define PIN7     0x80

Спасибо за ответы.

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

Ср авг 17, 2022 15:26:52

Да, тут всё правильно ответили - через CR1 и CR2 задаются режимы работ, в ODR пишется собственно байт на выход порта. Но не стОит останавливаться на этом, есть ещё и альтернативные функции... лучше не программно дёргать, а к таймеру подключить. У меня, например, в управляшке для бесколлекторного мотора TIM2 работает генератором сигнала (TIM2_OC2Init(TIM2_OCMODE_TOGGLE, TIM2_OUTPUTSTATE_ENABLE,CCR2_Val, TIM2_OCPOLARITY_HIGH); - переключает выход с программируемой частотой), а первый таймер - частотомер - захватывает фронты с датчика и измеряет скорость вращения.

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

Чт окт 20, 2022 11:09:19

Здравствуйте! Подскажите как в STM8S103 заставить работать АЦП2. В нете везде примеры только с АЦП1. Мне же нужно реализовать два независимых канала измерения. Однин на АЦП1 как "Сторож" напряжения. Второй на АЦП2 измерение температуры. Перерыл кучу инфы, так и не получилось заставить измерять по АЦП2. Брал за основу исходник с АЦП1 - измерения происходят нормально. Перенастраиваю исходник на АЦП2 - и не работает. Компилятор SDCC.


uint16_t ADC_read(uint8_t channel)
{
/* Configure ADC channel */

ADC2_TDRL = 0x03; //отключить триггеры шмитта каналы 0 и 1
// ADC2_TDRH = 0xFF; //отключить триггеры шмитта


ADC2_CSR = channel;

/* Right-align data */
//ADC1_CR2 |= (1 << ADC1_CR2_ALIGN); // включить выравнивание по правому краю
ADC2_CR2 |= (1 << ADC2_CR2_ALIGN); // включить выравнивание по правому краю



//ADC2_CSR |= (1 << ADC2_CSR_EOCIE); // включить формирование прерываний


/* Wake ADC from power down */

// ADC1_CR1 |= (1 << ADC1_CR1_ADON); //включить питание на АЦП1, второй повтор начнет преобразование
ADC2_CR1 |= (1 << ADC2_CR1_ADON); //включить питание на АЦП2, второй повтор начнет преобразование


uint8_t adcH, adcL;
// ADC1_CR1 |= (1 << ADC1_CR1_ADON); //начать преобразование
ADC2_CR1 |= (1 << ADC2_CR1_ADON); //начать преобразование


// ждем окончание преобразования
// while (!(ADC2_CSR & (1 << ADC2_CSR_EOC)));

adcL = ADC2_DRL;
adcH = ADC2_DRH;
ADC2_CSR &= ~(1 << ADC2_CSR_EOC); // clear EOC flag

return (adcL | (adcH << 8));

}

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

Чт окт 20, 2022 11:54:23

Proton78 писал(а):STM8S103 заставить работать АЦП2
Ну надо как-то в него добавить второй АЦП, так как их там один. :)

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

Чт окт 20, 2022 12:44:27

Proton78 писал(а):STM8S103 заставить работать АЦП2
Ну надо как-то в него добавить второй АЦП, так как их там один. :)

Вот же шшшшш..... Два дня убил на эту хрень. Перерыл кучу инфы. В учебниказ по STM8 написано что два АЦП. А в даташит именно на этот контроллер посмотреть не додумался. Благодарю за прозрение.

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

Чт окт 20, 2022 13:07:45

там может быть ADC1 или ADC2. просто неверно поняли.

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

Вт окт 25, 2022 15:17:21

Добрый день! Пытаюсь обуздать STM8. Задача - сымитировать работу сдвигового регистра. На всякий случай поясню суть: после сигнала latch идет серия тактовых сигналов, по которым отдаем в DATA биты по очереди. Проблема в том, что что latch читается легко, а вот с чтением CLK возникли проблемы. Не пойму, что не так, но либо читается один импульс, либо не читается вообще. СТМка работает на частоте 16мгц.

График сигналов в аттаче.
photo_2022-10-25_17-05-05.jpg
(33.49 KiB) Скачиваний: 45


Код функции
Код:
void proc(void){ 
  while(GPIO_ReadInputPin(LATCH_PORT,LATCH_PIN)==0){};    // Ждем изменения latch   
  for (u8 i = 0; i < 8; i++) {   
    if (data & (1 << i))
      dataL();               // сброс бита
    else
      dataH();                // установка бита
   
     while( GPIO_ReadInputPin(CLK_PORT, CLK_PIN)==0){};    // Ждем изменения clk
  }
 
  dataH(); 
}


В строке while( GPIO_ReadInputPin(CLK_PORT, CLK_PIN)==0) ожидание что 0, что 1 дает один и тот же результат - биты отдаются сразу пачкой, такое ощущение, что чтение порта не работает, хотя сконфигурирован как вход GPIO_Init(CLK_PORT, (GPIO_Pin_TypeDef)(CLK_PIN), GPIO_MODE_IN_FL_NO_IT);

Подобный код на ардуине работал превосходно, даже с учетом тормозов фреймворка Arduino, а тут, на голой СТМке как будто камня не хватает для выборки сигнала..
Последний раз редактировалось Ромыч Вт окт 25, 2022 16:14:42, всего редактировалось 1 раз.

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

Вт окт 25, 2022 15:55:55

1. Это в какой среде написано?
2. А для чего - просто для развлекательно-познавательных целей? Вообще-то SPI можно соответственно задаче сконфигурировать. Ну или хотя бы CLK сконфигурировать с прерыванием от изменения уровня - тогда будет точно по переходу 1->0 или 0->1 срабатывать... Здесь же фактически ждётся не изменение CLK, а только пока он равен нулю.

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

Вт окт 25, 2022 15:56:55

Ромыч, код - адова жесть! Можно ведь использовать таймер или на худой конец прерывания.
Не приведено, что внутри функций GPIO_ReadInputPin, dataL, dataH и data1H - об этом нужно догататься самостоятельно? Первая функция сильно похожа на SPL, неужто на несчастную STM8 еще и это дерьмище вкорячили? Жуть!

В общем, прочитав этот код я совершенно не могу даже логику работы понять!

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

Вт окт 25, 2022 16:03:33

Написано в IAR + SPL. Цели - познавательно-развлекательные. SPI, к сожалению, уже занят... CLK вешал на прерывание, но оно тригеррится слишком поздно, когда вся пачка сигналов уже прошла. Как я понял, перед прерыванием выполняются текущие инструкции и (скорее всего) МК работает со стеком для подготовки прерывания. Соответственно, код из обработчика выполняется слишком поздно...

Здесь же фактически ждётся не изменение CLK, а только пока он равен нулю.

не совсем. первый бит выставляется сразу после Latch, далее он должен поменяться после CLK, потому, чисто в целях отладки, без разницы нуля ждать или единицы, максимум, возможен пропуск одного цикла Clk. Проблема в том, что while не работает... не могу понять почему.

Первая функция сильно похожа на SPL, неужто на несчастную STM8 еще и это дерьмище вкорячили? Жуть!

SPL и есть.. а где лучше писать? в STM я совсем новичок, и в местных сортах пенного не разбираюсь. пробовал родную IDE, но что то с космиком не сдружился.. может посоветуете что лучше? ясное дело, что ASM рулит, но пока не готов в него лезть. через ардуиновскую библу тоже нет желания работать.

Код установки уровня, ничего хитрого
Код:
void dataL(void){
   GPIO_WriteLow(DATA_PORT, DATA_PIN);
}

void dataH(void){
   GPIO_WriteHigh(DATA_PORT, DATA_PIN);
}
Последний раз редактировалось Ромыч Вт окт 25, 2022 16:25:52, всего редактировалось 1 раз.

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

Вт окт 25, 2022 16:18:40

По картинкам вроде бы отрицательная полярность импульсов используется. Может быть, попробовать
while( GPIO_ReadInputPin(CLK_PORT, CLK_PIN)==1){};
Последний раз редактировалось Vladislav14 Вт окт 25, 2022 16:28:06, всего редактировалось 2 раз(а).

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

Вт окт 25, 2022 16:19:52

не работает. данные все равно отдаются одной пачкой, как будто бы while там и нет вовсе

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

Вт окт 25, 2022 16:28:24

И ещё вопрос - какой конкретно контроллер? Если 103f3p6, то у него по умолчанию тактовая /8, т.е. 2 MHz. Чтобы было 16:
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);

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

Вт окт 25, 2022 16:30:07

И ещё вопрос - какой конкретно контроллер? Если 103f3p6, то у него по умолчанию тактовая /8, т.е. 2 MHz. Чтобы было 16:
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);

да, именно его, на отладочной чинской платке. CLK_PRESCALER_HSIDIV1 стоит, потому и уточнил, что камень работает на 16мгц :)
Ответить