Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 21.07.2019
Сообщений: 3
1

Qserialport

21.07.2019, 12:35. Показов 1633. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день. У меня есть stm32, на ацп приходят данные с потенциометра. Затем я их обрабатывают и отправлю в com порт. Подскажите ,пожалуйста, как мне эти данные считать в qt creator и вывести на LCD дисплей.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.07.2019, 12:35
Ответы с готовыми решениями:

QSerialPort в Qt
Здравствуйте! В проекте необходим QSerialPort для связи с Arduino (хотя бы только принимать...

QSerialPort
интересная проблема с портом... данные пишутся в порт только после вызова функции...

QSerialPort
Здравствуйте, начинаю осваивать Qt. Хочу написать простую программу для работы с ком портом, с GUI...

QSerialPort in QThread
Всем привет, никак не могу разобраться с проблемой Вот класс для работы с ком портом хедер: ...

16
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
16.09.2019, 12:11 2
Sanalex97, у меня сейчас подобная задача, в процессе поиска наткнулся на вашу тему, удалось найти решение?
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
16.09.2019, 12:18 3
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
удалось найти решение?
А какое решение вам нужно? Как считать данные из последовательного порта?
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
16.09.2019, 12:28 4
insite2012 у меня сейчас задача: 12 битное АЦП микроконтроллера оцифровывает 8 входов, формирует массив из 16 8ми битных чисел (12 битные данные с одного входа занимают по две 8ми битные ячейки в массиве), дальше этот массив передается по USART в COM порт ПК. Далее мне необходимо написать программу на ПК (для этого выбрал Qt creator и C++), которая будет принимать этот массив (читать данные с COM порта), обрабатывать его (16 8ми битных чисел массива необходимо обратно собрать в 8 12ти(16ти) битных) и далее строить график, где будут отображаться данные с АПЦ. Массив приходит раз в 500 миллесекунд. По y значение числа массива (т.е. всего на графике будет 8 кривых), по x время.
Вот как-то так. Пока ориентируюсь на QserialPort (чтение порта) и Qwt (для графика), но ввиду того, что на ПК особо ничего не писал такое, опыта нет, да и специальность другая. Более менее пишу на С на микроконтроллеры, но это совсем другое.
В построение графика пока еще не лезу, сейчас хочу разобраться с приемом и обработкой данных по COM порту, но как-то не клеится
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
16.09.2019, 12:40 5
DmitryDDDD, я под мк не пишу (хотя надо бы, но нет времени пока с этим направлением начинать).
Что касается вашей задачи со стороны ПК, то я ее вижу примерно так:
создать класс для чтения данных, в нем методы: открытия порта (open()), закрытия порта ((close()), начала чтения данных (startReading()), окончания чтения данных (stopReading()), и сигналы для сообщения о прогрессе операции и передаче считанных данных. Простой каркас класса для чтения я могу вам накидать, а дальше сами, реализуете логику чтения в методе.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
16.09.2019, 12:44 6
Под МК я код написал, в этом плане все проверено и отлично работает. Вот с кодом для ПК проблемы. Было бы отлично, если бы вы накидали каркас, а я бы уже попробовал разобраться, так все же проще, чем с нуля.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.09.2019, 13:05 7
Наверное стоит показать код на MK.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
16.09.2019, 13:10 8
insite2012, Avazart ну можно конечно, если это как-то поможет.

main.c
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// ADC, DMA, USART
 
#include "main.h"
 
//------------------------------------------------------------------
// Includes
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32F4xx_adc.h"
#include "stm32f4xx_dma.h"
 
#include "stm32f4xx_exti.h"
#include "misc.h"
#include "stm32f4xx_flash.h"
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
//uint8_t ADC_buffer[8];
uint8_t ADC_buffer[16];
uint8_t readyToTransmitFlag;
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
void SetSysClock_100(void)
{
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);
  while(!(RCC->CR & RCC_CR_HSERDY));
 
  RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  PWR->CR |= PWR_CR_VOS;
  RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
  RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
  RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
  uint16_t PLL_M = 4;
  uint16_t PLL_N = 100;
  uint16_t PLL_P = 2;
  uint16_t PLL_Q = 4;
  RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
  RCC->CR |= RCC_CR_PLLON;
 
  while((RCC->CR & RCC_CR_PLLRDY));
  
  FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
 
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= RCC_CFGR_SW_PLL;
 
   while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
}
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
// Interrupt of DMA function
void DMA2_Stream0_IRQHandler(void)
{
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
  readyToTransmitFlag = 1;
}
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
//void SendStrtoPC(uint8_t* ADC_buffer_p, uint8_t count)
void SendStrtoPC(uint8_t* ADC_buffer_p, uint8_t count)
{
    uint8_t i=0;
        
      while(i < count)
      {
         while(!USART_GetFlagStatus(USART2, USART_FLAG_TXE));
         USART_SendData(USART2, ADC_buffer_p[i]);
         i++;
      }
}
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
void Timer_ADC (void)
{
// If HCLK = 100 MHz, then frequency of APB1 timer clocks = 100 MHz, 
// Prescaler = 50000, Period = 1000, T = 500 msec
    TIM_TimeBaseInitTypeDef TIM_Time_user;
        
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    
    TIM_Time_user.TIM_Prescaler = 50000 - 1;
    TIM_Time_user.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_Time_user.TIM_Period = 1000 - 1;
    TIM_Time_user.TIM_ClockDivision = TIM_CKD_DIV1;
    
    TIM_TimeBaseInit(TIM3, &TIM_Time_user);
            
    TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
    TIM_Cmd(TIM3, ENABLE);
}
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
void GPIO_ini (void)
{
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE); 
 
     GPIO_InitTypeDef GPIO_InitStructureA;                                               
    GPIO_InitStructureA.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;  
    GPIO_InitStructureA.GPIO_Mode = GPIO_Mode_AN;                                      
    GPIO_InitStructureA.GPIO_PuPd = GPIO_PuPd_NOPULL ;                                 
   GPIO_Init(GPIOA, &GPIO_InitStructureA); 
 
     GPIO_InitTypeDef GPIO_InitStructureC;                                               
    GPIO_InitStructureC.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5;  
    GPIO_InitStructureC.GPIO_Mode = GPIO_Mode_AN;                                      
    GPIO_InitStructureC.GPIO_PuPd = GPIO_PuPd_NOPULL ;                                 
   GPIO_Init(GPIOC, &GPIO_InitStructureC); 
}
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
void ADC_ini (void)
{
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    
   ADC_InitTypeDef ADC_Init_user;   
//      ADC_Init_user.ADC_Resolution = ADC_Resolution_8b;
        ADC_Init_user.ADC_Resolution = ADC_Resolution_12b;
        ADC_Init_user.ADC_ScanConvMode = ENABLE;
        ADC_Init_user.ADC_ContinuousConvMode = DISABLE;
        ADC_Init_user.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
        ADC_Init_user.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
        ADC_Init_user.ADC_DataAlign = ADC_DataAlign_Right;
        ADC_Init_user.ADC_NbrOfConversion = 8;              
     ADC_Init(ADC1, &ADC_Init_user);
     
      ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 4, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 5, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 6, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 7, ADC_SampleTime_15Cycles);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 8, ADC_SampleTime_15Cycles);
        
     ADC_Cmd(ADC1, ENABLE);
}
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------
void DMA_ADC (void)
{
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
     
     DMA_InitTypeDef DMA_ini_ADC;
         DMA_ini_ADC.DMA_Channel = DMA_Channel_0;
         DMA_ini_ADC.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
         DMA_ini_ADC.DMA_Memory0BaseAddr = (uint32_t)ADC_buffer;
         DMA_ini_ADC.DMA_DIR = DMA_DIR_PeripheralToMemory;
         DMA_ini_ADC.DMA_BufferSize = sizeof(ADC_buffer);
         DMA_ini_ADC.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
         DMA_ini_ADC.DMA_MemoryInc = DMA_MemoryInc_Enable;
//       DMA_ini_ADC.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
         DMA_ini_ADC.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//       DMA_ini_ADC.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
         DMA_ini_ADC.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
         DMA_ini_ADC.DMA_Mode = DMA_Mode_Circular;
         DMA_ini_ADC.DMA_Priority = DMA_Priority_High;
       DMA_ini_ADC.DMA_FIFOMode = DMA_FIFOMode_Disable;
       DMA_ini_ADC.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
         DMA_ini_ADC.DMA_MemoryBurst = DMA_MemoryBurst_Single;
         DMA_ini_ADC.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
     DMA_Init(DMA2_Stream0, &DMA_ini_ADC);
    
     ADC_DMACmd(ADC1, ENABLE);   
     ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
    
   NVIC_EnableIRQ (DMA2_Stream0_IRQn); 
     DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
     
     DMA_Cmd(DMA2_Stream0, ENABLE);
 }
