?目录
? ? ? ? 1.前言
? ? ? ? 2.SPI学习
? ? ? ? 3.TIM同步
? ? ? ? 4.总结
?前言
????????最近又从语音转向硬件方向,不过由于初入硬件,感觉如坠泥潭。主要是各个外设的功能太复杂了,引用我老师的一句话。做硬件就是要又硬又软。而今天写这篇文章主要是因为解决了一些小问题,所以记录一下,以防以后碰见。
? ? ? ? 感谢下文(内容关于TIM同步)的作者,通过参考下文解决了我一些问题
(29条消息) STM32定时器同步模式 四种_学海无涯-CSDN博客_stm32 定时器同步https://blog.csdn.net/qq_30567891/article/details/78988828
SPI学习
? ? ? ? SPI(Serial Peripheral Interface)串行外设接口,能够进行全双工的数据传输,本次项目中主要使用进行语音数据的传输,SPI的引脚定义可以参照参考手册。
- NSS:SPI的开关,可以配置为内部开关或外部的硬件开关,通常打开是置0
- MISO:主机输入,从机输出(传输数据),每次传输大小可以指定
- MOSI:主机输出,从机输入(传输数据)
- SCK:SPI的时钟,相当于SPI的驱动能力
????????时序图随便从网上找的,可以看到SPI的数据传输是有两个步骤的,一是数据的改变,二是数据的采样,采样的值就是实际的传输值。两个步骤都是在SCK的边沿进行,至于到底是上升沿还是下降沿可以自己通过CPOL和CPHA进行设置。下图即展示了相关边沿及时序
????????值得注意的是,我的项目中NSS设置成了硬件启动,然后在STM32中引一个引脚接到NSS引脚上,通过改变引脚电平启动SPI,这样相当于软件方式的硬件启动,虽然我感觉不如直接设置成软件启动。不知道为什么要这么设计[迷惑]
TIM同步
????????简单总结一下,TIM内部具有ITR的触发功能,比如TIM1可以因为ENABLE、UPDATE、COMPARE事件发出TRO(触发器输出),然后由于内部连接,可以在TIM2中接受这个信号成为TRI,接受后也可以触发一些事件,例如Gated门控、Trigger开启等。
? ? ? ? TIM可以配置成PWM模式,输出方波,这个输出方波是根据CRR的值和COUNT值进行方波输出,当CRR<COUNT输出0,当CRR>COUNT输出1。而且,PWM模式属于基础功能,不影响触发器模式,所以也可以使用TIM同步来进行PWM同步方波输出。
? ? ? ? 坑1:HAL库中,如果配置成了从机Trigger同步模式,一定要注意从机计时器也需要使用HAL_TIM_PWM_Start()。不用担心使用这个会直接开始计时器输出PWM方波,因为在HAL库中,有这么一段话(下面代码贴出来了)/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */在Trigger模式中,不会开启,因为它是自动触发开启的。
HAL_TIM_PWM_Start(&htimn, TIM_CHANNEL_n);
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Check the TIM channel state */
if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY)
{
return HAL_ERROR;
}
/* Set the TIM channel state */
TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY);
/* Enable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* Enable the main output */
__HAL_TIM_MOE_ENABLE(htim);
}
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
{
__HAL_TIM_ENABLE(htim);
}
/* Return function status */
return HAL_OK;
}
????????坑2:主机计时器要在从机计时器前初始化。如果从计时器先初始化,那么可以就可以接受触发信号,这会导致在主计时器初始化时,按照HAL库逻辑会这么进入MX_TIMn_Init->HAL_TIM_Base_Init->TIM_Base_SetConfig(),在TIM_Base_SetConfig函数中有这么一段话
/* Generate an update event to reload the Prescaler
and the repetition counter (only for advanced timer) value immediately */
TIMx->EGR = TIM_EGR_UG;
所以很明显,这会直接导致从计时器在主计时器初始化时开启,这跟我们想象的不一样啊,大哥。这些坑真让我头疼,发出来大家注意一下,也让我以后注意别再踩这些坑了[哭哭]
总结
? ? ? ? 一定要参考那3300多页的STM32参考手册,虽然很多很杂,不过确实是最为准确的手册了。哭着看吧
|