STM32F103 & Arduino IDE

nik182
Offline
Зарегистрирован: 04.05.2015

Я с 1602 столкнулся в начале изучения stm. С тех пор много воды утекло. А ты, как всегда, только словеса развешиваешь ни листинга в доказательство, ни схемы. Можешь хотя бы сформулировать в чем я не прав? Конкретно так. Без эмоций. За точным определением атомарности можешь в wiki сходить или куда ещё, если сам не знаешь что такое атомарность. По крайней мере там смысл атомарности не далеко от того что я описал. Так и с остальным. Напиши несколько строк атомарной установки нулевых битов порта?   

ssss
Offline
Зарегистрирован: 01.07.2016

nik182 пишет:

Я с 1602 столкнулся в начале изучения stm. С тех пор много воды утекло.

Не смеши... что в них изменилось за это время???

Я их цеплял ещё на ПИК16... если знаешь что это такое...

Цитата:

А ты, как всегда, только словеса развешиваешь ни листинга в доказательство, ни схемы.

В доказательство чего... что ты облажался??? )))))))

Вот оно мне так надо... это тебе надо...

Цитата:

Можешь хотя бы сформулировать в чем я не прав? Конкретно так. Без эмоций.

Скажи честно... ты мои посты ваще не читаешь??? А то ты по своему унылому троллингу и до 0 лэвэла не дотягиваешь...

Цитата:

За точным определением атомарности можешь в wiki сходить или куда ещё, если сам не знаешь что такое атомарность. По крайней мере там смысл атомарности не далеко от того что я описал.

Не важно что ты описал и как... важно что ты понял и как это применил... Это хоть не подлежит обсуждению??? Не???

nik182
Offline
Зарегистрирован: 04.05.2015

Опять одни слова. На пике у меня есть прибор, который в реестр средств измерения включен ещё в 98 году. Там тоже 1602 стоит. 

tesak47
Offline
Зарегистрирован: 22.01.2015

Здравствуйте уважаемые форумчане!

Работаю учителем. С ребенком готовим проект 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);
  }
}

 

 

b707
Offline
Зарегистрирован: 26.05.2017

tesak47 пишет:

Часы то тикают то не тикают, если поднести руку к плате или дотронусь до кварца то начинают идти.

раз реагируют на руку - проблема не программная, а аппаратная. У меня на двух платах из шести было ровно то же самое. Оказалось, был не пропаян часовой кварц , вот он:

просто аккуратно паяльником пропаиваете его 4 ножки - и часы пойдут

nik182
Offline
Зарегистрирован: 04.05.2015

А у меня пришло 5 штук и у всех не работали часовые кварцы. Пришлось подпаивать свои кварцы прямо по верх на ноги. 

b707
Offline
Зарегистрирован: 26.05.2017

nik182 пишет:

А у меня пришло 5 штук и у всех не работали часовые кварцы. Пришлось подпаивать свои кварцы прямо по верх на ноги. 

а точно они не работали? - может просто не припаяны, как у меня?

nik182
Offline
Зарегистрирован: 04.05.2015

Точно. Первым делом пропаял. Выпаять не смог. Подлезть паяльником сразу к четырём ногам не получается. Подпаял просто круглые бочёнки часовых кварцев к ногам и положил сверху. Теперь красивая композиция из двух кварцев разных типоразмеров. И что то мне говорит, что в тех, что на плате были изначально, в корпусах вообще не было кварцев. После подпайки второго работает совершенно штатно, не мешает. Такой китайский экономичный вариант. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А чо, на BluePill есть RTC встроенный?  Прям с кварцем? 

b707
Offline
Зарегистрирован: 26.05.2017

DetSimen пишет:

А чо, на BluePill есть RTC встроенный?  Прям с кварцем? 

да, и вполне работает.

Я его использую в часах в моем единственном проекте на Амперке - "Офисные часы на матрицах"

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

О_О  пора доставать из пыльного мешка свои STM-ки да щюпать как следовает, а не наскоками. 

nik182
Offline
Зарегистрирован: 04.05.2015

И даже нога (крайняя) под батарейку литиевую выведена. Я тут из стола как то достал платку к которой примерно пол года литиевая батарейка была подключена. Время убежало секунд на 30. Не так плохо за пол года, но тут вопросы к кварцу. Ещё RTC содержит 42 16-битных регистра, которые можно использовать как память, которая сохраняется, пока батарейка подключена. Не eeprom конечно, но что то хранить можно.  

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

nik182 пишет:

Ещё RTC содержит 42 16-битных регистра, которые можно использовать как память, которая сохраняется, пока батарейка подключена.

Да ты прям для меня открываешь неизведанные горизонты. О_О   Спасибо.  

b707
Offline
Зарегистрирован: 26.05.2017

nik182 пишет:

Не eeprom конечно, но что то хранить можно.  

ну. с еепром-то на СТМ никаких проблем нет - библиотека ЕЕПРОМ эмулируется через флеш, места навалом

nik182
Offline
Зарегистрирован: 04.05.2015

