/* ********************************************************************************************************* * IAR Development Kits * on the * * Nano130 * * Filename : spi_flash.c * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ #include "includes.h" // 片选 #define LIS2DH12_CS_LOW() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12) #define LIS2DH12_CS_HIGH() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12) // 加速度计ID uint8_t Accelero_ID = 0; // 运动状态(默认为1,万一加速度计有问题) volatile uint8_t Motion_Status = 1; // 运动检测:第一次需要定位 volatile uint8_t Motion_Detected = 1; typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; //**************************************** // 定义LIS2DH12内部地址 //**************************************** #define CTRL_REG1 0x20 #define CTRL_REG2 0x21 #define CTRL_REG3 0x22 #define CTRL_REG4 0x23 #define CTRL_REG5 0x24 #define CTRL_REG6 0x25 #define ACT_THS 0x3E #define ACT_DUR 0x3F #define WHO_AM_I 0x0F //地址寄存器(默认数值0x33,只读) uchar Single_WriteSPI(uchar REG_Address,uchar REG_data) { LIS2DH12_CS_LOW(); // Write Address *(__IO uint8_t *)&SPI2->DR = (REG_Address & 0x3F); while(!(SPI2->SR & SPI_SR_RXNE)); *(__IO uint8_t *)&SPI2->DR; // Write data *(__IO uint8_t *)&SPI2->DR = REG_data; while(!(SPI2->SR & SPI_SR_RXNE)); *(__IO uint8_t *)&SPI2->DR; LIS2DH12_CS_HIGH(); return 1; } uchar Single_ReadSPI(uchar REG_Address, uchar *REG_data) { LIS2DH12_CS_LOW(); // Read Address *(__IO uint8_t *)&SPI2->DR = ((REG_Address & 0x3F) | 0x80); while(!(SPI2->SR & SPI_SR_RXNE)); *(__IO uint8_t *)&SPI2->DR; // 提供Clock *(__IO uint8_t *)&SPI2->DR = 0; while(!(SPI2->SR & SPI_SR_RXNE)); *REG_data = *(__IO uint8_t *)&SPI2->DR; LIS2DH12_CS_HIGH(); return 1; } // 读取运动状态 void Accelero_ReadStatus(uint8_t int2_pin) { // 当前运动状态 Motion_Status = !int2_pin; // Active low PRINTF("\r\nHard Motion status = %d\r\n", Motion_Status); // 检测到了运动(需要重新定位) if(Motion_Status) Motion_Detected = 1; } /** * @brief EXTI line detection callback. * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line. * @retval None */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == LL_EXTI_LINE_10) { if(Wakeup_Sleeping) { SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); delay_ms(10); Vcc_Enable(); delay_ms(40); Wakeup_Sleeping = 0; printf("\nWakeup by Accelero ...\n"); } // 读取运动状态 Accelero_ReadStatus(LL_GPIO_IsInputPinSet(GPIOD, LL_GPIO_PIN_10)); } } // 加速度中断处理,本函数被【key.c】模块中【GPDEF_IRQHandler】函数调用 void Accelero_Init() { LL_EXTI_InitTypeDef EXTI_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); /**SPI2 GPIO Configuration PB13 ------> SPI2_SCK PB14 ------> SPI2_MISO PB15 ------> SPI2_MOSI */ GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_5; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); /**/ LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_12); /**/ GPIO_InitStruct.Pin = LL_GPIO_PIN_12; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; LL_GPIO_Init(GPIOB, &GPIO_InitStruct); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); /**/ LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTD, LL_SYSCFG_EXTI_LINE10); /**/ EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_10; EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE; EXTI_InitStruct.LineCommand = ENABLE; EXTI_InitStruct.Mode = LL_EXTI_MODE_IT; EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING; LL_EXTI_Init(&EXTI_InitStruct); /**/ LL_GPIO_SetPinPull(GPIOD, LL_GPIO_PIN_10, LL_GPIO_PULL_UP); /**/ LL_GPIO_SetPinMode(GPIOD, LL_GPIO_PIN_10, LL_GPIO_MODE_INPUT); } // 初始化LIS2DH12 void Accelero_Open() { LL_SPI_InitTypeDef SPI_InitStruct = {0}; LL_EXTI_InitTypeDef EXTI_InitStruct = {0}; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); /* SPI2 parameter configuration*/ SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT; SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2; SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; SPI_InitStruct.CRCPoly = 7; LL_SPI_Init(SPI2, &SPI_InitStruct); LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA); LL_SPI_DisableNSSPulseMgt(SPI2); LL_SPI_SetRxFIFOThreshold(SPI2, LL_SPI_RX_FIFO_TH_QUARTER); LL_SPI_Enable(SPI2); Single_WriteSPI(CTRL_REG1, 0x5F); //控制寄存器,(100Hz, Low-power mode,Enable XYZ) Single_WriteSPI(CTRL_REG2, 0x00); //控制寄存器,(High-pass filter disabled) Single_WriteSPI(CTRL_REG3, 0x00); //控制寄存器 Single_WriteSPI(CTRL_REG4, 0x00); //控制寄存器,(4-wire SPI,Self-test disabled, HR=0, FS= ±2g) Single_WriteSPI(CTRL_REG5, 0x00); //控制寄存器,(FIFO disabled) Single_WriteSPI(CTRL_REG6, 0x08); //控制寄存器,(Enable activity interrupt on INT2 pin) // Activate/Inactivate: 门限寄存器,(x 4g/250 mg) if(dcBuff.configDisplay.op_SEND_GPS_DATA) // 槽车最灵敏,只在行驶过程中判断 Single_WriteSPI(ACT_THS, 4); else if(dcBuff.configDisplay.op_USE_CAPACITY_SENSOR) // 杜瓦瓶最不灵敏(电池容量低) Single_WriteSPI(ACT_THS, 40); else // 罐箱 Single_WriteSPI(ACT_THS, 20); // Activate/Inactivate: 持续时间寄存器 Single_WriteSPI(ACT_DUR, 40); // 读出ID:测试通信是否正常 Accelero_CheckID(); NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); NVIC_EnableIRQ(EXTI15_10_IRQn); } // 读出ID放在Accelero_ID(检查加速度计是否正常) void Accelero_CheckID() { // 读出ID:测试通信是否正常 Single_ReadSPI(WHO_AM_I, &Accelero_ID); PRINTF("\r\nAccelero ID = 0x%02X\r\n", Accelero_ID); if(Accelero_ID == ACCELERO_ID) { Motion_Status = !LL_GPIO_IsInputPinSet(GPIOD, LL_GPIO_PIN_10); PRINTF("\r\nInit Motion status = %d\r\n", Motion_Status); } }