Arduino M0 - программный интерфейс Serial (SERCOM) - не работает на пинах D3 и D4
- Войдите на сайт для отправки комментариев
Всем доброго дня! Столкнулся с необходимостью инициализировать программный интерфейс Serial на Arduino M0 (библиотека SoftwareSerial на платах с 32-битными процессорами не работает). Имеющийся аппаратный интерфейс занят конвертером TTL-RS485, а подключить по интерфейсу SPI нужно еще один девайс - SIM800L.
Почитал ресурсы, еще почитал (тут именно про пины D3 и D4), и еще почитал. В результате получилось инициализировать Serial на пинах D11(RX) и D10(TX):
#include <Arduino.h>
#include "wiring_private.h" // Библиотека даёт возможность изменения функций пинов МК (pinPeripheral() function)
Uart SIM800L (&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2); // Назначаем функции пинам МК: RX - pin D11 | TX - pin D10
String _response = ""; // Объявляем строковый массив для хранения ответов модуля SIM800L (функции sendATcommand и waitResponse)
void setup() {
SerialUSB.begin(57600);
while (!SerialUSB) {}; // Ожидание инициализации com-порта
SerialUSB.println(F("Start programm!"));
SIM800L.begin(57600);
pinPeripheral(10, PIO_SERCOM); // TX (Assign pins 10 & 11 SERCOM functionality)
pinPeripheral(11, PIO_SERCOM); // RX (Assign pins 10 & 11 SERCOM functionality)
sendATcommand("AT", true); // Автоопределение скорости обмена данными с модулем SIM800L
}
void SERCOM1_Handler()
{
SIM800L.IrqHandler();
}
void loop()
{
if (SIM800L.available()) SerialUSB.println(waitResponse());
if (SerialUSB.available()) SIM800L.write(SerialUSB.read());
}
String sendATcommand(String cmd, bool waiting)
{
String _resp = "";
SerialUSB.println(cmd);
SIM800L.println(cmd);
if (waiting)
{
_resp = waitResponse();
SerialUSB.println(_resp);
}
return _resp;
}
String waitResponse()
{
String _resp = "";
unsigned long _timeout = millis() + 10000;
while (!SIM800L.available() && millis() < _timeout) {};
if (SIM800L.available())
{
_resp = SIM800L.readString();
}
else
{
SerialUSB.println(F("Timeout wait answer SIM800L is over!"));
}
return _resp;
}
Этот код работает... При обращении к модулю SIM800L - возвращаются ответы от модуля.
При попытке инициализировать Serial на пинах D3(RX) и D4(TX) следующим образом:
#include <Arduino.h>
#include "wiring_private.h" // Библиотека даёт возможность изменения функций пинов МК (pinPeripheral() function)
Uart SIM800L (&sercom2, 3, 4, SERCOM_RX_PAD_1, UART_TX_PAD_0);
String _response = ""; // Объявляем строковый массив для хранения ответов модуля SIM800L (функции sendATcommand и waitResponse)
void setup() {
SerialUSB.begin(57600);
while (!SerialUSB) {}; // Ожидание инициализации com-порта
SerialUSB.println(F("Start programm!"));
SIM800L.begin(57600);
pinPeripheral(4, PIO_SERCOM_ALT); // TX (Assign pins 10 & 11 SERCOM functionality)
pinPeripheral(3, PIO_SERCOM_ALT); // RX (Assign pins 10 & 11 SERCOM functionality)
sendATcommand("AT", true); // Автоопределение скорости обмена данными с модулем SIM800L
}
void SERCOM2_Handler()
{
SIM800L.IrqHandler();
}
void loop()
{
if (SIM800L.available()) SerialUSB.println(waitResponse());
if (SerialUSB.available()) SIM800L.write(SerialUSB.read());
}
String sendATcommand(String cmd, bool waiting)
{
String _resp = "";
SerialUSB.println(cmd);
SIM800L.println(cmd);
if (waiting)
{
_resp = waitResponse();
SerialUSB.println(_resp);
}
return _resp;
}
String waitResponse()
{
String _resp = "";
unsigned long _timeout = millis() + 10000;
while (!SIM800L.available() && millis() < _timeout) {};
if (SIM800L.available())
{
_resp = SIM800L.readString();
}
else
{
SerialUSB.println(F("Timeout wait answer SIM800L is over!"));
}
return _resp;
}
Этот вариант кода при обращении к модулю SIM800L возвращает превышение таймаута ожидания ответа от модуля "Timeout wait answer SIM800L is over!".
Кто "копал" SERCOM и M0 - подскажите куда копать в какую сторону? Пины D11 и D10 использовать не могу - на них висит SPI и SD-Card Module, помогите советом кто в теме, буду очень признателен!!!
В общем и целом разобрался. Скорее всего, тему поднял не в соответсвующей ветке форума. Для кого интересно... Использовать можно sercom1, sercom2, sercom3, sercom4. Использовать sercom0 и sercom5 неполучиться, т.к. они задействованы аппаратно и обратный вызов не возможен - компиляция не проходит из-за ошибки оверхеда. Приведу пример для пинов D7(RX) и D6(TX):
#include <Arduino.h> #include "wiring_private.h" Uart mySerial (&sercom3, 7, 6, SERCOM_RX_PAD_3, UART_TX_PAD_2); // Инициализация объекта класса UART на пинах 6(TX) и 7(RX) void setup() { mySerial.begin(57600); pinPeripheral(6, PIO_SERCOM_ALT); // TX pin UART (SERCOM) - переопределение пинов МК pinPeripheral(7, PIO_SERCOM_ALT); // RX pin UART (SERCOM) - переопределение пинов МК } void SERCOM3_Handler() {mySerial.IrqHandler();} // Функция обработки прерывания void loop() { }Аналогично работает на остальных пинах, с вышеуказанными sercom'и.