Извини, я не хотел горизонты. RTC в stm32f1 сильно кастрированный. Практически только секунды считает. Всё остальное самому приходится пересчитывать.  

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

nik182 пишет:

Извини, я не хотел горизонты. RTC в stm32f1 сильно кастрированный. Практически только секунды считает. Всё остальное самому приходится пересчитывать.  

Дак вот вапще ничего страшного.  Я вообще даже не знал, что и это возможно.  Наерна, засяду за книшки по STM, самому аш интересно стало.  Благодарю.  

ВН
Offline
Зарегистрирован: 25.02.2016

 С полгода назад ST начала свободно распространять STM32CubeIDE, в сети сейчас вроде уже достаточно материала про это дело.

 

 

nik182
Offline
Зарегистрирован: 04.05.2015

Книжки конечно хорошо. Только вот индийцы уже практически всё написали. Всю инициализацию периферии можно просто по умолчанию доверить им. Если конечно каких то уж совсем тонкостей душа захочет, то придётся по мануалам полазить. А так поставить 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.    

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ВН пишет:

 С полгода назад ST начала свободно распространять STM32CubeIDE, в сети сейчас вроде уже достаточно материала про это дело.

была 1.0, сейчас вроде 1.2 и кайло не нужен, ограничений по коду нет )))

(st-stm32cubeide_1.2.0_5034_20200108_0926_x86_64.exe)

ВН
Offline
Зарегистрирован: 25.02.2016

ua6em пишет:

была 1.0, сейчас вроде 1.2 и кайло не нужен, ограничений по коду нет )))

(st-stm32cubeide_1.2.0_5034_20200108_0926_x86_64.exe)

Это да, и stm32cubemx, о котором выше писал nik182, туда уже интегрирован + библиотека HAL.

 

mixail844
Offline
Зарегистрирован: 30.04.2012

Имхо, лучше пользоваться связкой CubeMX32 + Atollic True Studio 9.3, шустрее и стабильнее работает в дебаге чем cubeide 1.0 (1.2 не пробывал, но по release notes там нет удобных плагинов для работы с freertos из коробки, так же встроенный в cubeide генератор как то хуже работает - если помню правильно: перезаписывает файлы самого проекта тем самым удаляя вручную добавленные папки в include directories)

nik182
Offline
Зарегистрирован: 04.05.2015

mixail844 пишет:
Имхо, лучше пользоваться связкой 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а можно сгенерить ошибку. Это ж как можно сделать в официальной среде? 

b707
Offline
Зарегистрирован: 26.05.2017

подниму ветку.

Подскажите. СТМ-овский аддон для компиляции тоже использует тулчейн arm-none-eabi-gcc из пакета поддержки Ардуино Дуе? Если да, какая там версия? что-то у меня показывается, что самый свежий дистрибутив в менеджере плат Ардуино для Дуе - это версия 1.6.12. включающая внутри компилятор версии 4.8.3-2014q1. соответственно 2014 года :)

Я, конечно, могу обновить тулчейн вручную, без помощи Ардуино ИДЕ... проверил, пакет xpack-arm-none-eabi-gcc-9.2.1-1.1 легко ставится вместо штатного. Но хотелось бы штатными средствами. чтобы потом не наткнутся на несовместимости в коде

Densl
Offline
Зарегистрирован: 28.11.2018

А где посмотреть какой тулчейн подключён а данный момен?

b707
Offline
Зарегистрирован: 26.05.2017

Densl пишет:
А где посмотреть какой тулчейн подключён а данный момен?

в момент компиляции вываливается куча строчек вызова компилятора и линкера - смотрите путь. откуда они вызываются - это и есть тулчейн

например, на моем компе:

C:\Users\Dmit\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\9.2.1-1.1.1/bin/arm-none-eabi-g++

 

Densl
Offline
Зарегистрирован: 28.11.2018

У меня только показывает компилятор 4.8.3-4014q1 в адоне от Роджера кларка установленного локально на комп без интернета.

b707
Offline
Зарегистрирован: 26.05.2017

Densl пишет:
У меня только показывает компилятор 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. Идете в папку, где у вас установлен старый тулчейн, у меня это

C:\Users\Dmit\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\

внутри этой папки есть папка с номером версии, у вас это 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 перезапускаете ардуино ИДЕ и пробуете собрать свои старые проекты

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Ухты, я, когда создавал эту тему, и не думал что она так зайдёт, десять страниц на форуме. Спасибо Вам, народ

rocket.space
Offline
Зарегистрирован: 24.09.2021

Здравствуйте!
Могли бы вы подсказать, как записать данные на sd-карту с bluepill через Arduino IDE? Попробовала несколько библиотек, пока безуспешно. Ядро от Роджера Кларка стоит.

rocket.space
Offline
Зарегистрирован: 24.09.2021

Здравствуйте! Удалось ли вам разобраться с этим? Тот же вопрос стоит. Использую ядро Роджера Кларка Arduino-STM32. Пытаюсь по второму SPI записать данные на карточку с BluePill. Если сможете подсказать, будет невероятно здорово!