//------------------------------------------------------------------
 
 
//------------------------------------------------------------------------------------------------------------------------
int main(void) 
{
//------------------------------------------------------------------
// Initialization
//
    SetSysClock_100();
    SystemCoreClockUpdate();    
    USART2_ini();
    Timer_ADC();
    GPIO_ini();
    ADC_ini();
    DMA_ADC();
//------------------------------------------------------------------
    
 
//------------------------------------------------------------------    
 
//------------------------------------------------------------------
 
    
//------------------------------------------------------------------
// Delay definition
//
    DWT_DelayUpdate();
    DWT_Init();
    uint32_t DWT_GetTick(void);
    void DWT_Delay_sec(uint32_t sec);
    void DWT_Delay_ms(uint32_t ms);
    void DWT_Delay_us(uint32_t us);
    uint8_t DWT_Test_sec(uint32_t start, uint32_t time);
    uint8_t DWT_Test_ms(uint32_t start, uint32_t time);
    uint8_t DWT_Test_us(uint32_t start, uint32_t time);
    uint32_t DWT_Time_sec(uint32_t start, uint32_t current);
    uint32_t DWT_Time_ms(uint32_t start, uint32_t current);
    uint32_t DWT_Time_us(uint32_t start, uint32_t current);
//------------------------------------------------------------------
 
 
    while(1)
    {
//------------------------------------------------------------------        
     if (readyToTransmitFlag == 1)
     {
//        SendStrtoPC(ADC_buffer, 8);
              SendStrtoPC(ADC_buffer, 16);
        readyToTransmitFlag = 0;
     }
//------------------------------------------------------------------                
    }
 
}
//------------------------------------------------------------------------------------------------------------------------


