Использование последовательной связи в .c-файлах
В настоящее время я пытаюсь подключить Arduino Uno к своему компьютеру и позволить им обмениваться данными через UART. Я начал использовать проект из Github (здесь), который я пытаюсь изменить, чтобы получить следующий шаг через UART. Из-за этого я не могу переключать языки программирования, а также мне нужно переопределить загрузчик.
Однако я не могу заставить работать последовательное соединение.
#include "Joystick.h"
#include <avr/io.h>
#include <util/delay.h>
#include <Arduino.h>
Это операторы #include
вверху, но <Arduino.h>
не найден...
Если я удалю эти операторы, Serial
не будет найден (из main
-Method: Serial.begin(9600);
)
Я впервые программирую на C. Я проглядел глупую ошибку? Спасибо за любую помощь...
@MonsterDruide1, 👍0
Обсуждение1 ответ
Лучший ответ:
Я бы рассмотрел возможность использования HoodLoader2 вместо этого проекта LUFA. Если вы не можете этого сделать, вы можете скомпилировать части Arduino Core вместе с проектом LUFA.
Основные шаги:
- Добавьте необходимые исходные файлы Arduino в переменную
SRC
в Makefile. - Добавьте основную папку Arduino в путь включения, добавив к переменным
CC_FLAGS
иCXX_FLAGS
. - Переместите функцию main в новый файл
main.cpp
, а также добавьте ее в MakefileSRC
. - Включите файл
Joystick.h
в основной файл в блокеextern "C"
. - Включите файл
HardwareSerial.h
в основной файл.
Мои файлы после этих изменений:
Создать файл
# Set the MCU accordingly to your device (e.g. at90usb1286 for a Teensy 2.0++, or atmega16u2 for an Arduino UNO R3)
MCU = atmega16u2
ARCH = AVR8
F_CPU = 16000000
F_USB = $(F_CPU)
OPTIMIZATION = s
TARGET = Joystick
SRC = $(TARGET).c Descriptors.c main.cpp $(LUFA_SRC_USB)
LUFA_PATH = ./lufa/LUFA
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS =
ARDUINO_PATH = ${HOME}/.arduino15/packages/arduino/hardware/avr/1.8.1/cores/arduino
SRC += $(ARDUINO_PATH)/HardwareSerial.cpp
SRC += $(ARDUINO_PATH)/HardwareSerial1.cpp
SRC += $(ARDUINO_PATH)/Print.cpp
CXX_FLAGS += -I$(ARDUINO_PATH) -I./HoodLoader2/avr/variants/HoodLoader2
CC_FLAGS += -I$(ARDUINO_PATH) -I./HoodLoader2/avr/variants/HoodLoader2
...
main.cpp
extern "C" {
#include "Joystick.h"
}
#include <HardwareSerial.h>
// Основная точка входа.
int main(void) {
// Мы начнем с настройки оборудования и периферийных устройств.
SetupHardware();
// Затем мы разрешаем глобальные прерывания для нашего использования.
GlobalInterruptEnable();
// Инициализировать UART
Serial1.begin(115200);
Serial1.println(F("Hello, world"));
// Как только это будет сделано, мы войдем в бесконечный цикл.
for (;;)
{
// Нам нужно запустить нашу задачу для обработки и доставки данных для наших конечных точек IN и OUT.
HID_Task();
// Нам также нужно запустить основную задачу управления USB.
USB_USBTask();
}
}
Джойстик.c
Удалена функция main
.
Чтобы заставить его скомпилироваться после этих изменений:
# (inside of the snowball-thrower folder)
git submodule add https://github.com/NicoHood/HoodLoader2.git HoodLoader2
make
У меня это компилируется без проблем, но я понятия не имею, работает ли это на самом деле.
Обновление:
Вы заметите, что программа использует больше оперативной памяти, чем доступно ATmeg16U2. Вы можете решить эту проблему, переместив массив step
в PROGMEM
или уменьшив последовательные буферы.
avr-size --mcu=atmega16u2 --format=avr Joystick.elf
AVR Memory Usage
----------------
Device: atmega16u2
Program: 5076 bytes (31.0% Full)
(.text + .data + .bootloader)
Data: 527 bytes (102.9% Full)
(.data + .bss + .noinit)
[INFO] : Finished building project "Joystick".
Я пробовал это, но я не могу подтвердить, что программа действительно запустилась. Я подключал мост UART-to-USB и тестировал его раньше, но PuTTY не выводит начальную тестовую запись. Вместо этого последняя вещь, которая была запрограммирована с помощью Arduino, выполняется и выводится в PuTTY... Я решил проблему с оперативной памятью, просто удалив последнюю часть массива step
, потому что я пытаюсь полностью избежать это путем потоковой передачи записей через UART. Однако ни начальный выход не отображается, ни коммутатор не замечает подключения нового контроллера., @MonsterDruide1
Мне нужно исправить себя: коммутатор заметит, если я отключу TX & RX во время прошивки нового файла .hex. Но все еще нет выхода из PuTTY (и да, я снова подключаю TX и RX после завершения прошивки образа). Соединение/взаимодействие с коммутатором такое же, как и раньше, так что все в порядке, но последовательное соединение по-прежнему не работает., @MonsterDruide1
@MonsterDruide1 Сначала загрузите пустой скетч в ATmega328P (используя оригинальную прошивку Arduino 16U2) или подключите его контакт сброса к земле. А также поменять местами контакты RX/TX. **RX** адаптера UART-to-USB должен быть подключен к контакту **RX** Arduino (это контакт TX '16U2), а **TX** к **TX. **. Внутри контакты RX/TX подключены [вот так](https://tttapa.github.io/Pages/Arduino/ESP8266/Flashing/images/ESP8266-UNO-flash.svg) (игнорируйте ESP8266, представьте, что это адаптер UART-USB)., @tttapa
ДА!!!! Большое спасибо за всю эту помощь. Теперь все работает как положено!, @MonsterDruide1
- Команда strtok() с Serial связью
- Как изменить переменную при нажатии кнопки, подключенной к контакту 2
- Как программно обнаружить последовательный порт Arduino на разных платформах?
- Java NetBeans отправляет значение и получает значение от Arduino
- Почему нужно использовать latin-1 вместо utf-8 при использовании python с arduino?
- Акцептант векселей ИКТ
- Соединение I2C с модулем камеры MT9D111, странные результаты после записи регистров через i2C
- ПК не может получить доступ к порту HC-06 Bluetooth COM
Вы используете Arduino IDE для компиляции?, @chrisl
@chrisl Нет, я использую make-файл, содержащийся в проекте GitHub. Я изменяю переменную $PATH каждый раз, чтобы она содержала arduinoInstallDir/hardware/tools/avr/bin, который включает avr-gcc, необходимый для его компиляции., @MonsterDruide1
Вы можете очень легко комбинировать код C и C++. Просто скомпилируйте свои части кода как C++ и включите существующие функции C, которые вам нужны, как
extern "C"
. Если вам нужно вызвать функцию C++ из кода C, также объявите ее какextern "C"
. Затем вы можете использовать все функции C++ из ядра Arduino, если хотите., @tttapa@tttapa Я изо всех сил пытался понять, как это работает, но не могу понять. Я нашел примеры того, как включить один метод, но не всю библиотеку. Также думается о переводе всего этого проекта на C++, но это тоже не сработает, так как я не до конца его понимаю. Если бы вы могли привести пример того, как включить полную библиотеку, такую как <Arduino.h>, в файл C и сделать ее пригодной для использования, я был бы очень благодарен., @MonsterDruide1
Я начал разбираться, но мне кажется, что код предназначен для работы на ATmega16U2 UNO, а не на ATmeg328P. В этом случае я не думаю, что для этого чипа есть ядро Arduino, поэтому вам придется программировать стек USB CDC самостоятельно (возможно, с помощью LUFA, но у меня нет времени разбираться в этом). И ИМХО, это абсолютно не стоит времени. Я бы использовал микроконтроллер, который изначально поддерживает USB и имеет достойную программную поддержку, например Teensy 3.x., @tttapa
@tttapa Проект, который я связал с discord, уже делает то, что я хочу, но теперь я хочу расширить эту программу, чтобы читать следующее нажатие кнопки из последовательного соединения с ПК, но для чтения из последовательного порта мне нужно использовать библиотеку от Arduino к которому я не могу получить доступ. Так что с USB-подключением проблем нет., @MonsterDruide1
Я не думаю, что вы поняли мой комментарий. В UNO есть 2 микроконтроллера, один может запускать код Arduino (ATmega328P), другой не может (ATmega16U2). Вы не можете использовать
Serial.begin
на этом втором микроконтроллере. Причина, по которой вы не можете написать для него код Arduino, заключается в том, что никто не написал для него библиотеку Arduino Core. Вы можете сделать это сами, вы, вероятно, можете переработать много кода из [ядра ATmega32U4](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/CDC.cpp), но это было бы пустой тратой времени, ИМХО, и, вероятно, это будет противоречить существующему коду LUFA, который у вас есть., @tttapa@tttapa Можно ли позволить первому контроллеру (ATmega 328P) получать данные с последовательного порта и передавать их на ATmega16U2?, @MonsterDruide1
У ATmega16U2 есть UART, к которому у вас есть доступ, так что вы можете его использовать, но я думал, что вы хотите Serial over USB?, @tttapa
@tttapa Код из GitHub уже использует USB-порт, поэтому я подумал, что могу подключить другую связь к соединению UART. Поэтому в настоящее время я пытаюсь позволить 16U2 читать с UART и передавать эти данные через USB., @MonsterDruide1