b707
Offline
Зарегистрирован: 26.05.2017

rocket.space покажите код, как пробовали

rocket.space
Offline
Зарегистрирован: 24.09.2021

Пробовала примерно вот так как ниже.
И использовала конфиг для выбора параметров для стм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);

}

 

 

b707
Offline
Зарегистрирован: 26.05.2017

вы же написали, что используете ядро Роджера Кларка? Зачем тогда какие-то конфиги и библиотеки с сайта ардуино? - там совсем другой аддон, с кларковским он не совместим.

У вас в коде жуткая смесь из разных СТМ пакетов. Так не заработает.

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

Неужели у Кларка нет примера работы с СДкартой? - не верю

rocket.space
Offline
Зарегистрирован: 24.09.2021

Вы правы, у Кларка есть папка 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. 

b707
Offline
Зарегистрирован: 26.05.2017

у вас каша в голове

sdio - это совсем иной интерфейс, используется для прошивки и отладки контроллеров СТМ, ничего общего с SPI и SDCard не имеет

примеры работы с картой ищите либо в каталоге SDCard. либо в SPI

rocket.space
Offline
Зарегистрирован: 24.09.2021

Поняла. Спасибо большое! Однако не подскажете где найти пример работы с sdcard и spi? spi ладно, это есть в ядре, но про sdcard ничего не нашла.

b707
Offline
Зарегистрирован: 26.05.2017

rocket.space пишет:

Поняла. Спасибо большое! Однако не подскажете где найти пример работы с sdcard и spi? spi ладно, это есть в ядре, но про sdcard ничего не нашла.

вы правы. я сейчас вот так с ходу тоже не нашел.

Но пишут,  что стандартная библиотека SD.h для ардуино совместима с СТМ32. Я бы вам для начала советовал попробовать запустить СДкарту на SPI1 - там она гарантировано должна работать со стандартной библиотекой.  А когда заработает - уже разбираться. как ее перетащить на SPI2

rocket.space
Offline
Зарегистрирован: 24.09.2021

Хорошо! Большое вам спасибо!

rocket.space
Offline
Зарегистрирован: 24.09.2021

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);

}

 

b707
Offline
Зарегистрирован: 26.05.2017

добрый вечер

Нашел модуль SD-карты для проверки

Попробовал через стандартную библиотеку 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

Кстати, а модуль карточки вы проверяли? с обычной ардуино работает?

rocket.space
Offline
Зарегистрирован: 24.09.2021

Здравствуйте! Спасибо вам большое за код, очень выручаете! Не догадалась просто объявить саму карточку, а не 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 проверяли? Спасибо вам за отзывчивость и много полезной информации!

 

 

 

 

 

 

 

 

 

b707
Offline
Зарегистрирован: 26.05.2017

rocket.space пишет:

И на всякий случай спрошу. 4 гб и 8 гб sdhc это нормально? Карточки проверялись только на телефоне. Форматирования никакого не было, они новые, или нужно их как-то отформатировать? Вы тоже на bluepill проверяли?

начну с конца - конечно я проверял на блюпиле, ведь ветка-то про это :)

Карточки sdhc нормально, как можете видеть в сообщении выше - у меня как раз SDHC 4gb. 8ГБ тоже должна работать. Карточки обязательно должны быть отформатированы, файловая система FAT16 или FAT32. Новые карты из магазина, скорее всего, уже имеют формат, но для гарантии я бы отформатировал их в виндоуз

rocket.space
Offline
Зарегистрирован: 24.09.2021

Большое спасибо! То есть вы указывали CS-пин PA4, верно?

b707
Offline
Зарегистрирован: 26.05.2017

rocket.space пишет:

Большое спасибо! То есть вы указывали CS-пин PA4, верно?

хм, после таких вопросов закрадывается сомнение... а вы код-то мой открывали?

const int chipSelect = PB9;

 

rocket.space
Offline
Зарегистрирован: 24.09.2021

Конечно я видела эту строчку и поэтому удивилась. Вроде как у Bluepill cs-пины это PA4, PB12. Или я ошибаюсь?

b707
Offline
Зарегистрирован: 26.05.2017

rocket.space пишет:

Конечно я видела эту строчку и поэтому удивилась. Вроде как у 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)) {

 

rocket.space
Offline
Зарегистрирован: 24.09.2021

Поняла вас. Большое спасибо за информацию!

b707
Offline
Зарегистрирован: 26.05.2017

Коллеги, я правильно понимаю, что настройка таймера как мастера для генерации сигнала TRGO например по совпадению CC4 не помешает мне использовать на этом же таймере прерывание, например по переполнению?

В апноутах по таймерам это как-то не освещено

ssss
Offline
Зарегистрирован: 01.07.2016

Абсолютно...

Прерывания... TRGO и ДМА... независимые модули... если только не менять настройки таймера на лету... софтварно или хардварно...

b707
Offline
Зарегистрирован: 26.05.2017

Вопросец по мастер-слейв таймерам

Задача - генерить пачку прямоугольных импульсов, частота 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, аддон Кларка