#include "stdio.h" #include "string.h" #include "gpio.h" #include "AngleSensor.h" #define DATA_SIZE 6U /*! SPI发送和接收数组*/ uint8_t g_spiTxBuff1[DATA_SIZE] = {0}; uint8_t g_spiRxBuff1[DATA_SIZE] = {0}; static float angle_offset = 0.0; static float angle_raw = 0.0; /***************************/ void SPI0_Callback(void *device, uint32_t wpara, uint32_t lpara); void AngleSensor_Init(void) { SPI_ConfigType spiConfig; /*初始化SPI引脚,功能复用选择.*/ //GPIO_SetFunc(GPIOB, GPIO_PIN15, GPIO_FUN3);//SCK //GPIO_SetFunc(GPIOB, GPIO_PIN14, GPIO_FUN3);//MOSI //GPIO_SetFunc(GPIOC, GPIO_PIN0, GPIO_FUN3);//MISO //GPIO_SetFunc(GPIOC, GPIO_PIN1, GPIO_FUN3);//CS /*清零配置结构体变量.*/ memset(&spiConfig, 0x00, sizeof(spiConfig)); /*初始化SPI参数,波特率 = 2Mbps = (F_BCLK / (SCK_LOW+1 + SCK_HIGH+1)).*/ spiConfig.csSetup = 4;/*片选建立时间 = (CS_SETUP + 1) * CLK_PERIOD.*/ spiConfig.csHold = 4;/*片选保持时间 = (CS_HOLD + 1) * CLK_PERIOD.*/ spiConfig.sckHigh = 5;/*SCK高电平时间 = (SCK_HIGH + 1) * CLK_PERIOD.*/ spiConfig.sckLow = 5;/*SCK低电平时间 = (SCK_LOW + 1) * CLK_PERIOD.*/ spiConfig.csIdle = 3;/*两条数据间最短时间间隔 = (CS_IDLE + 1) * CLK_PERIOD.*/ spiConfig.mode = SPI_MASTER;//设置为主机模式 spiConfig.cpha = SPI_CPHA_2EDGE;//设置数据采样相位,第2个边沿采样数据 spiConfig.cpol = SPI_CPOL_LOW;//设置SCK空闲时极性,空闲时SCK为低 spiConfig.frmSize = SPI_FRAME_SIZE_16BITS; spiConfig.rxMsbFirstEn = ENABLE;//选择从最高位开始接收 spiConfig.txMsbFirstEn = ENABLE;//选择从最高位开始发送 spiConfig.csOutputEn = ENABLE;//CS有SPI硬件控制 spiConfig.continuousCSEn= ENABLE;//片选连续模式 spiConfig.dmaRxEn = DISABLE;//禁止使用DMA接收数据 spiConfig.dmaTxEn = DISABLE;//禁止使用DMA发送数据 spiConfig.modeFaultEn = DISABLE;//模式故障禁止 spiConfig.wakeUpEn = DISABLE;//主机模式不支持唤醒功能 spiConfig.spiEn = ENABLE; spiConfig.callBack = SPI0_Callback; spiConfig.interruptEn = ENABLE;//使能NVIC中断 spiConfig.txUFInterruptEn = ENABLE;//打开TXUF中断,可禁止 spiConfig.rxOFInterruptEn = ENABLE;//打开RXOF中断,可禁止 spiConfig.modeFaultInterruptEn = DISABLE;//模式故障中断 SPI_Init(SPI0, &spiConfig); while(AngleSensor_GetAngle() < 0){ mdelay(5); } } void AngleSensor_Setoffset(float offset) { angle_offset = offset; } float AngleSensor_GetAngle(void) { uint16_t angle_value; //uint8_t safeword =0; //uint8_t crc; float angle = 0.0; g_spiTxBuff1[0] = 0x21; g_spiTxBuff1[1] = 0x80; g_spiTxBuff1[2] = 0xFF; g_spiTxBuff1[3] = 0xFF; g_spiTxBuff1[4] = 0xFF; g_spiTxBuff1[5] = 0xFF; SPI_TransmitReceivePoll(SPI0, g_spiRxBuff1, g_spiTxBuff1, 6); angle_value = g_spiRxBuff1[3]&0x7F; //printf("g_spiRxBuff1[2]:0x%x, g_spiRxBuff1[3]:0x%x \r\n", g_spiRxBuff1[2], g_spiRxBuff1[3]); //printf("g_spiRxBuff1[4]:0x%x, g_spiRxBuff1[5]:0x%x \r\n", g_spiRxBuff1[4], g_spiRxBuff1[5]); angle_value = (angle_value<<8)|g_spiRxBuff1[2]; angle = (360.0*angle_value)/32768; if((g_spiRxBuff1[5]&0xF0) != 0x70){ angle = -180.0; }else{ angle_raw = angle; angle += angle_offset; if(angle > 360.0){ angle -= 360.0; } if(angle < 0.0){ angle += 360.0; } } return angle; } float AngleSensor_GetAngleRaw(void) { return angle_raw; } void AngleSensor_PrintInfo(void) { printf("AngleSensor angle:%f \r\n", AngleSensor_GetAngle()); } void AngleSensor_DeInit(void) { SPI_DeInit(SPI0); } /** * @prototype SPI1_Callback(void *device, uint32_t wpara, uint32_t lpara) * * @param[in] ... * @return void * * @brief SPI1中断回调函数. */ void SPI0_Callback(void *device, uint32_t wpara, uint32_t lpara) { if (wpara & SPI_STATUS_TXUF_Msk) { //TX下溢处理 } else if (wpara & SPI_STATUS_RXOF_Msk) { //RX溢出处理 } }