main.h
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#ifndef MAIN_H_
#define MAIN_H_
 
#include "USART.h"
#include "ADC.h"
 
 
#include "stm32f4xx.h"
 
//------------------------------------------------------------------------------------------------------------------------
//------------------------------
//
 
//------------------------------------------------------------------------------------------------------------------------
 
 
//------------------------------------------------------------------------------------------------------------------------
// Delay definition
//
void DWT_DelayUpdate(void);
void DWT_Init(void);
uint32_t DWT_GetTick(void);
void DWT_Delay_sec(uint32_t sec);
void DWT_Delay_ms(uint32_t ms);
void DWT_Delay_us(uint32_t us);
uint8_t DWT_Test_sec(uint32_t start, uint32_t time);
uint8_t DWT_Test_ms(uint32_t start, uint32_t time);
uint8_t DWT_Test_us(uint32_t start, uint32_t time);
uint32_t DWT_Time_sec(uint32_t start, uint32_t current);
uint32_t DWT_Time_ms(uint32_t start, uint32_t current);
uint32_t DWT_Time_us(uint32_t start, uint32_t current);
//------------------------------------------------------------------------------------------------------------------------
 
 
//------------------------------------------------------------------------------------------------------------------------
// Delay function
//
extern uint32_t SystemCoreClock;
static uint32_t Delay_us, Delay_ms;
 
