@21小跑堂
要制作的小车,预定是通过手机驱动小车的装置,为了能显示通讯信息,给开发板配置了一个LCD。这块LCD的接口采用SPI模式。开发板本身是提供了SPI接口设备的。根据CW32F030数据手册,SPI1使用APB3总线, 但是在实际测试SPI_Simplex_Interrupt例程时发现,SPI设备实际使用APB2总线时钟。 如果想使用SPI1的CS自动输出,按照文档,需要GPIO的AF复用功能, 但在gpio库中定义如下: 使用的是AFR9和AFR15,也与数据手册说明的不一致。另外根据例程SPI_FLASH,在使用CS功能的时候,即使是设置了“片选信号由SSI寄存器控制” /**
* [url=home.php?mod=space&uid=247401]@brief[/url] 软件内部配置NSS
*
* @param SPIx :SPIx外设
* 参数可以是:
* CW_SPI1、CW_SPI2
* @param SPI_NSSInternalSoft :NSS状态
* 参数可以是:
* [url=home.php?mod=space&uid=2817080]@ARG[/url] SPI_NSSInternalSoft_Set: Set NSS
* @arg SPI_NSSInternalSoft_Reset: Reset NSS
* @note
* -SPIx_CR1.SSM = 1时有效,即软件NSS(SPI_InitStruct->SPI_NSS = SPI_NSS_Soft)
* -主机时:0 - CS输出低 1 - CS输出高
* -从机时:0 - 本机被选中 1 - 本机未被选中
*/
void SPI_NSSInternalSoftwareConfig(SPI_TypeDef* SPIx, uint8_t SPI_NSSInternalSoft) {
assert_param(IS_SPI_ALL_PERIPH(SPIx));
assert_param(IS_SPI_NSS_INTERNAL(SPI_NSSInternalSoft));
SPIx->SSI = SPI_NSSInternalSoft;
}
我的理解是:对于主机模式,应该在SPI发送数据时,CS自动由SSI寄存器发出低电平,从而控制从设备。但从测试结果看,不成功。原因还在调查中。并且在SPI_FLASH例程中,依然是显式地通过代码控制CS对应的GPIO输出低电平,达到允许从设备接收数据的目的。见以下代码: /**
* @brief 向FLASH发送 写使能 指令
*
*/
void SPI_FLASH_WriteEnable(void)
{
FLASH_SPI_CS_LOW();
//发送 写使能 指令
SPI_FLASH_SendByte(FLASH_CMD_WriteEnable);
FLASH_SPI_CS_HIGH();
}
至此,我暂时放弃了以SPI设备驱动LCD的方式(以后有时间,还是要调通的),仍然选择了传统的以GPIO模拟SPI的方式驱动LCD液晶屏。 使用以下GPIO口: // SCK = LCD-D0 紫色 PC1
#define LCD_GPIO_CLK_ENABLE() __RCC_GPIOA_CLK_ENABLE()
#define PIN_LCD25696_SCK GPIO_PIN_7
#define PORT_LCD25696_SCK CW_GPIOA
// 蓝色 PC0 SDA = LCD-D1/D2/D3连接起来作为SDA;D4/D5/D6/D7接VDD
#define PIN_LCD25696_SDA GPIO_PIN_6
#define PORT_LCD25696_SDA CW_GPIOA
// 绿色 LCD-CS : 片选 PE5, LED3
#define PIN_LCD25696_CS GPIO_PIN_5
#define PORT_LCD25696_CS CW_GPIOA
// 黄色 LCD-RESET : 复位 PA3
#define PIN_LCD25696_RESET GPIO_PIN_4
#define PORT_LCD25696_RESET CW_GPIOA
// 橙色 LCD-RS : 指令、数据寄存器选择 PA7
#define PIN_LCD25696_RS GPIO_PIN_3
#define PORT_LCD25696_RS CW_GPIOA
测试过程中发现,SPI设备有“发送缓冲区空”中断,没有“发送完成”中断。如果程序中设置了许可SPI的发送缓冲区空中断,那么程序运行时,即使从来没有通过SPI发送任何数据,这个中断依旧会不断发生,并且只能通过向SPI的数据寄存器赋值来清除这个中断。而LCD显示处理过程中,由于需要模拟SCK以及数据的串行输出处理,如果这个过程中出现中断,会导致显示异常。所以在处理LCD显示数据的时候,一定要禁止所有中断,在显示完成后再开放中断。 在LCD驱动成功后,接着追加了控制小车电机的处理,主要是驱动电机正反转。以GPIO方式输出控制信号,其实还是很简单的。我是用了一款专门用于驱动电机的模块,采用L9110集成块,L9110S是为控制和驱动电机设计的两通道推挽式功率放大专用集成电路器件,将分立电路集成在单片IC之中,使外围器件成本降低,整机可靠性提高。该芯片有两个TTL/CMOS兼容电平的输入,具有良好的抗干扰性;两个输出端能直接驱动电机的正反向运动,它具有较大的电流驱动能力,每通道能通过800mA的持续电流,峰值电流能力可达1.5A;同时它具有较低的输出饱和压降;内置的钳位二极管能释放感性负载的反向冲击电流,使它在驱动继电器、直流电机、步进电机或开关功率管的使用上安全可靠。模块如下图所示:
我的小车是两个车轮搭配一个万向转脚保持平衡的,有两个驱动电机分别驱动左右轮,用这个模块刚刚好。模块的电气属性如下: 因为使用普通电机,和这个模块接线非常简单,在程序不动的情况下,输出接线简单对调就能改变正反转,非常好用。为了方便小车运动状态的调整,设置了小车向前、向后、向左、向右,快速向左、快速向右的运动处理。操控部分,计划使用手机通过WIFI模块向开发板发出控制信号,再通过GPIO口和电机驱动板驱动车轮。目前WIFI处理部分还没有处理,所以在编写好电机驱动驱动部分的代码后,暂时通过串口向开发板发送控制信号。 在调试串口时,发现开发板提供的串口插座并不能使用,这个串口连向哪些GPIO口,我也没有细查。最后是通过MCU的输出排针中PA08和PA09实现和计算机之间的串口通讯的。为了能顺利完成通讯,自己简单建立了一个通讯协议,以ATCx(x=0-9,A-Z)+换行符方式,设置转向、前进、后退以及以后可能的扩展指令(本来预定要追加速度控制的,通过给车轮电机追加PWM方式实现,但实现起来有一些繁琐,目前还没有处理)。 目前小车还处于程序调试状态,所以没有组装起来,看起来比较乱。 开发过程中,感觉提供的数据手册有参考价值,但不能完全作为开发依据,必须参照官方提供的例程。
|