Files
LaserTracing/source/src/bsp.c
T
YuanHongbin 72844ff821 feat: 新增激光定时关闭与姿态角持续输出测试功能,编码转UTF-8
1. 激光定时自动关闭:默认10分钟,laser on启动计时,超时自动关并上报
2. laser time <min>可配置定时分钟数,0=关闭定时
3. att on/off持续输出姿态角(Pitch/Roll/Yaw),不注册不低功耗
4. 20个源文件从GB2312编码转为UTF-8 with BOM
2026-07-20 17:04:48 +08:00

953 lines
30 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <time.h>
#include <math.h>
#include "sysctrl.h"
#include "gpio.h"
#include "flash.h"
#include "bsp.h"
#include "lpuart.h"
#include "uart.h"
#include "lpm.h"
#include "lptim.h"
#include "spi.h"
#include "reset.h"
#include "wdt.h"
#include "rtc.h"
#include "i2c.h"
#include "bgr.h"
#include "adc.h"
#include "UartDebug.h"
#include "lsm6dsl_app.h"
#include "mmc5983.h"
#include "sx127x.h"
extern void LPUartRx_CallBack(uint8_t Rx);
extern void Uart1Rx_CallBack(uint8_t Rx);
extern void DebugUartIRQ(uint8_t Data);
extern void SysTick_CallBack(void);
extern void RtcIRQHander(void);
extern void LPTimer0IRQHander(void);
extern void LORA_RxCallBack(uint8_t *rBuff, uint8_t rlen);
static __IO uint32_t SysTickCnt = 0;
static volatile uint32_t u32AdcRestult;
static void SystemClkDivInit(void)//系统时钟分频设置
{
//时钟分频设置
Sysctrl_SetHCLKDiv(SysctrlHclkDiv1);
Sysctrl_SetPCLKDiv(SysctrlPclkDiv1);
}
static void SystemClkInit(en_sysctrl_rch_freq_t enRchFreq)//时钟初始化
{
///< RCH时钟不同频率的切换,需要先将时钟切换到RCL
Sysctrl_SetRCLTrim(SysctrlRclFreq38400);
Sysctrl_SetRCLStableTime(SysctrlRclStableCycle64);
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
/*内部高速时钟初始化 24MHZ*/
/*Sysctrl_SetRCHTrim(enRchFreq);
Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
//< HCLK不超过24M:此处设置FLASH读等待周期为0 cycle
Flash_WaitCycle(FlashWaitCycle0);
Sysctrl_SysClkSwitch(SysctrlClkRCH);//系统时钟源选择
*/
/*内部高速时钟初始化 48MHZ*/
stc_sysctrl_pll_cfg_t stcPLLCfg;
///< 加载目标频率的RCH的TRIM值
Sysctrl_SetRCHTrim(SysctrlRchFreq4MHz);
///< 使能RCH
Sysctrl_ClkSourceEnable(SysctrlClkRCH, TRUE);
stcPLLCfg.enInFreq = SysctrlPllInFreq4_6MHz; //RCH 4MHz
stcPLLCfg.enOutFreq = SysctrlPllOutFreq36_48MHz; //PLL 输出
stcPLLCfg.enPllClkSrc = SysctrlPllRch; //输入时钟源选择RCH
stcPLLCfg.enPllMul = SysctrlPllMul12; //4MHz x 12 = 48MHz
Sysctrl_SetPLLFreq(&stcPLLCfg);
///< 当使用的时钟源HCLK大于24M:设置FLASH 读等待周期为1 cycle(默认值也为1 cycle)
Flash_WaitCycle(FlashWaitCycle1);
///< 使能PLL
Sysctrl_ClkSourceEnable(SysctrlClkPLL, TRUE);
///< 时钟切换到PLL
Sysctrl_SysClkSwitch(SysctrlClkPLL);
/*外部低速晶振初始化 32.768KHz*/
/* Sysctrl_XTLDriverCfg(SysctrlXtlAmp3, SysctrlXtalDriver3);
Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384);
Sysctrl_ClkSourceEnable(SysctrlClkXTL, TRUE);
*/
}
static void SystemRCLInit(void)
{
Sysctrl_SetRCLTrim(SysctrlRclFreq38400); ///< 配置RCL时钟为38400kHz
Sysctrl_SetRCLStableTime(SysctrlRclStableCycle256);
Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE); ///< 使能RCL时钟
}
void Uart0Init(uint32_t Baud)
{
stc_gpio_cfg_t stcGpioCfg;
stc_uart_cfg_t stcCfg;
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
///<TX
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(UART0_TX_PORT, UART0_TX_PIN, &stcGpioCfg);
Gpio_SetAfMode(UART0_TX_PORT, UART0_TX_PIN, GpioAf1);
//<RX
stcGpioCfg.enDir = GpioDirIn;
stcGpioCfg.enPu = GpioPuEnable;
Gpio_Init(UART0_RX_PORT, UART0_RX_PIN, &stcGpioCfg);
Gpio_SetAfMode(UART0_RX_PORT, UART0_RX_PIN, GpioAf1);
DDL_ZERO_STRUCT(stcCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,TRUE);
///<UART 初始化
stcCfg.enStopBit = UartMsk1bit; ///<1停止位
// stcCfg.enMmdorCk = UartMskEven; ///<偶校验
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<PCLK获取
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<采样分频
stcCfg.stcBaud.u32Baud = Baud; ///<波特率
stcCfg.enRunMode = UartMskMode1; ///<工作模式
Uart_Init(M0P_UART0, &stcCfg);
///<UART 中断使能
Uart_ClrStatus(M0P_UART0, UartRC); ///<清接收中断请求
Uart_ClrStatus(M0P_UART0, UartTC); ///<清发送中断请求
//Uart_EnableIrq(M0P_UART1,UartTxIrq); ///<使能发送中断
Uart_EnableIrq(M0P_UART0, UartRxIrq); ///<使能接收中断
EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE); ///<系统中断使能
}
static void Uart1Init(void)
{
stc_gpio_cfg_t stcGpioCfg;
stc_uart_cfg_t stcCfg;
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
///<TX
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(UART1_TX_PORT, UART1_TX_PIN, &stcGpioCfg);
Gpio_SetAfMode(UART1_TX_PORT, UART1_TX_PIN, GpioAf3);
//<RX
stcGpioCfg.enDir = GpioDirIn;
stcGpioCfg.enPu = GpioPuEnable;
Gpio_Init(UART1_RX_PORT, UART1_RX_PIN, &stcGpioCfg);
Gpio_SetAfMode(UART1_RX_PORT, UART1_RX_PIN, GpioAf3);
DDL_ZERO_STRUCT(stcCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE);
///<UART 初始化
stcCfg.enStopBit = UartMsk1bit; ///<1停止位
//stcCfg.enMmdorCk = UartMskEven; ///<偶校验
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<PCLK获取
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<采样分频
stcCfg.stcBaud.u32Baud = 115200; ///<波特率
stcCfg.enRunMode = UartMskMode1; ///<工作模式
Uart_Init(M0P_UART1, &stcCfg);
///<UART 中断使能
Uart_ClrStatus(M0P_UART1, UartRC); ///<清接收中断请求
Uart_ClrStatus(M0P_UART1, UartTC); ///<清发送中断请求
//Uart_EnableIrq(M0P_UART1,UartTxIrq); ///<使能发送中断
Uart_EnableIrq(M0P_UART1, UartRxIrq); ///<使能接收中断
EnableNvic(UART1_3_IRQn, IrqLevel3, TRUE); ///<系统中断使能
}
void LpUart0Init(uint32_t Baud)
{
stc_gpio_cfg_t stcGpioCfg;
stc_lpuart_cfg_t stcCfg;
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
///<TX
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(LPUart0_TxPortx,LPUART0_TxPinx,&stcGpioCfg);
Gpio_SetAfMode(LPUart0_TxPortx,LPUART0_TxPinx,GpioAf4); //配置PB10为LPUART0_TX
//<RX
stcGpioCfg.enDir = GpioDirIn;
Gpio_Init(LPUart0_RxPortx,LPUART0_RxPinx,&stcGpioCfg);
Gpio_SetAfMode(LPUart0_RxPortx,LPUART0_RxPinx,GpioAf3); //配置PB11为LPUART0_RX
DDL_ZERO_STRUCT(stcCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralLpUart0,TRUE);
///<LPUART 初始化
stcCfg.enStopBit = LPUart1bit; ///<1停止位
//stcCfg.enMmdorCk = LPUartEven; ///<偶校验
stcCfg.stcBaud.enSclkSel = LPUartMskRcl; ///<传输时钟源
stcCfg.stcBaud.u32Sclk = 38400; ///<PCLK获取
stcCfg.stcBaud.enSclkDiv = LPUartMsk4Or8Div; ///<采样分频
stcCfg.stcBaud.u32Baud = Baud; ///<波特率
stcCfg.enRunMode = LPUartMskMode1; ///<工作模式
LPUart_Init(M0P_LPUART0, &stcCfg);
///<LPUART 中断使能
LPUart_ClrStatus(M0P_LPUART0,LPUartRC); ///<清接收中断请求
LPUart_ClrStatus(M0P_LPUART0,LPUartTC); ///<清发送中断请求
//LPUart_EnableIrq(M0P_LPUART0,LPUartTxIrq); ///<使能发送中断
LPUart_EnableIrq(M0P_LPUART0,LPUartRxIrq); ///<使能接收中断
EnableNvic(LPUART0_IRQn,IrqLevel3,TRUE); ///<系统中断使能
}
/*****************************************************************************************
* 函数名称: AdcInit
* 功能描述: ADC初始化
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
static void AdcInit(void)
{
///< 开启ADC/BGR GPIO外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
Gpio_SetAnalogMode(VBAT_PORTx, VBAT_PINx); //PA04 (AIN4)
stc_adc_cfg_t stcAdcCfg;
DDL_ZERO_STRUCT(stcAdcCfg);
///< 开启ADC/BGR外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
Bgr_BgrEnable(); ///< 开启BGR
///< ADC 初始化配置
stcAdcCfg.enAdcMode = AdcSglMode; ///<采样模式-单次
stcAdcCfg.enAdcClkDiv = AdcMskClkDiv8; ///<采样分频-1
stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle12Clk; ///<采样周期数-12
stcAdcCfg.enAdcRefVolSel = AdcMskRefVolSelAVDD; ///<参考电压选择-AVDD
stcAdcCfg.enAdcOpBuf = AdcMskBufEnable; ///<OP BUF配置-关
stcAdcCfg.enInRef = AdcMskInRefDisable; ///<内部参考电压使能-关
stcAdcCfg.enAdcAlign = AdcAlignRight; ///<转换结果对齐方式-右
Adc_Init(&stcAdcCfg);
Adc_CfgSglChannel(VBAT_ADC_PORTx); // 配置单次采样通道
Adc_SGL_Always_Start(); // 启动单次一直采样
}
/*****************************************************************************************
* 函数名称: Battery_Level_Percent_Table
* 功能描述: 电池电量百分比转换
* 参 数: voltage,采集到的电压
* 返 回 值: 无
*****************************************************************************************/
static float Battery_Level_Percent_Table[37] = {9000, 9100, 9200, 9300, 9400, 9500, 9600, 9700, 9800, 9900,
10000, 10100, 10200, 10300, 10400, 10500, 10600, 10700, 10800, 10900,
11000, 11100, 11200, 11300, 11400, 11500, 11600, 11700, 11800, 11900,
12000, 12100, 12200, 12300, 12400, 12500, 12600};
static int Percentage(float voltage)
{
if(voltage < Battery_Level_Percent_Table[0])
return 0;
for(uint8_t i = 0; i < 37; i++)
{
if(voltage <= Battery_Level_Percent_Table[i])
{
return (int)((Battery_Level_Percent_Table[i] - Battery_Level_Percent_Table[0]) / (Battery_Level_Percent_Table[36] - Battery_Level_Percent_Table[0]) * 100);
}
}
return 100;
}
/*****************************************************************************************
* 函数名称: ADC_IRQHandler
* 功能描述: ADC采集中断,放在主循环内一直循环采集
* 参 数: 无
* 返 回 值: 无
*****************************************************************************************/
float VBAT_12V;//< ADC采集到的电压
uint8_t VBAT_Percentage;//电池电压百分比
void ADCLoopHandler(void)
{
if(Adc_GetIrqStatus(AdcMskIrqSgl))//ADC中断状态获取
{
VBAT_12V = (Adc_GetSglResult() * VBAT_CAL);//< 获取实际电压
VBAT_Percentage = Percentage(VBAT_12V);//获取百分比
//DBG_LOG("VBAT_Percentage:%d\n",VBAT_Percentage);
Adc_ClrIrqStatus(AdcMskIrqSgl);//清除ADC中断状态
}
}
void RTCInit(uint8_t sec)
{
stc_rtc_initstruct_t RtcInitStruct;
Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc,TRUE); //RTC模块时钟打开
RtcInitStruct.rtcAmpm = RtcPm; //24小时制
RtcInitStruct.rtcClksrc = RtcClkRcl; //外部低速时钟
RtcInitStruct.rtcPrdsel.rtcPrdsel = RtcPrdx; //周期中断类型PRDX
RtcInitStruct.rtcPrdsel.rtcPrdx = sec * 2 - 1; //周期中断时间间隔 30秒
Rtc_ReadDateTime(&RtcInitStruct.rtcTime);
if(RtcInitStruct.rtcTime.u8Year < 0x23 || RtcInitStruct.rtcTime.u8Year > 0x99 || RtcInitStruct.rtcTime.u8Month > 0x12) {
RtcInitStruct.rtcTime.u8Second = 0x30;
RtcInitStruct.rtcTime.u8Minute = 0x38;
RtcInitStruct.rtcTime.u8Hour = 0x08;
RtcInitStruct.rtcTime.u8Day = 0x02;
RtcInitStruct.rtcTime.u8DayOfWeek = 0x06;
RtcInitStruct.rtcTime.u8Month = 0x09;
RtcInitStruct.rtcTime.u8Year = 0x23;
}
RtcInitStruct.rtcCompen = RtcCompenEnable;
RtcInitStruct.rtcCompValue = 0; //补偿值 根据实际情况进行补偿
Rtc_Init(&RtcInitStruct);
Rtc_AlmIeCmd(TRUE); //使能闹钟中断
EnableNvic(RTC_IRQn, IrqLevel3, TRUE); //使能RTC中断向量
Rtc_Cmd(TRUE); //使能RTC开始计数
Rtc_StartWait(); //启动RTC计数,如果要立即切换到低功耗,需要执行此函数
}
/******************************************************************************
* 函数名称: LPTimer0Init
* 功能描述: 低功耗定时器0初始化
* 参 数: sTime 定时中断秒时间
* 返 回 值: 无
******************************************************************************/
void LPTimer0Init(uint16_t _100ms)
{
Lptim_Cmd(M0P_LPTIMER0, FALSE);
stc_lptim_cfg_t stcLptCfg;
DDL_ZERO_STRUCT(stcLptCfg);
///< 使能LPTIM0 外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralLpTim0, TRUE);
stcLptCfg.enPrs = LptimPrsDiv256;
stcLptCfg.enGate = LptimGateLow;
stcLptCfg.enGatep = LptimGatePLow;
stcLptCfg.enTcksel = LptimRcl;
stcLptCfg.enTogen = LptimTogEnLow;
stcLptCfg.enCt = LptimTimerFun; //警示器功能
stcLptCfg.enMd = LptimMode1; //工作模式为模式1:无自动重装载16位计数器/定时器
stcLptCfg.u16Arr = 0x10000 - (_100ms * 13); //预装载寄存器值
Lptim_Init(M0P_LPTIMER0, &stcLptCfg);
Lptim_ClrItStatus(M0P_LPTIMER0); //清除中断标志位
Lptim_ConfIt(M0P_LPTIMER0, TRUE); //允许LPTIMER中断
EnableNvic(LPTIM_0_1_IRQn, IrqLevel3, TRUE);
Lptim_Cmd(M0P_LPTIMER0, TRUE);
}
void LPTimer0_ON(uint16_t _100ms)
{
LPTimer0Init(_100ms);
}
void LPTimer0_OFF(void)
{
EnableNvic(LPTIM_0_1_IRQn, IrqLevel3, FALSE);
Lptim_Cmd(M0P_LPTIMER0, FALSE);
}
static void GPIOInit(void)
{
stc_gpio_cfg_t GpioInitStruct;
DDL_ZERO_STRUCT(GpioInitStruct);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
//未使用或引出的脚设为输入上拉
GpioInitStruct.enDir = GpioDirIn;
GpioInitStruct.enPu = GpioPuEnable;
Gpio_Init(GpioPortA, GpioPin0, &GpioInitStruct);
Gpio_Init(GpioPortA, GpioPin1, &GpioInitStruct);
Gpio_Init(GpioPortA, GpioPin2, &GpioInitStruct);
Gpio_Init(GpioPortA, GpioPin5, &GpioInitStruct);
Gpio_Init(GpioPortA, GpioPin6, &GpioInitStruct);
Gpio_Init(GpioPortA, GpioPin7, &GpioInitStruct);
Gpio_Init(GpioPortA, GpioPin8, &GpioInitStruct);
Gpio_Init(GpioPortB, GpioPin2, &GpioInitStruct);
Gpio_Init(GpioPortB, GpioPin8, &GpioInitStruct);
Gpio_Init(GpioPortB, GpioPin9, &GpioInitStruct);
Gpio_Init(GpioPortB, GpioPin15, &GpioInitStruct);
Gpio_Init(GpioPortF, GpioPin6, &GpioInitStruct);
//end
/********************************** GPIO输出 ****************************************/
GpioInitStruct.enDir = GpioDirOut; ///< 端口方向配置->输出
GpioInitStruct.enDrv = GpioDrvH; ///< 端口驱动能力配置->高驱动能力
GpioInitStruct.enPu = GpioPuDisable; ///< 端口上下拉配置->无
GpioInitStruct.enPd = GpioPdDisable;
GpioInitStruct.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭
GpioInitStruct.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB
GpioInitStruct.bOutputVal = false; ///< 端口默认输出配置->低电平
//< RS485控制引脚
Gpio_Init(RS485_CTRL_PORTx,RS485_CTRL_PINx,&GpioInitStruct);
//< 激光控制引脚
Gpio_Init(LASER1_ON_OFF_PORTx,LASER1_ON_OFF_PINx,&GpioInitStruct);
Gpio_Init(LASER2_ON_OFF_PORTx,LASER2_ON_OFF_PINx,&GpioInitStruct);
Gpio_Init(LASER3_ON_OFF_PORTx,LASER3_ON_OFF_PINx,&GpioInitStruct);
//< ADC???????
Gpio_Init(AD_ON_OFF_PORTx,AD_ON_OFF_PINx,&GpioInitStruct);
GpioInitStruct.bOutputVal = true; ///< 端口默认输出配置->高电平
//< LORA --> RST
Gpio_Init(LORA_RST_PORTx,LORA_RST_PINx,&GpioInitStruct);
//< LED_State
Gpio_Init(LED_STATE_PORTx,LED_STATE_PINx,&GpioInitStruct);
/********************************** GPIO输入 ****************************************/
GpioInitStruct.enDir = GpioDirIn; ///< 端口方向配置->输入
GpioInitStruct.enPu = GpioPuDisable; ///< 端口上下拉配置->无
GpioInitStruct.enPd = GpioPdDisable;
GpioInitStruct.enOD = GpioOdDisable;
//< LORA --> DIO0
Gpio_Init(LORA_DIO0_PORTx,LORA_DIO0_PINx,&GpioInitStruct);
//< LORA --> DIO0
Gpio_Init(LORA_DIO1_PORTx,LORA_DIO1_PINx,&GpioInitStruct);
//< ACC_INT1
Gpio_Init(LSM6DSLTR_INT1_PORTx,LSM6DSLTR_INT1_PINx,&GpioInitStruct);
//< ACC_INT2
Gpio_Init(LSM6DSLTR_INT2_PORTx,LSM6DSLTR_INT2_PINx,&GpioInitStruct);
//< MMC_INT
Gpio_Init(MMC5983MA_INT_PORTx,MMC5983MA_INT_PINx,&GpioInitStruct);
GlobalIntEnable();
}
void GlobalIntEnable(void)//全局中断使能
{
EnableNvic(PORTB_IRQn, IrqLevel3, TRUE);
EnableNvic(PORTC_E_IRQn, IrqLevel3, TRUE);
}
void GlobalIntDisable(void)//全局中断失能
{
EnableNvic(PORTB_IRQn, IrqLevel3, FALSE);
EnableNvic(PORTC_E_IRQn, IrqLevel3, FALSE);
}
void LORAIntEnable(void)//LORA中断使能
{
Gpio_EnableIrq(LORA_DIO0_PORTx, LORA_DIO0_PINx, GpioIrqRising);//LORA_DIO0
Gpio_EnableIrq(LORA_DIO1_PORTx, LORA_DIO1_PINx, GpioIrqRising);//LORA_DIO1
}
void LORAIntDisable(void)//LORA中断失能
{
Gpio_DisableIrq(LORA_DIO0_PORTx, LORA_DIO0_PINx, GpioIrqRising);
Gpio_DisableIrq(LORA_DIO1_PORTx, LORA_DIO1_PINx, GpioIrqRising);
}
void ACCandMMCIntEnable(void)//加速度和地磁中断使能
{
Gpio_EnableIrq(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx, GpioIrqRising);//ACC_Int1
Gpio_EnableIrq(LSM6DSLTR_INT2_PORTx, LSM6DSLTR_INT2_PINx, GpioIrqRising);//ACC_Int2
Gpio_EnableIrq(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx, GpioIrqRising);//MMC_Int
}
void ACCandMMCIntDisable(void)//加速度和地磁中断失能
{
Gpio_DisableIrq(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx, GpioIrqRising);//ACC_Int1
Gpio_DisableIrq(LSM6DSLTR_INT2_PORTx, LSM6DSLTR_INT2_PINx, GpioIrqRising);//ACC_Int2
Gpio_DisableIrq(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx, GpioIrqRising);//MMC_Int
}
static void SPI0Init(void)
{
stc_gpio_cfg_t GpioInitStruct;
stc_spi_cfg_t SpiInitStruct;
DDL_ZERO_STRUCT(GpioInitStruct);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
/************************** SPI0配置:主机-->LORA *******************************/
GpioInitStruct.enDir = GpioDirOut;
Gpio_Init(SPI0_NSS_PORTx,SPI0_NSS_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI0_NSS_PORTx,SPI0_NSS_PINx,SPI0_NSS_AF); //配置SPI0_NSS
Gpio_Init(SPI0_SCK_PORTx,SPI0_SCK_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI0_SCK_PORTx,SPI0_SCK_PINx,SPI0_SCK_AF); //配置SPI0_SCK
Gpio_Init(SPI0_MOSI_PORTx,SPI0_MOSI_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI0_MOSI_PORTx,SPI0_MOSI_PINx,SPI0_MOSI_AF); //配置SPI0_MOSI
GpioInitStruct.enDir = GpioDirIn; ///< 端口方向配置->输入
Gpio_Init(SPI0_MISO_PORTx,SPI0_MISO_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI0_MISO_PORTx, SPI0_MISO_PINx,SPI0_MISO_AF); //配置SPI0_MISO
Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi0,TRUE); ///< 打开SPI0外设时钟
Reset_RstPeripheral0(ResetMskSpi0); ///<复位模块
//SPI0模块配置:主机
SpiInitStruct.enSpiMode = SpiMskMaster; //配置位主机模式
SpiInitStruct.enPclkDiv = SpiClkMskDiv4; //波特率:PCLK/4
SpiInitStruct.enCPHA = SpiMskCphasecond; //第二边沿采样
SpiInitStruct.enCPOL = SpiMskcpolhigh; //极性为高
Spi_Init(M0P_SPI0, &SpiInitStruct);
}
static void SPI1Init(void)
{
stc_gpio_cfg_t GpioInitStruct;
stc_spi_cfg_t SpiInitStruct;
DDL_ZERO_STRUCT(GpioInitStruct);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
/************************** SPI1配置:主机-->LORA *******************************/
GpioInitStruct.enDir = GpioDirOut;
Gpio_Init(SPI1_NSS_PORTx,SPI1_NSS_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI1_NSS_PORTx,SPI1_NSS_PINx,SPI1_NSS_AF); //配置SPI1_NSS
Gpio_Init(SPI1_SCK_PORTx,SPI1_SCK_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI1_SCK_PORTx,SPI1_SCK_PINx,SPI1_SCK_AF); //配置SPI1_SCK
Gpio_Init(SPI1_MOSI_PORTx,SPI1_MOSI_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI1_MOSI_PORTx,SPI1_MOSI_PINx,SPI1_MOSI_AF); //配置SPI1_MOSI
GpioInitStruct.enDir = GpioDirIn; ///< 端口方向配置->输入
Gpio_Init(SPI1_MISO_PORTx,SPI1_MISO_PINx,&GpioInitStruct);
Gpio_SetAfMode(SPI1_MISO_PORTx, SPI1_MISO_PINx,SPI1_MISO_AF); //配置SPI1_MISO
Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi1,TRUE); ///< 打开SPI0外设时钟
Reset_RstPeripheral0(ResetMskSpi1); ///<复位模块
//SPI1模块配置:主机
SpiInitStruct.enSpiMode = SpiMskMaster; //配置位主机模式
SpiInitStruct.enPclkDiv = SpiClkMskDiv2; //波特率:PCLK/2
SpiInitStruct.enCPHA = SpiMskCphasecond; //第二边沿采样
SpiInitStruct.enCPOL = SpiMskcpolhigh; //极性为高
Spi_Init(M0P_SPI1, &SpiInitStruct);
}
uint8_t Spi0SendReceive(uint8_t sData)
{
return Spi_RWByte(M0P_SPI0, sData);
}
uint8_t Spi1SendReceive(uint8_t sData)
{
return Spi_RWByte(M0P_SPI1, sData);
}
static void I2C0Init(void)
{
stc_gpio_cfg_t stcGpioCfg;
stc_i2c_cfg_t stcI2cCfg;
DDL_ZERO_STRUCT(stcI2cCfg);
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //开启GPIO时钟门控
stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出
stcGpioCfg.enOD = GpioOdEnable; ///< 开漏输出
stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能
stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止
stcGpioCfg.bOutputVal = TRUE;
Gpio_Init(I2C0_SCL_PORTx, I2C0_SCL_PINx, &stcGpioCfg); ///< 端口初始化
Gpio_SetAfMode(I2C0_SCL_PORTx, I2C0_SCL_PINx, I2C0_SCL_AF);
Gpio_Init(I2C0_SDA_PORTx, I2C0_SDA_PINx, &stcGpioCfg);
Gpio_SetAfMode(I2C0_SDA_PORTx, I2C0_SDA_PINx, I2C0_SDA_AF);
Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c0,TRUE); ///< 开启I2C0时钟门控
stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟
stcI2cCfg.u32Baud = 400000; ///< 1MHz
stcI2cCfg.enMode = I2cMasterMode; ///< 主机模式
stcI2cCfg.u8SlaveAddr = 0xD5; ///< 从地址,主模式无效
stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭
I2C_Init(M0P_I2C0, &stcI2cCfg); ///< 模块初始化
}
static void I2C1Init(void)
{
stc_gpio_cfg_t stcGpioCfg;
stc_i2c_cfg_t stcI2cCfg;
DDL_ZERO_STRUCT(stcI2cCfg);
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //开启GPIO时钟门控
stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出
stcGpioCfg.enOD = GpioOdEnable; ///< 开漏输出
stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能
stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止
stcGpioCfg.bOutputVal = TRUE;
Gpio_Init(I2C1_SCL_PORTx, I2C1_SCL_PINx, &stcGpioCfg); ///< 端口初始化
Gpio_SetAfMode(I2C1_SCL_PORTx, I2C1_SCL_PINx, I2C1_SCL_AF);
Gpio_Init(I2C1_SDA_PORTx, I2C1_SDA_PINx, &stcGpioCfg);
Gpio_SetAfMode(I2C1_SDA_PORTx, I2C1_SDA_PINx, I2C1_SDA_AF);
Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c1,TRUE); ///< 开启I2C1时钟门控
stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟
stcI2cCfg.u32Baud = 400000; ///< 1MHz
stcI2cCfg.enMode = I2cMasterMode; ///< 主机模式
stcI2cCfg.u8SlaveAddr = 0xD5; ///< 从地址,主模式无效
stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭
I2C_Init(M0P_I2C1, &stcI2cCfg); ///< 模块初始化
}
static void WdtInit(void)
{
#if (USE_WDT == 1)
///< 开启WDT外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralWdt,TRUE);
///< WDT 初始化
Wdt_Init(WdtResetEn, WdtT52s4);
Wdt_Start();
#endif
}
void FlashWrite(uint32_t Addr, uint32_t *wData, int wLen)
{
while(Ok != Flash_SectorErase(Addr));
for(int i = 0; i < wLen; i++) {
Flash_WriteWord(Addr + i * 4, wData[i]);
}
}
void FlashRead(uint32_t Addr, uint32_t *rData, int rLen)
{
uint32_t u32Addr = Addr;
for(int i = 0; i < rLen; i++) {
rData[i] = *((volatile uint32_t*)(u32Addr + i * 4));
}
}
void FeedDog(void)
{
#if (USE_WDT == 1)
Wdt_Feed();
#endif
}
static uint8_t BCDToDec(uint8_t bcd)
{
return ((bcd >> 4)& 0x0f) * 10 + (bcd & 0x0f);
}
static uint8_t DecToBCD(uint8_t Dec)
{
return (Dec / 10) << 4 | (Dec % 10);
}
void TimeGet(struct tm *cTime)
{
stc_rtc_time_t RtcDateTime;
Rtc_ReadDateTime(&RtcDateTime);
cTime->tm_year = BCDToDec(RtcDateTime.u8Year) + 100;
cTime->tm_mon = BCDToDec(RtcDateTime.u8Month) - 1;
cTime->tm_mday = BCDToDec(RtcDateTime.u8Day);
cTime->tm_hour = BCDToDec(RtcDateTime.u8Hour) + 8;
cTime->tm_min = BCDToDec(RtcDateTime.u8Minute);
cTime->tm_sec = BCDToDec(RtcDateTime.u8Second);
cTime->tm_isdst = 0;
}
uint32_t TimeTs(void)
{
struct tm cTime;
TimeGet(&cTime);
time_t cTimet = mktime(&cTime);
return cTimet;
}
void TimeShow(uint32_t dwStamp)
{
struct tm *stime;
stime = localtime(&dwStamp);
DBG_LOG("%d/",stime->tm_year + 1900);
DBG_LOG("%d/",stime->tm_mon + 1);
DBG_LOG("%d ",stime->tm_mday);
DBG_LOG("%d:",stime->tm_hour);
DBG_LOG("%d:",stime->tm_min);
DBG_LOG("%d\r\n",stime->tm_sec);
}
void TimeSync(time_t ts)
{
struct tm *td;
stc_rtc_time_t RtcDateTime;
td = localtime(&ts);
RtcDateTime.u8Year = DecToBCD(td->tm_year - 100);
RtcDateTime.u8Month = DecToBCD(td->tm_mon + 1);
RtcDateTime.u8Day = DecToBCD(td->tm_mday);
RtcDateTime.u8DayOfWeek = DecToBCD(td->tm_wday);
RtcDateTime.u8Hour = DecToBCD(td->tm_hour);
RtcDateTime.u8Minute = DecToBCD(td->tm_min);
RtcDateTime.u8Second = DecToBCD(td->tm_sec);
Rtc_SetTime(&RtcDateTime);
}
void PrintfMess(void)
{
DBG_LOG("\r\n");
uint32_t CT = TimeTs();
TimeShow(CT);
#if(USE_LED == 1)
LED_ON();
#endif
#if(USE_VBAT_AD == 1)
DBG_LOG("VBAT_Percentage:%d\r\n",VBAT_Percentage);
#endif
}
void DBGUartSendByte(uint8_t sData)
{
if(gDebugChannel == DBG_CH_RS485_1) {
LPUart_SendData(M0P_LPUART0, sData);
} else {
Uart_SendDataPoll(M0P_UART0, sData);
}
}
void DBGUartSend(uint8_t *sData, int sLen)
{
if(gDebugChannel == DBG_CH_RS485_1) {
LPUart0SendArray(sData, sLen);
} else {
for(int i = 0; i < sLen; i++) {
Uart_SendDataPoll(M0P_UART0, sData[i]);
}
}
}
void LPUart0SendArray(uint8_t *sData, uint8_t sLen)
{
RS485_CTRL_TX();
for(int i = 0; i < sLen; i++) {
LPUart_SendData(M0P_LPUART0, sData[i]);
}
RS485_CTRL_RX();
}
uint32_t GetSysTick(void)
{
return SysTickCnt;
}
void delay_us(uint32_t uS)//24MHz一个nop延时0.5us12MHz延时1us
{
uS *= 2;
while(uS--)
{
__NOP();
}
}
void delay_ms(uint32_t mS)
{
volatile uint32_t cTick, mTick;
cTick = GetSysTick();
while(1){
mTick = GetSysTick();
if(mTick - cTick >= mS)
break;
}
}
void SysTick_IRQHandler(void)
{
SysTickCnt++;
SysTick_CallBack();
}
void PortA_IRQHandler(void)
{
}
void PortB_IRQHandler(void)
{
//LORA DIO0
if(TRUE == Gpio_GetIrqStatus(LORA_DIO0_PORTx, LORA_DIO0_PINx)) {
Gpio_ClearIrq(LORA_DIO0_PORTx, LORA_DIO0_PINx);
Sx1276LoRaLoopHandler(); //lora
}
//LORA DIO1
if(TRUE == Gpio_GetIrqStatus(LORA_DIO1_PORTx, LORA_DIO1_PINx)) {
Gpio_ClearIrq(LORA_DIO1_PORTx, LORA_DIO1_PINx);
}
}
void PortC_IRQHandler(void)
{
//加速度INT1
if(TRUE == Gpio_GetIrqStatus(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx)) {
Gpio_ClearIrq(LSM6DSLTR_INT1_PORTx, LSM6DSLTR_INT1_PINx);
Lsm6dsInt1CallBack();
}
//地磁INT
if(TRUE == Gpio_GetIrqStatus(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx)) {
Gpio_ClearIrq(MMC5983MA_INT_PORTx, MMC5983MA_INT_PINx);
MMC5983IntCallBack();
}
}
///<LPUART0 中断服务函数
void LpUart0_IRQHandler(void)
{
if(LPUart_GetStatus(M0P_LPUART0, LPUartRC)) { ///接收数据
LPUart_ClrStatus(M0P_LPUART0, LPUartRC); ///<清接收中断请求
uint8_t u8RxData = LPUart_ReceiveData(M0P_LPUART0); ///读取数据
LPUartRx_CallBack(u8RxData);
DebugUartIRQ(u8RxData);
}
}
void Uart0_IRQHandler(void)
{
if(Uart_GetStatus(M0P_UART0, UartRC)) { ///接收数据
Uart_ClrStatus(M0P_UART0, UartRC); ///<清接收中断请求
uint8_t u8RxData = Uart_ReceiveData(M0P_UART0); ///读取数据
DebugUartIRQ(u8RxData);
}
}
void Rtc_IRQHandler(void)
{
if(Rtc_GetPridItStatus() == TRUE) {
Rtc_ClearPrdfItStatus(); //清除中断标志位
RtcIRQHander();
}
}
void LpTim0_IRQHandler(void)
{
if(Lptim_GetItStatus(M0P_LPTIMER0) == TRUE)
{
Lptim_ClrItStatus(M0P_LPTIMER0);//清除LPTimer0的中断标志位
LPTimer0IRQHander();
}
}
///<深度休眠模式外部端口配置(STK)
static void DeepSleepGPIOCfg(void)
{
stc_gpio_cfg_t GpioInitStruct;
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);
//低功耗状态下未使用的脚配置
//输入上拉
GpioInitStruct.enDir = GpioDirIn;
GpioInitStruct.enPu = GpioPuEnable;
Gpio_Init(SPI0_NSS_PORTx,SPI0_NSS_PINx,&GpioInitStruct);
Gpio_Init(SPI0_SCK_PORTx,SPI0_SCK_PINx,&GpioInitStruct);
Gpio_Init(SPI0_MISO_PORTx,SPI0_MISO_PINx,&GpioInitStruct);
//输入下拉
GpioInitStruct.enDir = GpioDirIn;
GpioInitStruct.enPd = GpioPdEnable;
Gpio_Init(SPI0_MOSI_PORTx,SPI0_MOSI_PINx,&GpioInitStruct);
}
void EnterDeepSleep(void)
{
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
//< LORA
Sx1276LoRaSleep();//Lora睡眠
LORAIntDisable();//关闭LORA中断
ACCandMMCIntDisable();//关闭加速度和地磁中断
#if (USE_VBAT_AD == 1)//< AD
AD_OFF();
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE);
Sysctrl_ClkSourceEnable(SysctrlClkPLL,FALSE);
Bgr_BgrDisable(); ///< 关闭BGR
Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, FALSE);
Adc_SGL_Stop();//关闭单次采样
#endif
#if (USE_SPI0 == 1)
Sysctrl_SetPeripheralGate(SysctrlPeripheralSpi0,FALSE);//关闭SPI0外设时钟
#endif
#if (USE_UART0 == 1)
EnableNvic(UART0_2_IRQn, IrqLevel3, false);
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0,FALSE); //关闭UART0时钟
#endif
DeepSleepGPIOCfg();
Lpm_GotoDeepSleep(FALSE);
}
void WakeUpInit(void)
{
SystemClkDivInit();
SystemClkInit(SysctrlRchFreq24MHz);
GPIOInit();
#if (USE_VBAT_AD == 1)//< AD
AD_ON();
AdcInit();
#endif
#if (USE_UART0 == 1)
Uart0Init(500000);
#endif
#if (USE_SPI0 == 1)
SPI0Init();
#endif
#if (USE_WDT == 1)//< WDT
WdtInit();
#endif
LORAIntEnable();//开启LORA中断
Sx1276LoRaWakeup();//LORA唤醒
ACCandMMCIntEnable();//开启加速度和地磁中断
SysTick_Config(SystemCoreClock/1000);
}
void SystemReset(void)
{
NVIC_SystemReset();
}
void BspInit(void)
{
SystemClkDivInit();
SystemClkInit(SysctrlRchFreq24MHz);
GPIOInit();
#if (USE_VBAT_AD == 1)//< AD
AD_ON();
AdcInit();
#endif
#if (USE_UART0 == 1)//< DEBUG
Uart0Init(500000);
#endif
#if (USE_RTC == 1)//< RTC
RTCInit(30);
#endif
#if (USE_WDT == 1)//< WDT
WdtInit();
#endif
#if (USE_SPI0 == 1)
SPI0Init();
#endif
#if (USE_SPI1 == 1)
SPI1Init();
#endif
#if (USE_LPUART0 == 1)//< LPUART0
LpUart0Init(9600);
#endif
#if(USE_I2C0 == 1)
I2C0Init();
#endif
#if(USE_I2C1 == 1)
I2C1Init();
#endif
SysTick_Config(SystemCoreClock/1000);
while(Ok != Flash_Init(6, TRUE));
}