void DWT_DelayUpdate(void)
{
    Delay_ms = SystemCoreClock / 1000;    // Number of timing steps of MC core per a millisecond
    Delay_us = SystemCoreClock / 1000000; // Number of timing steps of MC core per a microsecond
}
 
void DWT_Init(void)
{
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
    DWT_DelayUpdate();
}
 
uint32_t DWT_GetTick(void)
{
   return DWT->CYCCNT;
}
 
void DWT_Delay_sec(uint32_t sec) // In seconds
{
    uint32_t Count = DWT->CYCCNT;
    sec = sec * SystemCoreClock;
    while((DWT->CYCCNT - Count) < sec);
}
 
void DWT_Delay_ms(uint32_t ms) // In milliseconds
{
    uint32_t Count = DWT->CYCCNT;
    ms = ms * Delay_ms;
    while((DWT->CYCCNT - Count) < ms);
}
 
void DWT_Delay_us(uint32_t us) // In microseconds
{
    uint32_t Count = DWT->CYCCNT;
    us = us * Delay_us;
    while((DWT->CYCCNT - Count) < us);
}
 
// 0 - if time is less than set. 1 if time is equality or more than set.
// Variables: start - number of steps of MC core in the beggining of measuring. time - time.
uint8_t DWT_Test_sec(uint32_t start, uint32_t time)
{
    return (((DWT->CYCCNT - start) >= (time*SystemCoreClock)) ? 1 : 0);
}
 
uint8_t DWT_Test_ms(uint32_t start, uint32_t time)
{
    return (((DWT->CYCCNT - start) >= (time*Delay_ms)) ? 1 : 0);
}
 
uint8_t DWT_Test_us(uint32_t start, uint32_t time)
{
    return (((DWT->CYCCNT - start) >= (time*Delay_us)) ? 1 : 0);
}
 
 
// Time from the beggining of measuring.
// Variables: start - number of steps of MC core in the beggining of measuring. current - number of steps of MC core in this moment.
uint32_t DWT_Time_sec(uint32_t start, uint32_t current)
{
    return (current - start) / SystemCoreClock;
}
 
uint32_t DWT_Time_ms(uint32_t start, uint32_t current)
{
    return (current - start) / Delay_ms;
}
 
uint32_t DWT_Time_us(uint32_t start, uint32_t current)
{
    return (current - start) / Delay_us;
}
//------------------------------------------------------------------------------------------------------------------------
 
 
#endif


USART.c
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//------------------ SETTING THE USART INTERFACE -------------------------
 
#include "USART.h"
 
//------------------------------------------------------------------------------------------------------------------------
//--------------------- USART Function -------------------
//
void USART2_ini(void)
{
    
    // Pins configyration:
    // TX - PA2
    // RX - PA3
    // GND - GND
    
    // Setting the pins 
    GPIO_InitTypeDef GPIO_Init_USART;
    USART_InitTypeDef USART_InitUser;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    
    GPIO_Init_USART.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3;
    GPIO_Init_USART.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init_USART.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init_USART.GPIO_OType = GPIO_OType_PP;
    GPIO_Init_USART.GPIO_PuPd = GPIO_PuPd_UP;
    
    GPIO_Init(GPIOA, &GPIO_Init_USART);
    
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
    
    // Setting the USART2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    
    USART_InitUser.USART_BaudRate=9600;
    USART_InitUser.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    USART_InitUser.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
    USART_InitUser.USART_Parity=USART_Parity_No;
    USART_InitUser.USART_StopBits=USART_StopBits_1;
    USART_InitUser.USART_WordLength=USART_WordLength_8b;
    
    USART_Init(USART2, &USART_InitUser);
    
    USART_Cmd(USART2, ENABLE);
    
}
 
//------------------------------------------------------------------------------------------------------------------------


USART.h
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//------------ HEADER FILE FOR USART-------------
 
//------------------------------------------------------------------------------------------------------------------------
//------------- USART ---------------------------
//
#ifndef MCU_INI_H
#define MCU_INI_H
 
