В разработке оказалось несколько устройств в составе которых кроме прочего планируется использовать F030F6P6. Они маленькие и достаточно производительные. Для мониторинга вполне достаточно. Программист я так себе, занимаюсь в основном железом. Но пощупать некоторые функции приходится, и тогда на помощь приходит Arduino IDE.
STM32G030F6P6
32х битный МК на ядре CORTEX M0+ , доступен в корпусах SO8, TSSOP20, LQFP32. В этой статье речь пойдет о втором варианте.
В линейке есть версии от 32 до 64кб флэш. Оперативной памяти у всех 8кб.
Рабочая частота до 64МГц, но в корпусе TSSOP20 доступно только внешнее либо внутреннее тактирование. Использовать кварц возможности нет.
Куча интерфейсов, таймеров и прочих плюшек, как и бывает у STM. Впрочем подробнее вы можете посмотреть в даташите.
И такое бывает...
Иногда такое случается, что в процессе отладки появляются сюрпризы. Например у ESP32 при использовании модема не работает второй порт АЦП. У STM32 подобных недоразумений я не встречал, но бывает что перепутаешь ногу, и окажется вдруг например что ШИМ на него повесить нельзя. Это может стать большой проблемой, если устройство уже начали готовить к серии, а может даже заказали производство плат. К тому-же отладка тех же БП, если управление на МК, без хотя бы какой-то тестовой прошивки невозможна.
Так вот наиболее быстро написать тестовую прошивку можно в Arduino IDE. Способствует этому большое количество поддерживаемых архитектур и бесконечное множество доступных библиотек.
Есть конечно готовые модули на том же алиэкспресс. Но не всегда есть возможность ждать, да и собрать такую небольшую плату не составляет труда, и не отнимает много времени.
От слов к делу
Для тестов именно этого МК я нарисовал простейшую схему и плату. Как бы я не любил кварцевые резонаторы, в данном корпусе этот вид тактирования недоступен. А значит и обвязки у нас 6 элементов- 2 конденсатора по питанию, безопасный USART1, подтяжка на Reset и на BOOT0.
Скомпоновано это в форм-фактор рассчитанный на установку в беспаечную макетную плату. Рисунок платы кстати можно использовать как шпаргалку по портам.
Программирование
В конкретно данном случае мне было необходимо проверить работу датчика температуры DS18B20 на порту PA5.
Настройки среды остались стандартные.
Ядро используется самое распространенное Arduino Core STM32.
Программирование по SWD при помощи ST Link. Не забудьте установить прошивальщик, к нему будет обращаться Arduino IDE при прошивке.
При программировании STM32 из Arduino IDE есть конечно свои нюансы. Например для UART нужно назначать пины явно, особенно в тех случаях когда он может мультиплексироваться.
Тут например пришлось заглянуть в файл PeripheralPins.c
#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_TX[] = {
{PA_2, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART2)},
{PA_9_R, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART1)},
{PA_14, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART2)},
{PB_6, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_USART1)},
{NC, NP, 0}
};
#endif
#ifdef HAL_UART_MODULE_ENABLED
WEAK const PinMap PinMap_UART_RX[] = {
{PA_3, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART2)},
{PA_10_R, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART1)},
{PA_15, USART2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART2)},
{PB_7, USART1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF0_USART1)},
{NC, NP, 0}
};
#endif
Т.к. 1 нога нашего МК может назначаться как PB7 или PB8, а 20я- PB3/PB4/PB5 или PB7, то взглянув в этот файлик можно понять что маппинг будет выглядеть так:
HardwareSerial Serial1(PB7,PB6);
Код для работы с датчиком был позаимствован здесь. Итого на копипасту прошивки и легкую подгонку ушло минут 10-15. А отладочная плата мне пригодится и в будущем при работе с данным МК.
Весь код
int DSPIN = PA5;
// RX TX
HardwareSerial Serial1(PB7, PB6); //привязываем порты к USART
void setup() {
Serial1.begin(9600); //инициализация USART1
}
void loop() {
delay(500);
double temp = TempRead();
temp = temp * 0.0625; // conversion accuracy is 0.0625 / LSB
Serial1.print("Temperature: ");
Serial1.print(temp);
Serial1.println(" °C");
Serial1.println("");
}
boolean DS18B20_Init()
{
pinMode(DSPIN, OUTPUT);
digitalWrite(DSPIN, HIGH);
delayMicroseconds(5);
digitalWrite(DSPIN, LOW);
delayMicroseconds(750);//480-960
digitalWrite(DSPIN, HIGH);
pinMode(DSPIN, INPUT);
int t = 0;
while (digitalRead(DSPIN))
{
t++;
if (t > 60) return false;
delayMicroseconds(1);
}
t = 480 - t;
pinMode(DSPIN, OUTPUT);
delayMicroseconds(t);
digitalWrite(DSPIN, HIGH);
return true;
}
void DS18B20_Write(byte data)
{
pinMode(DSPIN, OUTPUT);
for (int i = 0; i < 8; i++)
{
digitalWrite(DSPIN, LOW);
delayMicroseconds(10);
if (data & 1) digitalWrite(DSPIN, HIGH);
else digitalWrite(DSPIN, LOW);
data >>= 1;
delayMicroseconds(50);
digitalWrite(DSPIN, HIGH);
}
}
byte DS18B20_Read()
{
pinMode(DSPIN, OUTPUT);
digitalWrite(DSPIN, HIGH);
delayMicroseconds(2);
byte data = 0;
for (int i = 0; i < 8; i++)
{
digitalWrite(DSPIN, LOW);
delayMicroseconds(1);
digitalWrite(DSPIN, HIGH);
pinMode(DSPIN, INPUT);
delayMicroseconds(5);
data >>= 1;
if (digitalRead(DSPIN)) data |= 0x80;
delayMicroseconds(55);
pinMode(DSPIN, OUTPUT);
digitalWrite(DSPIN, HIGH);
}
return data;
}
int TempRead()
{
if (!DS18B20_Init()) return 0;
DS18B20_Write (0xCC); // Send skip ROM command
DS18B20_Write (0x44); // Send reading start conversion command
if (!DS18B20_Init()) return 0;
DS18B20_Write (0xCC); // Send skip ROM command
DS18B20_Write (0xBE); // Read the register, a total of nine bytes, the first two bytes are the conversion value
int temp = DS18B20_Read (); // Low byte
temp |= DS18B20_Read () << 8; // High byte
return temp;
}
Файлы
Схема и ПП нарисованы в DipTrace.
Такой вот немного ленивый пост. Может кому такому же ленивому как я пригодится плата, ведь можно сэкономить минут 20 на ее рисовании :)