Программирование STM8
Re: Программирование STM8
Коллеги, приветствую!
Поделитесь установщиком программы stm8 st visual develop ide.
STM не хочет делиться.
Спасибо
Поделитесь установщиком программы stm8 st visual develop ide.
STM не хочет делиться.
Спасибо
-
Vladislav14
- Родился
- Сообщения: 16
- Зарегистрирован: Вс мар 27, 2022 15:49:30
Re: Программирование STM8
[uquote="Migel Yka",url="/forum/viewtopic.php?p=4230970#p4230970"]Коллеги, приветствую!
Поделитесь установщиком программы stm8 st visual develop ide.[/uquote]
Скачивал 1.03.2022, обновлял лицензию
https://disk.yandex.ru/d/1eq_QJid_5Jw5Q
Поделитесь установщиком программы stm8 st visual develop ide.[/uquote]
Скачивал 1.03.2022, обновлял лицензию
https://disk.yandex.ru/d/1eq_QJid_5Jw5Q
-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Программирование STM8
Добрый день. Решил помигать светодиодиком на STM8. В Platformio установил соответствующий пакет, и выбрал пример native-blink (пока пробую без библиотек). В коде примера смотрю на настройку пина, и вижу следующее (привожу лишь необходимые на мой взгляд куски:
То есть, для настройки пина на выход пуш-пулл с быстрыми фронтами, надо выставить соответвующий бит (5 по счету) в 3-х регистрах. И это делается этой хитрой конструкцией. Почему она для меня хитрая ? Потому что в AVR и PIC я привык выставлять биты конструкцией вида DDRB |= 1<<5;
Ну и сбрасывать соответственно похожим образом: DDRB &= ~(1<<5);
Залез в хидер, нашёл там union, внутри которого структура с битовыми полями.
но как сбрасывать, так и не понял.
Как с помощью этой конструкции сбросить бит в регистре ?
Код: Выделить всё
#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, внутри которого структура с битовыми полями.
Спойлер
Код: Выделить всё
/** Port A data direction register (DDR at 0x5002) */
union {
/// bytewise access to DDR
uint8_t byte;
/// bitwise access to register DDR
struct {
BITFIELD_UINT DDR0 : 1; // bit 0
BITFIELD_UINT DDR1 : 1; // bit 1
BITFIELD_UINT DDR2 : 1; // bit 2
BITFIELD_UINT DDR3 : 1; // bit 3
BITFIELD_UINT DDR4 : 1; // bit 4
BITFIELD_UINT DDR5 : 1; // bit 5
BITFIELD_UINT DDR6 : 1; // bit 6
BITFIELD_UINT DDR7 : 1; // bit 7
}; // DDR bitfield
/// register _PORT_DDR reset value
#define sfr_PORT_DDR_RESET_VALUE ((uint8_t) 0x00)
} DDR;
Как с помощью этой конструкции сбросить бит в регистре ?
Re: Программирование STM8
LED_PORT.DDR.byte - это обращение ко всем битам, то есть к
/// bytewise access to DDR
uint8_t byte;
И можете работать с ним как раньше.
Union объединяет эти определения или делает эквивалентным их или проецирует этот байт на структуру и обратно (не знаю, как лучше сказать...)
то есть, к биту можно обратиться как LED_PORT.DDR.DDR0 = 0
/// bytewise access to DDR
uint8_t byte;
И можете работать с ним как раньше.
Union объединяет эти определения или делает эквивалентным их или проецирует этот байт на структуру и обратно (не знаю, как лучше сказать...)
то есть, к биту можно обратиться как LED_PORT.DDR.DDR0 = 0
-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Программирование STM8
[uquote="Martian",url="/forum/viewtopic.php?p=4274000#p4274000"]...к биту можно обратиться как LED_PORT.DDR.DDR0 = 0[/uquote]
Вот, такое обращение с использованием битовых полей для меня логично и понятно)) Ранее с обьединениями дела не имел, лишь вскользь читал в Кернигане и Ричи.
То есть, для сброса бита при обращении к структуре объединения как к целому байту мне необходимо писать LED_PORT.DDR.byte &= ~(LED_PIN); ?
И правильно ли я понял, что установку битов лучше производить конструкцией типа LED_PORT.DDR.byte |= LED_PIN, иначе если делать как в примере, то все остальные биты регистра будут сбрасываться ?
Вот, такое обращение с использованием битовых полей для меня логично и понятно)) Ранее с обьединениями дела не имел, лишь вскользь читал в Кернигане и Ричи.
То есть, для сброса бита при обращении к структуре объединения как к целому байту мне необходимо писать LED_PORT.DDR.byte &= ~(LED_PIN); ?
И правильно ли я понял, что установку битов лучше производить конструкцией типа LED_PORT.DDR.byte |= LED_PIN, иначе если делать как в примере, то все остальные биты регистра будут сбрасываться ?
Re: Программирование STM8
да, но только со сдвигом единички, то есть, (1 << LED_PIN)То есть, для сброса бита при обращении к структуре объединения как к целому байту мне необходимо писать LED_PORT.DDR.byte &= ~(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;-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Программирование STM8
[uquote="Martian",url="/forum/viewtopic.php?p=4274031#p4274031"]... да, но только со сдвигом единички, то есть, (1 <<LED_PIN).[/uquote]
Ну, учитывая, что в хидере пины представлены битовыми масками, а не порядковыми номерами битов, то наверное все таки без единичек))
Спасибо за ответы.
Ну, учитывая, что в хидере пины представлены битовыми масками, а не порядковыми номерами битов, то наверное все таки без единичек))
Код: Выделить всё
/*-------------------------------------------------------------------------
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
-
Vladislav14
- Родился
- Сообщения: 16
- Зарегистрирован: Вс мар 27, 2022 15:49:30
Re: Программирование STM8
Да, тут всё правильно ответили - через CR1 и CR2 задаются режимы работ, в ODR пишется собственно байт на выход порта. Но не стОит останавливаться на этом, есть ещё и альтернативные функции... лучше не программно дёргать, а к таймеру подключить. У меня, например, в управляшке для бесколлекторного мотора TIM2 работает генератором сигнала (TIM2_OC2Init(TIM2_OCMODE_TOGGLE, TIM2_OUTPUTSTATE_ENABLE,CCR2_Val, TIM2_OCPOLARITY_HIGH); - переключает выход с программируемой частотой), а первый таймер - частотомер - захватывает фронты с датчика и измеряет скорость вращения.
Re: Программирование STM8
Здравствуйте! Подскажите как в 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 <<
);
}
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 <<
}
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Программирование STM8
Ну надо как-то в него добавить второй АЦП, так как их там один.Proton78 писал(а):STM8S103 заставить работать АЦП2
Re: Программирование STM8
[uquote="Z_h_e",url="/forum/viewtopic.php?p=4307262#p4307262"]
[/uquote]
Вот же шшшшш..... Два дня убил на эту хрень. Перерыл кучу инфы. В учебниказ по STM8 написано что два АЦП. А в даташит именно на этот контроллер посмотреть не додумался. Благодарю за прозрение.
Ну надо как-то в него добавить второй АЦП, так как их там один.Proton78 писал(а):STM8S103 заставить работать АЦП2
Вот же шшшшш..... Два дня убил на эту хрень. Перерыл кучу инфы. В учебниказ по STM8 написано что два АЦП. А в даташит именно на этот контроллер посмотреть не додумался. Благодарю за прозрение.
Re: Программирование STM8
там может быть ADC1 или ADC2. просто неверно поняли.
- Ромыч
- Прорезались зубы
- Сообщения: 210
- Зарегистрирован: Ср янв 06, 2010 22:02:25
- Откуда: Уфа сити
- Контактная информация:
Re: Программирование STM8
Добрый день! Пытаюсь обуздать STM8. Задача - сымитировать работу сдвигового регистра. На всякий случай поясню суть: после сигнала latch идет серия тактовых сигналов, по которым отдаем в DATA биты по очереди. Проблема в том, что что latch читается легко, а вот с чтением CLK возникли проблемы. Не пойму, что не так, но либо читается один импульс, либо не читается вообще. СТМка работает на частоте 16мгц.
График сигналов в аттаче. Код функции
В строке 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, а тут, на голой СТМке как будто камня не хватает для выборки сигнала..
График сигналов в аттаче. Код функции
Код: Выделить всё
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();
}Подобный код на ардуине работал превосходно, даже с учетом тормозов фреймворка Arduino, а тут, на голой СТМке как будто камня не хватает для выборки сигнала..
Последний раз редактировалось Ромыч Вт окт 25, 2022 16:14:42, всего редактировалось 1 раз.
Что в цивилизованном мире называют "устаревшие технологии", в России зовется "технологии, проверенные временем"
-
Vladislav14
- Родился
- Сообщения: 16
- Зарегистрирован: Вс мар 27, 2022 15:49:30
Re: Программирование STM8
1. Это в какой среде написано?
2. А для чего - просто для развлекательно-познавательных целей? Вообще-то SPI можно соответственно задаче сконфигурировать. Ну или хотя бы CLK сконфигурировать с прерыванием от изменения уровня - тогда будет точно по переходу 1->0 или 0->1 срабатывать... Здесь же фактически ждётся не изменение CLK, а только пока он равен нулю.
2. А для чего - просто для развлекательно-познавательных целей? Вообще-то SPI можно соответственно задаче сконфигурировать. Ну или хотя бы CLK сконфигурировать с прерыванием от изменения уровня - тогда будет точно по переходу 1->0 или 0->1 срабатывать... Здесь же фактически ждётся не изменение CLK, а только пока он равен нулю.
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: Программирование STM8
Ромыч, код - адова жесть! Можно ведь использовать таймер или на худой конец прерывания.
Не приведено, что внутри функций GPIO_ReadInputPin, dataL, dataH и data1H - об этом нужно догататься самостоятельно? Первая функция сильно похожа на SPL, неужто на несчастную STM8 еще и это дерьмище вкорячили? Жуть!
В общем, прочитав этот код я совершенно не могу даже логику работы понять!
Не приведено, что внутри функций GPIO_ReadInputPin, dataL, dataH и data1H - об этом нужно догататься самостоятельно? Первая функция сильно похожа на SPL, неужто на несчастную STM8 еще и это дерьмище вкорячили? Жуть!
В общем, прочитав этот код я совершенно не могу даже логику работы понять!
- Ромыч
- Прорезались зубы
- Сообщения: 210
- Зарегистрирован: Ср янв 06, 2010 22:02:25
- Откуда: Уфа сити
- Контактная информация:
Re: Программирование STM8
Написано в IAR + SPL. Цели - познавательно-развлекательные. SPI, к сожалению, уже занят... CLK вешал на прерывание, но оно тригеррится слишком поздно, когда вся пачка сигналов уже прошла. Как я понял, перед прерыванием выполняются текущие инструкции и (скорее всего) МК работает со стеком для подготовки прерывания. Соответственно, код из обработчика выполняется слишком поздно...
SPL и есть.. а где лучше писать? в STM я совсем новичок, и в местных сортах пенного не разбираюсь. пробовал родную IDE, но что то с космиком не сдружился.. может посоветуете что лучше? ясное дело, что ASM рулит, но пока не готов в него лезть. через ардуиновскую библу тоже нет желания работать.
Код установки уровня, ничего хитрого
не совсем. первый бит выставляется сразу после Latch, далее он должен поменяться после CLK, потому, чисто в целях отладки, без разницы нуля ждать или единицы, максимум, возможен пропуск одного цикла Clk. Проблема в том, что while не работает... не могу понять почему.Здесь же фактически ждётся не изменение CLK, а только пока он равен нулю.
Первая функция сильно похожа на 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 раз.
Что в цивилизованном мире называют "устаревшие технологии", в России зовется "технологии, проверенные временем"
-
Vladislav14
- Родился
- Сообщения: 16
- Зарегистрирован: Вс мар 27, 2022 15:49:30
Re: Программирование STM8
По картинкам вроде бы отрицательная полярность импульсов используется. Может быть, попробовать
while( GPIO_ReadInputPin(CLK_PORT, CLK_PIN)==1){};
while( GPIO_ReadInputPin(CLK_PORT, CLK_PIN)==1){};
Последний раз редактировалось Vladislav14 Вт окт 25, 2022 16:28:06, всего редактировалось 2 раза.
- Ромыч
- Прорезались зубы
- Сообщения: 210
- Зарегистрирован: Ср янв 06, 2010 22:02:25
- Откуда: Уфа сити
- Контактная информация:
Re: Программирование STM8
не работает. данные все равно отдаются одной пачкой, как будто бы while там и нет вовсе
Что в цивилизованном мире называют "устаревшие технологии", в России зовется "технологии, проверенные временем"
-
Vladislav14
- Родился
- Сообщения: 16
- Зарегистрирован: Вс мар 27, 2022 15:49:30
Re: Программирование STM8
И ещё вопрос - какой конкретно контроллер? Если 103f3p6, то у него по умолчанию тактовая /8, т.е. 2 MHz. Чтобы было 16:
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
- Ромыч
- Прорезались зубы
- Сообщения: 210
- Зарегистрирован: Ср янв 06, 2010 22:02:25
- Откуда: Уфа сити
- Контактная информация:
Re: Программирование STM8
[uquote="Vladislav14",url="/forum/viewtopic.php?p=4309822#p4309822"]И ещё вопрос - какой конкретно контроллер? Если 103f3p6, то у него по умолчанию тактовая /8, т.е. 2 MHz. Чтобы было 16:
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);[/uquote]
да, именно его, на отладочной чинской платке. CLK_PRESCALER_HSIDIV1 стоит, потому и уточнил, что камень работает на 16мгц
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);[/uquote]
да, именно его, на отладочной чинской платке. CLK_PRESCALER_HSIDIV1 стоит, потому и уточнил, что камень работает на 16мгц
Что в цивилизованном мире называют "устаревшие технологии", в России зовется "технологии, проверенные временем"