#include "stm32f4xx.h"
 
void USART2_ini(void);
 
//------------------------------------------------------------------------------------------------------------------------
 
#endif
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
16.09.2019, 13:24 9
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Вот с кодом для ПК проблемы.
Что-то типа того. Я не спец пока в C++ вообще и в Qt в частности, раньше писал на C#, но постепенно перехожу на Qt.
Еще момент, который стоит учесть - последовательный порт довольно тормозная штука, и надо бы предусмотреть в массиве, что вы посылаете старт и стоп сигналы. Хотя это опционально, может и так пойдет, как есть.

Connector.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef CONNECTOR_H
#define CONNECTOR_H
 
#include <QThread>
#include <QObject>
#include <QSerialPort>
#include "Exception.h"
 
class Connector : public QObject
{
    Q_OBJECT
private:
    QString m_portName;
    int m_readSize;
    bool m_processing;
    QSerialPort* m_pSerialPort=nullptr;
    QByteArray m_readedData;
public:
    explicit Connector(const QString& portName, int readSize, QObject *parent = 0);
    bool connect();
    void disconnect();
    QByteArray getReadedData();
 
signals:
    void signalStart();
    void signalStop();
    void signalBlockReaded();
    void signalException(const QString& message);
 
public slots:
    void slotStart();
    void slotStop();
};
 
#endif // CONNECTOR_H
Connector.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "Connector.h"
 
Connector::Connector(const QString &portName, int readSize, QObject *parent)
    : QObject(parent), m_processing(false)
{
    m_portName=portName;
    m_readSize=readSize;
}
 
bool Connector::connect()
{
    m_pSerialPort=new QSerialPort(m_portName);
    m_pSerialPort->setBaudRate(QSerialPort::Baud9600);
    m_pSerialPort->setParity(QSerialPort::NoParity);
    m_pSerialPort->setDataBits(QSerialPort::Data8);
    return m_pSerialPort->open(QIODevice::ReadWrite);
}
 
void Connector::disconnect()
{
    if(m_pSerialPort){
        if(m_pSerialPort->isOpen()){
            m_pSerialPort->close();
        }
        delete m_pSerialPort;
    }
    m_pSerialPort=nullptr;
}
 
QByteArray Connector::getReadedData()
{
    return m_readedData;
}
 
void Connector::slotStart()
{
    try{
        m_processing=true;
        emit signalStart();
        while(m_processing){
            for(int i=0;i<=10;i++){
                while(m_pSerialPort->waitForBytesWritten(50)){
                    m_readedData.append(m_pSerialPort->readAll());
                }
                if(m_readedData.size()==m_readSize){
                    emit signalBlockReaded();
                    continue;
                }
                else{
                    QThread::msleep(50);
                }
                if(i==10){
                    throw Exception(QObject::tr("Wrong readed data size"));
                }
            }
        }
    }
    catch(std::exception& ex){
        emit signalException(QString(ex.what()));
        disconnect();
    }
    catch(...){
        emit signalException(QObject::tr("Generic application failure"));
        disconnect();
    }
}
 
void Connector::slotStop()
{
    m_processing=false;
    emit signalStop();
}
Exception.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef EXCEPTION_H
#define EXCEPTION_H
#include <QtCore>
 
 
class Exception
{
private:
    QString m_message;
public:
    Exception(const QString& message);
    QString getMessage();
};
 
#endif // EXCEPTION_H
Exception.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
#include "Exception.h"
 
Exception::Exception(const QString& message)
{
    m_message=message;
}
 
