Я с 1602 столкнулся в начале изучения stm. С тех пор много воды утекло. А ты, как всегда, только словеса развешиваешь ни листинга в доказательство, ни схемы. Можешь хотя бы сформулировать в чем я не прав? Конкретно так. Без эмоций. За точным определением атомарности можешь в wiki сходить или куда ещё, если сам не знаешь что такое атомарность. По крайней мере там смысл атомарности не далеко от того что я описал. Так и с остальным. Напиши несколько строк атомарной установки нулевых битов порта?
Я с 1602 столкнулся в начале изучения stm. С тех пор много воды утекло.
Не смеши... что в них изменилось за это время???
Я их цеплял ещё на ПИК16... если знаешь что это такое...
Цитата:
А ты, как всегда, только словеса развешиваешь ни листинга в доказательство, ни схемы.
В доказательство чего... что ты облажался??? )))))))
Вот оно мне так надо... это тебе надо...
Цитата:
Можешь хотя бы сформулировать в чем я не прав? Конкретно так. Без эмоций.
Скажи честно... ты мои посты ваще не читаешь??? А то ты по своему унылому троллингу и до 0 лэвэла не дотягиваешь...
Цитата:
За точным определением атомарности можешь в wiki сходить или куда ещё, если сам не знаешь что такое атомарность. По крайней мере там смысл атомарности не далеко от того что я описал.
Не важно что ты описал и как... важно что ты понял и как это применил... Это хоть не подлежит обсуждению??? Не???
Работаю учителем. С ребенком готовим проект bluetooth часы - будильник на stm32f103. С этой платкой познакомился месяц назад. С ардуино уверенно обращаюсь. Так вот никак не могу запустить на ней RTC. В смысле они работают, только отстают неприлично много. Подключал батарею, прошивал пример от встроенной библиотеки <RTClock.h>... результата нет.
Часы то тикают то не тикают, если поднести руку к плате или дотронусь до кварца то начинают идти.
Почитав форум нашел похожую проблему. Но хочется убедиться что все делаю правильно. Очень прошу друзья залить скетч на плату и проверить ход часов.
#include <EEPROM.h>
#include <RTClock.h>
#define LED_PIN PC13
#define ALARM_LED PA7
#define BUTTON PA9
RTClock rt (RTCSEL_LSE);
unsigned int alarmSet, sunsetSet, pwmSet, inData;
unsigned long prevTime, timeSet;
byte h, m, s, hS, mS, sS, checker, c;
byte hA = 8;
byte mA = 30;
byte sA = 0;
void setup() {
Serial.begin(9600);
Serial2.begin(9600);
Serial.println();
Serial.println("HELLO");
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON, INPUT_PULLDOWN);
digitalWrite(LED_PIN, 1);
pinMode(ALARM_LED, PWM);
pwmWrite(ALARM_LED, 0);
rt.attachSecondsInterrupt(blink);
}
void loop() {
if (Serial2.available() > 0) {
Serial2.setTimeout(10);
String str = Serial2.readString();
str.trim();
checker = str.substring(0, 1).toInt();
str = str.substring(1);
inData = str.toInt();
if (inData > 500000) {
return;
}
Serial.print("incoming data: ");
Serial.print(str);
Serial.print(", ");
if (checker == 1) {
rt.setTime(inData);
h = inData / 3600;
m = (inData - h * 3600) / 60;
s = inData - h * 3600 - m * 60;
Serial2.print(h);
Serial2.print(":");
Serial2.print(m);
}
if (checker == 2) {
hA = inData / 3600;
mA = (inData - hA * 3600) / 60;
sA = inData - hA * 3600 - mA * 60;
Serial.print("alarm is set: ");
Serial.print(hA);
Serial.print(":");
Serial.println(mA);
}
if (checker == 3) {
hS = inData / 3600;
mS = (inData - hS * 3600) / 60;
sS = inData - hS * 3600 - mS * 60;
Serial.print("sunset is set: ");
Serial.print(hS);
Serial.print(":");
Serial.println(mS);
}
if (checker == 4) {
pwmSet = inData;
pwmWrite(ALARM_LED, pwmSet);
Serial.println(inData);
}
}
}
void rtc() {
h = rt.hour();
m = rt.minute();
s = rt.second();
if (h == hA && m == mA) {
Serial.println("alarm!!!");
for (pwmSet; pwmSet < 65535; pwmSet++) {
pwmWrite(ALARM_LED, pwmSet);
if (digitalRead(BUTTON) == 1) {
pwmSet = 0;
pwmWrite(ALARM_LED, pwmSet);
break;
}
delay(1);
}
}
if (h == hS && m == mS && pwmSet > 0) {
Serial.print("sunset!!!");
for (pwmSet; pwmSet > 0; pwmSet--) {
pwmWrite(ALARM_LED, pwmSet);
if (digitalRead(BUTTON) == 1) {
pwmSet = 0;
pwmWrite(ALARM_LED, pwmSet);
break;
}
delay(1);
}
}
}
void blink () {
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
rtc();
Serial.print(h);
Serial.print(":");
Serial.print(m);
Serial.print(":");
Serial.println(s);
}
А это пример из родной библиотеки:
#include <RTClock.h>
RTClock rt (RTCSEL_LSE); // initialise
uint32 tt;
#define LED_PIN PB1
// This function is called in the attachSecondsInterrpt
void blink ()
{
digitalWrite(LED_PIN,!digitalRead(LED_PIN));
}
void setup()
{
pinMode(LED_PIN, OUTPUT);
rt.attachSecondsInterrupt(blink);// Call blink
}
void loop()
{
if (rt.getTime()!=tt)
{
tt = rt.getTime();
Serial.print("time is: ");
Serial.println(tt);
}
}
Часы то тикают то не тикают, если поднести руку к плате или дотронусь до кварца то начинают идти.
раз реагируют на руку - проблема не программная, а аппаратная. У меня на двух платах из шести было ровно то же самое. Оказалось, был не пропаян часовой кварц , вот он:
просто аккуратно паяльником пропаиваете его 4 ножки - и часы пойдут
Точно. Первым делом пропаял. Выпаять не смог. Подлезть паяльником сразу к четырём ногам не получается. Подпаял просто круглые бочёнки часовых кварцев к ногам и положил сверху. Теперь красивая композиция из двух кварцев разных типоразмеров. И что то мне говорит, что в тех, что на плате были изначально, в корпусах вообще не было кварцев. После подпайки второго работает совершенно штатно, не мешает. Такой китайский экономичный вариант.
И даже нога (крайняя) под батарейку литиевую выведена. Я тут из стола как то достал платку к которой примерно пол года литиевая батарейка была подключена. Время убежало секунд на 30. Не так плохо за пол года, но тут вопросы к кварцу. Ещё RTC содержит 42 16-битных регистра, которые можно использовать как память, которая сохраняется, пока батарейка подключена. Не eeprom конечно, но что то хранить можно.
Книжки конечно хорошо. Только вот индийцы уже практически всё написали. Всю инициализацию периферии можно просто по умолчанию доверить им. Если конечно каких то уж совсем тонкостей душа захочет, то придётся по мануалам полазить. А так поставить stm32cubemx, выбрать процессор, среду, периферию с режимами и нажать кнопку генерация кода. Получим несколько файлов проекта, где в main останется дописать свой функционал. Тулчейн от http://www.stm32duino.com/ кушает нормально эти файлы.
После установки stm32cubemx в папке юзера открывается папка c:\Users\*****\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.0\ в которой много интересного. В частности примеры использования периферии в конкретных задачах. Например c:\Users\*****\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Examples\UART\ пример как заставить printf печатать в uart.
Имхо, лучше пользоваться связкой CubeMX32 + Atollic True Studio 9.3, шустрее и стабильнее работает в дебаге чем cubeide 1.0 (1.2 не пробывал, но по release notes там нет удобных плагинов для работы с freertos из коробки, так же встроенный в cubeide генератор как то хуже работает - если помню правильно: перезаписывает файлы самого проекта тем самым удаляя вручную добавленные папки в include directories)
Имхо, лучше пользоваться связкой CubeMX32 + Atollic True Studio 9.3, шустрее и стабильнее работает в дебаге чем cubeide 1.0 (1.2 не пробывал, но по release notes там нет удобных плагинов для работы с freertos из коробки, так же встроенный в cubeide генератор как то хуже работает - если помню правильно: перезаписывает файлы самого проекта тем самым удаляя вручную добавленные папки в include directories)
Поддерживаю про связку CubeMX32 + Atollic True Studio 9.3. В таком варианте сразу получаем рабочий выходной файл. В кубеиде ни разу не смог скомпилировать с первого раза. Приходилось с бубном лезть в дебри настроек. Приходилось отключать опции, которые у меня не использовались, но давали ошибки компиляции в глубине CMSIS, что для меня было удивительно - как в отлаженной системе SMSISа можно сгенерить ошибку. Это ж как можно сделать в официальной среде?
Подскажите. СТМ-овский аддон для компиляции тоже использует тулчейн arm-none-eabi-gcc из пакета поддержки Ардуино Дуе? Если да, какая там версия? что-то у меня показывается, что самый свежий дистрибутив в менеджере плат Ардуино для Дуе - это версия 1.6.12. включающая внутри компилятор версии 4.8.3-2014q1. соответственно 2014 года :)
Я, конечно, могу обновить тулчейн вручную, без помощи Ардуино ИДЕ... проверил, пакет xpack-arm-none-eabi-gcc-9.2.1-1.1 легко ставится вместо штатного. Но хотелось бы штатными средствами. чтобы потом не наткнутся на несовместимости в коде
внутри этой папки есть папка с номером версии, у вас это 4.8.3-2014q1
3. Перемещаете эту папку целиком в какое-то другое место за пределами каталогов Ардуино (на случай. чтобы можно было восстановить. если что-то пойдет не так)
4. на это место копируете папку из скачанного архива (например в версии 9.2.1 она называется xpack-arm-none-eabi-gcc-9.2.1-1.1) и переименовываете ее в 9.2.1-1.1
5 перезапускаете ардуино ИДЕ и пробуете собрать свои старые проекты
Здравствуйте!
Могли бы вы подсказать, как записать данные на sd-карту с bluepill через Arduino IDE? Попробовала несколько библиотек, пока безуспешно. Ядро от Роджера Кларка стоит.
Здравствуйте! Удалось ли вам разобраться с этим? Тот же вопрос стоит. Использую ядро Роджера Кларка Arduino-STM32. Пытаюсь по второму SPI записать данные на карточку с BluePill. Если сможете подсказать, будет невероятно здорово!
Пробовала примерно вот так как ниже.
И использовала конфиг для выбора параметров для стм32 по примеру проекта из интернета. SDCONFIG.h при необходимости тоже могу показать. Он взят отсюда https://github.com/Bakisha/STM32-SID-PLAYER/tree/master/SD_CARD. Также пробовала библиотеку STM32duino которая по сайте Ардуино есть. Ссылка на нее - https://github.com/stm32duino/STM32SD. При компиляции возникают многочисленные ошибки, прежде всего не хватает файла stm32_def.h и нескольких других файлов.
#include <SPI.h>
#include "SDCONFIG.h"
#include <SdFat.h>
#define SDCARD_SPI SPI2
#define SDCARD_MISO_PIN PB15
#define SDCARD_MOSI_PIN PB14
#define SDCARD_SCK_PIN PB13
#define SDCARD_SS_PIN PB12
#define CS_SDCARD PB12 // can be changed
#define SD_SPEED 20 // Maximum SD Card SPI speed in MHz
//SPIClass SPI_2(2);
SdFat sd;
String dataStr;
bool status;
//SdFile myFile("test.txt", FILE_WRITE);
void setup() {
Serial.begin(115200);
// SPI_2.begin();
// SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
// SPI_2.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
// SPI_2.setClockDivider(SPI_CLOCK_DIV16); // Use a different speed to SPI 1
// pinMode(CS_SDCARD, OUTPUT);
status=sd.begin(CS_SDCARD, SD_SCK_MHZ(SD_SPEED));
if(!status){
dataStr="ERROR1 - can't open sd card";
Serial.println(dataStr);
} else{
dataStr="OK1 - SD started";
Serial.println(dataStr);
}
}
void loop() {
dataStr="Hi!";
Serial.println(dataStr);
}
вы же написали, что используете ядро Роджера Кларка? Зачем тогда какие-то конфиги и библиотеки с сайта ардуино? - там совсем другой аддон, с кларковским он не совместим.
У вас в коде жуткая смесь из разных СТМ пакетов. Так не заработает.
SPI пины определять дефайнами не надо, они уже прописаны в ядре
Далее использовать инициализацию SPI через SPIClass, как раз ту. что вы зачем-то комментировали:
//SPIClass SPI_2(2);
// SPI_2.begin();
// SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
// SPI_2.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
// SPI_2.setClockDivider(SPI_CLOCK_DIV16); // Use a different speed to SPI 1
Неужели у Кларка нет примера работы с СДкартой? - не верю
Вы правы, у Кларка есть папка SDIO для работы с SD. В ней нет примера работы с SD, только .cpp файл и хедер. Там есть класс SdCard. Точнее сам класс и его конструктор там не объявлен. Лишь определены методы этого класса. Внутри хедера инклудится файл SdFat. Установила в менеджере библиотек ардуино ее, эту библиотеку. Далее в файле SdFat нет объявления опять же этого класса. Но есть инклуд других файлов находящихся также в библиотеке SdFat для ардуино - это в том числе файл с объявленным классом SdioCard SdioCard.h. Однако во-первых в функции инициализации этого объекта в SdFat есть параметр в виде объекта SdCondig (некий конфиг с опциями), а в SDIO Роджера Кларка, с которой все это начинается в параметрах begin() стоит void. Тем самым оно не компилится. Но ладно это, я убрала и в объявлении функции begin() в SdFat-е этот параметр. И оно уж совсем не работает. Подскажите, как надо сделать. Заранее большое спасибо! А так да, я пробовала писать объявление sd-карты в виде SdioCard sdcard; Ну и потом sdcard.begin() или sdcard.begin(sdconf), где sdconf - объект класса SdConfig.
Поняла. Спасибо большое! Однако не подскажете где найти пример работы с sdcard и spi? spi ладно, это есть в ядре, но про sdcard ничего не нашла.
вы правы. я сейчас вот так с ходу тоже не нашел.
Но пишут, что стандартная библиотека SD.h для ардуино совместима с СТМ32. Я бы вам для начала советовал попробовать запустить СДкарту на SPI1 - там она гарантировано должна работать со стандартной библиотекой. А когда заработает - уже разбираться. как ее перетащить на SPI2
b707 здравствуйте!
Могли бы вы посмотреть, пожалуйста, на код и может быть подскажете, что в нем может быть не так. Использую первый SPI. Как я понимаю, когда используется первый, то возможно и не нужно его инициализировать в принципе, но у меня ни с такого рода инициализацией, которая в комментариях, не работает, ни без нее. То есть в ком-порт сейчас выводятся сообщения "Initialization Failed" и все в таком духе. Взяла как вы и посоветовали библиотеку SD. Заранее большое спасибо!
#include <SPI.h>
#include <SD.h>
//#define CS_SDCARD PA4 // can be changed
//#define SD_SPEED 20 // Maximum SD Card SPI speed in MHz
SDClass sdcard;
//SPIClass SPI_1(1);
//File myFile;
String dataStr;
void setup() {
Serial.begin(115200);
// SPI_1.begin();
// SPI_1.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
// SPI_1.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
// SPI_1.setClockDivider(SPI_CLOCK_DIV16);
dataStr="Initializing SD card...";
Serial.print(dataStr);
while(!sdcard.begin(20,PA4)) {
Serial.println("initialization failed. Things to check:");
Serial.println("1. is a card inserted?");
Serial.println("2. is your wiring correct?");
Serial.println("3. did you change the chipSelect pin to match your shield or module?");
Serial.println("Note: press reset or reopen this Serial Monitor after fixing your issue!");
}
Serial.println("initialization done.");
}
void loop() {
dataStr="Hi!";
Serial.println(dataStr);
}
Попробовал через стандартную библиотеку SD.h - на STM32 запустился пример для обычного ардуино вообще без правки, за исключением указания CS пина:
#include <SPI.h>
#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = PB9;
void setup() {
// SPI.setModule(2);
Serial.begin(9600);
delay(5000);
Serial.print("\nInitializing SD card...");
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
// неверное подключение или карта неисправна
Serial.println("initialization failed");
return;
} else {
// всё ок!
Serial.println("Wiring is correct and a card is present.");
}
// считываем тип карты и выводим его в COM-порт
Serial.print("\nCard type: ");
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknown");
}
// инициализация файловой системы
if (!volume.init(card)) {
// неверная файловая система
Serial.println("Could not find FAT16/FAT32 partition.");
return;
}
// считываем тип и вычисляем размер первого раздела
uint32_t volumesize;
Serial.print("\nVolume type is FAT");
Serial.println(volume.fatType(), DEC);
Serial.println();
volumesize = volume.blocksPerCluster(); // блоков на кластер
volumesize *= volume.clusterCount(); // кластеров
volumesize *= 512; // 512 байтов в блоке, итого байт..
Serial.print("Volume size (bytes): ");
Serial.println(volumesize);
Serial.print("Volume size (Kbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Mbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
// выводим список файлов
root.ls(LS_R | LS_DATE | LS_SIZE);
}
void loop(void) {
}
Вывод:
Initializing SD card...Wiring is correct and a card is present.
Card type: SDHC
Volume type is FAT32
Volume size (bytes): 3935064064
Volume size (Kbytes): 3842836
Volume size (Mbytes): 3752
Files found on the card (name, date and size in bytes):
GRLDR 2013-07-24 07:02:18 272255
USBDRIVE.TAG 2009-12-12 21:54:48 0
MENU.LST 2016-08-16 00:00:42 1998
......
По умолчанию код работает на канале SPI1. Для того, чтобы запустить его на SPI2 - достаточно раскомментировать строчку 11
Кстати, а модуль карточки вы проверяли? с обычной ардуино работает?
Здравствуйте! Спасибо вам большое за код, очень выручаете! Не догадалась просто объявить саму карточку, а не SDClass-объект ранее. Однако у меня до сих пор инициализация не успешна. Предположительно проблема в модуле действительно. Опробовано два варианта. На ардуино сразу скажу ничего не проверялось, а наверное очень зря.
1 - взят модуль чтения-записи https://amperkot.ru/products/modul_chteniya_i_zapisi_microsd_card_reader_spi/23871298.html. Однако я позже заметила, что он от 4.5 в минимум может работать, а тут 3.3 в логика у платы stm32f103c8t6. Поэтому нужно что-то с этим сделать. Постараюсь решить эту проблему.
2 - На первое время был сооружен колхоз, то есть взят обычный SD-адаптер и припаян, он работает от 3.3 как раз. Картинку принципа подключения прикладываю ниже. На второй картинке справа то, что сейчас использовалось. Предположительно как раз проблема сейчас в самом модуле.
И на всякий случай спрошу. 4 гб и 8 гб sdhc это нормально? Карточки проверялись только на телефоне. Форматирования никакого не было, они новые, или нужно их как-то отформатировать? Вы тоже на bluepill проверяли? Спасибо вам за отзывчивость и много полезной информации!
И на всякий случай спрошу. 4 гб и 8 гб sdhc это нормально? Карточки проверялись только на телефоне. Форматирования никакого не было, они новые, или нужно их как-то отформатировать? Вы тоже на bluepill проверяли?
начну с конца - конечно я проверял на блюпиле, ведь ветка-то про это :)
Карточки sdhc нормально, как можете видеть в сообщении выше - у меня как раз SDHC 4gb. 8ГБ тоже должна работать. Карточки обязательно должны быть отформатированы, файловая система FAT16 или FAT32. Новые карты из магазина, скорее всего, уже имеют формат, но для гарантии я бы отформатировал их в виндоуз
Конечно я видела эту строчку и поэтому удивилась. Вроде как у Bluepill cs-пины это PA4, PB12. Или я ошибаюсь?
ошибаетесь. Немного теории - К каждой SPI шине можно подключить по нескольку устройств. при этом пины SCK MISO MOSI у них будут общими, а вот CS должен быть у каждого девайса свой. Уже из этого следует, что для CS невозможно заранее выделить один определенный пин .
CS пином может быть любой цифровой пин по выбору программиста, главное сообщить его номер соответсвующему устройству. В данном случае вы указываете его в момент инициализации библиотеки SD. В моем коде это выглядит так:
const int chipSelect = PB9;
void setup() {
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Коллеги, я правильно понимаю, что настройка таймера как мастера для генерации сигнала TRGO например по совпадению CC4 не помешает мне использовать на этом же таймере прерывание, например по переполнению?
Задача - генерить пачку прямоугольных импульсов, частота 1 МГц, скважность значения не имеет. В пачке должно быть строго 138 импульсов ( устройство-получатель считает фронты). Сгенерили одну пачку, сделали перерыв на 5 мкс, генерим следующую и так далее
Беру таймер3, выставляю частоту обновления 1 МГц, настраиваю на нем PWM , описываю его как мастер с генерацией TRGO по переполнению. Таймер4 конфигурирую как слейв с внешним тактированием от Таймера3, в нем задаю ARR = 137 (138-1):
void setup() {
//останавливаем таймеры
Timer3.c_dev()->regs.bas->CR1 &= ~TIMER_CR1_CEN;
Timer4.c_dev()->regs.bas->CR1 &= ~TIMER_CR1_CEN;
// описываем пин PB0( Timer3 CH3) как PWM
pinMode(PB0, PWM);
// инициализируем на Timer3 CH3 режим PWM
pwmWrite(PB0, 36);
noInterrupts();
// конфигурируем период таймера 1 МГц
Timer3.c_dev()->regs.bas->PSC =0;
Timer3.c_dev()->regs.bas->ARR = 72-1;
// конфигурируем событие UPDATE Timer3 как мастер-клок для слейв таймеров
Timer3.c_dev()->regs.bas->CR2 &= ~TIMER_CR2_MMS;
Timer3.c_dev()->regs.bas->CR2 |= TIMER_CR2_MMS_UPDATE;
// конфигурируем период таймера 4
Timer4.c_dev()->regs.bas->PSC =0;
Timer4.c_dev()->regs.bas->ARR = 138-1;
// описываем таймер как слейв с внешним тактированием от Таймера3
Timer4.setSlaveFlags(TIMER_SMCR_TS_ITR2 | TIMER_SMCR_SMS_EXTERNAL);
// задаем UPDATE_INTERRUPT
Timer4.attachInterrupt(TIMER_UPDATE_INTERRUPT, scan_R);
interrupts();
// запускаем оба таймера
Timer4.c_dev()->regs.bas->EGR |= TIMER_EGR_UG_BIT;
Timer4.c_dev()->regs.bas->CR1 |= TIMER_CR1_CEN;
Timer3.c_dev()->regs.bas->EGR |= TIMER_EGR_UG_BIT;
Timer3.c_dev()->regs.bas->CR1 |= TIMER_CR1_CEN;
}
в прерывании по переполнению таймера 4 первым делом останавливаю таймер3:
void scan_R() {
// первым делом останавливаем таймер
Timer3.c_dev()->regs.bas->CR1 &= ~TIMER_CR1_CEN;
..... // что-то делаем
//запускаем обратно
Timer3.c_dev()->regs.bas->CR1 |= TIMER_CR1_CEN;
}
Итог - в первой пачке импульсов 140 штук, во всех последующих 139. Полдня пробовал так и этак - не могу понять, почему так. Откуда лишние импульсы? Можно было бы предположить, что пока происходит вход в прерывание таймера4, таймер 3 убегает вперед. Но на 2 периода? - это же минимум 100 системных тиков? не слишком много? В интернете везде пишут, что вход в прерывание на STM32F103 - 15 тактов?
Вопрос - как правильно остановить таймер. чтобы не набегало лишних импульсов?
Сорри, сразу не указал - мк = stm32f103c8, аддон Кларка
Я с 1602 столкнулся в начале изучения stm. С тех пор много воды утекло. А ты, как всегда, только словеса развешиваешь ни листинга в доказательство, ни схемы. Можешь хотя бы сформулировать в чем я не прав? Конкретно так. Без эмоций. За точным определением атомарности можешь в wiki сходить или куда ещё, если сам не знаешь что такое атомарность. По крайней мере там смысл атомарности не далеко от того что я описал. Так и с остальным. Напиши несколько строк атомарной установки нулевых битов порта?
Я с 1602 столкнулся в начале изучения stm. С тех пор много воды утекло.
Не смеши... что в них изменилось за это время???
Я их цеплял ещё на ПИК16... если знаешь что это такое...
А ты, как всегда, только словеса развешиваешь ни листинга в доказательство, ни схемы.
В доказательство чего... что ты облажался??? )))))))
Вот оно мне так надо... это тебе надо...
Можешь хотя бы сформулировать в чем я не прав? Конкретно так. Без эмоций.
Скажи честно... ты мои посты ваще не читаешь??? А то ты по своему унылому троллингу и до 0 лэвэла не дотягиваешь...
За точным определением атомарности можешь в wiki сходить или куда ещё, если сам не знаешь что такое атомарность. По крайней мере там смысл атомарности не далеко от того что я описал.
Не важно что ты описал и как... важно что ты понял и как это применил... Это хоть не подлежит обсуждению??? Не???
Опять одни слова. На пике у меня есть прибор, который в реестр средств измерения включен ещё в 98 году. Там тоже 1602 стоит.
Здравствуйте уважаемые форумчане!
Работаю учителем. С ребенком готовим проект bluetooth часы - будильник на stm32f103. С этой платкой познакомился месяц назад. С ардуино уверенно обращаюсь. Так вот никак не могу запустить на ней RTC. В смысле они работают, только отстают неприлично много. Подключал батарею, прошивал пример от встроенной библиотеки <RTClock.h>... результата нет.
Часы то тикают то не тикают, если поднести руку к плате или дотронусь до кварца то начинают идти.
Почитав форум нашел похожую проблему. Но хочется убедиться что все делаю правильно. Очень прошу друзья залить скетч на плату и проверить ход часов.
А это пример из родной библиотеки:
Часы то тикают то не тикают, если поднести руку к плате или дотронусь до кварца то начинают идти.
раз реагируют на руку - проблема не программная, а аппаратная. У меня на двух платах из шести было ровно то же самое. Оказалось, был не пропаян часовой кварц , вот он:
просто аккуратно паяльником пропаиваете его 4 ножки - и часы пойдут
А у меня пришло 5 штук и у всех не работали часовые кварцы. Пришлось подпаивать свои кварцы прямо по верх на ноги.
А у меня пришло 5 штук и у всех не работали часовые кварцы. Пришлось подпаивать свои кварцы прямо по верх на ноги.
а точно они не работали? - может просто не припаяны, как у меня?
Точно. Первым делом пропаял. Выпаять не смог. Подлезть паяльником сразу к четырём ногам не получается. Подпаял просто круглые бочёнки часовых кварцев к ногам и положил сверху. Теперь красивая композиция из двух кварцев разных типоразмеров. И что то мне говорит, что в тех, что на плате были изначально, в корпусах вообще не было кварцев. После подпайки второго работает совершенно штатно, не мешает. Такой китайский экономичный вариант.
А чо, на BluePill есть RTC встроенный? Прям с кварцем?
А чо, на BluePill есть RTC встроенный? Прям с кварцем?
Я его использую в часах в моем единственном проекте на Амперке - "Офисные часы на матрицах"
О_О пора доставать из пыльного мешка свои STM-ки да щюпать как следовает, а не наскоками.
И даже нога (крайняя) под батарейку литиевую выведена. Я тут из стола как то достал платку к которой примерно пол года литиевая батарейка была подключена. Время убежало секунд на 30. Не так плохо за пол года, но тут вопросы к кварцу. Ещё RTC содержит 42 16-битных регистра, которые можно использовать как память, которая сохраняется, пока батарейка подключена. Не eeprom конечно, но что то хранить можно.
Ещё RTC содержит 42 16-битных регистра, которые можно использовать как память, которая сохраняется, пока батарейка подключена.
Да ты прям для меня открываешь неизведанные горизонты. О_О Спасибо.
Не eeprom конечно, но что то хранить можно.
ну. с еепром-то на СТМ никаких проблем нет - библиотека ЕЕПРОМ эмулируется через флеш, места навалом
Извини, я не хотел горизонты. RTC в stm32f1 сильно кастрированный. Практически только секунды считает. Всё остальное самому приходится пересчитывать.
Извини, я не хотел горизонты. RTC в stm32f1 сильно кастрированный. Практически только секунды считает. Всё остальное самому приходится пересчитывать.
Дак вот вапще ничего страшного. Я вообще даже не знал, что и это возможно. Наерна, засяду за книшки по STM, самому аш интересно стало. Благодарю.
С полгода назад ST начала свободно распространять STM32CubeIDE, в сети сейчас вроде уже достаточно материала про это дело.
Книжки конечно хорошо. Только вот индийцы уже практически всё написали. Всю инициализацию периферии можно просто по умолчанию доверить им. Если конечно каких то уж совсем тонкостей душа захочет, то придётся по мануалам полазить. А так поставить stm32cubemx, выбрать процессор, среду, периферию с режимами и нажать кнопку генерация кода. Получим несколько файлов проекта, где в main останется дописать свой функционал. Тулчейн от http://www.stm32duino.com/ кушает нормально эти файлы.
После установки stm32cubemx в папке юзера открывается папка c:\Users\*****\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.0\ в которой много интересного. В частности примеры использования периферии в конкретных задачах. Например c:\Users\*****\STM32Cube\Repository\STM32Cube_FW_F1_V1.8.0\Projects\STM3210E_EVAL\Examples\UART\ пример как заставить printf печатать в uart.
С полгода назад ST начала свободно распространять STM32CubeIDE, в сети сейчас вроде уже достаточно материала про это дело.
была 1.0, сейчас вроде 1.2 и кайло не нужен, ограничений по коду нет )))
(st-stm32cubeide_1.2.0_5034_20200108_0926_x86_64.exe)
была 1.0, сейчас вроде 1.2 и кайло не нужен, ограничений по коду нет )))
(st-stm32cubeide_1.2.0_5034_20200108_0926_x86_64.exe)
Это да, и stm32cubemx, о котором выше писал nik182, туда уже интегрирован + библиотека HAL.
Имхо, лучше пользоваться связкой CubeMX32 + Atollic True Studio 9.3, шустрее и стабильнее работает в дебаге чем cubeide 1.0 (1.2 не пробывал, но по release notes там нет удобных плагинов для работы с freertos из коробки, так же встроенный в cubeide генератор как то хуже работает - если помню правильно: перезаписывает файлы самого проекта тем самым удаляя вручную добавленные папки в include directories)
Поддерживаю про связку CubeMX32 + Atollic True Studio 9.3. В таком варианте сразу получаем рабочий выходной файл. В кубеиде ни разу не смог скомпилировать с первого раза. Приходилось с бубном лезть в дебри настроек. Приходилось отключать опции, которые у меня не использовались, но давали ошибки компиляции в глубине CMSIS, что для меня было удивительно - как в отлаженной системе SMSISа можно сгенерить ошибку. Это ж как можно сделать в официальной среде?
подниму ветку.
Подскажите. СТМ-овский аддон для компиляции тоже использует тулчейн arm-none-eabi-gcc из пакета поддержки Ардуино Дуе? Если да, какая там версия? что-то у меня показывается, что самый свежий дистрибутив в менеджере плат Ардуино для Дуе - это версия 1.6.12. включающая внутри компилятор версии 4.8.3-2014q1. соответственно 2014 года :)
Я, конечно, могу обновить тулчейн вручную, без помощи Ардуино ИДЕ... проверил, пакет xpack-arm-none-eabi-gcc-9.2.1-1.1 легко ставится вместо штатного. Но хотелось бы штатными средствами. чтобы потом не наткнутся на несовместимости в коде
А где посмотреть какой тулчейн подключён а данный момен?
в момент компиляции вываливается куча строчек вызова компилятора и линкера - смотрите путь. откуда они вызываются - это и есть тулчейн
например, на моем компе:
У меня только показывает компилятор 4.8.3-4014q1 в адоне от Роджера кларка установленного локально на комп без интернета.
в одной цифре ошиблись. там на конце 2014q1 - что означает первый квартал 2014 года.
Это компилятор вполне рабочий, но, очевидно, никакие "вкусняшки" с++14 и с++17 не поддерживает
Можете поставить более новый, скачав его вот отсюда
https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases
там куча разных версий, версия 10 у меня что-то не пошла, я ставил v9.2.1-1.1
инструкция по установке:
1. Скачиваете архив для своей ОС, распаковываете во временную папку
2. Идете в папку, где у вас установлен старый тулчейн, у меня это
внутри этой папки есть папка с номером версии, у вас это 4.8.3-2014q1
3. Перемещаете эту папку целиком в какое-то другое место за пределами каталогов Ардуино (на случай. чтобы можно было восстановить. если что-то пойдет не так)
4. на это место копируете папку из скачанного архива (например в версии 9.2.1 она называется xpack-arm-none-eabi-gcc-9.2.1-1.1) и переименовываете ее в 9.2.1-1.1
5 перезапускаете ардуино ИДЕ и пробуете собрать свои старые проекты
Ухты, я, когда создавал эту тему, и не думал что она так зайдёт, десять страниц на форуме. Спасибо Вам, народ
Здравствуйте!
Могли бы вы подсказать, как записать данные на sd-карту с bluepill через Arduino IDE? Попробовала несколько библиотек, пока безуспешно. Ядро от Роджера Кларка стоит.
Здравствуйте! Удалось ли вам разобраться с этим? Тот же вопрос стоит. Использую ядро Роджера Кларка Arduino-STM32. Пытаюсь по второму SPI записать данные на карточку с BluePill. Если сможете подсказать, будет невероятно здорово!
rocket.space покажите код, как пробовали
Пробовала примерно вот так как ниже.
И использовала конфиг для выбора параметров для стм32 по примеру проекта из интернета. SDCONFIG.h при необходимости тоже могу показать. Он взят отсюда https://github.com/Bakisha/STM32-SID-PLAYER/tree/master/SD_CARD. Также пробовала библиотеку STM32duino которая по сайте Ардуино есть. Ссылка на нее - https://github.com/stm32duino/STM32SD. При компиляции возникают многочисленные ошибки, прежде всего не хватает файла stm32_def.h и нескольких других файлов.
вы же написали, что используете ядро Роджера Кларка? Зачем тогда какие-то конфиги и библиотеки с сайта ардуино? - там совсем другой аддон, с кларковским он не совместим.
У вас в коде жуткая смесь из разных СТМ пакетов. Так не заработает.
SPI пины определять дефайнами не надо, они уже прописаны в ядре
Далее использовать инициализацию SPI через SPIClass, как раз ту. что вы зачем-то комментировали:
Неужели у Кларка нет примера работы с СДкартой? - не верю
Вы правы, у Кларка есть папка SDIO для работы с SD. В ней нет примера работы с SD, только .cpp файл и хедер. Там есть класс SdCard. Точнее сам класс и его конструктор там не объявлен. Лишь определены методы этого класса. Внутри хедера инклудится файл SdFat. Установила в менеджере библиотек ардуино ее, эту библиотеку. Далее в файле SdFat нет объявления опять же этого класса. Но есть инклуд других файлов находящихся также в библиотеке SdFat для ардуино - это в том числе файл с объявленным классом SdioCard SdioCard.h. Однако во-первых в функции инициализации этого объекта в SdFat есть параметр в виде объекта SdCondig (некий конфиг с опциями), а в SDIO Роджера Кларка, с которой все это начинается в параметрах begin() стоит void. Тем самым оно не компилится. Но ладно это, я убрала и в объявлении функции begin() в SdFat-е этот параметр. И оно уж совсем не работает. Подскажите, как надо сделать. Заранее большое спасибо! А так да, я пробовала писать объявление sd-карты в виде SdioCard sdcard; Ну и потом sdcard.begin() или sdcard.begin(sdconf), где sdconf - объект класса SdConfig.
у вас каша в голове
sdio - это совсем иной интерфейс, используется для прошивки и отладки контроллеров СТМ, ничего общего с SPI и SDCard не имеет
примеры работы с картой ищите либо в каталоге SDCard. либо в SPI
Поняла. Спасибо большое! Однако не подскажете где найти пример работы с sdcard и spi? spi ладно, это есть в ядре, но про sdcard ничего не нашла.
Поняла. Спасибо большое! Однако не подскажете где найти пример работы с sdcard и spi? spi ладно, это есть в ядре, но про sdcard ничего не нашла.
вы правы. я сейчас вот так с ходу тоже не нашел.
Но пишут, что стандартная библиотека SD.h для ардуино совместима с СТМ32. Я бы вам для начала советовал попробовать запустить СДкарту на SPI1 - там она гарантировано должна работать со стандартной библиотекой. А когда заработает - уже разбираться. как ее перетащить на SPI2
Хорошо! Большое вам спасибо!
b707 здравствуйте!
Могли бы вы посмотреть, пожалуйста, на код и может быть подскажете, что в нем может быть не так. Использую первый SPI. Как я понимаю, когда используется первый, то возможно и не нужно его инициализировать в принципе, но у меня ни с такого рода инициализацией, которая в комментариях, не работает, ни без нее. То есть в ком-порт сейчас выводятся сообщения "Initialization Failed" и все в таком духе. Взяла как вы и посоветовали библиотеку SD. Заранее большое спасибо!
добрый вечер
Нашел модуль SD-карты для проверки
Попробовал через стандартную библиотеку SD.h - на STM32 запустился пример для обычного ардуино вообще без правки, за исключением указания CS пина:
Вывод:
По умолчанию код работает на канале SPI1. Для того, чтобы запустить его на SPI2 - достаточно раскомментировать строчку 11
Кстати, а модуль карточки вы проверяли? с обычной ардуино работает?
Здравствуйте! Спасибо вам большое за код, очень выручаете! Не догадалась просто объявить саму карточку, а не SDClass-объект ранее. Однако у меня до сих пор инициализация не успешна. Предположительно проблема в модуле действительно. Опробовано два варианта. На ардуино сразу скажу ничего не проверялось, а наверное очень зря.
1 - взят модуль чтения-записи https://amperkot.ru/products/modul_chteniya_i_zapisi_microsd_card_reader_spi/23871298.html. Однако я позже заметила, что он от 4.5 в минимум может работать, а тут 3.3 в логика у платы stm32f103c8t6. Поэтому нужно что-то с этим сделать. Постараюсь решить эту проблему.
2 - На первое время был сооружен колхоз, то есть взят обычный SD-адаптер и припаян, он работает от 3.3 как раз. Картинку принципа подключения прикладываю ниже. На второй картинке справа то, что сейчас использовалось. Предположительно как раз проблема сейчас в самом модуле.
И на всякий случай спрошу. 4 гб и 8 гб sdhc это нормально? Карточки проверялись только на телефоне. Форматирования никакого не было, они новые, или нужно их как-то отформатировать? Вы тоже на bluepill проверяли? Спасибо вам за отзывчивость и много полезной информации!
И на всякий случай спрошу. 4 гб и 8 гб sdhc это нормально? Карточки проверялись только на телефоне. Форматирования никакого не было, они новые, или нужно их как-то отформатировать? Вы тоже на bluepill проверяли?
начну с конца - конечно я проверял на блюпиле, ведь ветка-то про это :)
Карточки sdhc нормально, как можете видеть в сообщении выше - у меня как раз SDHC 4gb. 8ГБ тоже должна работать. Карточки обязательно должны быть отформатированы, файловая система FAT16 или FAT32. Новые карты из магазина, скорее всего, уже имеют формат, но для гарантии я бы отформатировал их в виндоуз
Большое спасибо! То есть вы указывали CS-пин PA4, верно?
Большое спасибо! То есть вы указывали CS-пин PA4, верно?
хм, после таких вопросов закрадывается сомнение... а вы код-то мой открывали?
Конечно я видела эту строчку и поэтому удивилась. Вроде как у Bluepill cs-пины это PA4, PB12. Или я ошибаюсь?
Конечно я видела эту строчку и поэтому удивилась. Вроде как у Bluepill cs-пины это PA4, PB12. Или я ошибаюсь?
ошибаетесь. Немного теории - К каждой SPI шине можно подключить по нескольку устройств. при этом пины SCK MISO MOSI у них будут общими, а вот CS должен быть у каждого девайса свой. Уже из этого следует, что для CS невозможно заранее выделить один определенный пин .
CS пином может быть любой цифровой пин по выбору программиста, главное сообщить его номер соответсвующему устройству. В данном случае вы указываете его в момент инициализации библиотеки SD. В моем коде это выглядит так:
Поняла вас. Большое спасибо за информацию!
Коллеги, я правильно понимаю, что настройка таймера как мастера для генерации сигнала TRGO например по совпадению CC4 не помешает мне использовать на этом же таймере прерывание, например по переполнению?
В апноутах по таймерам это как-то не освещено
Абсолютно...
Прерывания... TRGO и ДМА... независимые модули... если только не менять настройки таймера на лету... софтварно или хардварно...
Вопросец по мастер-слейв таймерам
Задача - генерить пачку прямоугольных импульсов, частота 1 МГц, скважность значения не имеет. В пачке должно быть строго 138 импульсов ( устройство-получатель считает фронты). Сгенерили одну пачку, сделали перерыв на 5 мкс, генерим следующую и так далее
Беру таймер3, выставляю частоту обновления 1 МГц, настраиваю на нем PWM , описываю его как мастер с генерацией TRGO по переполнению. Таймер4 конфигурирую как слейв с внешним тактированием от Таймера3, в нем задаю ARR = 137 (138-1):
в прерывании по переполнению таймера 4 первым делом останавливаю таймер3:
Итог - в первой пачке импульсов 140 штук, во всех последующих 139. Полдня пробовал так и этак - не могу понять, почему так. Откуда лишние импульсы? Можно было бы предположить, что пока происходит вход в прерывание таймера4, таймер 3 убегает вперед. Но на 2 периода? - это же минимум 100 системных тиков? не слишком много? В интернете везде пишут, что вход в прерывание на STM32F103 - 15 тактов?
Вопрос - как правильно остановить таймер. чтобы не набегало лишних импульсов?
Сорри, сразу не указал - мк = stm32f103c8, аддон Кларка