На всякий случай может кому пригодится. Требуется написать простую программку отправляющую байты по юарту, C# не тру, поэтому выбор пал на Qt Creator.
Все просто и примеров куча, а ничего не работает. После Visual C# не привычно чуть менее чем полностью. В общем наковырял, работает, проверено.
Непосредственно для работы с портом нужно включить либу, было много разных мнений что то докачивать, доустанавливать шаманскими методами, в итоге оказалось все в комплекте из коробки, достаточно подцепить инклуд
#include <QtSerialPort/QSerialPort> |
Аналогично для получения информации о количестве доступных портов
#include <QtSerialPort/QSerialPortInfo> |
Единственное шаманское, что нужно сделать — в файл с расширением .pro нужно добавить
greaterThan(QT_MAJOR_VERSION, 4) { QT += widgets serialport } else { include($$QTSERIALPORT_PROJECT_ROOT/src/serialport/qt4support/serialport.prf) } |
Далее там где это необходимо открываем порт для чтения
serial.Open(QSerialPort::WriteOnly); |
Настраиваем нужные скорости и прочие плюшки
serial.setBaudRate(QSerialPort::Baud2400); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); serial.setFlowControl(QSerialPort::NoFlowControl); |
Доступные варианты настроек удобнее смотреть нажатием Ctrl+Space, когда начинаешь что то печатать
Для отправки байта
serial.putChar(0xEA); |
Для отправки нескольких байт
serial.write("hello"); |
Для того чтобы определить какое то действие для кнопки, щелкаем правой кнопкой мыши по ней в редакторе-перейти к слоту. В слотах выбираем то что нужно, если это щелчок мыши, то ищем clicked();. Далее в основном коде появляется обработчик нечто вроде void MainWindow::on_pushButton_2_clicked()
Небольшой пример:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QString> QSerialPort serial; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //read avaible comports foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) ui->comboBox->addItem(info.portName()); } MainWindow::~MainWindow() { delete ui; } //button send void MainWindow::on_pushButton_clicked() { //string for lineedit text QString str2 = ui->lineEdit->text(); serial.write(str2.toUtf8()); } //connect void MainWindow::on_pushButton_2_clicked() { //select name for our serial port from combobox if (serial.portName() != ui->comboBox->currentText()) { serial.close(); serial.setPortName(ui->comboBox->currentText()); } //setup COM port serial.setBaudRate(QSerialPort::Baud2400); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneStop); serial.setFlowControl(QSerialPort::NoFlowControl); serial.open(QSerialPort::WriteOnly); } void MainWindow::on_pushButton_3_clicked() { //close serial.close(); } |
А в чем проблема в C#?
// Пихаем байты в массив
byte[] DataOut = { 0xAB, 0x10L, 0x55 };
// Передаем массив в порт
port.Write(DataOut, 0, 3);
И где тут проблема? 😛
Проблема в том что в определенных кругах C# не котируется, меня попросили написать именно в QT, пришлось немного поковырять.
😛 тогда почему не тру? Просто надо в QT и все. У меня где-то есть ссылка на хороший видео учебник по нему. Если найду скину.
здраствуйте у вас много проектов, спасибо вам!! но я вот немогу зделать подключить stm32f4discovery к віртуальному ком порту вот код в кокосі
#include «stm32f4xx.h»
#include «stm32f4xx_gpio.h»
#include «stm32f4xx_adc.h»
#include «stm32f4_discovery.h»
#include
#include «stm32f4xx_tim.h» // загрузка бібліотек
#include
#include «stm32f4xx_usart.h»
#include «defines.h»
#include «attributes.h»
#define MAX_STRLEN 12 // this is the maximum string length of our string in characters
volatile char received_string[MAX_STRLEN+1]; // this will hold the recieved string
void Delay(__IO uint32_t nCount) {
while(nCount—) {
}
}
/* This funcion initializes the USART1 peripheral
*
* Arguments: baudrate —> the baudrate at which the USART is
* supposed to operate
*/
void init_USART1(uint32_t baudrate){
/* This is a concept that has to do with the libraries provided by ST
* to make development easier the have made up something similar to
* classes, called TypeDefs, which actually just define the common
* parameters that every peripheral needs to work correctly
*
* They make our life easier because we don’t have to mess around with
* the low level stuff of setting bits in the correct registers
*/
GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX
USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization
NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller)
/* enable APB2 peripheral clock for USART1
* note that only USART1 and USART6 are connected to APB2
* the other USARTs are connected to APB1
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* enable the peripheral clock for the pins used by
* USART1, PB6 for TX and PB7 for RX
*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* This sequence sets up the TX and RX pins
* so they work correctly with the USART1 peripheral
*/
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate!
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain)
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins
GPIO_Init(GPIOB, &GPIO_InitStruct); // now all the values are passed to the GPIO_Init() function which sets the GPIO registers
/* The RX and TX pins are now connected to their AF
* so that the USART1 can take over control of the
* pins
*/
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); //
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
/* Now the USART_InitStruct is used to define the
* properties of USART1
*/
USART_InitStruct.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function
USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard)
USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard)
USART_InitStruct.USART_Parity = USART_Parity_No; // we don’t want a parity bit (standard)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don’t want flow control (standard)
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver
USART_Init(USART1, &USART_InitStruct); // again all the properties are passed to the USART_Init function which takes care of all the bit setting
/* Here the USART1 receive interrupt is enabled
* and the interrupt controller is configured
* to jump to the USART1_IRQHandler() function
* if the USART1 receive interrupt occurs
*/
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // we want to configure the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled
NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff
// finally this enables the complete USART1 peripheral
USART_Cmd(USART1, ENABLE);
}
/* This function is used to transmit a string of characters via
* the USART specified in USARTx.
*
* It takes two arguments: USARTx —> can be any of the USARTs e.g. USART1, USART2 etc.
* (volatile) char *s is the string you want to send
*
* Note: The string has to be passed to the function as a pointer because
* the compiler doesn’t know the ‘string’ data type. In standard
* C a string is just an array of characters
*
* Note 2: At the moment it takes a volatile char because the received_string variable
* declared as volatile char —> otherwise the compiler will spit out warnings
* */
void USART_puts(USART_TypeDef* USARTx, volatile char *s){
while(*s){
// wait until data register is empty
while( !(USARTx->SR & 0x00000040) );
USART_SendData(USARTx, *s);
*s++;
}
}
int main(void) {
init_USART1(9600); // initialize USART1 @ 9600 baud
USART_puts(USART1, «Init complete! Hello World!\r\n»); // just send a message to indicate that it works
while (1){
/*
* You can do whatever you want in here
*/
}
}
// this is the interrupt request handler (IRQ) for ALL USART1 interrupts
void USART1_IRQHandler(void){
// check if the USART1 receive interrupt flag was set
if( USART_GetITStatus(USART1, USART_IT_RXNE) ){
static uint8_t cnt = 0; // this counter is used to determine the string length
char t = USART1->DR; // the character from the USART1 data register is saved in t
/* check if the received character is not the LF character (used to determine end of string)
* or the if the maximum string length has been been reached
*/
if( (t != ‘\n’) && (cnt < MAX_STRLEN) ){
received_string[cnt] = t;
cnt++;
}
else{ // otherwise reset the character counter and print the received string
cnt = 0;
USART_puts(USART1, received_string);
}
}
}
вот код в Сшарпі
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace plot
{
public partial class Form1 : Form
{
public int y;
public string y2;
public Form1()
{
InitializeComponent();
serialPort1.Open();
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
y2 = serialPort1.ReadExisting();
// label1.Text = Convert.ToString(y2);
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = Convert.ToString(y2);
}
private void timer1_Tick(object sender, EventArgs e)
{
}
}
}
Посмотрите проект под кокос http://avr-start.ru/?p=2539, он стопудово работает. Для начала совместите его с любой терминалкой, можно terra term. Когда заработает, можно из терминалки посылать байты в программу C#. Таким образом разбить задачу на две части. Когда обе части заработают, совместить их, ибо так очень сложно что то посоветовать надо тестить.
usb-com присоденил к порту юарт4 і все вроде в терміналке работает,но виводит не совсем hello «}ellohelmhellomellohell}elloiullohel}hel}ohell}ello}ullo}ullohellhel}helmhelmhul
lo}ello}ullo» чьом проблема??????
і как передать не символи а переменную???
спасиб
Здесь же написано.
void USART_puts(USART_TypeDef* USARTx, volatile char *s){
while(*s){
// wait until data register is empty
while( !(USARTx->SR & 0×00000040) );
USART_SendData(USARTx, *s);
*s++;
}
}
USART_puts(USART1, 0x01); // Передали в порт 0x01
Возможно со скоростью косяки, может кварц юзаете не внешний.
usb com порт куплен , не самодельний і stm32f4discovery там кварц 8 МГц. , що может бить ,??
Если вы юзаете дискавери, то у нее UART1 занят, на этих ножках сидит USB, скачайте Cube Mx посмотрите. Поэтому юзайте другой юарт и будет вам щастье
я юзаю тот шо у вас в примере http://avr-start.ru/?p=2539 , тоесть юарт4порт А0 А1.
Вспомнил. В общем на PA0 сидит кнопка, если вы ее не используете, то все должно быть норм. Это не совсем гуд что про это в статье не упомянуто, потом переделаю.
А кто собственно мешает переехать на другой порт. Или четвёртый это принципиально?
нет непринципиально!!! буду пробовать!! просто не очень умею ето програмировать!! ето просто хобби!
Стоп. А почему четвертый порт?
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);
Здесь же первый конфигурится?
Не забивайте себе голову, вот функция инициализации порта.
void usart1_config(uint16_t baud) {
USART_InitTypeDef USART_InitStructure;
/** Наиминование выводов
PA9 ——> USART1_TX
PA10 ——> USART1_RX
*/
// Тактирование USART2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//Заполняем структуру настройками USARTa
USART_InitStructure.USART_BaudRate = baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
//Инициализируем USART
USART_Init(USART1, &USART_InitStructure);
//Включаем USART
USART_Cmd(USART1, ENABLE);
}
Пример usart1_config(9600);
Все, первый порт настроен на 9600 1 стоп 8 в байте без проверки четности.
Не забываем перед UART-ом ноги правильно затактировать.
Если не умеете программировать, то читайте статьи задавайте вопросы, тут никто не умеет прогать и всех это хобби.
здесь да юарт1 но у автора юарт4 http://avr-start.ru/?p=2539
constanta, таки в чем сложность, давайте объясню
сматрите!! конечной целью было передать переменную(например дание из переменного резистора)через com порт или usb, используя стм32а4дыскаверы и прогаму с++ или С# ,нужно вывести значения на екран в оболонке С+, С#! у меня ето неполучилось потому пробую вывести хотяб какие то буквы но они приходят из ошибочними!! незнаю в чьом причина!
Вот проект под Кокос. Цель передать GET запрос серверу от GSM модуля.. Заточен под STM32F103C8, но для понимания это не важно. В проекте связь с модулем идет через UART. Вот этот кусо можете выдрать для своих целей. Там все расписано подробно и заблудится довольно таки сложно.
Ссылку удалю через неделю. Будут вопросы пиши.
ххххххххххх
вот проект но почему у меня заки «??????????» вместа текста???
constanta, вы спрашиваете у меня, почему проект с другого сайта у вас не работает? 🙂 Чем вам мой проект не угодил?
ви не так поняли ваш работает отлично, нет никаких проблем , вопрос в том почему у терміналки выводит не всьо как есть ето во первых, а в С# если я апрашываю то виводит «??????????» а не букви!?
подскажите как переменную передать а не просто символи??
земля дискавери и земля фт232 соединены?
да дискаверы ы usb-com соеденен!! но всьоравно нет результат!! в меня куплен usb-com или должен именно бить на ft232???
столкнулся ще з одной проблемой вот проверил ваш код и он не виводится у меня на оболонке C# а другой виводит но пишет «?????????» почему ваш невыводитса даже знаки «????????»!
завтра вечерком проверю
Для начала нарисуйте пожалуйста схему, как что и к чему у Вас подключено. Я если честно уже заблудился. Где COM? где Discovery. Все по порядку. Если в терминалке написанной на C# выводятся ???????, значит проблемы с кодировкой.
Алексей,а как кодировать???? сматрите уменя схема простая stm32f4 подключен к ком порту через переходник вот вся схема!!! три провода Rx, Tx, GND!
просто в нете много проектов а рабочих почти нет! или надо полпроекта почти поменять,щоб работал,
я обновил ту статью, все проверено, все работает
Алексей,а как кодировать????
#include
setlocale(LC_ALL,»Russian»);
#include скобка clocale скобка
admin, в термыналке стала хуже даже похожих букв не виводит а тогда хотяб какиэто похожиэ были!! в С# те саме що на тому проекті не обновленому «?????:::» знаки вопроса плюс крапки виводить ще!могу фото работи скинуть или відео!!
Aлексей шарп такой функції незнаєт!! та впринципе етот шарп ненужен если програма не виводит в терминалку то што надо !!! мне знаки вопроса там ненужни!! может я щота нетак делаю но вроди всьо компилируєтця!
Мне уже самому интересно. Я в выходные попробую написать два проекта под стм и шарп. Позже скину.
Алексей, і попробуйте і етот проект шо на сайте http://avr-start.ru/?p=2539 он рабочей но просто может я не так делаю!! бо если я вивожу переменную в шарпі і терміналке а не символи то оно одинаковие виводит ироглифи, а если сами символи то в терміналкє предадущий код давал букви но не все от етого слова а в шарпи знаки вопроса были!! спасиба Вам и Admin за помощь !!!!
constanta Перезалил архив в сообщении 13.12.2014 в 16:41. В архиве два проекта, один для C# другой для какоса под четвертую дискавери. Проект под кокос с этого сайта. Добавил лишь кнопку. Для отправки строки нужно на дискавери жмакнуть на синюю кнопку. В C# программе выбери свой порт из выпадающего меню и жми принять. После дави синюю кнопку на дискавери и радуйся полученной строке.
Алексей дание идут связь есть,всьо работает спасиб но приходит «*?» слова нет толька ироглиф, в чьом проблема!???