QString Exception::getMessage()
{
    return m_message;
}
Ну и естественно, все это надо бы запускать в отдельном потоке, чтобы GUI не подвисал.
0
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
16.09.2019, 14:14 10
insite2012,
Цитата Сообщение от insite2012 Посмотреть сообщение
Ну и естественно, все это надо бы запускать в отдельном потоке, чтобы GUI не подвисал.
Можно пользоваться сигналом
C++ (Qt)
1
void QIODevice::bytesWritten(qint64 bytes)
и
C++ (Qt)
1
void QIODevice::readyRead()
+ QTimer для таймаута.
Тогда не надо будет второй поток заводить.
А то как то жирновато держать целый поток на простом поллинге.
0
Эксперт .NET
5534 / 4298 / 1217
Регистрация: 12.10.2013
Сообщений: 12,332
Записей в блоге: 2
16.09.2019, 14:29 11
Цитата Сообщение от _SayHello Посмотреть сообщение
Можно пользоваться сигналом
Не спорю. Я в своем проекте делал примерно так как показал выше, но естественно не претендую на истину в последней инстанции (да и опыта в данном ЯП у меня не так много).
Цитата Сообщение от _SayHello Посмотреть сообщение
как то жирновато держать целый поток на простом поллинге.
Мне так привычнее, долгая работа - отдельный поток. Привык так делать в C#. Да и с учетом мощностей сегодняшних ПК, не думаю что особо критично.
0
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
16.09.2019, 14:47 12
DmitryDDDD, можешь покопаться тут:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#ifndef SERIALCOMMUNICATION_H
#define SERIALCOMMUNICATION_H
#include "communicationinterface.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QObject>
#include <QTimer>
 
typedef struct
{
    QString name;
    QSerialPort::BaudRate baudrate;
    QSerialPort::DataBits databits;
    QSerialPort::StopBits stopbits;
    QSerialPort::Parity parity;
    QSerialPort::FlowControl flowcontrol;
}SerialSettings_t;
 
 
class SerialCommunication : public QObject
{
    Q_OBJECT
private:
    QSerialPort * m_serial = nullptr;
    QSerialPortInfo * m_serialInfo = nullptr;
    QTimer * requestTimeout;
    QTimer * responseTimeout;
    SerialSettings_t m_settings;
    QByteArray request;
    QByteArray response;
    qint64 bytesWritten = 0;
    qint64 bytesReceived = 0;
 
    /*Private functions*/
    void fillSettings(void);
    /******************************/
public:
    /*Constructors and destructor*/
    SerialCommunication(const QString & name, QSerialPort::BaudRate baudrate = QSerialPort::Baud115200,
            QSerialPort::DataBits databits = QSerialPort::Data8, QSerialPort::StopBits stopbits = QSerialPort::OneStop,
            QSerialPort::Parity parity = QSerialPort::NoParity, QSerialPort::FlowControl flowcontrol = QSerialPort::NoFlowControl);
    SerialCommunication(const SerialSettings_t & settings);
    virtual ~SerialCommunication();
    /*****************************/
 
    /*Public functions*/
    void setSettings(const SerialSettings_t & settings);
    SerialSettings_t getSettings(void) const;
    /*****************************/
 
    /*Reimplemented functions*/
    bool open(QIODevice::OpenMode = QIODevice::ReadWrite);
    void close(void);
    bool sendMessage(const QByteArray & frame, int msec = 1000);
    bool receiveMessage(int msec = 1000);
    /************************/
 
public slots:
    void bytesWrittenSlot(qint64);
    void readyReadSlot();
    void requestTimeoutSlot(void);
    void responseTimeoutSlot(void);
 
signals:
    void messageReceived(const QByteArray &);
};
 
#endif // SERIALCOMMUNICATION_H
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "serialcommunication.h"
#include "communicationinterface.h"
 
/*Constructors and destructor*/
SerialCommunication::SerialCommunication(const QString & name, QSerialPort::BaudRate baudrate,
        QSerialPort::DataBits databits, QSerialPort::StopBits stopbits,
        QSerialPort::Parity parity, QSerialPort::FlowControl flowcontrol) : QObject(nullptr)
{
    m_serialInfo  = new  QSerialPortInfo(name);
    m_serial = new QSerialPort(const_cast<QSerialPortInfo&>(*m_serialInfo));
 
    m_serial->setBaudRate(baudrate);
    m_serial->setDataBits(databits);
    m_serial->setStopBits(stopbits);
    m_serial->setParity(parity);
    m_serial->setFlowControl(flowcontrol);
 
    m_settings.name = name;
    m_settings.baudrate = baudrate;
    m_settings.databits = databits;
    m_settings.stopbits = stopbits;
    m_settings.parity = parity;
    m_settings.flowcontrol = flowcontrol;
 
 
    requestTimeout = new QTimer();
    responseTimeout = new QTimer();
}
 
