试图理解这个#define
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了试图理解这个#define相关的知识,希望对你有一定的参考价值。
我正在尝试将stm32fxxx的16位录音机应用程序调整为24位,我偶然发现了令我困惑的#define
。
我已经将16位DMA更改为32位DMA以及一些缓冲区uint16_t
到uint32_t
等。不知道为什么uint32_t
并且没有签署int但我稍后会看到它。没有办法通过DMA传递24位,所以我将发送32位然后丢弃一个字节。
HAL_SAI_Transmit_DMA()
的第三个输入实际上预计uint16_t
的大小值。
#define AUDIO_OUT_BUFFER_SIZE 16384
#define AUDIODATA_SIZE 2
#define DMA_MAX_SZE 0xFFFF
#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
uint8_t BSP_AUDIO_OUT_Play(uint16_t* pBuffer, uint16_t Size)
{
// send audio samples over DMA from buffer to audio port
HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t*) pBuffer,
DMA_MAX(AUDIO_OUT_BUFFER_SIZE / AUDIODATA_SIZE));
return AUDIO_OK;
}
我猜我需要换到
AUDIODATA_SIZE 4
#define DMA_MAX_SZE 0xFFFFFFFF // 32bit
但是我想知道#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE)
应该做什么以及它是如何工作的!它几乎写成好像它的功能?其中x
是IO值?
AUDIODATA_SIZE
是每个样本中的字节数:
我为成为C的初学者而道歉但是我从未见过这样的事情而且只能假设其掩盖了缓冲区的大小。但为什么?
pBuffer
是指向传递给函数的uint16_t*
指针的指针,并根据需要投射到(uint8_t*)pBuffer
以获取HAL_SAI_Transmit_DMA
。我从来没有见过这样的指针,但是它有效。
我想知道这个定义应该做什么以及它是如何工作的!它几乎写成好像它的功能?其中x是IO值?
我认为你问的是DMA_MAX
宏。是的,它的编写几乎就像是一个函数,它在概念上也有点像一个函数。这就是为什么像这样的宏被称为“类似函数的宏”。另一种是“类似对象的宏”。
类似函数的宏仍然是一个宏。它的外观被替换为给定的替换文本,并且其任何参数的标识符内的所有外观都被(完全宏扩展的)宏参数替换,但有几个例外,我将在这里忽略。因此,这......
DMA_MAX(BufferSize / AUDIODATA_SIZE)
...扩展到这个:
(((BufferSize / AUDIODATA_SIZE) <= DMA_MAX_SZE)? (BufferSize / AUDIODATA_SIZE):DMA_MAX_SZE)
这使用三元运算符来评估BufferSize / AUDIODATA_SIZE
和DMA_MAX_SZE
中较小的一个。从提供的代码中可以看出,为什么以及如何(以及是否)做正确的事情是不明显的。
pBuffer是指向传递给函数的uint16_t *指针的指针,并根据需要转换为(uint8_t *)pBuffer,用于HAL_SAI_Transmit_DMA。我从来没有见过这样的指针,但是它有效。
允许从一个对象指针类型转换为另一个,有时甚至是明智的。特别是,转换为字符指针(如uint8_t *
)是一种定义明确的方法,用于访问对象表示的原始字节。
0xFFFF似乎不是位掩码,但最大大小为65535。
宏DMA_MAX(x)
只检查传递的参数是否小于最大值,如果没有将值限制为允许的最大值。也许某种方式的溢出检查?
它在逻辑上等同于这个伪代码:
if( (BufferSize / AUDIODATA_SIZE) <= DMA_MAX_SZE)
{
HAL_SAI_Transmit_DMA(... , BufferSize / AUDIODATA_SIZE);
}
else
{
HAL_SAI_Transmit_DMA(... , DMA_MAX_SZE);
}
作为旁注,最好不要像这样编写icky宏,而是使用临时变量:
uint16_t size;
if(BufferSize / AUDIODATA_SIZE <= DMA_MAX_SZE)
{
size = BufferSize / AUDIODATA_SIZE;
}
else
{
size = DMA_MAX_SZE;
}
HAL_SAI_Transmit_DMA(... , size);
这将编译为与您当前拥有的机器代码相同的机器代码,但更具可读性。
以上是关于试图理解这个#define的主要内容,如果未能解决你的问题,请参考以下文章