Abstract
上个文档描述的是整个项目的创建原因, 工程创建, 工程导入.
这个文档是进行具体的项目的配置, 根据原理图进行引脚信息, 从代码进行梳理, 一步一步确认引脚, 以及代码框架
我们需要配置的项:
- uart
- spi
- ldo
- RST
- IRQ
编译该工程注意路径中不能有空格!!!!!
Referance
rbb7 原理图文件: RBB_MCU7_V2.2-schematics.pdf
安森美 LDO dataSheet TI Level Shifter dataSheet:
UART 配置
这里的 uart 预留的是PD24和PD25, 我们芯片的该引脚也配置为如图的Rx和Tx.

进入到可视化配置界面, 搜索选择usart, add

进行调整引脚, , 选择uart2配置到PD25 和 PD26

需要调整的位置
USART_Sync
- 阻塞型
USART_Async
- 中断型

配置 SPI
Spi Key Word MISO : Master In Slave Out MOSI : Master Out Slave In CS: Chip Select
SPI 的几种模式
| mode | description |
|---|---|
| SPI_Master_Sync | 同步模式下的串行外设接口 (SPI) 主机通信 |
| SPI_Slave_Sync | 同步模式下的串行外设接口 (SPI)从机通信 |
| SPI_Master_Async | 中断的异步模式下串行外设接口(SPI)主机通信 |
| SPI_Slave_Async | 中断的异步模式下的串行外设接口(SPI)从机通信 |
| SPI_Master_DMA | DMA 模式下的串行外设接口 (SPI) 主机通信 |
| SPI_Master_RTOS | 支持 RTOS模式下串行外设接口 (SPI) 主机通信, |
SPI 分配
在rbb7代码中的QSPI是原理图上的S1_SPI, 代码中的SPI1是原理图的S2_SPI, 代码中的SPI2是原理图中的 SPI0 分配如下.
| 代码 | 原理图 |
|---|---|
| Qspi | S1_SPI |
| spi1 | S2_SPI |
| spi2 | SPI0 |
在项目中的配置是按照如下代码部分进行配置的, MCU7是Legacy版本, 所以对应的是两个链接器. debug 和代码中显示的都是两个, 链接器, HatvanPlus 只有一个 LDO. ( 代码中的注释有点迷惑, 一直以为是 HatvanPlus 其实是 Legacy )
按照如下配置进行配置雷达的驱动引脚配置, 就是没问题的. 调整 mcu 也只需调整这几个配置即可.
// detect board type
const bool isHatvanLegacy = Board_isHatvanLegacy();
if (isHatvanLegacy)
{
ShieldConnectorDefinition = &ShieldConnectorDefinitionHatvanLegacy[0];
BoardSpiDefinition = &BoardSpiDefinitionHatvanLegacy[0];
BoardRadarPinsConfigAvian = &BoardRadarPinsConfigAvianHatvanLegacy[0];
m_shieldConnectorCount = ARRAY_SIZE(ShieldConnectorDefinitionHatvanLegacy);
}Hatvan Legacy Board Connector Definition, 我们这个是对HatvanLegacy的连接器做配置.
ShieldConnectorDefinition_t ShieldConnectorDefinitionHatvanLegacy[] = {
[0] = {
.en_ldo = GPIO_ID('C', 30),
.ls_spi_oe = GPIO_ID('D', 24),
.ls_gpio_oe = GPIO_ID('D', 14),
.ls_gpio_dir = GPIO_ID('D', 18),
.oc_led = GPIO_ID('C', 1),
.oc1 = GPIO_ID('D', 16),
.oc2 = GPIO_ID('C', 9),
.oc3 = GPIO_ID('C', 28),
.oc4 = GPIO_ID('A', 27),
},
[1] = {
.en_ldo = GPIO_ID('C', 31),
.ls_spi_oe = GPIO_ID('C', 3),
.ls_gpio_oe = GPIO_ID('A', 1),
.ls_gpio_dir = GPIO_ID('C', 10),
.oc_led = GPIO_ID('C', 2),
.oc1 = GPIO_ID('A', 22),
.oc2 = GPIO_ID('D', 10),
.oc3 = GPIO_ID('C', 29),
.oc4 = GPIO_ID('D', 15),
},spi配置
PlatformSpiDefinition_t BoardSpiDefinitionHatvanLegacy[] = {
[0] = {
.peripheral_id = ID_QSPI,
.baudrate = 50000000,
.setup_interface = setup_qspi,
.addr = {
.peripheral = QSPI,
.tdr = (uint32_t)&QSPI->QSPI_TDR,
.rdr = (uint32_t)&QSPI->QSPI_RDR,
},
.pins = {
.csn = PIO_PA11_IDX,
.clk = PIO_PA14_IDX,
.clk_flags = IOPORT_MODE_MUX_A,
.miso = PIO_PA12_IDX,
.miso_flags = IOPORT_MODE_MUX_A,
.mosi = PIO_PA13_IDX,
.mosi_flags = IOPORT_MODE_MUX_A,
},
.dma = {
.tx_dma_channel = HV_DMA_HW_CH_TX_1,
.tx_dma_hw_id = HV_DMA_HW_INTF_TX_1,
.rx_dma_channel = HV_DMA_HW_CH_RX_1,
.rx_dma_hw_id = HV_DMA_HW_INTF_RX_1,
},
},
[1] = {
.peripheral_id = ID_SPI1,
.baudrate = 50000000,
.setup_interface = setup_spi,
.addr = {
.peripheral = SPI1,
.tdr = (uint32_t)&SPI1->SPI_TDR,
.rdr = (uint32_t)&SPI1->SPI_RDR,
},
.pins = {
.csn = PIO_PC25_IDX,
.clk = PIO_PC24_IDX,
.clk_flags = IOPORT_MODE_MUX_C,
.miso = PIO_PC26_IDX,
.miso_flags = IOPORT_MODE_MUX_C,
.mosi = PIO_PC27_IDX,
.mosi_flags = IOPORT_MODE_MUX_C,
},
.dma = {
.tx_dma_channel = HV_DMA_HW_CH_TX_2,
.tx_dma_hw_id = HV_DMA_HW_INTF_TX_2,
.rx_dma_channel = HV_DMA_HW_CH_RX_2,
.rx_dma_hw_id = HV_DMA_HW_INTF_RX_2,
},
},
};中断和复位设置
static const IPinsAvianConfig_t BoardRadarPinsConfigAvianHatvanLegacy[] = {
[0] = {
.gpioReset = GPIO_ID('A', 0),
.gpioIrq = GPIO_ID('C', 6),
},
[1] = {
.gpioReset = GPIO_ID('A', 17),
.gpioIrq = GPIO_ID('C', 11),
},
};平台初始化, 这里有点迷惑, 通常初始化都是按照上面的配置进行初始化, 但是这里的init是将所有的spi, ldo , LevelShifter, connector都初始化. 就是全都配置出来, 没有连接的那边的引脚(另外一个connector)其实都是打开的, 只不过没有数据通路.
PlatformSpi_initialize(BoardSpiDefinition, m_shieldConnectorCount);
--> inter PlatformSpi_initialize :
for (unsigned int i = 0; i < m_count; i++)
{
PlatformSpiDefinition_t *device = &m_definition[i];
return E_SUCCESS;接下来就是对LED的常规设置
// initialize LedSequence to be used for potential error signaling during detection
LedSequence_Constructor();
LedSequence_setStatus(LED_STATUS_OPERATING);再往后就是shield的错误检测, 如果shield没有错误就把LDO打开, 电平转换打开(使能connector)
static sr_t Board_detectShields(void)
{
/* Checks both connectors for unsupported or wrongly connected shields.
* In case no errors are detected, both connectors will be enabled,
* in order to allow radar device detection.
*/
for (uint8_t shieldId = 0; shieldId < m_shieldConnectorCount; shieldId++)
{
// detect the presence of a shield by probing the I2C lines
const sr_t detection = ShieldConnector_detect(&ShieldConnectorDefinition[shieldId], shieldId);
switch (detection)
{
case E_NOT_AVAILABLE: // allow shields without I2C bus
/* no break */
case E_SUCCESS:
break;
case E_NOT_POSSIBLE:
LedSequence_setRbbStatus(RBB_ERROR_HARDWARE_CONNECTED_WRONG);
return E_NOT_POSSIBLE;
break;
case E_NOT_SUPPORTED:
LedSequence_setRbbStatus(RBB_ERROR_HARDWARE_NOT_SUPPORTED);
return E_NOT_SUPPORTED;
break;
default:
LedSequence_setRbbStatus(RBB_ERROR_HARDWARE_INTERNAL_ERROR);
return detection;
break;
}
// power-up shield and configure its level shifters
ShieldConnector_enable(&ShieldConnectorDefinition[shieldId], shieldId, true);
}
return E_SUCCESS;
}shield没有问题利用所有配置创建雷达对象,
radar = Board_detectRadar(gpio, spi, i2c, &m_data);下面是具体雷达对象创建
static IRadar *Board_detectRadar(IGpio *gpio, ISpi *spi, II2c *i2c, IData **data)
{
// 遍历所有shield
for (uint8_t shieldId = 0; shieldId < m_shieldConnectorCount; shieldId++)
{
// 如果要是第二个shield, 就交换配置, 将配置交换到第一个配置位置
if (m_shieldConnectorCount == 2)
{
if (shieldId == 1)
{
PlatformInterfaces_swapI2cIds();
Board_swapSpiIds();
}
}
const sr_t avianDetection = Avian_Detect(spi, gpio, &BoardRadarConfigAvian[shieldId], &BoardRadarPinsConfigAvian[shieldId]);
if (avianDetection == E_SUCCESS)
{
Avian_Constructor(&m_avian, &DataAvian, gpio, spi, &BoardRadarConfigAvian[shieldId], &BoardRadarPinsConfigAvian[shieldId]);
DataAvian_Constructor(Board_acquisitionStatusCallback);
DataAvian_setBuffer(BoardRadarConfigAvian[shieldId].dataIndex, m_dataBuffer, DATA_BUFFER_SIZE);
DataAvian_registerInterrupt(BoardRadarConfigAvian[shieldId].dataIndex, &BoardIrqPinsConfigAvian[shieldId]);
*data = &DataAvian;
// 如果这里第一次配置成功就直接跳出该函数了, 就不会执行shield2 的配置.
return (IRadar *)&m_avian;
}到此所有的脚位配置信息完成
接下来进行定制配置项目的构建.
- 构建的部分包括
uart,LDO,SPI,IRQ,Rst- 使用
S2_SPI所以需要配置LDO2
所需要的引脚配置如下
| option | PIn |
|---|---|
| UART_RX | PD25 |
| UART_TX | PD26 |
| LDO_2 | PC31 |
| IRQ | PC11 (LOW) |
| RST | PA17 (LOW) |
| S2_SPI_CLK | PC24 |
| S2_SPI_CS | PC25(LOW) |
| S2_SPI_ MOSI | PC27 |
| S2_SPI_ MISO | PC26 |
下面进行相关的配置部分.
S2_SPI 原理图

LDO 配置
Chip enable: Applying VEN < 0.4 V disables the regulator, Pulling VEN > 1.2 V enables the LDO
将 LDO 打开, 将输出的电源给到levelShifter, 进行下一步操作.
| level | enable |
|---|---|
| Low | False |
| High | True |
根据原理图进行 LDO 引脚设置, LDO 的设置, 直接配置成默认拉高使能.

电平转化配置(Level Shifter Config)
电平转换, 的功能是将 mcu 的 3.3v 电平转换为 1.8v 电平和 radar 芯片的 spi 进行通信.
但是对于SN74AVC4T245RSVR这款电源芯片需要等待电平稳定后再输出, 所以使能LDO将电源提供给LevelShifter之后, 等待一段时间后再使能电平转换芯片.
对于该款电平转换芯片, 不仅有使能引脚 ( 控制开关) , 默认状态下是low (打开)
Sx_SPI_OEn level |
enable |
|---|---|
| high | False |
| low | True |
还有方向控制引脚 ( 控制转换方向 ), 默认状态下是High(MCU → sensor)
Sx_SPI_DIR level |
direction |
|---|---|
| high | MCU → sensor |
| low | MCU ← sensor |

从此往下的内容, 是没有调试工具的时候的代码猜测, 不需要关注
shield 型号判断
如果无法判断型号是 HatvanLegacy 和 HatvanPlus 时可以使能ldo_en 引脚, 这里是个人提供的方案.
官方方案是
使能LDO2然后检测PA8引脚是否拉高来判断是否为Legacy
| version | LDO_en |
|---|---|
| HatvanLegacy | C31 |
| HatvanPlus | C30 |
connector.h

然后到connecter 测量电压, 电平转换默认是正确配置, 查看是否能够检测到 LDO 电源(最好使能前后对比测量).