SerialCommunication::SerialCommunication(const SerialSettings_t & settings)  : QObject(nullptr)
{
    m_settings = settings;
    m_serialInfo = new QSerialPortInfo(settings.name);
    m_serial = new QSerialPort(const_cast<QSerialPortInfo&>(*m_serialInfo));
 
    this->fillSettings();
}
 
SerialCommunication::~SerialCommunication()
{
    delete m_serial;
    delete m_serialInfo;
}
/**********************************************************************************************/
 
/*Public functions*****************************************************************************/
void SerialCommunication::setSettings(const SerialSettings_t & settings)
{
    m_settings = settings;
}
 
SerialSettings_t SerialCommunication::getSettings(void) const
{
    return m_settings;
}
/**********************************************************************************************/
 
/*Reimplemented functions**********************************************************************/
bool SerialCommunication::open(QIODevice::OpenMode openmode)
{
    return m_serial->open(openmode);
}
 
void SerialCommunication::close(void)
{
    if(m_serial->isOpen())
        m_serial->close();
}
 
bool SerialCommunication::sendMessage(const QByteArray & frame, int msec)
{
    if(!m_serial->isOpen())
    {
        if(!this->open())
            return false;
    }
    request = frame;
    bytesWritten = 0;
    connect(m_serial, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64)));
    connect(requestTimeout, SIGNAL(timeout()), this, SLOT(requestTimeoutSlot()));
    m_serial->write(frame);
    requestTimeout->start(msec);
    return true;
}
 
bool SerialCommunication::receiveMessage(int msec)
{
    response.clear();
    connect(m_serial, SIGNAL(readyRead()), this, SLOT(readyReadSlot));
    connect(responseTimeout, SIGNAL(timeout()), this, SLOT(responseTimeoutSlot()));
    responseTimeout->start(msec);
    return true;
}
/***********************************************************************************************/
 
/*Private functions*/
void SerialCommunication::fillSettings(void)
{
    m_serial->setBaudRate(m_settings.baudrate);
    m_serial->setDataBits(m_settings.databits);
    m_serial->setStopBits(m_settings.stopbits);
    m_serial->setParity(m_settings.parity);
    m_serial->setFlowControl(m_settings.flowcontrol);
}
/*************************************************************************************************/
 
/*Slots********************************************************************************************/
void SerialCommunication::bytesWrittenSlot(qint64 num)
{
    bytesWritten += num;
    if(bytesWritten == request.size())
    {
        requestTimeout->stop();
        disconnect(m_serial, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64)));
        disconnect(requestTimeout, SIGNAL(timeout()), this, SLOT(requestTimeoutSlot()));
        /*
         * emit signal that message has been sent successfully
         */
    }
}
 
void SerialCommunication::requestTimeoutSlot(void)
{
    requestTimeout->stop();
    disconnect(m_serial, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWrittenSlot(qint64)));
    disconnect(requestTimeout, SIGNAL(timeout()), this, SLOT(requestTimeoutSlot()));
    /*
     * emit signal that message has been sent with error
     */
}
 
void SerialCommunication::readyReadSlot(void)
{
    response.append(m_serial->readAll());
}
 
