先踏踏实实的把stm32的外设串口,SPI搞清楚,不要眼高手低,看不起小事。用SPI通信将pixy的数据读出来,将数据用串口发到串口助手上,然后处理数据,利用STM32的定时器调节pwm,控制电机,先让小车跑起来,随后在写小车的程序,和调节PID参数
1.1阅读手册&.C源码:
使能串口外设时钟(挂在APB1下)所以调用
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState) 具体可以看一下RCC模块,和时钟树,总线架构。
初始化GPIO:这时要到GPIO模块来(PA9,PA10),复用功能

如果需要重映射配置AFIO寄存器;以串口一为例:AFIO_MAPR寄存器

初始化串口(usart):阅读源码:
typedef struct
{
uint32_t USART_BaudRate;
uint16_t USART_WordLength;
uint16_t USART_StopBits;
uint16_t USART_Parity;
uint16_t USART_Mode;
uint16_t USART_HardwareFlowControl;
} USART_InitTypeDef;
将串口的初始化的状态封装成一个结构体,就像GPIO模块那样,自己先定义这样一个结构体类型,赋值初始化,调用此函数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct)
USART_TypeDef* USARTx是一个结构体指针,它指向USART的首地址,结构体的内存字节对齐,和寄存器的地址一一对应
typedef struct
{
__IO uint16_t SR;
uint16_t RESERVED0; //填充用的,因为C语言结构体内存对齐原则。不然就和寄存器一一不对应了。
__IO uint16_t DR; //这里看看USART的寄存器地址映射图增强理解。
uint16_t RESERVED1;
__IO uint16_t BRR;
uint16_t RESERVED2;
__IO uint16_t CR1;
uint16_t RESERVED3;
__IO uint16_t CR2;
uint16_t RESERVED4;
__IO uint16_t CR3;
uint16_t RESERVED5;
__IO uint16_t GTPR;
uint16_t RESERVED6;
} USART_TypeDef;
开启串口一接受中断:
使能串口一:
编写串口中断函数:
串口发送数据:USART_SendData(USART_TypeDef* USARTx, uint16_t Data) //
1.2:中断向量控制器(NVIC):设置中断优先级:抢占优先级和子优先级;使用中断前,先要设置优先级分组,配置NVIC。
1.3:SPI外设模块使用:阅读源码&手册:
使能spi外设(APB1下)先使能外设模块时钟(和串口的套路差不多)pin要复用配置好GPIO的模式。初始化 最后使能外设模块。
SPI1-SPI3 SPI1和SPI3支持重映射,SPI2不支持重映射,默认PB12-PB15 (片选,SCK,SPI2_MISO,SPI2_MOSI)io配置:

51单片机模拟SPI时序操作ds1302(软件模拟)通过时序图模拟时序,通过位于,移位读出(写入)数据,注意高低位
typedef struct
{
uint16_t SPI_Direction; /*!< Specifies the SPI unidirectional or bidirectional data mode.单向双向数据模式
This parameter can be a value of @ref SPI_data_direction */
uint16_t SPI_Mode; /*!< Specifies the SPI operating mode. 主从模式
This parameter can be a value of @ref SPI_mode */
uint16_t SPI_DataSize; /*!< Specifies the SPI data size.
This parameter can be a value of @ref SPI_data_size */8或16位
uint16_t SPI_CPOL; /*!< Specifies the serial clock steady state.
This parameter can be a value of @ref SPI_Clock_Polarity */ //时钟的高低电平
uint16_t SPI_CPHA; /*!< Specifies the clock active edge for the bit capture.
This parameter can be a value of @ref SPI_Clock_Phase *///数据采样时从第一个还是第二个时 钟跳变开始
uint16_t SPI_NSS; /*!< Specifies whether the NSS signal is managed by
hardware (NSS pin) or by software using the SSI bit. This parameter can be a value of @ref SPI_Slave_Select_management */ //片选
uint16_t SPI_BaudRatePrescaler;
/*!< Specifies the Baud Rate prescaler value whch will be
used to configure the transmit and receive SCK clock.This parameter can be a value of @ref SPI_BaudRate_Prescaler.@note The communication clock is derived from the masterclock. The slave clock does not need to be set. *///波特率
uint16_t SPI_FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit.第一位是最高位还是最低位
This parameter can be a value of @ref SPI_MSB_LSB_transmission */
uint16_t SPI_CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. */
}SPI_InitTypeDef;
2.1:先明白Pixy的串行协议:SPI通信,在Data Out Port选项中设置:
一个数据16位,7个数据,共14字节的数据。
01 00 9B 00 7B 00 A4 00 23 00 55 AA 3A 01 01 00 EE 00 1F 00 1C 00 10 00 55 AA 55 AA
DC 01 01 00 9B 00 7E 00 A5 00 1D 00 55 AA 39 01 01 00 EE 00 20 00 1D 00 0D 00 55 AA
9A 00 7E 00 A5 00 1F 00 55 AA 36 01 01 00 EE 00 1E 00 1C 00 0D 00 55 AA 55 AA E4 01
A2 00 1F 00 55 AA 37 01 01 00 EE 00 1F 00 1C 00 0D 00 55 AA 55 AA D9 01 01 00 9B 00
这几串数据浪费了我4天时间,真坑。注意SPI与串口读出的数据开始标志数据不同,
学会用上位机配置好pixy。使用spi协议读出数据发给串口:
2.4:处理数据:

接下来用读到的pixy的数据就做你想做的事了。