引脚说明
硬件SPI与软件SPI相比,硬件SPI是靠硬件上面的SPI控制器,所有的时钟边缘采样,时钟发生,还有时序控制,都是由硬件完成的。它降低了CPU的使用率,提高了运行速度。软件SPI就是用代码控制IO输出高低电平,模拟SPI的时序,这种方法通信速度较慢,且不可靠。
想要使用硬件SPI驱动,需要确定使用的引脚是否有SPI外设功能。可以通过用户手册146页进行查看。
当前使用的是硬件SPI接口,而NRF24L01我们需要与它发送数据也需要接收数据,故使用的是4线的SPI,使用到了时钟线SCK、主机输出从机输入线MOSI、主机输入从机输出线MISO和软件控制的片选线NSS。所以除了这些引脚需要使用硬件SPI功能的引脚外,其他引脚都可以使用开发板上其他的GPIO。
这里选择使用PA5/PA6/PA7的SPI复用功能
。其他对应接入的引脚请按照你的需要。这里选择的引脚见右表。
有SPI功能的引脚
L298N控制电机速度的方式,是通过将IN1与IN2接入PWM,直接通过调整PWM的占空比进行速度控制。因此要求IN1/IN2/IN3/IN4都要使用PWM功能。
注意:在本次示例中只展示IN1和IN2的配置,IN3和IN4内容类似。
模
块接线图
移植步骤中的导入.c和.h文件与
【CW32模块使用】DHT11温湿度传感器
相同,
只是将.c和.h文件更改为bsp_L298N.c与bsp_L298N.h。这里不再过多讲述,移植完成后面修改相关代码。
在文件bsp_L298N.c中,编写如下代码。
/*
* Change Logs:
* Date Author Notes
* 2024-06-24 LCKFB-LP first version
*/
#include "bsp_L298N.h"
/******************************************************************
* 函 数 名 称:L298N_Init
* 函 数 说 明:PWM配置
* 函 数 形 参: pre定时器时钟预分频值 per周期
* 函 数 返 回:无
* 作 者:LC
* 备 注:
******************************************************************/
void L298N_Init(uint16_t ReloadValue)
{
RCC_L298N_GPIO_ENABLE(); // 使能GPIO时钟
RCC_IN1_TIMER_ENABLE(); // 使能通用定时器时钟
RCC_IN2_TIMER_ENABLE(); // 使能通用定时器时钟
GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体
GPIO_InitStruct.Pins = GPIO_IN1|GPIO_IN2; // GPIO引脚
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 输出速度高
GPIO_AF_IN1_ENABLE(); // 使用GPIO复用功能
GPIO_AF_IN2_ENABLE(); // 使用GPIO复用功能
GPIO_Init(PORT_GPIO, &GPIO_InitStruct); // 初始化
GTIM_InitTypeDef GTIM_InitStruct; // 通用定时器初始化结构体
GTIM_InitStruct.Mode = GTIM_MODE_TIME; // 定时器模式
GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE; // 连续计数模式
GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV64; // DCLK = PCLK / 64 = 64MHz/64 = 1MHz
GTIM_InitStruct.ReloadValue = ReloadValue; // 重装载值设置
GTIM_InitStruct.ToggleOutState = ENABLE; // 输出翻转功能
GTIM_TimeBaseInit(BSP_IN1_TIMER, >IM_InitStruct); // 初始化
GTIM_TimeBaseInit(BSP_IN2_TIMER, >IM_InitStruct); // 初始化
GTIM_OCInit(BSP_IN1_TIMER, BSP_PWM_CHANNEL, GTIM_OC_OUTPUT_PWM_HIGH); // 配置输出比较通道为PWM模式
GTIM_OCInit(BSP_IN2_TIMER, BSP_PWM_CHANNEL, GTIM_OC_OUTPUT_PWM_HIGH); // 配置输出比较通道为PWM模式
GTIM_Cmd(BSP_IN1_TIMER, ENABLE); // 使能定时器
GTIM_Cmd(BSP_IN2_TIMER, ENABLE); // 使能定时器
}
/******************************************************************
* 函 数 名 称:AO_Control
* 函 数 说 明:A端口电机控制
* 函 数 形 参:dir旋转方向 1正转0反转 speed旋转速度,范围(0 ~ per-1)
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void AO_Control(uint8_t dir, uint32_t speed)
{
if( dir == 1 )
{
//AO1输出
GTIM_SetCompare1(BSP_IN1_TIMER, 0 );
//AO2输出
GTIM_SetCompare1(BSP_IN2_TIMER, speed );
}
else
{
//AO1输出
GTIM_SetCompare1(BSP_IN1_TIMER, speed );
//AO2输出
GTIM_SetCompare1(BSP_IN2_TIMER, 0 );
}
}
在文件bsp_L298N.h中,编写如下代码。
#ifndef _BSP_L298N_H
#define _BSP_L298N_H
#include "board.h"
#define RCC_L298N_GPIO_ENABLE() __RCC_GPIOA_CLK_ENABLE()
#define PORT_GPIO CW_GPIOA
#define GPIO_IN1 GPIO_PIN_6
#define GPIO_IN2 GPIO_PIN_7
#define GPIO_AF_IN1_ENABLE() PA06_AFx_GTIM3CH1();
#define GPIO_AF_IN2_ENABLE() PA07_AFx_GTIM4CH1();
#define RCC_IN1_TIMER_ENABLE() __RCC_GTIM3_CLK_ENABLE()
#define RCC_IN2_TIMER_ENABLE() __RCC_GTIM4_CLK_ENABLE()
#define BSP_IN1_TIMER CW_GTIM3
#define BSP_IN2_TIMER CW_GTIM4
#define BSP_PWM_CHANNEL GTIM_CHANNEL1
void L298N_Init(uint16_t ReloadValue);
void AO_Control(uint8_t dir, uint32_t speed);
#endif