void SerialCommunication::responseTimeoutSlot(void)
{
    disconnect(m_serial, SIGNAL(readyRead()), this, SLOT(readyReadSlot));
    disconnect(responseTimeout, SIGNAL(timeout()), this, SLOT(responseTimeoutSlot()));
    emit messageReceived(response);
}
/***************************************************************************************************/
Шляпу что будет работать "из коробки" не поставлю не было времени протестить с железом, но как скелет можно использовать.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
16.09.2019, 15:40 13
_SayHello, insite2012, спасибо за предоставленные примеры, я покапаюсь в них, попробую разобраться, может что-то смогу понять, хотя на первый взгляд для меня пока что это "темный лес".
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.09.2019, 17:44 14
Цитата Сообщение от DmitryDDDD Посмотреть сообщение
Было бы отлично, если бы вы накидали каркас, а я бы уже попробовал разобраться, так все же проще, чем с нуля.
Думаю проще с нуля чем разбираться в коде который по-приводили.
Что мешает смотреть официальные примеры от Qt ?

Добавлено через 7 минут
C++
1
2
3
4
5
6
7
8
9
10
11
void SendStrtoPC(uint8_t* ADC_buffer_p, uint8_t count)
{
    uint8_t i=0;
        
      while(i < count)
      {
         while(!USART_GetFlagStatus(USART2, USART_FLAG_TXE));
         USART_SendData(USART2, ADC_buffer_p[i]);
         i++;
      }
}
Тут вероятно стоит сделать как то так:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void SendStrtoPC(uint8_t* ADC_buffer_p, uint8_t count)
{
    uint8_t i=0;
        
      while(i < count)
      {
         while(!USART_GetFlagStatus(USART2, USART_FLAG_TXE));
            USART_SendData(USART2, ADC_buffer_p[i]);
         i++;
      }
 
     /* добавляем разделитель говорящий о конце данных*/
    USART_SendData(USART2, '\r');
    USART_SendData(USART2, '\n');
}

Тогда в Qt можно будет использовать canReadLine() и readLine() что реально упрощает дело.
0
342 / 197 / 52
Регистрация: 18.10.2017
Сообщений: 1,938
16.09.2019, 21:11 15
Когда мне в самом начале 2000-х годов потребовалось в Qt использовать COM-порт, QSerialPort ещё не было
и я написал свой вариант класса для работы с COM-портом и пользуюсь им до сих пор. В этом классе есть свои
функции чтения и записи, с дополнительными функциональными возможностями, бывшими удобными мне
в тех условиях. А для чтения из порта у меня запущен поток, в котором run() заканчивается по окончанию чтения
очередной порции, но сам поток остаётся запущенным, только каждый раз запускается run().
COM-порт инициализируется с помощью структуры termios, как это делается в C.
0
4 / 4 / 0
Регистрация: 12.11.2018
Сообщений: 511
17.09.2019, 07:55 16
Avazart Да на самом деле ничего не мешает, просто перерыл много информации, но более менее похожее рабочее решение моей задачи не нашел, а для меня быстрее разобраться с уже готовым решением и переделать его под свою задачу, чем с нуля. Но тут видимо с наскока не получится. Поэтому да, буду смотреть примеры Qt. Я как-то уже не осознанно делал очень простой терминал, но уже забыл все.
За добавление к коду на МК спасибо, да, там есть смысл так сделать.

Добавлено через 47 минут
Avazart, А можете подсказать, какой из данных примеров наиболее приближен к поставленной задаче?

Blocking Master Example
Blocking Slave Example
Command Line Enumerator Example
Command Line Reader Async Example
Command Line Reader Sync Example
Command Line Writer Async Example
Command Line Writer Sync Example
Enumerator Example
Terminal Example
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
17.09.2019, 15:16 17
Да думаю нужно смотреть все. Ибо это только база.

Наиболее емкий как я помню Terminal Example.
0
17.09.2019, 15:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.09.2019, 15:16
Помогаю со студенческими работами здесь

QSerialPort ошибки
Собирал qt так https://www.cyberforum.ru/qt/thread1063918.html Собирал qserialport так ...

QSerialPort on Android
Всем привет, возможно ли в андроид приложении использовать QSerialPort? При попытке собрать проект...

FlowControl в QSerialPort
Пытаюсь немного доработать программу пример - terminal и столкнулся с тем, что для обмена с...

QSerialPort и readyRead
Доброго времени суток. Проблема состоит в том, как правильно переписать работу целого класса и при...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru