目录
目录
编辑2.2 任意位置按 Ctrl+S 将开始自动生成代码。
3.4在另一个任务里面获取stream buffer里面的数据:
1.关于stream buffer介绍
流缓冲区是FreeRTOSV10.0.0新增的一个功能,一种优化的进程间通信机制,专门用于只有一个写入者和一个读取者的场景,能够通过流缓冲区写入和读取任意字节长度的字节数据流。用户需要先创建一个流缓冲区,然后才可以使用它。使用原理如图1-1所示,有一个任务向流缓冲区写入数据,称为写入者(writer),有一个任务向流缓冲区读出数据,称为读取者(reader)。
创建流缓冲区时,用户需要设定其存储容量,例如1024字节。使用流缓冲区时,写入者一次可以写入任意长度的字节数据流,但是不能超过流缓冲区的存储容量,(本人在实现的时候没有考虑流缓冲和我所设置任务栈的存储容量,导致在读取数据的时候出现栈溢出,数据乱码的情况和任务发生阻塞的情况,通过调用printf不断调试打印,最终找到问题所在)。读取者一次可以读出任意长度的字节数据流,字节数据流没有起始符和结束符。使用流缓冲区在进程间传输数据时,使用的是复制数据的方式,即写入者将数据复制到流缓冲区,读取者从流缓冲区复制出数据。流缓冲区就像是一个管道,字节数据流在其中流动。
流缓冲与队列有点像,但两者是有区别的:队列的数据分为基本的项(item),项的格式是固定的,例如uint32_t类型的项,每次写入或读取一个项;流缓冲区的数据只是字节数据流,写入和读出的数据长度是任意的。
2.关于ADC的配置:
从原理图和CPU管脚图上可以看出,环境光传感器使用ACD1_IN15,而声音传感器则使用ACD1_IN116。
2.1配置使能ADC:
配置 ADC1,使能通道 IN15 和 IN16,选择 Single-ended(Differential 为差分信号),这时候
PA4和PA6两个管脚就设置为ADC输入模式了。
ADC 的时钟最好不要设置得太高,这里调整为 12MHz:
2.2 任意位置按 Ctrl+S 将开始自动生成代码。
修改 adc.c 文件,添加环境光强传感器和的声音传感器实现:
/* USER CODE BEGIN 1 */
enum
{
ADCCHN_NOISY,
ADCCHN_LUX,
ADCCHN_MAX,
};
int adc_sample_lux_noisy(uint32_t *lux, uint32_t *noisy)
{
uint8_t i;
uint32_t timeout = 0xffffff;
for(i=0; i<ADCCHN_MAX; i++)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, timeout);
if( ADCCHN_NOISY == i )
{
*noisy = HAL_ADC_GetValue(&hadc1);
}
else if( ADCCHN_LUX == i )
{
*lux = HAL_ADC_GetValue(&hadc1);
}
HAL_Delay(10);
}
HAL_ADC_Stop(&hadc1);
return 0;
}
/* USER CODE END 1 */
3.关于FreeRTOS的配置:
在FreeRTOS里面创建两个任务,一个任务负责采样存储,将采样的数据存储到Steam buffer里面
在创建任务的时候,要修改任务栈空间的大小,如果栈空间过小,任务执行的时候会出现堵塞。我在这里将128大小的栈空间改成256。使用以上方法创建两个任务,任务的优先级相同,用 ospriorityNormal,以下是创建好的任务。
3.1引入头文件
定义一个宏来制定流缓冲区大小,和触发水平。在这里聊一聊触发水平:当流缓冲区中的可用数据量达到或超过要求的字节数时,任务将被唤醒并继续执行。这意味着只有当有足够的数据可供读取时,任务才会继续执行。
3.2创建流缓冲区
3.3在任务里面获取ADC采样数据并存储:
3.4在另一个任务里面获取stream buffer里面的数据:
4.通过串口打印工具,打印出数据在PC端显示
上面的代码中设置触发水平为20,那么一个任务在读取流缓冲区时,当流缓冲区里的数据达到20字节时,就会解除读取者的阻塞状态,触发水平可以设置为1,但是不能超过流缓冲区大小。