[英]Passing Variables in a Queue FreeRTOS
On the STM32F103 I measure the voltage and display the result on the LCD.在 STM32F103 上,我测量电压并将结果显示在 LCD 上。 The result is displayed, the code is as follows:
显示结果,代码如下:
HAL_ADCEx_InjectedStart(&hadc1);
HAL_ADC_PollForConversion(&hadc1,100);
u0= 180 - (180*(3 - ((float)HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_1))*3/4096));
sprintf(str,"%.1fV",u0);
LCD_String(str);
HAL_ADCEx_InjectedStop(&hadc1);
I wanted to separate the operations into tasks, that is, we measure in the StartADC task and pass it through the queue to the StartLCDTask task, which displays the result on the display.我想将操作分离为任务,即我们在 StartADC 任务中测量并通过队列将其传递给 StartLCDTask 任务,该任务将结果显示在显示器上。 But instead of the measured value, the display shows 0V.
但显示器显示的不是测量值,而是 0V。 Where did I go wrong?
我哪里做错了?
/* Definitions for UARTQueue*/
osMessageQueueId_t UARTQueueHandle
/* creation of UARTQueue*/
UARTQueueHandle = osMessageQueueNew (8, sizeof(uint8_t), &UARTQueue_attributes);
typedef struct {
char Buf;
} QUEUE_t;
void StartADC(void *argument)
{
char u0;
for(;;)
{
HAL_ADCEx_InjectedStart(&hadc1);
HAL_ADC_PollForConversion(&hadc1,100);
u0= 180 - (180*(3 - ((float)HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_1))*3/4096));
osMessageQueuePut(UARTQueueHandle, &u0, 0, osWaitForever);
HAL_ADCEx_InjectedStop(&hadc1);
osDelay(200);
}
}
void StartLCDTask(void *argument)
{
QUEUE_t msg;
char str[9];
for(;;)
{
osMessageQueueGet(UARTQueueHandle, &msg, 0, osWaitForever);
sprintf(str,"%.0fV", (double)msg.Buf);
LCD_SetPos(0,0);
LCD_String(str);
}
}
In your first example, you do:在您的第一个示例中,您执行以下操作:
sprintf(str,"%.1fV",u0);
This implies u0
is float
.这意味着
u0
是float
。 If it's not, then this is UB (undefined behavior)如果不是,那么这是 UB(未定义的行为)
But, in your second example, u0
is char u0;
但是,在您的第二个示例中,
u0
是char u0;
You are truncating a floating point value to a char
.您正在将浮点值截断为
char
。 The fractional part will be lost.小数部分将丢失。
Then, you enqueue it and send it.然后,您将其排入队列并发送。
And, you're "cheating" a bit:而且,你有点“作弊”:
char
but receiving a QUEUE_t
.char
但收到QUEUE_t
。msg_size
of sizeof(uint8_t)
instead of sizeof(QUEUE_t)
sizeof(uint8_t)
而不是sizeof(QUEUE_t)
的msg_size
初始化This "happens" to work but it's sloppy.这“碰巧”有效,但很草率。 It's not very extensible.
它不是很可扩展。 It would break if the
QUEUE_t
struct was extended and needed multiple values to be sent.如果
QUEUE_t
结构被扩展并且需要发送多个值,它将中断。 We'll need to fix that below.我们需要在下面解决这个问题。
The recipient StartLCDTask
does:收件人
StartLCDTask
会:
sprintf(str, "%.0fV", (double) msg.Buf);
The two sprintf
are not equivalent.这两个
sprintf
不等价。
Now that you have two tasks you have the choice of which task/function does the calculation/conversion of the raw ADC value (which is a uint32_t
).现在您有两个任务,您可以选择哪个任务/函数来计算/转换原始 ADC 值(即
uint32_t
)。 In either case, we'll need to change QUEUE_t
to handle the value.无论哪种情况,我们都需要更改
QUEUE_t
来处理该值。
Here is a version that enqueues the raw value and has the display task do the conversion.这是一个将原始值排入队列并让显示任务进行转换的版本。
/* Definitions for UARTQueue*/
osMessageQueueId_t UARTQueueHandle;
typedef struct {
uint32_t adcraw;
} QUEUE_t;
/* creation of UARTQueue*/
void
init_queue(void)
{
UARTQueueHandle = osMessageQueueNew(8, sizeof(QUEUE_t),
&UARTQueue_attributes);
}
void
StartADC(void *argument)
{
QUEUE_t msg;
for (;;) {
HAL_ADCEx_InjectedStart(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
msg.adcraw = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1);
osMessageQueuePut(UARTQueueHandle, &msg, 0, osWaitForever);
HAL_ADCEx_InjectedStop(&hadc1);
osDelay(200);
}
}
void
StartLCDTask(void *argument)
{
QUEUE_t msg;
float_t u0;
char str[20];
for (;;) {
osMessageQueueGet(UARTQueueHandle, &msg, 0, osWaitForever);
u0 = msg.adcraw;
u0 = 180 - (180 * (3 - u0 * 3 / 4096));
sprintf(str, "%.0fV", u0);
LCD_SetPos(0, 0);
LCD_String(str);
}
}
UPDATE:更新:
Although I noted this before, I didn't realize the possible impact.虽然我之前注意到了这一点,但我没有意识到可能的影响。
In the single task code, the format is:在单任务代码中,格式为:
"%.1fV"
But, this got changed for the multiple task code:但是,这已针对多任务代码进行了更改:
"%.0fV"
I suspect that this is a typo.我怀疑这是一个错字。 I think the format should be the same in both cases.
我认为这两种情况的格式应该是一样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.