#c #wiringpi
Вопрос:
Я тестировал связь UART на C с помощью WiringPi.
Проблема:
Похоже, что C не выводит все данные в порт UART /dev/ttyAMA0
. Может быть, я делаю это неправильно?
Расследования:
Примечание : Я использую миником, minicom --baudrate 57600 --noinit --displayhex --device /dev/ttyAMA0
чтобы проверить полученные данные.
И еще! Контакты порта UART, RX и TX закорочены вместе.
Код python работал отлично, однако, когда я попытался реализовать его на C , полученные данные отличались.
Ожидаемые полученные данные должны быть: ef 01 ff ff ff ff 01 00 07 13 00 00 00 00 00 1b
.
Сравнение Полученных Данных:
Используемый язык | Данные, полученные от Minicom |
---|---|
Питон | ef 01 ff ff ff ff 01 00 07 13 00 00 00 00 00 1b |
C | эф 01 фф фф фф фф 01 |
Используемый код
Питон:
import serial
from time import sleep
uart = serial.Serial("/dev/ttyAMA0", baudrate=57600, timeout=1)
packet = [239, 1, 255, 255, 255, 255, 1, 0, 7, 19, 0, 0, 0, 0, 0, 27]
uart.write(bytearray(packet))
C :
Примечание: Код, скомпилированный с g -Wall -O3 -o test hello.cpp -lwiringPi
#include <iostream>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
using namespace std;
int main()
{
int serial_port;
if (wiringPiSetup() == -1)
exit(1);
if ((serial_port = serialOpen("/dev/ttyAMA0", 57600)) < 0)
{
fprintf(stderr, "Unable to open serial device: %sn", strerror(errno));
return 1;
}
cout << "Sending data to UART" << std::endl;
serialPuts(serial_port, "xefx01xffxffxffxffx01x00x07x13x00x00x00x00x00x1b");
return 0;
}
Ответ №1:
Вы не можете использовать serialPuts
для отправки нулевого терминатора. Как и во всех подобных функциях, он остановится, когда в строке будет обнаружен нулевой терминатор. В этом случае я думаю, что ваш лучший вариант-добавить функцию, которая использует обычную write
функцию, которая используется внутри собственных функций WiringPi.
Вы можете создать функцию-оболочку, чтобы она выглядела аналогично другим вызовам:
#include <cstddef>
void serialWrite(const int fd, const char* data, size_t length) {
write(fd, data, length);
}
и, возможно, шаблон функции, чтобы не приходилось вручную подсчитывать длину данных в фиксированных массивах данных:
template<size_t N>
void serialWrite(const int fd, const char(amp;data)[N], bool strip_last = true) {
serialWrite(fd, data, N - strip_last);
}
Теперь вы можете использовать его так:
serialWrite(serial_port, "xefx01xffxffxffxffx01x00x07x13x00x00x00x00x00x1b");
Примечание.Существует запрос на добавление аналогичной функции (вызываемой serialPut
) в библиотеку WiringPi, которую вы можете загрузить вместо использования официальной версии из основной версии ветви, если вы не хотите создавать свою собственную функцию.
Комментарии:
1. Это сделало свое дело! Однако мне потребовалось некоторое время, чтобы перекомпилировать всю библиотеку. Большое вам спасибо!
2. @Justsomesailboat Добро пожаловать! Рад, что все получилось!