瀏覽代碼

业务逻辑基本完成

guoqiang 1 年之前
父節點
當前提交
6ebc9d3691
共有 36 個文件被更改,包括 10211 次插入2093 次删除
  1. 127 0
      Device/AngleSensor.c
  2. 63 0
      Device/AngleSensor.h
  3. 137 0
      Device/Ds1302.c
  4. 74 0
      Device/Ds1302.h
  5. 187 0
      Device/Motor.c
  6. 69 0
      Device/Motor.h
  7. 472 0
      Device/W25Q64.c
  8. 191 0
      Device/W25Q64.h
  9. 250 0
      Device/adc.c
  10. 71 0
      Device/adc.h
  11. 64 20
      Device/gpio.c
  12. 43 11
      Device/gpio.h
  13. 307 0
      Device/pwm.c
  14. 66 0
      Device/pwm.h
  15. 77 20
      Device/timer.c
  16. 8 3
      Device/timer.h
  17. 27 27
      Device/uart.c
  18. 8 8
      Device/uart.h
  19. 1 1
      Device/watchdog.h
  20. 296 152
      Project/AirControlValve.uvguix.孙凯
  21. 195 19
      Project/AirControlValve.uvoptx
  22. 88 1
      Project/AirControlValve.uvprojx
  23. 5968 1715
      Project/JLinkLog.txt
  24. 183 0
      Project/RTE/Board_Support/AC78013MDQA/ac780x_debugout.c
  25. 2 0
      User/cfg.c
  26. 4 2
      User/cfg.h
  27. 43 9
      User/main.c
  28. 97 22
      User/main_task.c
  29. 50 0
      User/pid.c
  30. 69 0
      User/pid.h
  31. 374 60
      User/process.c
  32. 51 10
      User/process.h
  33. 210 7
      User/protocol.c
  34. 27 6
      User/protocol.h
  35. 215 0
      User/storage.c
  36. 97 0
      User/storage.h

+ 127 - 0
Device/AngleSensor.c

@@ -0,0 +1,127 @@
+#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};
+
+/*************<prototype>**************/
+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);
+	}
+
+}
+
+
+
+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;
+	}
+	
+	return angle;
+}
+
+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溢出处理
+	}
+	
+}
+
+

+ 63 - 0
Device/AngleSensor.h

@@ -0,0 +1,63 @@
+
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2018. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+
+/*************<start>******************/
+
+#ifndef ANGLESENSOR_H__
+#define ANGLESENSOR_H__
+
+#if 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "ac780x_spi.h"
+
+
+void AngleSensor_Init(void);
+float AngleSensor_GetAngle(void);
+void AngleSensor_PrintInfo(void);
+
+void AngleSensor_DeInit(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif 
+
+#endif //ANGLESENSOR_H__

+ 137 - 0
Device/Ds1302.c

@@ -0,0 +1,137 @@
+#include "Ds1302.h"
+#include "string.h"
+#include "gpio.h"
+#include "stdio.h"
+#include "ac780x_rtc.h"
+#include "ac780x.h"
+
+
+
+DateTime g_dateTime;
+
+/**
+ * RTCCallBackFunc
+ *
+ * @param[in]  wparam: reserved
+ * @param[in]  lparam: reserved
+ * @return 0: success, other: error value
+ *
+ * @brief  中断回调函数
+ * 改变LED输出,使得LED闪烁
+ */
+void RTCCallBackFunc(void *device, uint32_t wpara, uint32_t lpara)
+{
+	
+	if (wpara & RTC_SC_RPIF_Msk) //预分频中断
+	{
+	
+	}
+	if (wpara & RTC_SC_RTIF_Msk) //RTC溢出中断
+	{
+		//printf("g_timer0Cnt:%d \r\n", g_timer0Cnt);
+		DS1302_UpdateTime();
+	}	
+	
+}
+
+/**
+ * RTC_Timeout1s
+ *
+ * @param[in]  none
+ * @return   none
+ *
+ * @brief  配置RTC计时1S,时钟源为Bus clock
+ */
+void RTC_Timeout1s(void)
+{
+    uint32_t tmpMod = 239999;
+    uint32_t tmpPrescalerValue = 99;             //(99+1)*(239999+1)/24000000 = 1s
+    RTC_ConfigType RTCConfig;
+	
+		memset(&RTCConfig,0,sizeof(RTCConfig));
+
+    RTCConfig.clockSource = RTC_CLOCK_APB;                         //时钟源选择:0:Bus clk (demo板上总线时钟为24M);
+	                                                   //1: LSI 32KHz; 2: External OSC; 3:Internal 8M;
+    RTCConfig.periodValue = tmpMod;
+		RTCConfig.psrInterruptEn = DISABLE;
+    RTCConfig.rtcInterruptEn = ENABLE;
+    RTCConfig.psrValue = tmpPrescalerValue;      //time = (pre+1)*(mod+1)/clk
+    RTCConfig.rtcOutEn = DISABLE;
+    RTCConfig.callBack = RTCCallBackFunc;
+    RTC_Init(&RTCConfig);                        //配置RTC
+
+
+}
+
+
+
+
+void DS1302_Init(void)
+{
+
+	g_dateTime.year = 24;
+	g_dateTime.month = 7;
+	g_dateTime.day = 5;
+	g_dateTime.hour = 15;
+	g_dateTime.minute = 0;
+	g_dateTime.second = 0;
+	
+	RTC_Timeout1s();
+	
+
+}
+
+uint8_t Ds1302_ReadReg(uint8_t _address)
+{
+
+	
+	return 0;
+}
+
+
+void DS1302_SetTime(DateTime* pDateTime)
+{
+
+}
+
+
+void DS1302_UpdateTime()
+{
+	g_dateTime.second++;
+	if(g_dateTime.second >= 60){
+		g_dateTime.second=0;
+		g_dateTime.minute++;
+		if(g_dateTime.minute >= 60){
+			g_dateTime.minute=0;
+			g_dateTime.hour++;
+			if(g_dateTime.hour>= 24){
+					g_dateTime.hour=0;
+					g_dateTime.day++;
+			}
+		}
+	}
+	
+	//if(g_dateTime.day>= 3){
+	//
+	//}
+
+
+}
+
+
+void DS1302_PrintDateTime()
+{
+
+	
+		printf("DS1302 DateTime:[%d][%d][%d] \r\n", g_dateTime.hour, g_dateTime.minute, g_dateTime.second);
+
+}
+
+
+void DS1302_DeInit(void)
+{
+
+}
+
+
+

+ 74 - 0
Device/Ds1302.h

@@ -0,0 +1,74 @@
+
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2018. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+
+/*************<start>******************/
+
+#ifndef DS1302_H__
+#define DS1302_H__
+
+#if 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "ac780x_spi.h"
+
+typedef struct _datetime
+{
+    uint8_t year;
+    uint8_t month;
+    uint8_t day;
+    uint8_t hour;
+    uint8_t minute;
+    uint8_t second;
+}DateTime;
+
+extern DateTime g_dateTime;
+
+
+void DS1302_Init(void);
+void DS1302_SetTime(DateTime* pDateTime);
+void DS1302_UpdateTime();
+void DS1302_PrintDateTime();
+void DS1302_DeInit(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif 
+
+#endif //DS1302_H__

+ 187 - 0
Device/Motor.c

@@ -0,0 +1,187 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+/**********<Incldue>**********/
+
+
+
+#include "ac780x_gpio.h"
+#include "ac780x.h"
+#include "ac780x_timer.h"
+#include "ac780x_pwm.h"
+#include "Motor.h"
+/**********<Prototype>*********/
+
+/**********<Variable>*********/
+uint32_t g_positvePulse;///<pulse width positive value
+uint32_t g_negativePulse;///<pulse width negative value
+uint32_t g_freq;///<pulse width period value
+float g_duty;///<pulse duty value
+uint32_t g_hallStatus;///<hall status value
+uint32_t g_overFlowCount;//PWM1计数溢出中断
+/**
+* PWM1_CallBack
+*
+* @param[in] device: device pointer
+* @param[in] wpara: callback parameter
+* @param[in] lpara: callback parameter
+* @return none
+* @brief PWM CallBack
+*/
+void PWM1_CallBack(void *device, uint32_t wpara, uint32_t lpara)
+{
+    //PWM计数器溢出中断
+    if (wpara & PWM_INIT_CNTOF_Msk) 
+    {
+        g_overFlowCount ++;
+        //user add 
+    
+    }
+    //PWM通道中断
+    //通过判断回调返回的lpara对应PWM_STR_CHnSF_Msk位状态判断是否发生通道中断
+    if (lpara & PWM_STR_CHSF_Msk)
+    {
+        
+        //user add
+        //通道0中断
+        if (lpara & PWM_STR_CH0SF_Msk)
+        {
+            
+        }
+        //通道1中断
+        if (lpara & PWM_STR_CH1SF_Msk)
+        {
+            
+        }
+        
+        
+    }
+}
+
+
+/**
+*
+* @param[in] none
+*
+* @return none
+*
+* @brief Motor_Init
+*
+*/
+void Motor_Init(void)
+{
+    PWM_ConfigType pwmConfig;
+    PWM_ModulationConfigType initModeStruct;
+		PWM_IndependentChConfig independentChConfig[2];
+	
+		memset(&pwmConfig, 0, sizeof(pwmConfig));
+    memset(&initModeStruct, 0, sizeof(initModeStruct));
+	
+	  //MSP_PWM_Init(PWM1);
+	
+	  /* independent channel 2 configuration */
+    independentChConfig[0].channel = PWM_CH_2;
+    independentChConfig[0].chValue = 0;
+    independentChConfig[0].levelMode = PWM_HIGH_TRUE;
+    independentChConfig[0].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;
+    independentChConfig[0].interruptEn = DISABLE;
+    independentChConfig[0].initLevel = PWM_LOW_LEVEL;
+    independentChConfig[0].triggerEn = DISABLE;
+
+    /* independent channel 3 configuration */
+    independentChConfig[1].channel = PWM_CH_3;
+    independentChConfig[1].chValue = 0; //MOD_PWM>>1;
+    independentChConfig[1].levelMode = PWM_HIGH_TRUE;
+    independentChConfig[1].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;
+    independentChConfig[1].interruptEn = DISABLE;
+    independentChConfig[1].initLevel = PWM_LOW_LEVEL;
+    independentChConfig[1].triggerEn = DISABLE;
+
+    initModeStruct.countMode = PWM_UP_COUNT;
+    initModeStruct.deadtime = 24;
+    initModeStruct.deadtimePsc = PWM_DEADTIME_DIVID_1;
+    initModeStruct.initChOutputEn = ENABLE;
+    initModeStruct.initTriggerEn = DISABLE;
+		initModeStruct.independentChannelNum = 2;
+    initModeStruct.independentChConfig = independentChConfig;
+
+    pwmConfig.mode = PWM_MODE_MODULATION;
+    pwmConfig.clkSource = PWM_CLK_SOURCE_APB;
+    pwmConfig.clkPsc = PWM_PRES;
+    pwmConfig.initValue = 0;
+    pwmConfig.maxValue = MOD_PWM - 1;
+    pwmConfig.overflowInterrupEn = ENABLE;
+    pwmConfig.cntOverflowFreq = 0;
+    pwmConfig.interruptEn = DISABLE;
+    pwmConfig.callBack = PWM1_CallBack; //PWM中断回调
+    pwmConfig.initModeStruct = &initModeStruct;
+
+    PWM_Init(PWM1, &pwmConfig);	
+		NVIC_SetPriority(PWM1_IRQn, 0); //设置PWM模块中断的优先级
+}
+
+
+void Motor_Positive(uint8_t speed)
+{
+	uint16_t chValue=0;
+	if(speed > 100) speed = 100;
+		 
+	chValue = (uint16_t)speed*MOD_PWM/100;
+	
+	//printf("Motor_Positive, speed:%d \r\n", speed);
+	PWM_SetChannelCountValue(PWM1, PWM_CH_3, 0);
+	PWM_SetChannelCountValue(PWM1, PWM_CH_2, chValue);
+	
+}
+
+
+void Motor_Negative(uint8_t speed)
+{
+	uint16_t chValue=0;
+	if(speed > 100) speed = 100;
+		 
+	chValue = (uint16_t)speed*MOD_PWM/100;
+	//printf("Motor_Negative, speed:%d \r\n", speed);
+	
+	PWM_SetChannelCountValue(PWM1, PWM_CH_2, 0);
+	PWM_SetChannelCountValue(PWM1, PWM_CH_3, chValue);
+	
+}
+
+//电机停止转动 
+void Motor_Stop(void)
+{
+	PWM_SetChannelCountValue(PWM1, PWM_CH_2, 0);
+	PWM_SetChannelCountValue(PWM1, PWM_CH_3, 0);
+}
+
+/**********<End>*********/

+ 69 - 0
Device/Motor.h

@@ -0,0 +1,69 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+#ifndef MOTOR_H_
+#define MOTOR_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "string.h"
+#include "system_ac780x.h"
+#include "ac780x_gpio.h"
+#include "ac780x.h"
+#include "ac780x_timer.h"
+#include "ac780x_pwm.h"
+#include "ac780x_pwm_reg.h"
+
+//#define PRESCALER   				        (PWDT_CLK_PRESCALER_8)
+#define APB_CLK                             (APB_BUS_FREQ)
+#define FREQ                                (100) ///freq = 20KHz
+#define PWM_PRES                            (199)
+#define MOD_PWM                             (APB_CLK / FREQ / (PWM_PRES + 1))
+
+
+void Motor_Init(void);
+//设置电机正转速度 , speed 取值 0--100;
+void Motor_Positive(uint8_t speed);
+//设置电机反转速度 , speed 取值 0--100;
+void Motor_Negative(uint8_t speed);
+//电机停止转动 
+void Motor_Stop(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //MOTOR_H_

+ 472 - 0
Device/W25Q64.c

@@ -0,0 +1,472 @@
+#include"stdio.h"
+#include"string.h"
+
+#include"gpio.h"
+#include"W25Q64.h"
+
+#ifdef  USE_W25Q64
+/*************<macro>******************/
+#define W25X16_DATA_BUF_LEN		(520)//读取写入BUF长度
+
+
+#define W25X16_WRRD_DAT_ADDR	(0x00)
+
+
+
+/*************<enum>*******************/
+
+
+/*************<union>******************/
+
+
+/*************<struct>*****************/
+
+
+/*************<variable>***************/
+uint8_t		g_flashWrDataBuf[W25X16_DATA_BUF_LEN];
+uint8_t		g_flashRdDataBuf[W25X16_DATA_BUF_LEN];
+
+#ifdef  W25Q64_TEST
+#define W25X16_TEST_DAT_LEN		(512)//测试数据BUF长度
+uint8_t 	g_flshTstDataBuf[W25X16_TEST_DAT_LEN];
+#endif 
+
+uint8_t		g_flashWrRdRdy;
+uint16_t	g_flashWrRdTime;//读取写入计时
+
+
+/*************<prototype>**************/
+void SPI1_Callback(void *device, uint32_t wpara, uint32_t lpara);
+
+//static uint8_t 	W25Q64_IsBusy(void);
+//static void 	W25Q64_EnableWr(void);
+
+
+
+/**
+* @prototype W25Q64_Init(void)
+*
+* @param[in] void
+* @return	 void
+*
+* @brief  	 初始化 W25Q64.
+*/
+void W25Q64_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  = 4;/*两条数据间最短时间间隔 = (CS_IDLE + 1) * CLK_PERIOD.*/
+	spiConfig.mode   		= SPI_MASTER;//设置为主机模式
+	spiConfig.cpha	 		= SPI_CPHA_2EDGE;//设置数据采样相位,第2个边沿采样数据
+	spiConfig.cpol	 		= SPI_CPOL_HIGH;//设置SCK空闲时极性,空闲时SCK为低
+	spiConfig.frmSize 		= SPI_FRAME_SIZE_8BITS;
+	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		= SPI1_Callback;
+	spiConfig.interruptEn		= ENABLE;//使能NVIC中断
+	spiConfig.txUFInterruptEn 	= ENABLE;//打开TXUF中断,可禁止
+	spiConfig.rxOFInterruptEn 	= ENABLE;//打开RXOF中断,可禁止
+	spiConfig.modeFaultInterruptEn = DISABLE;//模式故障中断
+	SPI_Init(SPI1, &spiConfig);
+	
+	while( 0 == W25Q64_isGood()){
+		mdelay(1);
+	}
+	
+}
+
+/**
+* @prototype W25Q64_IsBusy(void)
+*
+* @param[in] void
+* @return	 0->Not busy. 1->Busy.
+*
+* @brief  	 判断W25X16是否忙.
+*/
+static uint8_t W25Q64_IsBusy(void)
+{
+	udelay(3);
+	g_flashWrDataBuf[0] = W25Q64_rSTATUS_REG_CMD;
+	SPI_TransmitReceivePoll(SPI1, g_flashRdDataBuf, g_flashWrDataBuf, 2);
+	//printf("W25Q64_IsBusy 0x%x \r\n", g_flashRdDataBuf[1]);
+	
+	return (g_flashRdDataBuf[1] & W25Q64_BUSY_MSK);
+}
+
+static void W25Q64_Wait_Busy(void)
+{
+  while(W25Q64_IsBusy());
+}
+
+/**
+* @prototype W25Q64_EnableWr(void)
+*
+* @param[in] void
+* @return	 void
+*
+* @brief  	 使能写W25Q64.
+*/
+static void W25Q64_EnableWr(void)
+{
+	/*先判断W25Q64是否忙.空闲时才能进行操作.*/
+	while(W25Q64_IsBusy());
+	g_flashWrDataBuf[0] = W25Q64_WRITE_ENABLE_CMD;
+	SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 1);
+}
+
+/**
+* @prototype W25Q64_DisableWr(void)
+*
+* @param[in] void
+* @return	 void
+*
+* @brief  	 禁止写W25Q64.
+*/
+static void W25Q64_DisableWr(void)
+{
+	/*先判断W25Q64是否忙.空闲时才能进行操作.*/
+	while(W25Q64_IsBusy());
+	g_flashWrDataBuf[0] = W25Q64_WRITE_DISABLE_CMD;
+	SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 1);
+}
+
+
+
+/**
+* @prototype W25Q64_ReadBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
+*
+* @param[in] startAddr: 起始地址
+* @param[in] pDataBuf:	数据缓存
+* @param[in] dataLen:	数据长度
+* @return	   void
+*
+* @brief  从W25Q64读取指定长度字节数据.
+*/
+void W25Q64_ReadBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
+{
+	while(W25Q64_IsBusy());
+	
+	//printf("W25Q64_ReadBytes 111 \r\n ");
+	
+	g_flashWrDataBuf[0] = W25Q64_READ_DATA_CMD;
+	g_flashWrDataBuf[1] = (startAddr >> 16);
+	g_flashWrDataBuf[2] = (startAddr >>  8);
+	g_flashWrDataBuf[3] = (startAddr >>  0);
+	SPI_TransmitReceivePoll(SPI1, g_flashRdDataBuf, g_flashWrDataBuf, (dataLen + 4));//可读取任意长度数据
+	
+		//printf("W25Q64_ReadBytes 222 \r\n ");
+	memcpy(pDataBuf, &g_flashRdDataBuf[4], dataLen);
+}
+
+/**
+* @prototype W25Q64_WriteBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
+*
+* @param[in] startAddr: 起始地址
+* @param[in] pDataBuf:	数据缓存
+* @param[in] dataLen:	数据长度
+* @return	 void
+*
+* @brief  	 向W25Q64写入指定长度字节数据.
+*/
+void W25Q64_WriteBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
+{
+	uint8_t ii,restLen, wrTimes;
+	
+	if ((startAddr + dataLen-1) > W25Q64_ADDR_MAX){return;}
+	
+	restLen = (dataLen % PAGE_SIZE);//少于256字节长度
+	wrTimes = (dataLen / PAGE_SIZE);//每次最多写入256字节
+	
+	/*满足256字节的数据写入.*/
+	for (ii = 0; ii < wrTimes; ii++)
+	{
+		/*使能写.*/
+		W25Q64_EnableWr();
+		
+		/*写入数据.*/
+		g_flashWrDataBuf[0] = W25Q64_PAGE_WRITE_CMD;
+		g_flashWrDataBuf[1] = (startAddr >> 16);
+		g_flashWrDataBuf[2] = (startAddr >> 8);
+		g_flashWrDataBuf[3] = (startAddr >> 0);
+		memcpy(&g_flashWrDataBuf[4], &pDataBuf[ii * PAGE_SIZE], PAGE_SIZE);//单次写入最多256字节
+		SPI_TransmitPoll(SPI1, g_flashWrDataBuf, (PAGE_SIZE + 4));
+		startAddr += PAGE_SIZE;
+	}
+	
+	/*不足256字节的数据写入.*/
+	if (restLen > 0)
+	{
+		/*使能写.*/
+		W25Q64_EnableWr();
+		
+		/*写入数据.*/
+		g_flashWrDataBuf[0] = W25Q64_PAGE_WRITE_CMD;
+		g_flashWrDataBuf[1] = (startAddr >> 16);
+		g_flashWrDataBuf[2] = (startAddr >> 8);
+		g_flashWrDataBuf[3] = (startAddr >> 0);
+		//memcpy(&g_flashWrDataBuf[4], &pDataBuf[wrTimes * 256], restLen);
+		
+		memcpy(&g_flashWrDataBuf[4], &pDataBuf[wrTimes * PAGE_SIZE], restLen);
+		SPI_TransmitPoll(SPI1, g_flashWrDataBuf, (restLen + 4));
+	}
+}
+
+/**
+* @prototype W25Q64_ErsSector(uint32_t startAddr, uint8_t secErNum)
+*
+* @param[in] startAddr:擦除 sector 对齐
+* @param[in] secErNum:需要擦除的sec数
+* @return	 void
+*
+* @brief  	 擦除W25Q64.
+*/
+void W25Q64_ErsSector(uint32_t startAddr, uint8_t secErNum)
+{
+	uint8_t  ii;
+	
+	if (0 != startAddr%SECTOR_SIZE ){return;}
+	if ((startAddr + secErNum*SECTOR_SIZE -1) > W25Q64_ADDR_MAX){return;}
+	
+	for (ii = 0; ii < secErNum; ii++)
+	{
+		/*使能写,在擦除、写入后自动关闭写.*/
+		W25Q64_EnableWr();
+		
+		/*装载擦除指令,并发送指令.*/
+		g_flashWrDataBuf[0] = W25Q64_SECTOR_ERASE_CMD;
+		g_flashWrDataBuf[1] = (startAddr >> 16);
+		g_flashWrDataBuf[2] = (startAddr >>  8);
+		g_flashWrDataBuf[3] = (startAddr >>  0);
+		SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 4);
+		
+		startAddr += SECTOR_SIZE;
+	}
+}
+
+
+/**
+* @prototype W25Q64_ErsBlock(uint32_t startAddr, uint8_t blkErNum)
+*
+* @param[in] startAddr:擦除 BLOCK 对齐
+* @param[in] blkErNum:需要擦除的blk数
+* @return	 	 void
+*
+* @brief  	 擦除W25Q64
+*/
+void W25Q64_ErsBlock(uint32_t startAddr, uint8_t blkErNum)
+{
+	uint8_t  ii;
+	
+	if (0 != startAddr%BLOCK_SIZE ){return;}
+	if ((startAddr + blkErNum*BLOCK_SIZE -1) > W25Q64_ADDR_MAX){return;}
+	
+	for (ii = 0; ii < blkErNum; ii++)
+	{
+		/*使能写,在擦除、写入后自动关闭写.*/
+		W25Q64_EnableWr();
+		
+		/*装载擦除指令,并发送指令.*/
+		g_flashWrDataBuf[0] = W25Q64_BLOCK_ERASE_CMD;
+		g_flashWrDataBuf[1] = (startAddr >> 16);
+		g_flashWrDataBuf[2] = (startAddr >>  8);
+		g_flashWrDataBuf[3] = (startAddr >>  0);
+		SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 4);
+		
+		startAddr += BLOCK_SIZE;
+	}
+}
+
+
+/**
+* @prototype W25Q64_ErsChip(void)
+*
+* @return	 void
+*
+* @brief  	 擦除W25Q64.
+*/
+void W25Q64_ErsChip(void)
+{
+		/*使能写,在擦除、写入后自动关闭写.*/
+		W25Q64_EnableWr();
+		
+		/*装载擦除指令,并发送指令.*/
+		g_flashWrDataBuf[0] = W25Q64_CHIP_ERASE_CMD;
+		SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 1);
+		
+}
+
+//Power Down mode
+void W25Q64_Power_Down()
+{
+	/*先判断W25Q64是否忙.空闲时才能进行操作.*/
+	//while(W25Q64_IsBusy());
+	g_flashWrDataBuf[0] = W25Q64_PWR_DOWN_CMD;
+	SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 1);
+	
+}
+//Weka up Mode
+void W25Q64_ReleasePowerDown(void)
+{
+	
+	/*先判断W25Q64是否忙.空闲时才能进行操作.*/
+	//while(W25Q64_IsBusy());
+	g_flashWrDataBuf[0] = W25Q64_RELEASE_PWR_DOWN_CMD;
+	SPI_TransmitPoll(SPI1, g_flashWrDataBuf, 1);
+	
+}
+
+/**
+* @prototype SPI1_Callback(void *device, uint32_t wpara, uint32_t lpara)
+*
+* @param[in] ...
+* @return	 void
+*
+* @brief  	 SPI1中断回调函数.
+*/
+void SPI1_Callback(void *device, uint32_t wpara, uint32_t lpara)
+{
+	if (wpara & SPI_STATUS_TXUF_Msk)
+	{
+		//TX下溢处理
+	}
+	else if (wpara & SPI_STATUS_RXOF_Msk)
+	{
+		//RX溢出处理
+	}
+}
+
+//ID
+uint32_t W25Q64_ReadDevID(void)
+{
+  uint32_t dev_id=0;
+
+	g_flashWrDataBuf[0] = W25Q64_JEDEC_DEVICE_ID;
+	SPI_TransmitReceivePoll(SPI1, g_flashRdDataBuf, g_flashWrDataBuf, 4);//可读取任意长度数据
+	
+	dev_id = (uint32_t)((uint32_t)g_flashRdDataBuf[1]<<16)| ((uint32_t)g_flashRdDataBuf[2]<<8)| g_flashRdDataBuf[3]; 
+	
+  return dev_id;
+}
+
+uint8_t W25Q64_isGood(void)
+{
+	g_flashWrDataBuf[0] = W25Q64_JEDEC_DEVICE_ID;
+	SPI_TransmitReceivePoll(SPI1, g_flashRdDataBuf, g_flashWrDataBuf, 4);//可读取任意长度数据
+	
+	if(0xef == g_flashRdDataBuf[1]){
+		return 1;
+	}else{
+		return 0;
+	}
+	
+}
+
+
+#ifdef  W25Q64_TEST
+
+/*             ##################################################################                */
+
+/**
+* @prototype W25Q64_ReadDataTest(void)
+*
+* @param[in] void
+* @return	 void
+*
+* @brief  	 测试W25Q64读取功能.
+*/
+void W25Q64_ReadDataTest(void)
+{
+	/*准备计时.*/
+	g_flashWrRdRdy	= 1;
+	g_flashWrRdTime = 0;
+	
+	/*读取数据.*/
+	memset(g_flshTstDataBuf, 0x00, W25X16_TEST_DAT_LEN);
+	printf("W25Q64_ReadDataTest 1111\r\n");
+	W25Q64_ReadBytes(W25X16_WRRD_DAT_ADDR, g_flshTstDataBuf, W25X16_TEST_DAT_LEN);
+	printf("W25Q64_ReadDataTest 2222\r\n");
+	
+	/*停止计时.*/
+	g_flashWrRdRdy	= 0;
+	/*打印数据和时间.*/
+	for (uint16_t ii = 0; ii < W25X16_TEST_DAT_LEN; ii++)
+	{
+		printf("%d ", g_flshTstDataBuf[ii]);
+	}
+	printf("\r\n");
+	printf("Read W25Q64 1K bytes time is: %d ms", g_flashWrRdTime);
+	printf("\r\n");
+}
+	
+/**
+* @prototype W25Q64_WriteDataTest(void)
+*
+* @param[in] void
+* @return	 void
+*
+* @brief  	 测试W25Q64写功能.
+*/
+void W25Q64_WriteDataTest(void)
+{
+	/*擦除数据.*/
+	W25Q64_ErsSector(W25X16_WRRD_DAT_ADDR, 1);//擦除1个扇区4KB
+	
+	/*准备数据.*/
+	for (uint16_t ii = 0; ii < W25X16_TEST_DAT_LEN; ii++)
+	{
+		g_flshTstDataBuf[ii] = ii/10;
+		printf("%d ", g_flshTstDataBuf[ii]);
+	}
+	printf("\r\n");
+	
+	/*准备计时.*/
+	g_flashWrRdRdy	= 1;
+	g_flashWrRdTime = 0;
+	
+
+	/*写入数据.*/
+	W25Q64_WriteBytes(W25X16_WRRD_DAT_ADDR, g_flshTstDataBuf, W25X16_TEST_DAT_LEN);
+	
+	/*停止计时.*/
+	g_flashWrRdRdy	= 0;
+	/*打印时间.*/
+	printf("Write W25Q64 1K bytes time is: %d ms", g_flashWrRdTime);
+	printf("\r\n");
+}
+
+
+#endif 
+
+void W25Q64_PrintInfo(void)
+{
+	printf("\r\n");
+	printf("W25Q64 DeviceID: 0x%x", W25Q64_ReadDevID());
+	printf("\r\n");
+}
+
+#endif 
+
+//------------------------------- End-------------------------------------------

+ 191 - 0
Device/W25Q64.h

@@ -0,0 +1,191 @@
+
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2018. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+
+/*************<start>******************/
+
+#ifndef W25Q64_H__
+#define W25Q64_H__
+
+#define USE_W25Q64			(1)
+//#define W25Q64_TEST			(1)
+
+#ifdef  USE_W25Q64
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+#include "ac780x_spi.h"
+
+#define W25Q64_BUSY_MSK			(0x01)
+#define W25Q64_WEL_MSK			(0x02)
+
+//ID
+#define W25Q64                          0xEF16
+
+// W25Q64 Registors
+#define W25Q64_WRITE_ENABLE_CMD         (0X06)
+#define W25Q64_WRITE_DISABLE_CMD        (0x04)
+#define W25Q64_rSTATUS_REG_CMD          (0x05)
+#define W25Q64_wSTATUS_REG_CMD          (0x01)
+#define W25Q64_READ_DATA_CMD            (0x03)
+#define W25Q64_FAST_READ_DATA_CMD       (0x0B)
+#define W25Q64_FAST_READ_DUAL_CMD       0x3B
+#define W25Q64_PAGE_WRITE_CMD           (0x02)
+#define W25Q64_BLOCK_ERASE_CMD          (0xD8)
+#define W25Q64_SECTOR_ERASE_CMD         (0x20)
+#define W25Q64_CHIP_ERASE_CMD           (0xC7)
+
+#define W25Q64_PWR_DOWN_CMD             0xB9
+#define W25Q64_RELEASE_PWR_DOWN_CMD     0xAB
+
+#define W25Q64_DEVICE_ID                0xAB
+#define W25Q64_MANUFACT_ID              0x90
+#define W25Q64_JEDEC_DEVICE_ID          0x9F
+
+
+
+
+//Block0 64K
+#define Block0_Header_Addr      0x000000
+#define Block0_Tail_Addr        0x00FFFF
+
+//... Block N ... 
+
+//Block127 64K
+#define Block127_Header_Addr      0x7F0000
+#define Block127_Tail_Addr           0x7FFFFF
+
+
+
+//#define EE_CS_Low                    do{GPIO_SetPinLevel(LDOEn_PORT, LDOEn_PIN, GPIO_LEVEL_HIGH);}while(0)
+//#define EE_CS_High                   do{GPIO_SetPinLevel(LDOEn_PORT, LDOEn_PIN, GPIO_LEVEL_HIGH);}while(0)
+
+
+#define W25Q64_ADDR_MAX			(0x7FFFFF)
+
+#define		PAGE_SIZE			(256)						 		// 256 bytes
+#define 	SECTOR_SIZE		(PAGE_SIZE*16)	 		// 4-Kbyte
+#define		BLOCK_SIZE		(SECTOR_SIZE*16)	  // 64-Kbyte	
+#define 	FLASH_SIZE	  (BLOCK_SIZE*128)	  // 8M字节
+
+
+/*************<extern>*****************/	
+extern uint8_t		g_flashWrRdRdy;
+extern uint16_t		g_flashWrRdTime;//读取写入计时
+
+/*************<prototype>**************/
+
+
+void W25Q64_Init(void);
+
+/**
+* @prototype W25Q64_ReadBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
+*
+* @param[in] startAddr: 起始地址
+* @param[in] pDataBuf:	数据缓存
+* @param[in] dataLen:	数据长度
+* @return	   void
+*
+* @brief  从W25Q64读取指定长度字节数据.
+*/
+void W25Q64_ReadBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen);
+
+/**
+* @prototype W25Q64_WriteBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen)
+*
+* @param[in] startAddr: 起始地址,
+* @param[in] pDataBuf:	数据缓存
+* @param[in] dataLen:	数据长度
+* @return	 void
+*
+* @brief  	 向W25Q64写入指定长度字节数据.
+*/
+void W25Q64_WriteBytes(uint32_t startAddr, uint8_t *pDataBuf, uint16_t dataLen);
+
+/**
+* @prototype W25Q64_ErsSector(uint32_t startAddr, uint8_t secErNum)
+*
+* @param[in] startAddr:擦除 sector 对齐
+* @param[in] secErNum:需要擦除的sec数
+* @return	 void
+*
+* @brief  	 擦除W25Q64.
+*/
+void W25Q64_ErsSector(uint32_t startAddr, uint8_t secErNum);
+
+/**
+* @prototype W25Q64_ErsBlock(uint32_t startAddr, uint8_t blkErNum)
+*
+* @param[in] startAddr:擦除 BLOCK 对齐
+* @param[in] blkErNum:需要擦除的blk数
+* @return	 	 void
+*
+* @brief  	 擦除W25Q64
+*/
+void W25Q64_ErsBlock(uint32_t startAddr, uint8_t blkErNum);
+
+/**
+* @prototype W25Q64_ErsChip(void)
+*
+* @return	 void
+*
+* @brief  	 擦除W25Q64.
+*/
+void W25Q64_ErsChip(void);
+
+//ID
+uint32_t W25Q64_ReadDevID(void);
+
+//检查是否读取到正确的制造商ID  
+uint8_t W25Q64_isGood(void);
+
+#ifdef  W25Q64_TEST
+
+void W25Q64_ReadDataTest(void);
+void W25Q64_WriteDataTest(void);
+
+#endif 
+
+void W25Q64_PrintInfo(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif 
+
+#endif //W25Q64_H__
+
+

+ 250 - 0
Device/adc.c

@@ -0,0 +1,250 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+/**********<Incldue>**********/
+#include "adc.h"
+#include "timer.h"
+
+/*********<Variable>********/
+uint8_t g_dmaFinish = 0;//DMA传输完成
+uint8_t g_halfDmaFinish = 0; //DMA传输半完成
+uint8_t g_dmaTransError = 0; //DMA传输错误
+uint16_t __align(2) g_ADCValueBuffer[ADC_SAMPLE_CHANNEL*ADC_FILTER_NUM] = {0};
+uint32_t g_timer0Cnt = 0;
+//uint32_t g_averageSampleValue = 0;
+/**
+ * ADC_DMACallback
+ *
+ * @param[in]  wpara:dmaChannelStatus 
+ *             lpara:0
+ * @return 0
+ *
+ * @brief ADC DMA中断回调函数。
+ */
+
+void ADC_DMACallback(void *device, uint32_t wpara, uint32_t lpara)
+{
+    /*
+     wparam为DMA通道状态,状态含义可参考CHANNELx_STATUS寄存器,
+     CHANNELx_STATUS[2] 传输错误
+     CHANNELx_STATUS[1] 半传输完成(相对设置的transferNum,如果半传输中断有使能,transferNum设为6,则DATA_TRANS_NUM为3时产生中断,进入回调)
+     CHANNELx_STATUS[0] 传输完成
+    */
+    if ((wpara & 0x01) == 0x1)
+    {
+        g_dmaFinish = 1;
+    }
+    if ((wpara & 0x02) == 0x2)
+    {
+        g_halfDmaFinish = 1;
+    }
+    if ((wpara & 0x04) == 0x4)
+    {
+        g_dmaTransError = 1;
+    }
+}
+/**
+ * ADC_DMAInit
+ *
+ * @param[in] void
+ * @return void
+ *
+ * @brief ADC DMA初始化,配置DMA相关参数。
+ */
+void ADC_DMAInit(void)
+{
+    DMA_ConfigType tmpDMAConfig;
+    memset(&tmpDMAConfig, 0x00, sizeof(DMA_ConfigType));
+    
+	
+    tmpDMAConfig.channelEn = ENABLE;                     ///<使能DMAx通道
+    tmpDMAConfig.finishInterruptEn = ENABLE;                   ///<使能DMA传输完成中断
+    tmpDMAConfig.halfFinishInterruptEn = DISABLE;               ///<去能DMA半传输完成中断
+    tmpDMAConfig.errorInterruptEn = ENABLE;                    ///<使能DMA传输错误中断
+    tmpDMAConfig.channelPriority = DMA_PRIORITY_VERY_HIGH;///<设置DMA通道优先级,0~3 :优先级由低到高
+    tmpDMAConfig.circular = ENABLE;                      ///<使能循环模式,如果只想工作一次,设为0即可。
+    tmpDMAConfig.direction = DMA_READ_FROM_PERIPH;          ///<0: 从外设读取,1:从存储器读取
+    tmpDMAConfig.MEM2MEM = DISABLE;                     ///<0:在非存储器与存储器之间传输,1:在存储器与存储器之间传输
+    tmpDMAConfig.memByteMode = DMA_MEM_BYTE_MODE_1TIME;  ///<MEM字分割传输数,0:32-bit,1:16-bit[15:0]; 2:16-bit[23:16][7:0];3:8-bit。详情可参考AC781X芯片手册  表20-2 可编程数据宽度&数据对齐 
+    tmpDMAConfig.memIncrement = ENABLE;                  ///<1:MEM地址增加
+    tmpDMAConfig.periphIncrement = DISABLE;               ///<0:外设地址固定
+    tmpDMAConfig.memSize = DMA_MEM_SIZE_16BIT;           ///<0:8-bit,1:16-bit,2:32-bit
+    tmpDMAConfig.periphSize = DMA_PERIPH_SIZE_16BIT;     ///<0:8-bit,1:16-bit,2:32-bit
+    tmpDMAConfig.transferNum = ADC_SAMPLE_CHANNEL*ADC_FILTER_NUM;         ///<DMA通道传输长度
+    tmpDMAConfig.periphSelect = DMA_PEPIRH_ADC0;  //外设选择
+		tmpDMAConfig.periphStartAddr = (uint32_t)(&(ADC0->RDR)); ///<Move ADC DR to memory
+		
+		tmpDMAConfig.memStartAddr = (uint32_t)g_ADCValueBuffer; //设置DMA开始地址
+    tmpDMAConfig.memEndAddr = (uint32_t)g_ADCValueBuffer+sizeof(g_ADCValueBuffer);//设置DMA结束地址
+    tmpDMAConfig.callBack = ADC_DMACallback; ///<设置DMA中断回调
+
+    DMA_Init(DMA0_CHANNEL2, &tmpDMAConfig);                     		 ///<ADC 使用DMA1通道,每个模块对应的DMA通道,可参考 AC781X芯片手册 表20-1 DMA请求列表
+    
+		NVIC_SetPriority(DMA0_CHANNEL2_IRQn, 3);
+		NVIC_ClearPendingIRQ(DMA0_CHANNEL2_IRQn);
+		NVIC_EnableIRQ(DMA0_CHANNEL2_IRQn);                              ///<使能DMA1中断请求
+}
+/**
+ * CTU_Config
+ *
+ * @param[in] void
+ * @return void
+ *
+ * @brief 配置CTU模块,Timer0触发ADC规则组采样。
+ */
+void CTU_Config(void)
+{
+    CTU_ConfigType ctuConfig;
+    memset(&ctuConfig, 0x00, sizeof(ctuConfig));
+    ctuConfig.uart0RxFilterEn = DISABLE;  //去能UART0_RX滤波
+    ctuConfig.rtcCaptureEn = DISABLE;  //去能RTC捕获
+    ctuConfig.acmpCaptureEn = DISABLE;  //去能ACMP捕获
+    ctuConfig.uart0RxCaptureEn = DISABLE;  //去能UART0_RX捕获
+    ctuConfig.uartTxModulateEn = DISABLE;  //去能UART0_TX调制
+    ctuConfig.clkPsc = CTU_CLK_PRESCALER_1;  //分频
+    ctuConfig.adcRegularTriggerSource = CTU_TRIGGER_ADC_TIMER_CH0_OVERFLOW; //Timer0触发ADC规则组采样。
+    ctuConfig.delay0Time = 0;  //触发延迟
+//    ctuConfig.adcInjectTriggerSource = CTU_TRIGGER_ADC_PWM0_INIT;  // 
+//    ctuConfig.delay1Time = 0;
+//    ctuConfig.pwdt0In3Source = CTU_PWDT_IN3_SOURCE_UART0_RX;
+//    ctuConfig.pwdt1In3Source = CTU_PWDT_IN3_SOURCE_UART0_RX; 
+    CTU_Init(&ctuConfig);
+}
+
+
+/**
+ * ADC_init
+ *
+ * @param[in] void
+ * @return void
+ *
+ * @brief 初始化ADC,配置ADC参数。
+ */
+void ADC_init()
+{
+    ADC_ConfigType tempAdcConfig;
+    ADC_ConfigType* adcConfig;
+    adcConfig = &tempAdcConfig;
+	
+    //配置PINMUX
+    //GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2);///<ADC_IN8 Analog function enable
+	
+   
+    adcConfig->scanModeEn = ENABLE;                   //扫描模式
+    adcConfig->continousModeEn = DISABLE;             //连续模式
+    adcConfig->regularDiscontinousModeEn = DISABLE;   //1:打开规则组间断转换模式
+    adcConfig->injectDiscontinousModeEn = DISABLE;    //1:打开注入组间断转换模式
+    adcConfig->injectAutoModeEn = DISABLE;            //1:自动注入模式
+    adcConfig->intervalModeEn = DISABLE;              //1:注入组为间隔转换模式
+    adcConfig->regularDiscontinousNum = 0;            //
+    adcConfig->EOCInterruptEn = DISABLE;              //EOC中断去能
+    adcConfig->IEOCInterruptEn = DISABLE;             //IEOC中断去能
+    adcConfig->interruptEn = DISABLE;                 //去能中断
+    adcConfig->regularDMAEn = ENABLE;                 //使能ADC DMA
+    adcConfig->regularTriggerMode = ADC_TRIGGER_EXTERNAL;//ADC触发源,外部触发
+    //adcConfig->injectTriggerMode = ADC_TRIGGER_INTERNAL; //ADC触发源,内部触发
+    adcConfig->regularSequenceLength = ADC_SAMPLE_CHANNEL;               //规则组长度设为1
+    //adcConfig->injectSequenceLength = 0;               //注入组长度设为0
+    adcConfig->dataAlign = ADC_DATA_ALIGN_RIGHT;       //右对齐
+    adcConfig->powerMode = ADC_POWER_ON;               //上电
+		adcConfig->clkPsc = ADC_CLK_PRESCALER_1; ///<Set ADC Clk = 24M/2/(0+1)
+		
+    ADC_Init(ADC0, adcConfig);                      ///<ADC works Mode Config
+    /*
+        ADC转换率计算公式:
+        转换时间= 采样时间+转换时间+同步时间
+        转换时间= (SPT+12)/ADC模块时钟频率+5/APB时钟频率
+        备注:
+        1.同步时间为5个APB CLK。
+        2.ADC时钟频率 = APB时钟频率 /(分频系数+1)
+	*/
+    ADC_SetRegularGroupChannel(ADC0, ADC_CH_7, ADC_SPT_CLK_7, 0);  //set ADC_CH_7 为第1个采样序列 电池电压监测 
+		ADC_SetRegularGroupChannel(ADC0, ADC_CH_8, ADC_SPT_CLK_7, 1); ///set ADC_CH_8 为第2个采样序列 电机电流监测
+    //ADC_SetRegularGroupChannel(ADC0, ADC_CH_BANDGAP, ADC_SPT_CLK_7, 2); ///set ADC_CH_BANDGAP 为第3个采样序列
+    //ADC_SetRegularGroupChannel(ADC0, ADC_CH_TSENSOR, ADC_SPT_CLK_7, 3); ///set ADC_CH_TSENSOR 为第4个采样序列
+		
+    ADC_DMAInit();   //ADC DMA初始化
+}
+
+void printADCValue(void)
+{
+   uint8_t index;
+    printf("\r\n adc sample data is:");
+    for (index = 0; index<ADC_SAMPLE_CHANNEL*ADC_FILTER_NUM; index++)
+    {
+        printf("  0x%x",g_ADCValueBuffer[index]);
+    }
+    printf(",  g_timer0Cnt:%d \r\n", g_timer0Cnt);
+}
+
+
+float getBatteryVoltage(void)
+{
+	uint16_t sum = 0;
+	uint8_t i;
+	for(i=0; i<ADC_FILTER_NUM; i++){
+		sum += g_ADCValueBuffer[2*i];
+	}
+	
+	sum = sum/ADC_FILTER_NUM;
+	return ((6.6*sum)/4096);
+}
+
+
+float getMotorCurrent(void)
+{
+	uint16_t sum = 0;
+	uint8_t i;
+	for(i=0; i<ADC_FILTER_NUM; i++){
+		sum += g_ADCValueBuffer[2*i+1];
+	}
+	
+	sum = sum/ADC_FILTER_NUM;
+	return ((3.3*sum)/4096);
+}
+
+/**
+ * ADC_SampleTimerTrigerRegular
+ *
+ * @param[in] void
+ * @return void
+ *
+ * @brief Timer定时触发规则组ADC_CHANNEL0单次采样。
+ */
+void ADCSample_Init(void)
+{
+    CTU_Config();
+    ADC_init();
+    //Timer0_Init();
+}
+
+/**********<End>*********/

+ 71 - 0
Device/adc.h

@@ -0,0 +1,71 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+ 
+
+#ifndef ADC_H
+#define ADC_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "string.h"
+#include "ac780x_adc.h"
+#include "ac780x_adc_reg.h"
+#include "ac780x_gpio.h"
+#include "ac780x.h"
+#include "ac780x_debugout.h"
+#include "ac780x_dma.h"
+#include "ac780x_ctu.h"
+#include "ac780x_timer.h"
+#include "ac780x_pwm.h"
+
+
+#define ADC_SAMPLE_CHANNEL               (2)
+#define ADC_FILTER_NUM               		 (8)
+
+//void  ADC_DMACallback(void *device, uint32_t wpara, uint32_t lpara);
+//extern uint32_t g_ADCValueBuffer[ADC_SAMPLE_CHANNEL];
+void ADCSample_Init(void);
+float getBatteryVoltage(void);
+float getMotorCurrent(void);
+
+void printADCValue(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ADC_H */
+
+

+ 64 - 20
Device/gpio.c

@@ -55,31 +55,19 @@
 /*************<prototype>**************/
 
 /**
-* @prototype GPIO_LedInit(void)
+* @prototype GPIO_Init(void)
 *
 * @param[in] void
 * @return	 void
 *
 * @brief  	 初始化引脚.
 */
-void GPIO_PortInit(void)
+void Gpio_Init(void)
 {
 	
-		GPIO_SetFunc(GPIO_CLOSE_KEY, GPIO_FUN0);
-		GPIO_SetFunc(GPIO_OPEN_KEY, GPIO_FUN0);
-		GPIO_SetFunc(GPIO_COVER_KEY, GPIO_FUN0);
-	
-		GPIO_SetDir(GPIO_CLOSE_KEY, GPIO_IN);
-		GPIO_SetDir(GPIO_OPEN_KEY, GPIO_IN);
-		GPIO_SetDir(GPIO_COVER_KEY, GPIO_IN);
-	
-		GPIO_SetPullup(GPIO_CLOSE_KEY, ENABLE);
-		GPIO_SetPullup(GPIO_OPEN_KEY, ENABLE);
-		GPIO_SetPullup(GPIO_COVER_KEY, ENABLE);
-	
-	//set pin mux uart0
-    GPIO_SetFunc(GPIOA, GPIO_PIN7, GPIO_FUN1);
-    GPIO_SetFunc(GPIOA, GPIO_PIN8, GPIO_FUN1);
+	//set pin mux uart1
+    GPIO_SetFunc(GPIOA, GPIO_PIN4, GPIO_FUN3);
+    GPIO_SetFunc(GPIOA, GPIO_PIN5, GPIO_FUN3);
 	
 	
 	/*初始化引脚功能,如果引脚上电后默认为GPIO,可省略掉初始化步骤.
@@ -87,10 +75,66 @@ void GPIO_PortInit(void)
 		GPIO_SetFunc(RS485CTRL_PORT, RS485CTRL_PIN, GPIO_FUN0);
 		GPIO_SetDir(RS485CTRL_PORT, RS485CTRL_PIN, GPIO_OUT);
 	
-		GPIO_SetFunc(RUNLED_PORT, RUNLED_PIN, GPIO_FUN0);
-		GPIO_SetDir(RUNLED_PORT, RUNLED_PIN, GPIO_OUT);
-	
+		GPIO_SetFunc(GREENLED_PORT, GREENLED_PIN, GPIO_FUN0);
+		GPIO_SetDir(GREENLED_PORT, GREENLED_PIN, GPIO_OUT);
+		
+		GPIO_SetFunc(REDLED_PORT, REDLED_PIN, GPIO_FUN0);
+		GPIO_SetDir(REDLED_PORT, REDLED_PIN, GPIO_OUT);
 	
+		//LDO enable 
+		GPIO_SetFunc(LDOEn_PORT, LDOEn_PIN, GPIO_FUN0);
+		GPIO_SetDir(LDOEn_PORT, LDOEn_PIN, GPIO_OUT);
+		LDOEn_EN;
+		
+		//adc0 ch7 ch8
+		GPIO_SetFunc(GPIOA, GPIO_PIN2, GPIO_FUN2); // adc IN8 电机电流监测
+    GPIO_SetFunc(GPIOA, GPIO_PIN3, GPIO_FUN2); // adc IN7 电池电压监测 
+		
+		//配置GPIO为PWM
+    //config PWM1 pinmux
+    GPIO_SetFunc(GPIOB, GPIO_PIN7, GPIO_FUN1);//PWM1_CH0 
+    GPIO_SetFunc(GPIOB, GPIO_PIN8, GPIO_FUN1);//PWM1_CH1
+		
+		//DC24V power supply 
+		GPIO_SetFunc(POWER_DETECT_PORT, POWER_DETECT_PIN, GPIO_FUN0);
+		GPIO_SetDir(POWER_DETECT_PORT, POWER_DETECT_PIN, GPIO_IN);
+		GPIO_SetPulldown(POWER_DETECT_PORT, POWER_DETECT_PIN, ENABLE);
+		
+		//cover detect pin init 
+		GPIO_SetFunc(COVER_DETECT_PORT, COVER_DETECT_PIN, GPIO_FUN0);
+		GPIO_SetDir(COVER_DETECT_PORT, COVER_DETECT_PIN, GPIO_IN);
+		GPIO_SetPullup(COVER_DETECT_PORT, COVER_DETECT_PIN, ENABLE);
+		
+		/*初始化SPI1引脚,功能复用选择. W25Q64 使用*/
+		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
+		
+		/* 初始化SPI0引脚,功能复用选择. AngleSensor 使用 */
+		GPIO_SetFunc(GPIOB, GPIO_PIN5, GPIO_FUN3);//SCK
+		GPIO_SetFunc(GPIOB, GPIO_PIN4, GPIO_FUN3);//MISO
+		GPIO_SetFunc(GPIOA, GPIO_PIN7, GPIO_FUN3);//MOSI
+		GPIO_SetFunc(GPIOA, GPIO_PIN8, GPIO_FUN3);//CS
+		
+		/*初始化RTC  ds1302*/
+		//GPIO_SetFunc(GPIOB, GPIO_PIN13, GPIO_FUN3);//I2C1_SCL
+		//GPIO_SetFunc(GPIOC, GPIO_PIN4, GPIO_FUN3);//I2C1_sda
+		
+		GPIO_SetFunc(GPIOB, GPIO_PIN6, GPIO_FUN0);
+		GPIO_SetDir(GPIOB, GPIO_PIN6, GPIO_OUT);
+}
+
+
+uint8_t Gpio_IsDC24(void)
+{
+	 return GPIO_GetPinLevel(POWER_DETECT_PORT,POWER_DETECT_PIN);
+}
+
+uint8_t Gpio_IsOpenCover(void)
+{
+
+	return GPIO_GetPinLevel(COVER_DETECT_PORT,COVER_DETECT_PIN);
 }
 
 

+ 43 - 11
Device/gpio.h

@@ -46,11 +46,6 @@ extern "C" {
 /*************<macro>******************/
 
 /* define key gpio */
-#define GPIO_CLOSE_KEY   GPIOA,GPIO_PIN15
-#define GPIO_OPEN_KEY    GPIOA,GPIO_PIN0
-#define GPIO_COVER_KEY   GPIOA,GPIO_PIN1
-
-
 
 #define RS485CTRL_PORT (GPIOB)
 #define RS485CTRL_PIN  (GPIO_PIN3)
@@ -58,13 +53,45 @@ extern "C" {
 #define RS485_TX_EN				do{GPIO_SetPinLevel(RS485CTRL_PORT, RS485CTRL_PIN, GPIO_LEVEL_HIGH);}while(0)
 #define RS485_RX_EN			do{GPIO_SetPinLevel(RS485CTRL_PORT, RS485CTRL_PIN, GPIO_LEVEL_LOW);}while(0)
 
-#define RUNLED_PORT			(GPIOA)
-#define RUNLED_PIN			(GPIO_PIN2)
+//LDO 使能脚 设备启动拉高
+
+#define LDOEn_PORT (GPIOC)
+#define LDOEn_PIN  (GPIO_PIN2)
+
+#define LDOEn_EN				do{GPIO_SetPinLevel(LDOEn_PORT, LDOEn_PIN, GPIO_LEVEL_HIGH);}while(0)
+#define LDOEn_DISABLE				do{GPIO_SetPinLevel(LDOEn_PORT, LDOEn_PIN, GPIO_LEVEL_LOW);}while(0)
+
+#define GREENLED_PORT			(GPIOA)
+#define GREENLED_PIN			(GPIO_PIN1)
+
+#define REDLED_PORT			(GPIOA)
+#define REDLED_PIN			(GPIO_PIN0)
 
 /*RUNLED动作定义.*/	
-#define RUNLED_ON				do{GPIO_SetPinLevel(RUNLED_PORT, RUNLED_PIN, GPIO_LEVEL_HIGH);}while(0)
-#define RUNLED_OFF			do{GPIO_SetPinLevel(RUNLED_PORT, RUNLED_PIN, GPIO_LEVEL_LOW);}while(0)
-#define RUNLED_TOGGLE			do{if(GPIO_GetPinLevel(RUNLED_PORT, RUNLED_PIN)){RUNLED_OFF;}else{RUNLED_ON;}}while(0)
+#define GREENLED_ON				do{GPIO_SetPinLevel(GREENLED_PORT, GREENLED_PIN, GPIO_LEVEL_HIGH);}while(0)
+#define GREENLED_OFF			do{GPIO_SetPinLevel(GREENLED_PORT, GREENLED_PIN, GPIO_LEVEL_LOW);}while(0)
+#define REDLED_ON					do{GPIO_SetPinLevel(REDLED_PORT, REDLED_PIN, GPIO_LEVEL_HIGH);}while(0)
+#define REDLED_OFF				do{GPIO_SetPinLevel(REDLED_PORT, REDLED_PIN, GPIO_LEVEL_LOW);}while(0)
+
+#define GREENLED_TOGGLE		do{if(GPIO_GetPinLevel(GREENLED_PORT, GREENLED_PIN)){GREENLED_OFF;}else{GREENLED_ON;}}while(0)
+#define REDLED_TOGGLE			do{if(GPIO_GetPinLevel(REDLED_PORT, REDLED_PIN)){REDLED_OFF;}else{REDLED_ON;}}while(0)
+#define REDGREEN_TOGGLE		do{if(GPIO_GetPinLevel(REDLED_PORT, REDLED_PIN)){REDLED_OFF;GREENLED_ON;}else{GREENLED_OFF;REDLED_ON;}}while(0)
+
+/* DC24 power supply detect gpio */
+#define POWER_DETECT_PORT (GPIOA)
+#define POWER_DETECT_PIN  (GPIO_PIN11)
+
+/* open cover detect gpio */
+#define COVER_DETECT_PORT (GPIOC)
+#define COVER_DETECT_PIN  (GPIO_PIN6)
+
+/* W25Q64 chip_select */
+#define W25Q64_CS_Low                    do{GPIO_SetPinLevel(GPIOC, GPIO_PIN1, GPIO_LEVEL_LOW);}while(0)
+#define W25Q64_CS_High                   do{GPIO_SetPinLevel(GPIOC, GPIO_PIN1, GPIO_LEVEL_HIGH);}while(0)
+
+/* DS1302 En_select */
+#define DS1302_ENABLE                    do{GPIO_SetPinLevel(GPIOB, GPIO_PIN6, GPIO_LEVEL_HIGH);}while(0)
+#define DS1302_DISABLE                   do{GPIO_SetPinLevel(GPIOB, GPIO_PIN6, GPIO_LEVEL_LOW);}while(0)
 
 
 /*************<enum>*******************/
@@ -80,7 +107,12 @@ extern "C" {
 
 
 /*************<prototype>**************/
-void GPIO_PortInit(void);
+void Gpio_Init(void);
+
+uint8_t Gpio_IsDC24(void); 			//是否为外部电源供电
+uint8_t Gpio_IsOpenCover(void); //是否上盖打开
+
+
 
 #ifdef __cplusplus
 }

+ 307 - 0
Device/pwm.c

@@ -0,0 +1,307 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+/**********<Incldue>**********/
+
+
+
+#include "ac780x_gpio.h"
+#include "ac780x.h"
+#include "ac780x_timer.h"
+#include "ac780x_pwm.h"
+#include "pwm.h"
+/**********<Prototype>*********/
+
+/**********<Variable>*********/
+uint32_t g_positvePulse;///<pulse width positive value
+uint32_t g_negativePulse;///<pulse width negative value
+uint32_t g_freq;///<pulse width period value
+float g_duty;///<pulse duty value
+uint32_t g_hallStatus;///<hall status value
+uint32_t g_overFlowCount;//PWM1计数溢出中断
+/**
+* PWM1_CallBack
+*
+* @param[in] device: device pointer
+* @param[in] wpara: callback parameter
+* @param[in] lpara: callback parameter
+* @return none
+* @brief PWM CallBack
+*/
+void PWM1_CallBack(void *device, uint32_t wpara, uint32_t lpara)
+{
+    //PWM计数器溢出中断
+    if (wpara & PWM_INIT_CNTOF_Msk) 
+    {
+        g_overFlowCount ++;
+        //user add 
+    
+    }
+    //PWM通道中断
+    //通过判断回调返回的lpara对应PWM_STR_CHnSF_Msk位状态判断是否发生通道中断
+    if (lpara & PWM_STR_CHSF_Msk)
+    {
+        
+        //user add
+        //通道0中断
+        if (lpara & PWM_STR_CH0SF_Msk)
+        {
+            
+        }
+        //通道1中断
+        if (lpara & PWM_STR_CH1SF_Msk)
+        {
+            
+        }
+        
+        
+    }
+}
+
+
+/**
+*
+* @param[in] none
+*
+* @return none
+*
+* @brief PWM1 Init
+*
+*/
+void Pwm1_Init(void)
+{
+    PWM_ConfigType pwmConfig;
+    PWM_ModulationConfigType initModeStruct;
+		PWM_IndependentChConfig independentChConfig[2];
+	
+		memset(&pwmConfig, 0, sizeof(pwmConfig));
+    memset(&initModeStruct, 0, sizeof(initModeStruct));
+	
+	  //MSP_PWM_Init(PWM1);
+	
+	  /* independent channel 2 configuration */
+    independentChConfig[0].channel = PWM_CH_2;
+    independentChConfig[0].chValue = 0;
+    independentChConfig[0].levelMode = PWM_HIGH_TRUE;
+    independentChConfig[0].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;
+    independentChConfig[0].interruptEn = DISABLE;
+    independentChConfig[0].initLevel = PWM_LOW_LEVEL;
+    independentChConfig[0].triggerEn = DISABLE;
+
+    /* independent channel 3 configuration */
+    independentChConfig[1].channel = PWM_CH_3;
+    independentChConfig[1].chValue = 0; //MOD_PWM>>1;
+    independentChConfig[1].levelMode = PWM_HIGH_TRUE;
+    independentChConfig[1].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;
+    independentChConfig[1].interruptEn = DISABLE;
+    independentChConfig[1].initLevel = PWM_LOW_LEVEL;
+    independentChConfig[1].triggerEn = DISABLE;
+
+    initModeStruct.countMode = PWM_UP_COUNT;
+    initModeStruct.deadtime = 24;
+    initModeStruct.deadtimePsc = PWM_DEADTIME_DIVID_1;
+    initModeStruct.initChOutputEn = ENABLE;
+    initModeStruct.initTriggerEn = DISABLE;
+		initModeStruct.independentChannelNum = 2;
+    initModeStruct.independentChConfig = independentChConfig;
+
+    pwmConfig.mode = PWM_MODE_MODULATION;
+    pwmConfig.clkSource = PWM_CLK_SOURCE_APB;
+    pwmConfig.clkPsc = PWM_PRES;
+    pwmConfig.initValue = 0;
+    pwmConfig.maxValue = MOD_PWM - 1;
+    pwmConfig.overflowInterrupEn = ENABLE;
+    pwmConfig.cntOverflowFreq = 0;
+    pwmConfig.interruptEn = DISABLE;
+    pwmConfig.callBack = PWM1_CallBack; //PWM中断回调
+    pwmConfig.initModeStruct = &initModeStruct;
+
+    PWM_Init(PWM1, &pwmConfig);	
+		NVIC_SetPriority(PWM1_IRQn, 0); //设置PWM模块中断的优先级
+}
+
+
+//设置电机转运速度 , speed 取值 0--100;
+void Motor_Setspeed(int8_t speed)
+{
+	 uint16_t chValue=0;
+	 if(speed >= 0){ //电机正转, 开锁
+		 
+		if(speed > 100) speed = 100;
+		 
+		chValue = (uint16_t)(speed*1.0*MOD_PWM/100);
+		PWM_SetChannelCountValue(PWM1, PWM_CH_3, 0);
+		PWM_SetChannelCountValue(PWM1, PWM_CH_2, chValue);
+		
+	 }else{//电机反转, 关锁
+		 
+		 speed = -speed;
+		 if(speed > 100) speed = 100;
+		 
+		chValue = (uint16_t)(speed*1.0*MOD_PWM/100);
+		PWM_SetChannelCountValue(PWM1, PWM_CH_2, 0);
+		PWM_SetChannelCountValue(PWM1, PWM_CH_3, chValue);
+		 
+	 }
+
+}
+
+void Motor_Positive(int8_t speed)
+{
+	uint16_t chValue=0;
+	if(speed > 100) speed = 100;
+		 
+	chValue = (uint16_t)(speed*1.0*MOD_PWM/100);
+	PWM_SetChannelCountValue(PWM1, PWM_CH_2, chValue);
+	
+}
+
+
+void Motor_Negative(int8_t speed)
+{
+	uint16_t chValue=0;
+	if(speed > 100) speed = 100;
+		 
+	chValue = (uint16_t)(speed*1.0*MOD_PWM/100);
+	PWM_SetChannelCountValue(PWM1, PWM_CH_3, chValue);
+}
+
+
+# if 0
+
+/**
+* PWM1_GenerateFrequency
+* 
+* @param[in] none
+* @return none
+*
+* @brief 
+* 1.PWM1_CH0,PWM1_CH1组合模式,PWM1_CH0输出频率为20K,占空比为25%的波形,PWM1_CH1与PWM1_CH0波形互补,带1us死区插入。
+* 2.PWM1_CH6,PWM1_CH7独立PWM模式(边沿对齐),生成频率为20K,PWM1_CH6占空比50%,PWM1_CH7占空比25%的波形。
+* 3.PWM计数器溢出中断,对输出PWM波进行计数
+*
+*/
+void PWM1_GenerateFrequency(void)
+{
+    PWM_CombineChConfig combineChConfig[1]; //组合模式相关结构体
+    PWM_IndependentChConfig independentChConfig[2];//独立模式相关结构体
+    PWM_ModulationConfigType pwmConfig; //PWM模式相关结构体
+    PWM_ConfigType config; //PWM模块结构体
+    //结构体数据清零
+    memset(&combineChConfig, 0, sizeof(combineChConfig));
+    memset(&independentChConfig, 0, sizeof(independentChConfig));
+    memset(&pwmConfig, 0, sizeof(pwmConfig));
+    memset(&config, 0, sizeof(config));
+    
+    /*通道0/1配成组合模式PWM输出*/
+    /*
+    向上计数组合模式:
+    周期=(MCVR-CNTIN+1)*PWM计数器时钟周期
+    占空比=|CH(n+1)V-CH(n)V|*PWM计数器时钟周期
+    向上-向下计数组合模式:
+    周期=2*(MCVR-CNTIN)*PWM计数器时钟周期
+    占空比=2*(|CH(n+1)V-CH(n)V|)*PWM计数器时钟周期
+    */
+    combineChConfig[0].pairChannel = PWM_CH_0; //PWM通道对数,PWM_CH_0/2/4/6对应PAIR0/1/2/3
+    /*
+    组合模式占空比由ch1stValue,ch2ndValue共同决定,pwmConfig.countMode配为PWM_UP_COUNT(计数器向上计数)时,占空比为:(ch1stValue-ch2ndValue)/(config.maxValue + 1)
+    */
+    combineChConfig[0].ch1stValue = MOD_PWM >> 2; //通道2n channel值,n为PWM对数编号 
+    combineChConfig[0].ch2ndValue = MOD_PWM >> 1; //通道2n+1 channel值,n为PWM对数编号 
+    combineChConfig[0].levelMode = PWM_HIGH_TRUE; //输出PWM高有效,如果占空比设为25%,是指的高有效电平占比25%
+    combineChConfig[0].deadtimeEn = ENABLE;//死区插入使能,组合模式才支持死区插入
+    combineChConfig[0].complementEn = ENABLE;//互补模式使能,使能后,PWM通道波形互补,DISABLE波形输出同向
+    combineChConfig[0].ch1stMatchDir = PWM_MATCH_DIR_DOWN;//仅在向上-向下计数(countMode为PWM_UP_DOWN_COUNT)组合模式有效,用于选择匹配生效点方向
+    combineChConfig[0].ch2ndMatchDir = PWM_MATCH_DIR_DOWN;//仅在向上-向下计数(countMode为PWM_UP_DOWN_COUNT)组合模式有效,用于选择匹配生效点方向
+    combineChConfig[0].ch1stPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;//输出极性高有效,PWM mask后PWM输出低电平
+    combineChConfig[0].ch2ndPolarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH;//输出极性高有效,PWM mask后PWM输出低电平
+    combineChConfig[0].ch1stInterruptEn = DISABLE;//PWM通道匹配中断使能位
+    combineChConfig[0].ch2ndInterruptEn = DISABLE;//PWM通道匹配中断使能位
+    combineChConfig[0].ch1stInitLevel = PWM_LOW_LEVEL;//PWM初始电平输出为低,该配置受initChOutputEn控制,决定PWM计数器未工作前PWM口的输出电平值。
+    combineChConfig[0].ch2ndInitLevel = PWM_LOW_LEVEL;//PWM初始电平输出为低,该配置受initChOutputEn控制,决定PWM计数器未工作前PWM口的输出电平值。
+    combineChConfig[0].ch1stTriggerEn = DISABLE;//通道2n外部触发使能,n为PWM对数编号
+    combineChConfig[0].ch2ndTriggerEn = DISABLE;//通道2n+1外部触发使能,n为PWM对数编号
+    /*
+    边沿对齐PWM模式:
+    周期=(MCVR-CNTIN+1)*PWM计数器时钟周期
+    占空比=(CHnV-CNTIN+1)*PWM计数器时钟周期
+    中心对齐PWM模式:
+    周期=2*(MCVR-CNTIN)*PWM计数器时钟周期
+    占空比=2*(CH(n)V-CNTIN)*PWM计数器时钟周期
+    */
+    /*channel 6*/
+    independentChConfig[0].channel = PWM_CH_6; //通道6
+    independentChConfig[0].chValue = MOD_PWM >> 1;//通道6 channel值,输出占空比 = chValue / (config.maxValue + 1) = 50%
+    independentChConfig[0].levelMode = PWM_HIGH_TRUE; //输出PWM高有效
+    independentChConfig[0].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH; //输出极性高有效,PWM mask后PWM输出低电平
+    independentChConfig[0].interruptEn = DISABLE;//PWM通道匹配中断使能位
+    independentChConfig[0].initLevel = PWM_LOW_LEVEL;//PWM初始电平输出为低,该配置受initChOutputEn控制,决定PWM计数器未工作前PWM口的输出电平值。
+    independentChConfig[0].triggerEn = DISABLE;//通道外部触发使能
+    /*channel 7*/
+    independentChConfig[1].channel = PWM_CH_7; //通道7
+    independentChConfig[1].chValue = MOD_PWM >> 2;//通道7 channel值,输出占空比 = chValue / (config.maxValue + 1) = 25%
+    independentChConfig[1].levelMode = PWM_HIGH_TRUE; //输出PWM高有效
+    independentChConfig[1].polarity = PWM_OUTPUT_POLARITY_ACTIVE_HIGH; //输出极性高有效,PWM mask后PWM输出低电平
+    independentChConfig[1].interruptEn = DISABLE;//PWM通道匹配中断使能位
+    independentChConfig[1].initLevel = PWM_LOW_LEVEL;//PWM初始电平输出为低,该配置受initChOutputEn控制,决定PWM计数器未工作前PWM口的输出电平值。
+    independentChConfig[1].triggerEn = DISABLE;//通道外部触发使能
+
+    /*modulation mode config*/
+    pwmConfig.countMode = PWM_UP_COUNT; //PWM计数器模式 (不同的计数模式频率及占空比计算方式不同)
+    pwmConfig.independentChannelNum = 2; //独立通道数
+    pwmConfig.combineChannelNum = 1; //组合对数
+    pwmConfig.independentChConfig = independentChConfig; //独立通道配置变量地址赋值
+    pwmConfig.combineChConfig = combineChConfig; //组合通道配置变量地址赋值
+    pwmConfig.deadtimePsc = PWM_DEADTIME_DIVID_1;//死区插入分频值,与deadtime一起决定插入死区的时间。
+    pwmConfig.deadtime = 24;  //死区时间 = (DTPSC * DTVAL)/PWM计数器时钟周期 = 1*24/24000000 = 1us
+    pwmConfig.initChOutputEn = ENABLE; //使能初始化通道输出,使能后独立PWM模式的initLevel和组合PWM模式的ch1stInitLevel和ch2ndPolarity配置才会生效
+    pwmConfig.initTriggerEn = DISABLE; //通道外部触发使能
+    
+    /*pwm config*/
+    config.mode = PWM_MODE_MODULATION;//PWM模块配置为PWM模式
+    config.initModeStruct = &pwmConfig;//PWM配置结构体地址赋值
+    config.clkSource = PWM_CLK_SOURCE_APB; //PWM时钟源配置
+    config.clkPsc = PWM_PRES;//PWM时钟源分频
+    config.initValue = 0;//计数器初始寄存器值
+    config.maxValue = MOD_PWM - 1; //PWM计数器最大值
+    config.overflowInterrupEn = ENABLE;//计数器溢出中断使能
+    config.cntOverflowFreq = 0;//CNTOF中断产生的频率与计数器频率的关系(0-127), 0表示每次计数器溢出都产生溢出中断,1表示间隔1次,2表示间隔2次,以此内推。
+    config.interruptEn = ENABLE; //PWM中断使能
+    config.callBack = PWM1_CallBack; //PWM中断回调
+    
+    PWM_Init(PWM1, &config); //配置初始化生效
+
+    NVIC_SetPriority(PWM1_IRQn, 0); //设置PWM模块中断的优先级
+}
+
+#endif 
+/**********<End>*********/

+ 66 - 0
Device/pwm.h

@@ -0,0 +1,66 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+#ifndef MOTOR_H_
+#define MOTOR_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if  1
+#include "string.h"
+#include "system_ac780x.h"
+#include "ac780x_gpio.h"
+#include "ac780x.h"
+#include "ac780x_timer.h"
+#include "ac780x_pwm.h"
+#include "ac780x_pwm_reg.h"
+
+//#define PRESCALER   				        (PWDT_CLK_PRESCALER_8)
+#define APB_CLK                             (APB_BUS_FREQ)
+#define FREQ                                (20000) ///freq = 20KHz
+#define PWM_PRES                            (0)
+#define MOD_PWM                             (APB_CLK / FREQ / (PWM_PRES + 1))
+
+void Pwm1_Init(void);
+//设置电机转运速度 , speed 取值 0--100;
+void Motor_Setspeed(int8_t speed);
+void Motor_Positive(int8_t speed);
+void Motor_Negative(int8_t speed);
+
+#endif 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //MOTOR_H_

+ 77 - 20
Device/timer.c

@@ -41,6 +41,7 @@
 #include "process.h"
 #include "uart.h"
 #include "timer.h"
+#include "W25Q64.h"
 
 /*************<macro>******************/
 
@@ -56,19 +57,19 @@
 
 /*************<variable>***************/
 
-
+extern uint32_t g_timer0Cnt;
 /*************<prototype>**************/
-void TIM_CHN2_Callback(void *device, uint32_t wpara, uint32_t lpara);
+void Timer_Callback(void *device, uint32_t wpara, uint32_t lpara);
 
 /**
-* @prototype TIMER_PrdInit(void)
+* @prototype Timer0_Init(void)
 *
 * @param[in] void
 * @return	 void
 *
-* @brief  	 初始化定时器通道2.
+* @brief  	 初始化定时器通道0 , 用于ADC 规则组采集功能.
 */
-void TIMER_PrdInit(void)
+void Timer0_Init(void)
 {
 	TIMER_ConfigType tmrConfig;
 	
@@ -78,10 +79,44 @@ void TIMER_PrdInit(void)
 	/*配置定时器.*/
 	tmrConfig.linkModeEn	= DISABLE;
 	tmrConfig.interruptEn	= ENABLE;	
-	tmrConfig.periodValue	= TIM_CHN2_PRD_1ms;
+	tmrConfig.periodValue	= TIM_PRD_10ms;
 	tmrConfig.timerEn		= ENABLE;
-	tmrConfig.callBack 		= TIM_CHN2_Callback;
-	TIMER_Init(TIMER_CHANNEL2, &tmrConfig);
+	tmrConfig.callBack 		= Timer_Callback;
+	TIMER_Init(TIMER_CHANNEL0, &tmrConfig);
+	
+	NVIC_SetPriority(TIMER_CHANNEL0_IRQn, 1);
+  NVIC_ClearPendingIRQ(TIMER_CHANNEL0_IRQn);
+  NVIC_EnableIRQ(TIMER_CHANNEL0_IRQn);
+	
+}
+
+
+/**
+* @prototype Timer1_Init(void)
+*
+* @param[in] void
+* @return	 void
+*
+* @brief  	 初始化定时器通道1, 用于记数.
+*/
+void Timer1_Init(void)
+{
+	TIMER_ConfigType tmrConfig;
+	
+	/*清零变量.*/
+	memset(&tmrConfig, 0x00, sizeof(tmrConfig));
+	
+	/*配置定时器.*/
+	tmrConfig.linkModeEn	= DISABLE;
+	tmrConfig.interruptEn	= ENABLE;	
+	tmrConfig.periodValue	= TIM_PRD_1ms;
+	tmrConfig.timerEn		= ENABLE;
+	tmrConfig.callBack 		= Timer_Callback;
+	TIMER_Init(TIMER_CHANNEL1, &tmrConfig);
+	
+	NVIC_SetPriority(TIMER_CHANNEL1_IRQn, 2);
+  NVIC_ClearPendingIRQ(TIMER_CHANNEL1_IRQn);
+  NVIC_EnableIRQ(TIMER_CHANNEL1_IRQn);
 }
 
 /**
@@ -92,21 +127,43 @@ void TIMER_PrdInit(void)
 *
 * @brief  	 定时器通道2中断回调函数.
 */
-void TIM_CHN2_Callback(void *device, uint32_t wpara, uint32_t lpara)
+void Timer_Callback(void *device, uint32_t wpara, uint32_t lpara)
 {
+		if (TIMER_CHANNEL0 == device){
+				g_timer0Cnt++;
+				Process_Timer10msCB();
+		}else if(TIMER_CHANNEL1 == device){
+			
+			if (g_blinkLedTime < 0xFFFF)
+			{
+					g_blinkLedTime++;
+			}
+			
+			if(rs485_info.dmasend_count < 0xFF){
+					rs485_info.dmasend_count++;
+			}
+			
+			if(g_detectTime < 0xFF){
+					g_detectTime++;
+			}
+			
+			if (g_flashWrRdRdy)
+			{
+				g_flashWrRdTime++;
+			}
+			
+			if(g_runReady){
+				g_runTime++;
+			}
+			
+			if(g_period1000ms < 0xFFFF)
+			{
+				g_period1000ms++;
+			}
 	
-	if (g_blinkLedTime < 0xFFFF)
-	{
-			g_blinkLedTime++;
-	}
-	
-	if(uart0_info.dmasend_count < 0xFF){
-		  uart0_info.dmasend_count++;
-	}
 	
-	if(g_detectTime < 0xFF){
-			g_detectTime++;
-	}
+		}
+
 	
 }
 

+ 8 - 3
Device/timer.h

@@ -44,8 +44,12 @@ extern "C" {
 #include "ac780x_timer.h"
 
 /*************<macro>******************/
-#define PERH_BUS_CLK		(24000000U)
-#define TIM_CHN2_PRD_1ms	(PERH_BUS_CLK / 1000 - 1)
+
+#define TIM_PRD_5us                      (APB_BUS_FREQ/200000-1)
+#define TIM_PRD_1ms                      (APB_BUS_FREQ/1000-1)
+#define TIM_PRD_5ms                      (APB_BUS_FREQ/200-1)
+#define TIM_PRD_10ms                     (APB_BUS_FREQ/100-1)
+#define TIM_PRD_1s                       (APB_BUS_FREQ-1)
 
 
 /*************<enum>*******************/
@@ -61,7 +65,8 @@ extern "C" {
 
 
 /*************<prototype>**************/
-void TIMER_PrdInit(void);
+void Timer0_Init(void);
+void Timer1_Init(void);
 
 #ifdef __cplusplus
 }

+ 27 - 27
Device/uart.c

@@ -39,14 +39,14 @@
 
 //#include "Comm.h"
 
-#define UARTx   UART0
-#define UARTx_IRQn  UART0_IRQn
+#define UART485   UART1
+#define UART485_IRQn  UART1_IRQn
 
 
-UART_INFO  uart0_info;
+UART_INFO  rs485_info;
 
-uint32_t dmaRxBuf[UART0_RECV_DATA_POOL_COUNT>>2];
-uint32_t dmaTxBuf[UART0_TRANSMIT_DATA_POOL_COUNT>>2];
+uint32_t dmaRxBuf[UART_RECV_DATA_POOL_COUNT>>2];
+uint32_t dmaTxBuf[UART_TRANSMIT_DATA_POOL_COUNT>>2];
 
 
 int TransmitData(uint8_t *pdata, uint16_t length);
@@ -66,7 +66,7 @@ void UartTxDMAEventCallback(void *device, uint32_t wpara, uint32_t lpara)
 {
     if (wpara & DMA_CHANNEL_STATUS_FINISH_Msk)    //!<DMA finish
     {
-			 uart0_info.dmasend_count = UART_DMASEND_COUNT_END;
+			 rs485_info.dmasend_count = UART_DMASEND_COUNT_END;
     }
     else if (wpara & DMA_CHANNEL_STATUS_HALF_FINISH_Msk)  //!<DMA half finish
     {
@@ -132,7 +132,7 @@ static void UartRxIdleCallBack(void *device, uint32_t wpara, uint32_t lpara)
 				DMA_SetChannel(DMA0_CHANNEL1, DISABLE);
 			
         ///接收不足4字节会在DMA fifo中缓存
-        uart0_info.recv_len = DMA0_CHANNEL1->DATA_TRANS_NUM + DMA0_CHANNEL1->FIFO_LEFT_NUM;
+        rs485_info.recv_len = DMA0_CHANNEL1->DATA_TRANS_NUM + DMA0_CHANNEL1->FIFO_LEFT_NUM;
 			
         ///将DMA fifo数据flush出来,因为mem设置为32bit,所以fifo也是4字节对齐
         ///(即使fifo里只有1个字节也会刷出4字节,需要保证缓存冗余不会溢出)
@@ -144,14 +144,14 @@ static void UartRxIdleCallBack(void *device, uint32_t wpara, uint32_t lpara)
 
 
 /**
-* uart_Initialize
+* rs485_Initialize
 * 
 * @param[in] none
 * @return none
 *
-* @brief uart 初始化
+* @brief rs485 初始化
 */
-void uart_Initialize(void)
+void rs485_Initialize(void)
 {
     UART_ConfigType  uartConfig = {0}; 
 		
@@ -190,21 +190,21 @@ void uart_Initialize(void)
 	
 		
     uartConfig.callBack = UartRxIdleCallBack;   ///<uart2 interrupt callback
-    UART_Init(UARTx, &uartConfig);
-    UARTx->IDLE |= UART_IDLE_IDLEIE_Msk | UART_IDLE_ILEN_Msk;    ///<enable uart idle interrupt
+    UART_Init(UART485, &uartConfig);
+    UART485->IDLE |= UART_IDLE_IDLEIE_Msk | UART_IDLE_ILEN_Msk;    ///<enable uart idle interrupt
     
     ///Enable UARTx interrupt
-    NVIC_SetPriority(UARTx_IRQn, 3);
-    NVIC_ClearPendingIRQ(UARTx_IRQn);
-    NVIC_EnableIRQ(UARTx_IRQn);
+    NVIC_SetPriority(UART485_IRQn, 5);
+    NVIC_ClearPendingIRQ(UART485_IRQn);
+    NVIC_EnableIRQ(UART485_IRQn);
 		
-		uart0_info.dmasend_count = 0;
-		uart0_info.recv_buffer = (uint8_t *)dmaRxBuf;
-		uart0_info.send_buffer = (uint8_t *)dmaTxBuf;
-		uart0_info.recv_len = 0;
-		uart0_info.send_len = 0;
+		rs485_info.dmasend_count = 0;
+		rs485_info.recv_buffer = (uint8_t *)dmaRxBuf;
+		rs485_info.send_buffer = (uint8_t *)dmaTxBuf;
+		rs485_info.recv_len = 0;
+		rs485_info.send_len = 0;
 		
-		UART_ReceiveDMA(UARTx, DMA0_CHANNEL1, uart0_info.recv_buffer, UART0_RECV_DATA_POOL_COUNT, UartRxDMAEventCallback); 
+		UART_ReceiveDMA(UART485, DMA0_CHANNEL1, rs485_info.recv_buffer, UART_RECV_DATA_POOL_COUNT, UartRxDMAEventCallback); 
     
 }
 
@@ -217,12 +217,12 @@ void uart_Initialize(void)
 *
 * @brief uart 发送函数,通过中断发送 
 */
-int uart0_TransmitData(uint8_t *pdata, uint16_t length) 
+int rs485_TransmitData(uint8_t *pdata, uint16_t length) 
 {
 						
 		RS485_TX_EN; 
-		uart0_info.dmasend_count = UART_DMASEND_COUNT_START;
-		UART_TransmitDMA(UARTx, DMA0_CHANNEL0, pdata, length, UartTxDMAEventCallback); 
+		rs485_info.dmasend_count = UART_DMASEND_COUNT_START;
+		UART_TransmitDMA(UART485, DMA0_CHANNEL0, pdata, length, UartTxDMAEventCallback); 
 
 		//uart0_info.recv_len=0;
 		//UART_ReceiveDMA(UARTx, DMA0_CHANNEL1, uart0_info.recv_buffer, UART0_RECV_DATA_POOL_COUNT, UartRxDMAEventCallback); 
@@ -230,10 +230,10 @@ int uart0_TransmitData(uint8_t *pdata, uint16_t length)
     return 0;
 }
 
-void uart0_RecvData(void)
+void rs485_RecvData(void)
 {
-		uart0_info.recv_len=0;
-		UART_ReceiveDMA(UARTx, DMA0_CHANNEL1, uart0_info.recv_buffer, UART0_RECV_DATA_POOL_COUNT, UartRxDMAEventCallback); 
+		rs485_info.recv_len=0;
+		UART_ReceiveDMA(UART485, DMA0_CHANNEL1, rs485_info.recv_buffer, UART_RECV_DATA_POOL_COUNT, UartRxDMAEventCallback); 
 }
 
 

+ 8 - 8
Device/uart.h

@@ -51,14 +51,14 @@ extern "C" {
 
 
 
-#define UART0_BaudRate    9600
-#define UART0_TRANSMIT_DATA_POOL_COUNT 64
-#define UART0_RECV_DATA_POOL_COUNT     320  
+#define UART_BaudRate    9600
+#define UART_TRANSMIT_DATA_POOL_COUNT (128)
+#define UART_RECV_DATA_POOL_COUNT     (320)  
 
 //rs485 send/recv ctrl
 #define UART_DMASEND_COUNT_START   (1)  
 #define UART_DMASEND_COUNT_END   (100)
-#define UART_DMASEND_COUNT_RESET   (105)   
+#define UART_DMASEND_COUNT_RESET   (107)   
 
 typedef struct
 {
@@ -71,11 +71,11 @@ typedef struct
 }UART_INFO;
 
 
-extern UART_INFO  uart0_info;
+extern UART_INFO  rs485_info;
 
-void uart_Initialize(void);
-int uart0_TransmitData(uint8_t *pdata, uint16_t length);
-void uart0_RecvData(void);
+void rs485_Initialize(void);
+int rs485_TransmitData(uint8_t *pdata, uint16_t length);
+void rs485_RecvData(void);
 
 #ifdef __cplusplus
 }

+ 1 - 1
Device/watchdog.h

@@ -40,7 +40,7 @@ extern "C" {
 #include "ac780x.h"
 
 
-#define WATCHDOG_ENABLE   (1)  //
+//#define WATCHDOG_ENABLE   (1)  //
 #define WATCHDOG_TIMEOUT  2  // 2s 
 
 

File diff suppressed because it is too large
+ 296 - 152
Project/AirControlValve.uvguix.孙凯


+ 195 - 19
Project/AirControlValve.uvoptx

@@ -140,7 +140,7 @@
         <SetRegEntry>
           <Number>0</Number>
           <Key>JL2CM3</Key>
-          <Name>-U59518874 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0AC780x_128KB.FLM -FS08000000 -FL020000 -FP0($$Device:AC78013MDQA$Flash\AC780x_128KB.FLM)</Name>
+          <Name>-U59518874 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0AC780x_128KB.FLM -FS08000000 -FL020000 -FP0($$Device:AC78013MDQA$Flash\AC780x_128KB.FLM)</Name>
         </SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
@@ -332,17 +332,65 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>12</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\User\storage.h</PathWithFileName>
+      <FilenameWithoutPath>storage.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>13</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\User\storage.c</PathWithFileName>
+      <FilenameWithoutPath>storage.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>14</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\User\pid.h</PathWithFileName>
+      <FilenameWithoutPath>pid.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>15</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\User\pid.c</PathWithFileName>
+      <FilenameWithoutPath>pid.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
     <GroupName>Lib</GroupName>
-    <tvExp>1</tvExp>
+    <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>12</FileNumber>
+      <FileNumber>16</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -354,7 +402,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>13</FileNumber>
+      <FileNumber>17</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -366,7 +414,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>14</FileNumber>
+      <FileNumber>18</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -378,7 +426,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>15</FileNumber>
+      <FileNumber>19</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -390,7 +438,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>16</FileNumber>
+      <FileNumber>20</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -402,7 +450,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>17</FileNumber>
+      <FileNumber>21</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -414,7 +462,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>18</FileNumber>
+      <FileNumber>22</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -426,7 +474,7 @@
     </File>
     <File>
       <GroupNumber>2</GroupNumber>
-      <FileNumber>19</FileNumber>
+      <FileNumber>23</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -446,7 +494,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>20</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -458,7 +506,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>21</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -470,7 +518,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>22</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -482,7 +530,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -494,7 +542,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -506,7 +554,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -518,7 +566,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -530,7 +578,7 @@
     </File>
     <File>
       <GroupNumber>3</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>31</FileNumber>
       <FileType>5</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -540,6 +588,134 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>32</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\adc.c</PathWithFileName>
+      <FilenameWithoutPath>adc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>33</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\adc.h</PathWithFileName>
+      <FilenameWithoutPath>adc.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>34</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\AngleSensor.h</PathWithFileName>
+      <FilenameWithoutPath>AngleSensor.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>35</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\AngleSensor.c</PathWithFileName>
+      <FilenameWithoutPath>AngleSensor.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>36</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\W25Q64.h</PathWithFileName>
+      <FilenameWithoutPath>W25Q64.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>37</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\W25Q64.c</PathWithFileName>
+      <FilenameWithoutPath>W25Q64.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>38</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\Motor.h</PathWithFileName>
+      <FilenameWithoutPath>Motor.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>39</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\Motor.c</PathWithFileName>
+      <FilenameWithoutPath>Motor.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>40</FileNumber>
+      <FileType>5</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\Ds1302.h</PathWithFileName>
+      <FilenameWithoutPath>Ds1302.h</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>41</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Device\Ds1302.c</PathWithFileName>
+      <FilenameWithoutPath>Ds1302.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>::Board Support</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>1</RteFlg>
   </Group>
 
   <Group>
@@ -552,7 +728,7 @@
 
   <Group>
     <GroupName>::Device</GroupName>
-    <tvExp>0</tvExp>
+    <tvExp>1</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>1</RteFlg>

+ 88 - 1
Project/AirControlValve.uvprojx

@@ -49,7 +49,7 @@
             <InvalidFlash>1</InvalidFlash>
           </TargetStatus>
           <OutputDirectory>.\Objects\</OutputDirectory>
-          <OutputName>AirControlValve_20240401</OutputName>
+          <OutputName>ElectricalValve_20240626</OutputName>
           <CreateExecutable>1</CreateExecutable>
           <CreateLib>0</CreateLib>
           <CreateHexFile>1</CreateHexFile>
@@ -438,6 +438,26 @@
               <FileType>1</FileType>
               <FilePath>..\User\process.c</FilePath>
             </File>
+            <File>
+              <FileName>storage.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\User\storage.h</FilePath>
+            </File>
+            <File>
+              <FileName>storage.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\User\storage.c</FilePath>
+            </File>
+            <File>
+              <FileName>pid.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\User\pid.h</FilePath>
+            </File>
+            <File>
+              <FileName>pid.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\User\pid.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>
@@ -528,8 +548,61 @@
               <FileType>5</FileType>
               <FilePath>..\Device\watchdog.h</FilePath>
             </File>
+            <File>
+              <FileName>adc.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Device\adc.c</FilePath>
+            </File>
+            <File>
+              <FileName>adc.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\Device\adc.h</FilePath>
+            </File>
+            <File>
+              <FileName>AngleSensor.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\Device\AngleSensor.h</FilePath>
+            </File>
+            <File>
+              <FileName>AngleSensor.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Device\AngleSensor.c</FilePath>
+            </File>
+            <File>
+              <FileName>W25Q64.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\Device\W25Q64.h</FilePath>
+            </File>
+            <File>
+              <FileName>W25Q64.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Device\W25Q64.c</FilePath>
+            </File>
+            <File>
+              <FileName>Motor.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\Device\Motor.h</FilePath>
+            </File>
+            <File>
+              <FileName>Motor.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Device\Motor.c</FilePath>
+            </File>
+            <File>
+              <FileName>Ds1302.h</FileName>
+              <FileType>5</FileType>
+              <FilePath>..\Device\Ds1302.h</FilePath>
+            </File>
+            <File>
+              <FileName>Ds1302.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Device\Ds1302.c</FilePath>
+            </File>
           </Files>
         </Group>
+        <Group>
+          <GroupName>::Board Support</GroupName>
+        </Group>
         <Group>
           <GroupName>::CMSIS</GroupName>
         </Group>
@@ -549,6 +622,12 @@
           <targetInfo name="AirControlValve"/>
         </targetInfos>
       </component>
+      <component Cbundle="AC780x Development Kit" Cclass="Board Support" Cgroup="AC780x Development Kit" Csub="Debug" Cvendor="AutoChips" Cversion="1.0.0" condition="AC780x Debug Interface">
+        <package name="AC780x_DFP" schemaVersion="1.4" url="http://fex.autochips.com:90/download/CMSIS_PACK/AC7801/" vendor="AutoChips" version="1.0.6"/>
+        <targetInfos>
+          <targetInfo name="AirControlValve"/>
+        </targetInfos>
+      </component>
       <component Cclass="Device" Cgroup="ATC Drivers" Csub="ACMP" Cvendor="AutoChips" Cversion="1.0.0" condition="AC780x System">
         <package name="AC780x_DFP" schemaVersion="1.4" url="http://fex.autochips.com:90/download/CMSIS_PACK/AC7801/" vendor="AutoChips" version="1.0.6"/>
         <targetInfos>
@@ -677,6 +756,14 @@
       </component>
     </components>
     <files>
+      <file attr="config" category="source" name="Device\Source\ac780x_debugout.c" version="1.0.0">
+        <instance index="0">RTE\Board_Support\AC78013MDQA\ac780x_debugout.c</instance>
+        <component Cbundle="AC780x Development Kit" Cclass="Board Support" Cgroup="AC780x Development Kit" Csub="Debug" Cvendor="AutoChips" Cversion="1.0.0" condition="AC780x Debug Interface"/>
+        <package name="AC780x_DFP" schemaVersion="1.4" url="http://fex.autochips.com:90/download/CMSIS_PACK/AC7801/" vendor="AutoChips" version="1.0.6"/>
+        <targetInfos>
+          <targetInfo name="AirControlValve"/>
+        </targetInfos>
+      </file>
       <file attr="config" category="header" name="Device\device_assert.h" version="1.0.0">
         <instance index="0">RTE\Device\AC78013MDQA\device_assert.h</instance>
         <component Cclass="Device" Cgroup="Startup" Cvendor="AutoChips" Cversion="1.0.0" condition="AC780x System"/>

File diff suppressed because it is too large
+ 5968 - 1715
Project/JLinkLog.txt


+ 183 - 0
Project/RTE/Board_Support/AC78013MDQA/ac780x_debugout.c

@@ -0,0 +1,183 @@
+/* Copyright Statement:
+*
+* This software/firmware and related documentation ("AutoChips Software") are
+* protected under relevant copyright laws. The information contained herein is
+* confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+* the prior written permission of AutoChips inc. and/or its licensors, any
+* reproduction, modification, use or disclosure of AutoChips Software, and
+* information contained herein, in whole or in part, shall be strictly
+* prohibited.
+*
+* AutoChips Inc. (C) 2020. All rights reserved.
+*
+* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+* RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+* ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+* WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+* NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+* RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+* INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+* TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+* RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+* OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+* SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+* RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+* ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+* RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+* AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+* CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+*/
+
+/*!
+ * @file ac780x_debugout.c
+ *
+ * @brief This file provides debug information output integration functions.
+ *
+*/
+/* ===========================================  Includes  =========================================== */
+#include "ac780x.h"
+#include "ac780x_gpio.h"
+#include "ac780x_uart.h"
+#include "ac780x_uart_reg.h"
+/* ============================================  Define  ============================================ */
+#define MAX_DEBUG_BUFF_SIZE 100             /* define uart max receive buffer size */
+
+#define DEBUG_UART           UART2          /* define uart2 for debug output   */
+#define DEBUG_UART_IRQ       UART2_IRQn     /* define uart2 interrupt vector   */
+#define DEBUG_UART_CLK       CLK_UART2      /* define uart2 ckgen clock value  */
+#define DEBUG_UART_SRST      SRST_UART2     /* define uart2 ckgen reset value  */
+#define DEBUG_UART_SMP       16.0F
+#define DEBUG_UART_BAUDRATE  115200.0F
+
+#define DEBUG_UART_TX     GPIOB,GPIO_PIN9   /* define uart2 tx gpio */
+#define DEBUG_UART_RX     GPIOB,GPIO_PIN10  /* define uart2 rx gpio */
+/* ===========================================  Typedef  ============================================ */
+
+/* ==========================================  Variables  =========================================== */
+/* debug uart receive buf */
+uint8_t g_debugBuff[MAX_DEBUG_BUFF_SIZE] = {0};
+
+/* debug init flag */
+static uint8_t s_debugInit = 0;
+
+/* define std FILE struct */
+struct __FILE
+{
+    int handle;
+};
+
+/* refine stdout,stdin,stderr */
+FILE __stdout;
+FILE __stdin;
+FILE __stderr;
+/* ====================================  Functions declaration  ===================================== */
+
+/* ======================================  Functions define  ======================================== */
+
+/*!
+* @brief refine _sys_exit
+*
+* @param[in] x:  no use
+* @return always 0
+*/
+int _sys_exit(int x)
+{
+    x = x;
+    return 0;
+}
+
+/*!
+* @brief refine _ttywrch
+*
+* @param[in] x:  no use
+* @return always 0
+*/
+int _ttywrch(int x)
+{
+    x = x;
+    return 0;
+}
+
+/*!
+* @brief put a char to UART
+*
+* @param[in] f:  file pointer for the std input
+* @param[in] ch: the char to put
+* @return return the char of be put
+*/
+int fputc(int ch, FILE *f)
+{
+    if (s_debugInit)
+    {
+        UART_SendData(DEBUG_UART, ch);
+    }
+    return ch;
+}
+
+/*!
+* @brief get a char
+*
+* @param[in] f: file pointer for the std input
+* @return -1: not get char,  other: the char get from UART
+*/
+int fgetc(FILE* f)
+{
+    int ch = -1;
+    if (s_debugInit)
+    {
+        if (UART_RxIsDataReady(DEBUG_UART))
+        {
+            ch = UART_ReceiveData(DEBUG_UART);
+        }
+    }
+
+    return ch;
+}
+
+/*!
+* @brief set the debug out is invalid
+*
+* @param[in] none
+* @return none
+*/
+void DeinitDebug(void)
+{
+    s_debugInit = 0;
+}
+
+/*!
+* @brief init debug out , and set the debug out is valid
+*
+* @param[in] none
+* @return none
+*/
+void InitDebug(void)
+{
+#ifdef DEBUG_CMD_INTERRUPT
+    NVIC_SetPriority(DEBUG_UART_IRQ, 3);
+    NVIC_ClearPendingIRQ(DEBUG_UART_IRQ);
+    NVIC_EnableIRQ(DEBUG_UART_IRQ);
+#endif
+
+    GPIO_SetFunc(DEBUG_UART_TX, GPIO_FUN3);
+    GPIO_SetFunc(DEBUG_UART_RX, GPIO_FUN3);
+    CKGEN_Enable(DEBUG_UART_CLK, ENABLE);
+    CKGEN_SoftReset(DEBUG_UART_SRST, ENABLE);
+
+    UART_SetDivisor(DEBUG_UART, (float)APB_BUS_FREQ / DEBUG_UART_SMP / DEBUG_UART_BAUDRATE);
+
+    UART_SetDataBits(DEBUG_UART, UART_WORD_LEN_8BIT);
+    UART_SetStopBit(DEBUG_UART, UART_STOP_1BIT);
+    UART_EnableTX(DEBUG_UART, ENABLE);
+    UART_EnableRX(DEBUG_UART, ENABLE);
+    UART_Set2ByteFIFO(DEBUG_UART, ENABLE);
+
+    UART_SetInterruptEn(DEBUG_UART, 9);
+
+    s_debugInit = 1;
+}
+
+/* =============================================  EOF  ============================================== */

+ 2 - 0
User/cfg.c

@@ -12,6 +12,8 @@ static void Factory_reset(void)
 		config->magic = CONFIG_MAGIC;
 		config->addr = DEFAULT_ADDR;
 		config->br_index = BaudRate_9600;
+		config->lock_threshold = 0.0;
+		config->lock_threshold = 0.0;
 	
 		//config->App2Size = 0;
 		//config->App2Crc = 0;

+ 4 - 2
User/cfg.h

@@ -58,7 +58,7 @@ extern "C" {
 
 #define CONFIG_MAGIC   		0xA5A5
 
-#define DEFAULT_ADDR     0x20
+#define DEFAULT_ADDR     0x50
 #define BROADCAST_ADDR   0xFF
 
 /* Éý¼¶±êÖ¾ */
@@ -76,8 +76,10 @@ typedef struct
 		uint16_t magic;
     uint8_t  addr;
     uint8_t  br_index;
+		float  	lock_threshold;
+		float	 	unlock_threshold;
 	
-		uint32_t  res[58];
+		uint32_t  res[56];
 	
 		uint16_t hw_version;
 		uint16_t devicetype;

+ 43 - 9
User/main.c

@@ -6,6 +6,12 @@
 #include "process.h"
 #include "main_task.h"
 #include "watchdog.h"
+#include "adc.h"
+#include "Motor.h"
+#include "W25Q64.h"
+#include "AngleSensor.h"
+#include "Ds1302.h"
+#include "storage.h"
 
 
 /*!
@@ -23,28 +29,56 @@ int main(void)
 	#endif
 	
 		InitDelay();
+		InitDebug();
+	
 		Config_Init();
 		Watchdog_Init();
-		
 	
 	#ifdef IS_BOOTLOADER
 		Start_BootLoader();
 	#endif
-	
-    GPIO_PortInit();
+
+    Gpio_Init();
 	  IAP_Init();
-	
-	
+
+		DS1302_Init();
+		AngleSensor_Init();
+		ADCSample_Init();
+		Motor_Init();
+		//W25Q64_Init();
+		Storage_Init();
+
 		Process_Init();
-	
-		TIMER_PrdInit();
+		Timer0_Init(); 
+		Timer1_Init();
     Task_Init();
-	
-	
+		//printf("111111 \r\n ");
+		
     while (1)
     {
 				Watchdog_Feed();
         Task_Handle();
+			
+		#ifdef  W25Q64_TEST
+
+				printf("read first \r\n ");
+		 W25Q64_ReadDataTest();
+			printf("read first end \r\n ");
+			//mdelay(1000);
+		//W25Q64_WriteDataTest();
+			Storage_AddItem(ITEM_RECORD, EVENT_MANUAL_LOCK);
+			
+			//mdelay(1000);
+			printf("read after write  \r\n ");
+			
+		W25Q64_ReadDataTest();
+			printf("read end  \r\n ");
+				mdelay(1000);
+			
+			break;
+			
+		#endif 
+
     }
 		
 }

+ 97 - 22
User/main_task.c

@@ -107,12 +107,46 @@ void mb_03_handle(void)
 				}
 				break;
 			case Cmd_LockStatus:
-				if(4 == read_len){
+				if(2 == read_len){
 					tx_offset += Read_LockStatus(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
 				}else{
 					g_mb_ctx.exception_code = INVALID_DATA;
 				}
-				
+				break;
+			case Cmd_ReadThreshold:
+				if(8 == read_len){
+					tx_offset += Read_Threshold(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
+			case Cmd_DateTime:
+				if(6 == read_len){
+					tx_offset += Read_DateTime(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
+			case Cmd_ReadAngle:
+				if(4 == read_len){
+					tx_offset += Read_Angle(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
+			case Cmd_ReadRecordNum:
+				if(2 == read_len){
+					tx_offset += Read_RecordsNum(g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
+			case Cmd_ReadRecords:
+				if((read_len>0)&(0 == read_len%SIZE_RECORD)&(read_len/SIZE_RECORD <= MAX_RECORDS_PERTIME)){
+					tx_offset += Read_Records(read_len/SIZE_RECORD,g_mb_ctx.txbuf+tx_offset, g_mb_ctx.txbuf_size-tx_offset);
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
 				break;
 			default:
 				g_mb_ctx.exception_code = INVALID_COMMAND;
@@ -134,7 +168,7 @@ void mb_03_handle(void)
 		g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
 		g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff); 
 								
-		uart0_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
+		rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
 			
 }
 
@@ -194,6 +228,33 @@ void mb_06_handle(void)
 				ret_write = RET_NEED_SAVE|RET_NEED_REBOOT;
 				//NVIC_SystemReset();
 				break;
+			case Cmd_LockOp:
+				if(2 == g_mb_ctx.rx_len-4-2){
+					ret_write = Write_LockOp(g_mb_ctx.rxbuf+4, 2); 
+					if(RET_DATAINVALID == ret_write)
+						g_mb_ctx.exception_code = INVALID_DATA;
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
+			case Cmd_Threshold:
+				if(2 == g_mb_ctx.rx_len-4-2){
+					ret_write = Write_ThresholdCalibration(g_mb_ctx.rxbuf+4, 2); 
+					if(RET_DATAINVALID == ret_write)
+						g_mb_ctx.exception_code = INVALID_DATA;
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
+			case Cmd_RecordDelete:
+				if(2 == g_mb_ctx.rx_len-4-2){
+					ret_write = Write_RecordsDelete(g_mb_ctx.rxbuf+4, 2); 
+					if(RET_DATAINVALID == ret_write)
+						g_mb_ctx.exception_code = INVALID_DATA;
+				}else{
+					g_mb_ctx.exception_code = INVALID_DATA;
+				}
+				break;
 			default:
 				g_mb_ctx.exception_code = INVALID_COMMAND;
 				break;
@@ -212,7 +273,7 @@ void mb_06_handle(void)
 				g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff); 
 		}
 		
-		uart0_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
+		rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
 		
 		if((ret_write&RET_NEED_SAVE) > 0 ){
 				SaveConfig();
@@ -319,6 +380,15 @@ void mb_10_handle(void)
 						g_mb_ctx.exception_code = INVALID_DATA;
 					}
 					break;
+				case Cmd_DateTime:
+					if(6 == data_len){
+						ret_write |= Write_DateTime(g_mb_ctx.rxbuf+7, 6); 
+						if(ret_write&RET_DATAINVALID)
+							g_mb_ctx.exception_code = INVALID_DATA;
+					}else{
+						g_mb_ctx.exception_code = INVALID_DATA;
+					}
+					break;
 
 				default:
 					g_mb_ctx.exception_code = INVALID_COMMAND;
@@ -342,7 +412,7 @@ void mb_10_handle(void)
 		g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
 		g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff); 
 		
-		uart0_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
+		rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
 		
 		if((ret_write&RET_NEED_SAVE) > 0 ){
 				SaveConfig();
@@ -386,7 +456,7 @@ void mb_42_handle(void)
 	g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
 	g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff); 
 	
-	uart0_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
+	rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
 	
 	if((ret_write&RET_NEED_SAVE) > 0 ){
 			SaveConfig();
@@ -415,7 +485,7 @@ void mb_funccodeerror_handle(void)
 	g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)((crc>>8) & 0x00ff);
 	g_mb_ctx.txbuf[g_mb_ctx.tx_len++] = (uint8_t)(crc & 0x00ff); 
 	
-	uart0_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
+	rs485_TransmitData(g_mb_ctx.txbuf, g_mb_ctx.tx_len);
 	
 }
 
@@ -450,10 +520,10 @@ void mb_handle(void)
 */
 void Uart0_RxDataHandle(void)
 {
-		g_mb_ctx.rxbuf = uart0_info.recv_buffer;
-		g_mb_ctx.rx_len = uart0_info.recv_len;
-		g_mb_ctx.txbuf = uart0_info.send_buffer;
-		g_mb_ctx.txbuf_size = UART0_TRANSMIT_DATA_POOL_COUNT;
+		g_mb_ctx.rxbuf = rs485_info.recv_buffer;
+		g_mb_ctx.rx_len = rs485_info.recv_len;
+		g_mb_ctx.txbuf = rs485_info.send_buffer;
+		g_mb_ctx.txbuf_size = UART_TRANSMIT_DATA_POOL_COUNT;
 		g_mb_ctx.tx_len = 0;
 		g_mb_ctx.exception_code = NO_EXCEPTION;
 	
@@ -462,8 +532,9 @@ void Uart0_RxDataHandle(void)
 		uint8_t ret_write = RET_OK;
 	
 		if(g_mb_ctx.rx_len > 2){
+			
+			//printf("len:%d, addr:0x%x \r\n", g_mb_ctx.rx_len, g_mb_ctx.rxbuf[0]);
 
-	
 			//check rs485 addr 
 			if(config->addr == g_mb_ctx.rxbuf[0] || BROADCAST_ADDR == g_mb_ctx.rxbuf[0]){
 				
@@ -638,14 +709,14 @@ void Uart0_RxDataHandle(void)
 		} //END rx_len 
 		
 		if(g_mb_ctx.rx_len > 0){
-			uart0_RecvData();
+			rs485_RecvData();
 		}
 		
 		
 		
 		//´¦Àí 485 ÊÕ·¢×´Ì¬ 
-		if(uart0_info.dmasend_count >= UART_DMASEND_COUNT_RESET){
-				uart0_info.dmasend_count = 0;
+		if(rs485_info.dmasend_count >= UART_DMASEND_COUNT_RESET){
+				rs485_info.dmasend_count = 0;
 				RS485_RX_EN;
 		}
 
@@ -663,14 +734,14 @@ void Uart0_RxDataHandle(void)
 
 void Task_Init(void)
 { 
-    uart_Initialize();
+    rs485_Initialize();
 
-		memcpy(uart0_info.send_buffer, (void *)"Booted", 6);
+		memcpy(rs485_info.send_buffer, (void *)"Booted", 6);
 		
-		uart0_info.send_len = 6;
+		rs485_info.send_len = 6;
 		
-		uart0_TransmitData(uart0_info.send_buffer, uart0_info.send_len);
-		uart0_RecvData();
+		rs485_TransmitData(rs485_info.send_buffer, rs485_info.send_len);
+		rs485_RecvData();
 		
 		
 }
@@ -686,9 +757,13 @@ void Task_Init(void)
 void Task_Handle(void)
 {
 	
-		Process_RunLedPrd();
-		Process_ThreeStatus();
+		Process_RunPrd();
+		//Process_Motor();
+		Process_Storage(); 
+
 		Uart0_RxDataHandle();
+		
+		Process_Poweroff();
 
 }
 

+ 50 - 0
User/pid.c

@@ -0,0 +1,50 @@
+#include "pid.h"
+ 
+//用于初始化pid参数的函数
+void PID_Init(PID *pid, float p, float i, float d, float maxI, float maxOut)
+{
+    pid->kp = p;
+    pid->ki = i;
+    pid->kd = d;
+    pid->maxIntegral = maxI;
+    pid->maxOutput = maxOut;
+	
+		pid->error = 0;
+		pid->lastError = 0;
+		pid->integral = 0;
+		pid->output = 0;
+}
+ 
+//进行一次pid计算
+//参数为(pid结构体,目标值,反馈值),计算结果放在pid结构体的output成员中
+void PID_Calc(PID *pid, float reference, float feedback)
+{
+ 	//更新数据
+    pid->lastError = pid->error; //将旧error存起来
+    pid->error = reference - feedback; //计算新error
+	
+    //计算微分
+    float dout = (pid->error - pid->lastError) * pid->kd;
+    //计算比例
+    float pout = pid->error * pid->kp;
+    //计算积分
+    pid->integral += pid->error * pid->ki;
+	
+    //积分限幅
+    if(pid->integral > pid->maxIntegral) 
+			pid->integral = pid->maxIntegral;
+    else if(pid->integral < -pid->maxIntegral) 
+			pid->integral = -pid->maxIntegral;
+		
+    //计算输出
+    pid->output = pout+dout + pid->integral;
+	
+    //输出限幅
+    if(pid->output > pid->maxOutput) 
+			pid->output =   pid->maxOutput;
+    else if(pid->output < -pid->maxOutput) 
+			pid->output = -pid->maxOutput;
+		
+		
+}
+ 

+ 69 - 0
User/pid.h

@@ -0,0 +1,69 @@
+
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2018. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+
+/*************<start>******************/
+
+#ifndef PID_H__
+#define PID_H__
+
+#if 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "ac780x.h"
+
+
+typedef struct
+{
+   	float kp, ki, kd; //三个系数
+    float error, lastError; //误差、上次误差
+    float integral, maxIntegral; //积分、积分限幅
+    float output, maxOutput; //输出、输出限幅
+}PID;
+
+
+void PID_Init(PID *pid, float p, float i, float d, float maxI, float maxOut);
+void PID_Calc(PID *pid, float reference, float feedback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif 
+
+#endif //PID_H__

+ 374 - 60
User/process.c

@@ -1,20 +1,73 @@
 #include "process.h"
 #include "gpio.h"
 #include "ac780x_gpio.h"
+#include "string.h"
+#include "adc.h"
+#include "Motor.h"
+#include "W25Q64.h"
+#include "AngleSensor.h"
+#include "pid.h"
+#include "cfg.h"
+#include "Ds1302.h"
+#include "storage.h"
 
-uint16_t	g_blinkLedTime;		/*LED闪烁频率控制时间*/
-uint16_t	g_blinkLedTgtTime;	/*LED目标闪烁频率*/
-uint8_t		g_detectTime;			/*三个开关状态,检测时间*/
+uint8_t		g_devicebusy = 0;
+uint16_t	g_blinkLedTime = 0;									/*LED闪烁频率控制时间*/
+uint16_t	g_blinkLedTgtTime = BLINK_LED_DFTT;	/*LED目标闪烁频率*/
+uint16_t	g_period1000ms = 0;
+uint8_t		g_detectTime = 0;										/*状态检测时间*/
 
-#define STATUS_DETECTINTERVAL  (60)  /*60ms * 8 == 500ms  */
+uint32_t	g_poweroff_count = 0;				/*外部电源停止后、每秒计数加1*/
 
-uint8_t g_lockstatus;
-uint8_t g_unlockstatus;
-uint8_t g_coverstatus;
+#define STATUS_DETECTINTERVAL  (10)  /*10ms */
 
-uint8_t lockbits;
-uint8_t unlockbits;
-uint8_t coverbits;
+
+uint8_t g_runstate; //运行状态,切换LED灯光 
+
+uint8_t g_lockstatus = STATUS_UNKOWN;
+uint8_t g_coverstatus = STATUS_COVERCLOSE;
+
+//电机状态 
+uint8_t g_motorstate = MOTOR_INIT;
+uint8_t  g_runReady = 0;
+uint16_t g_runTime = 0;
+
+//状态持续计数,用来起到滤波作用 
+//uint8_t tmp_status;
+uint8_t g_lockcount[STATUS_LOCKALL]={0};
+uint8_t g_covercount[STATUS_COVERALL]={0};
+
+static float s_angle = 0.0;
+static float tmp_angle = 0.0;
+static uint8_t get_lockstatus();
+static PID g_pid = {0}; 
+static uint8_t tmp_speed;
+//static uint8_t tmp_time = 0;
+
+static void update_runstate()
+{
+
+		switch(g_lockstatus){
+			case STATUS_INTERMEDIATE:
+				g_runstate = STATE_INTERMEDIATE;
+				break;
+			case STATUS_LOCK:
+				g_runstate = STATE_LOCK;
+				break;
+			case STATUS_UNLOCK:
+				g_runstate = STATE_UNLOCK;
+				break;
+			case STATUS_UNKOWN:
+				g_runstate = STATE_EXCEPTION;
+				break;
+			default:
+				break;
+		};
+	
+
+
+
+}
 
 void Process_Init(void)
 {
@@ -23,94 +76,355 @@ void Process_Init(void)
 		g_blinkLedTgtTime = BLINK_LED_DFTT;
 	
 		g_detectTime = 0;
-	
-		g_lockstatus = GPIO_LEVEL_HIGH == GPIO_GetPinLevel(GPIO_CLOSE_KEY)? STATUS_OPEN:STATUS_CLOSE;
-		g_unlockstatus = GPIO_LEVEL_HIGH == GPIO_GetPinLevel(GPIO_OPEN_KEY)? STATUS_OPEN:STATUS_CLOSE;
-		g_coverstatus = GPIO_LEVEL_HIGH == GPIO_GetPinLevel(GPIO_COVER_KEY)? STATUS_OPEN:STATUS_CLOSE;
-	
-		lockbits = g_lockstatus == STATUS_OPEN?0xFF:0x00;
-		unlockbits = g_unlockstatus == STATUS_OPEN?0xFF:0x00;
-		coverbits = g_coverstatus == STATUS_OPEN?0xFF:0x00;
+		g_runstate = STATE_LOCK;
+
+		s_angle = AngleSensor_GetAngle();
+		g_lockstatus=get_lockstatus();
+
+
+		
+		g_coverstatus=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
+
+		g_motorstate = MOTOR_READY;
 	
 		/*上电默认LED点亮.*/
-		RUNLED_ON;
+		update_runstate();
 }
 
-void Process_RunLedPrd(void)
+void Process_RunPrd(void)
 {
+	uint8_t i=0;
+	uint8_t _status = 0;
+	
 	/*周期性地检查LED闪烁,LED2和LED3同时闪烁.*/
 	if (g_blinkLedTime >= g_blinkLedTgtTime)
 	{
 		g_blinkLedTime = 0;
+		update_runstate();
 		
-		RUNLED_TOGGLE;
-	}
+		switch(g_runstate){
+			case STATE_LOCK:
+				REDLED_OFF;
+				GREENLED_TOGGLE;
+				break;
+			case STATE_UNLOCK:
+				GREENLED_OFF;
+				REDLED_TOGGLE;
+				break;
+			case STATE_INTERMEDIATE:
+				REDGREEN_TOGGLE;
+				break;
+			case STATE_OPENCOVER:
+				REDLED_OFF;
+			  GREENLED_ON;
+				break;
+			case STATE_EXCEPTION:
+			default:
+				GREENLED_OFF;
+			  REDLED_ON;
+				break;
+		
+		};
 	
-}
+		
 
+		//printADCValue();
+		//printMotorCurrent();
+		//printf(" Motor Current:%f mA \r\n", getMotorCurrent());
+		
+		//W25Q64_PrintInfo();
+		//AngleSensor_PrintInfo();
 
-void Process_ThreeStatus(void)
-{
-	if(g_detectTime >= STATUS_DETECTINTERVAL){
-		g_detectTime = 0;
 		
+	}
+	
+	
+	//
+	if(g_period1000ms >= 1000){
+		g_period1000ms=0;
 		
-		if (GPIO_LEVEL_HIGH == GPIO_GetPinLevel(GPIO_CLOSE_KEY)){
-			lockbits=(lockbits<<1)|0x01;
-		}else{
-			lockbits=(lockbits<<1)|0x00;
-		}
+		Storage_CountReduce();
 		
-		if (GPIO_LEVEL_HIGH == GPIO_GetPinLevel(GPIO_OPEN_KEY)){
-			unlockbits=(unlockbits<<1)|0x01;
-		}else{
-			unlockbits=(unlockbits<<1)|0x00;
-		}
+		g_poweroff_count++;
+		
+		if(Gpio_IsDC24()){
+			printf(" DC24 Supply \r\n");
 		
-		if (GPIO_LEVEL_HIGH == GPIO_GetPinLevel(GPIO_COVER_KEY)){
-			coverbits=(coverbits<<1)|0x01;
 		}else{
-			coverbits=(coverbits<<1)|0x00;
-		}
+			printf(" Battery Supply \r\n");
 		
-		if(g_lockstatus == STATUS_CLOSE && lockbits == 0xFF){
-				g_lockstatus = STATUS_OPEN;
-		}else if(g_lockstatus == STATUS_OPEN && lockbits == 0x00){
-				g_lockstatus = STATUS_CLOSE;
 		}
 		
-		if(g_unlockstatus == STATUS_CLOSE && unlockbits == 0xFF){
-				g_unlockstatus = STATUS_OPEN;
-		}else if(g_unlockstatus == STATUS_OPEN && unlockbits == 0x00){
-				g_unlockstatus = STATUS_CLOSE;
-		}
+		printf(" Battery Voltage:%f V \r\n", getBatteryVoltage());
+		
+	
+	}
+	
+	
+	
+	/*
+	
+	//10ms 
+	if(g_detectTime >= 10){
+		g_detectTime = 0;
 		
-		if(g_coverstatus == STATUS_CLOSE && coverbits == 0xFF){
-				g_coverstatus = STATUS_OPEN;
-		}else if(g_coverstatus == STATUS_OPEN && coverbits == 0x00){
-				g_coverstatus = STATUS_CLOSE;
+		//锁状态 
+		_status=get_lockstatus();
+		for(i=0; i<STATUS_LOCKALL; i++){
+			if(_status == i){
+				g_lockcount[i]++;
+				if(g_lockcount[i] >= 5){
+					g_lockstatus = i;
+				}
+				
+			}else{
+				g_lockcount[i]=0;
+			}
 		}
 		
+		//上盖状态 
+		_status=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
+		for(i=0; i<STATUS_COVERALL; i++){
+			if(_status == i){
+				g_covercount[i]++;
+				if(g_covercount[i] >= 10){
+					g_coverstatus = i;
+				}
+				
+			}else{
+				g_covercount[i]=0;
+			}
+		}
 	
 	}
 	
+	*/
+	
+}
+
+void Process_Timer10msCB(void)
+{
+	s_angle = AngleSensor_GetAngle();
+	g_lockstatus=get_lockstatus();
+	g_coverstatus=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
+	
 
+	//处理开关锁  
+	switch(g_motorstate){
+		case MOTOR_READY:
+			break;
+		case MOTOR_LOCKING:
+			if((STATUS_LOCK == g_lockstatus)|| (STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
+				Motor_Stop();
+				g_motorstate = MOTOR_STOPED;
+				g_runReady =1;
+				g_runTime=0;
+			}else{
+				PID_Calc(&g_pid, config->lock_threshold+3, s_angle);
+				
+				if(g_pid.error > 0){
+						tmp_speed =(uint8_t)(g_pid.output);
+						tmp_speed = tmp_speed<50?50:tmp_speed;
+						Motor_Positive(tmp_speed);
+				
+				}else{
+					Motor_Stop();
+					g_motorstate = MOTOR_STOPED;
+					g_runReady =1;
+					g_runTime=0;
+				}
+				
+			}
+			
+			break;
+		case MOTOR_UNLOCKING:
+			if((STATUS_UNLOCK == g_lockstatus)|| (STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
+				Motor_Stop();
+				g_motorstate = MOTOR_STOPED;
+				g_runReady =1;
+				g_runTime=0;
+			}else{
+				PID_Calc(&g_pid, config->unlock_threshold-3, s_angle);
+				
+				if(g_pid.error < 0){
+						tmp_speed =(uint8_t)(-g_pid.output);
+						tmp_speed = tmp_speed<50?50:tmp_speed;
+						Motor_Negative(tmp_speed);
+				
+				}else{
+					Motor_Stop();
+					g_motorstate = MOTOR_STOPED;
+					g_runReady =1;
+					g_runTime=0;
+				}
+				
+			}
+			break;
+		case MOTOR_STOPED:
+			if(g_runTime >= 5000){ //5S
+				g_motorstate = MOTOR_READY;
+			}
+			
+			break;
+		default:
+			break;
+
+	};
+	
+
+	//读取时间
+
+
+}
+
+
+uint8_t get_lockstatus()
+{
+		uint8_t status = STATUS_UNKOWN;
+		if(s_angle<0){
+			return status;
+		}
+	
+		if(config->lock_threshold > config->unlock_threshold){
+			
+			if((s_angle > config->lock_threshold)){
+					status = STATUS_LOCK;	
+			}else if(s_angle < config->unlock_threshold){
+					status = STATUS_UNLOCK;	
+			}else {
+					status = STATUS_INTERMEDIATE;	
+			}
+				
+		}
+		
+		return status;
+}
+
+
+
+
+uint8_t Process_GetLockStatus(void)
+{
+		return get_lockstatus();
+}
+	
+uint8_t Process_GetCoverStatus(void)
+{
+		if(Gpio_IsOpenCover()){
+			return STATUS_COVEROPEN;
+		}else{
+			return STATUS_COVERCLOSE;
+		}
+}
+
+
+uint8_t Process_OpLock(uint8_t speed)
+{
+	
+	if((MOTOR_READY == g_motorstate) & (STATUS_LOCK != g_lockstatus)){
+		//Motor_Positive(speed);
+		g_motorstate = MOTOR_LOCKING;
+		g_runReady =1;
+		g_runTime=0;
+		
+		PID_Init(&g_pid, 5, 10, 0, 80, 100);
+	}
+	
+	return 0;
 }
 
+uint8_t Process_OpUnlock(uint8_t speed)
+{
+	
+	if((MOTOR_READY == g_motorstate) & (STATUS_UNLOCK != g_lockstatus)){
+		//Motor_Negative(speed);
+		g_motorstate = MOTOR_UNLOCKING;
+		g_runReady =1;
+		g_runTime=0;
+	
+		PID_Init(&g_pid,5, 10, 0, 80, 100);
+	}
+
+	return 0;
+}
 
 
-uint8_t Process_LockStatus(void)
+uint8_t Process_CalibrationThreshold(uint8_t islock)
 {
-	return g_lockstatus==STATUS_OPEN?0x00:0x01;
+	if(islock){
+		
+		config->lock_threshold = AngleSensor_GetAngle();
+	
+	}else{
+		config->unlock_threshold = AngleSensor_GetAngle();
+	}
+	
+	return 0x00;
 }
 
-uint8_t Process_UnlockStatus(void)
+void Process_Storage(void)
 {
-	return g_unlockstatus==STATUS_OPEN?0x00:0x01;
+		static uint8_t pre_lstatus = STATUS_INTERMEDIATE;
+		static uint8_t pre_cstatus = STATUS_COVEROPEN;
+	
+		if(Gpio_IsDC24()){
+			
+			pre_lstatus = g_lockstatus;
+			pre_cstatus = g_coverstatus;
+			
+			
+		}else{
+			
+			if(pre_lstatus != g_lockstatus){
+					if(STATUS_LOCK == g_lockstatus){
+						
+						Storage_AddItem(ITEM_RECORD, EVENT_MANUAL_LOCK);
+					
+					}else if(STATUS_UNLOCK == g_lockstatus){
+						Storage_AddItem(ITEM_RECORD, EVENT_MANUAL_UNLOCK);
+					}
+				
+					pre_lstatus = g_lockstatus;
+			
+			}
+			
+			if(pre_cstatus != g_coverstatus){
+				if(STATUS_COVEROPEN == g_coverstatus){
+					Storage_AddItem(ITEM_RECORD, EVENT_OPENCOVER);
+				}
+				
+				pre_cstatus = g_coverstatus;
+			
+			}
+			
+		}
+		
+		
+
 }
 
-uint8_t Process_CoverStatus(void)
+void Process_Poweroff(void)
 {
-	return g_coverstatus==STATUS_OPEN?0x00:0x01;
+	static float battery_v = 0.0;
+		if(Gpio_IsDC24()){
+			
+			g_poweroff_count = 0;
+		}else{
+			
+			battery_v = getBatteryVoltage();
+			
+			if((g_poweroff_count >= 2*60*60) || (battery_v < (3.3))){ // 2小时后或电池电压小于3.3V 关机 
+				
+					g_poweroff_count = 0;
+					Storage_Save();
+					mdelay(500);
+					LDOEn_DISABLE;
+					//NVIC_SystemReset();
+					printf(" NVIC_SystemReset  \r\n");
+				
+			}
+		}
+
 }
 
+

+ 51 - 10
User/process.h

@@ -43,27 +43,68 @@ extern "C" {
 #include "ac780x_gpio.h"
 
 /*************<extern>*****************/	
-extern uint16_t		g_blinkLedTime;		/*LED闪烁频率控制时间*/
+extern uint8_t		g_devicebusy;       /* 电机是否在转*/
+extern uint16_t		g_blinkLedTime;		  /*LED闪烁频率控制时间*/
 extern uint16_t		g_blinkLedTgtTime;	/*LED目标闪烁频率*/
+extern uint16_t	  g_period1000ms;
 extern uint8_t		g_detectTime;	
+extern uint8_t  	g_runReady;
+extern uint16_t 	g_runTime;
 
 #define BLINK_LED_MINT		(100)	/*闪烁LED灯最小时间间隔*/
 #define BLINK_LED_MAXT		(2000)	/*闪烁LED灯最大时间间隔*/
-#define BLINK_LED_DFTT		(1000)	/*闪烁LED默认时间间隔*/
+#define BLINK_LED_DFTT		(500)	/*闪烁LED默认时间间隔*/
+
+//设备状态
+#define STATE_LOCK     				  (0x00)  /*锁止状态*/
+#define STATE_UNLOCK   					(0x01)	/*开锁状态*/
+#define STATE_INTERMEDIATE      (0x02)	/*中间状态*/
+#define STATE_OPENCOVER         (0x03)	/*开盖状态*/
+#define STATE_EXCEPTION         (0x04)	/*异常状态*/
+
+//锁舌状态
+enum _lockstatus {
+	STATUS_INTERMEDIATE = 0, 			/*中间状态*/
+	STATUS_LOCK,									/*锁止状态*/
+	STATUS_UNLOCK,								/*开锁状态*/
+	STATUS_UNKOWN,								/*未知状态,设备异常了*/
+	STATUS_LOCKALL
+};
+
+
+//上盖状态 
+enum _coverstatus {
+	STATUS_COVERCLOSE =0, 				/*闭合状态*/
+	STATUS_COVEROPEN,							/*开盖状态*/
+	STATUS_COVERALL
+};
+
+//电机状态 
+
+#define	MOTOR_INIT						(0)			
+#define	MOTOR_READY						(1)							
+#define	MOTOR_LOCKING					(2)
+#define	MOTOR_UNLOCKING				(3)
+#define	MOTOR_STOPED					(4)
+
 
-#define STATUS_OPEN  (0x01)
-#define STATUS_CLOSE (0x00)
 
 
 void Process_Init(void);
-void Process_RunLedPrd(void); 
+void Process_RunPrd(void); 
+
+void Process_Timer10msCB(void);
+
+
+void Process_Poweroff(void); 
+void Process_Storage(void); 
 
-void Process_ThreeStatus(void); 
+uint8_t Process_GetLockStatus(void); 
+uint8_t Process_GetCoverStatus(void); 
+uint8_t Process_OpLock(uint8_t speed); 
+uint8_t Process_OpUnlock(uint8_t speed); 
+uint8_t Process_CalibrationThreshold(uint8_t islock); 
 
-uint8_t Process_LockStatus(void); 
-uint8_t Process_UnlockStatus(void); 
-uint8_t Process_CoverStatus(void); 
-    
 #ifdef __cplusplus
 }
 #endif

+ 210 - 7
User/protocol.c

@@ -2,12 +2,19 @@
 #include "process.h"
 #include "cfg.h"
 #include "uart.h"
+#include "Motor.h"
+#include "AngleSensor.h"
+#include "Ds1302.h"
+#include "storage.h"
 
 
+static DataItem tmp_record;
+static uint8_t tmp_i=0;
+	
 #ifdef IS_BOOTLOADER
-uint32_t Firmware_Version[4] = {1, 0, 0, 20240401};
+uint32_t Firmware_Version[4] = {1, 0, 0, 20240711};
 #else
-uint32_t Firmware_Version[4] = {1, 1, 1, 20240401};
+uint32_t Firmware_Version[4] = {1, 1, 1, 20240711};
 #endif
 
 
@@ -101,21 +108,139 @@ uint16_t Read_Baudrate(uint8_t *pBuf, uint16_t buf_len)
 }
 
 
-uint16_t Read_LockStatus(uint8_t *pBuf, uint16_t buf_len)
+//读取锁状态 
+uint16_t Read_LockStatus(uint8_t *pBuf, uint16_t buf_len) 
 {
+	if( buf_len < 2){
+		return 0;
+	}
+	
+	pBuf[0] = Process_GetLockStatus();   //锁状态 
+	pBuf[1] = Process_GetCoverStatus();  //上盖状态
+	
+	return 2;
+}
 
+//读取开锁、上锁阀值 
+uint16_t Read_Threshold(uint8_t *pBuf, uint16_t buf_len)
+{
+	if( buf_len < 8){
+		return 0;
+	}
+	
+	pBuf[0] = ((uint8_t*)(&config->unlock_threshold))[0];
+	pBuf[1] = ((uint8_t*)(&config->unlock_threshold))[1];
+	pBuf[2] = ((uint8_t*)(&config->unlock_threshold))[2];
+	pBuf[3] = ((uint8_t*)(&config->unlock_threshold))[3];
+	
+	pBuf[4] = ((uint8_t*)(&config->lock_threshold))[0];
+	pBuf[5] = ((uint8_t*)(&config->lock_threshold))[1];
+	pBuf[6] = ((uint8_t*)(&config->lock_threshold))[2];
+	pBuf[7] = ((uint8_t*)(&config->lock_threshold))[3];
+	
+	return 8;
+
+}
+
+
+//读取编码器角度值  
+uint16_t Read_Angle(uint8_t *pBuf, uint16_t buf_len)
+{
 	if( buf_len < 4){
 		return 0;
 	}
 	
-	pBuf[0] = Process_LockStatus();
-	pBuf[1] = Process_UnlockStatus();
-	pBuf[2] = Process_CoverStatus();
-	pBuf[3] = 0x00;
+	float angle = AngleSensor_GetAngle();
+	
+	pBuf[0] = ((uint8_t*)(&angle))[0];
+	pBuf[1] = ((uint8_t*)(&angle))[1];
+	pBuf[2] = ((uint8_t*)(&angle))[2];
+	pBuf[3] = ((uint8_t*)(&angle))[3];
 	
 	return 4;
+
 }
 
+//读取设备日期时间 
+uint16_t Read_DateTime(uint8_t *pBuf, uint16_t buf_len)
+{
+
+	if( buf_len < 6){
+		return 0;
+	}
+	
+	DS1302_UpdateTime();
+	
+	
+	pBuf[0] = g_dateTime.year;
+	pBuf[1] = g_dateTime.month;
+	
+	pBuf[2] = g_dateTime.day;
+	pBuf[3] = g_dateTime.hour;
+	pBuf[4] = g_dateTime.minute;
+	pBuf[5] = g_dateTime.second;
+
+	return 6;
+	
+}
+
+
+//读取设备历史记录条数
+uint16_t Read_RecordsNum(uint8_t *pBuf, uint16_t buf_len)
+{
+	if( buf_len < 2){
+		return 0;
+	}
+	
+	uint16_t num = Storage_GetItemNum();
+	
+	pBuf[0] = (num>>8)&0xFF;
+	pBuf[1] = num&0xFF;
+	
+	return 2;
+	
+}
+
+//读取历史记录
+uint16_t Read_Records(uint8_t num, uint8_t *pBuf, uint16_t buf_len)
+{
+		if((num > MAX_RECORDS_PERTIME) ||(buf_len < SIZE_RECORD*num)){
+			return 0;
+		}
+		
+		if(num > Storage_GetItemNum()){
+			//return 0;
+			num = Storage_GetItemNum();
+		}
+		
+
+		for(tmp_i=0; tmp_i < num; tmp_i++){
+			if(0 == Storage_GetItemFromOldest2(tmp_i, &tmp_record))
+			{
+				pBuf[tmp_i*SIZE_RECORD+0] = tmp_record.itemtype;
+				pBuf[tmp_i*SIZE_RECORD+1] = tmp_record.eventtype;
+				
+				pBuf[tmp_i*SIZE_RECORD+2] = tmp_record.timestamp[0];
+				pBuf[tmp_i*SIZE_RECORD+3] = tmp_record.timestamp[1];
+				pBuf[tmp_i*SIZE_RECORD+4] = tmp_record.timestamp[2];
+				pBuf[tmp_i*SIZE_RECORD+5] = tmp_record.timestamp[3];
+				pBuf[tmp_i*SIZE_RECORD+6] = tmp_record.timestamp[4];
+				pBuf[tmp_i*SIZE_RECORD+7] = tmp_record.timestamp[5];
+			
+			}else{
+				break;
+			}
+			
+		}
+		
+		Storage_WaitDelete(tmp_i);
+		
+		return tmp_i*SIZE_RECORD;
+
+}
+
+
+
 
 /*=======================================================================================*/
 
@@ -130,6 +255,7 @@ uint8_t Write_Addr(uint8_t *pdata, uint8_t len)
 	}
 }
 
+
 uint8_t Write_Baudrate(uint8_t *pdata, uint8_t len)
 {
 	if(len == 2){
@@ -186,4 +312,81 @@ uint8_t Write_Devicetype(uint8_t *pdata, uint8_t len)
 }
 
 
+//开锁、上锁操作
+uint8_t Write_LockOp(uint8_t *pdata, uint8_t len)
+{
+	if(len == 2){
+		
+		if(0x01 == pdata[0]){ //开锁
+			Process_OpUnlock(pdata[1]); 
+		
+		}else if(0x02 == pdata[0]){ //上锁 
+			Process_OpLock(pdata[1]); 
+		}else if(0x03 == pdata[0]){ //正转测试 
+			Motor_Positive(pdata[1]);
+		}else if(0x04 == pdata[0]){ //反转测试 
+			Motor_Negative(pdata[1]);
+		}
+	
+		return RET_OK;
+		
+	}else{
+		return RET_DATAINVALID;
+	}
+}
+
+//开锁阀值、上锁阀值标定
+uint8_t Write_ThresholdCalibration(uint8_t *pdata, uint8_t len)
+{
+	
+	if(len == 2){
+		
+		if(0x01 == pdata[1]){ //开锁
+			Process_CalibrationThreshold(0);
+		
+		}else if(0x02 == pdata[1]){ //上锁 
+			Process_CalibrationThreshold(1);
+		}
+		return RET_OK|RET_NEED_SAVE;
+		
+	}else{
+		return RET_DATAINVALID;
+	}
+	
+}
+
+//标定设备日期时间 
+uint8_t Write_DateTime(uint8_t *pdata, uint8_t len)
+{
+	if(len == 6){
+		
+		g_dateTime.year = pdata[0];
+		g_dateTime.month = pdata[1];
+		g_dateTime.day = pdata[2];
+		g_dateTime.hour = pdata[3];
+		g_dateTime.minute = pdata[4];
+		g_dateTime.second = pdata[5];
+		
+		return RET_OK;
+		
+	}else{
+		return RET_DATAINVALID;
+	}
+
+}
+
+//删除已读取设备历史记录 
+uint8_t Write_RecordsDelete(uint8_t *pdata, uint8_t len)
+{
+		if(len == 2){
+		
+		Storage_DeleteConfirm();
+		
+		return RET_OK;
+		
+	}else{
+		return RET_DATAINVALID;
+	}
+	
+}
 

+ 27 - 6
User/protocol.h

@@ -50,8 +50,16 @@ extern "C" {
 
 #define Cmd_Addr    					 (0x0010)
 #define Cmd_Baudrate    			 (0x0011)
+#define Cmd_DateTime					 (0x0012)
 #define Cmd_LockStatus    		 (0x0020)
-//#define Cmd_FirmwareVersion    (0x0000)
+#define Cmd_LockOp    		 		 (0x0021)
+#define Cmd_Threshold    		 	 (0x0022)
+#define Cmd_ReadThreshold    	 (0x0023)
+#define Cmd_ReadAngle    	 		 (0x0027)
+//#define 
+#define Cmd_ReadRecordNum    	 (0x0029)
+#define Cmd_ReadRecords	       (0x002A)
+#define Cmd_RecordDelete  		 (0x005A)
 
 #define Cmd_IapUpgrade    		 (0xAABB)
 
@@ -66,7 +74,8 @@ extern "C" {
 #define INVALID_DATA   					(0x03)
 #define DEVICE_FAULT   					(0x04)
 
-
+#define SIZE_RECORD							(8)
+#define MAX_RECORDS_PERTIME     (12)
 
 //读取时返回,数据长度, 如果返回 0, 说明buf_len 不够, 设备故障
 
@@ -77,11 +86,16 @@ uint16_t Read_Devicetype(uint8_t *pBuf, uint16_t buf_len);
 uint16_t Read_Addr(uint8_t *pBuf, uint16_t buf_len);
 uint16_t Read_Baudrate(uint8_t *pBuf, uint16_t buf_len); 
 
-uint16_t Read_LockStatus(uint8_t *pBuf, uint16_t buf_len);
+uint16_t Read_LockStatus(uint8_t *pBuf, uint16_t buf_len); //读取锁状态 
+uint16_t Read_Threshold(uint8_t *pBuf, uint16_t buf_len);//读取开锁、上锁阀值 
+uint16_t Read_Angle(uint8_t *pBuf, uint16_t buf_len);//读取编码器角度值  
+uint16_t Read_DateTime(uint8_t *pBuf, uint16_t buf_len);//读取设备日期时间 
 
+uint16_t Read_RecordsNum(uint8_t *pBuf, uint16_t buf_len);//读取设备历史记录条数
+uint16_t Read_Records(uint8_t num, uint8_t *pBuf, uint16_t buf_len);//读取历史记录
 
 
-#define RET_ERROR_MASK     (0xF0)
+#define RET_ERROR_MASK    (0xF0)
 #define RET_OK  		 			(0x00)
 #define RET_NEED_SAVE			(0X01)
 #define RET_NEED_REBOOT		(0X02)
@@ -90,14 +104,21 @@ uint16_t Read_LockStatus(uint8_t *pBuf, uint16_t buf_len);
 #define RET_CMDINVALID  	(0x20)
 //#define RET_DATAINVALID  	(3)
 
+
 //写入成功时返回 RET_OK
 //写入不成功时,返回 RET_DATAINVALID
 uint8_t Write_Addr(uint8_t *pdata, uint8_t len); 
 uint8_t Write_Baudrate(uint8_t *pdata, uint8_t len);
 uint8_t Write_HardwareVersion(uint8_t *pdata, uint8_t len); 
 uint8_t Write_Deviceid(uint8_t *pdata, uint8_t len); 
-uint8_t Write_Devicetype(uint8_t *pdata, uint8_t len); 
-  
+uint8_t Write_Devicetype(uint8_t *pdata, uint8_t len);
+
+uint8_t Write_LockOp(uint8_t *pdata, uint8_t len); //开锁、上锁操作
+uint8_t Write_ThresholdCalibration(uint8_t *pdata, uint8_t len); //开锁阀值、上锁阀值标定
+uint8_t Write_DateTime(uint8_t *pdata, uint8_t len);//标定设备日期时间 
+
+uint8_t Write_RecordsDelete(uint8_t *pdata, uint8_t len);//读取设备历史记录确认 
+
     
 #ifdef __cplusplus
 }

+ 215 - 0
User/storage.c

@@ -0,0 +1,215 @@
+#include "storage.h"
+#include "Ds1302.h"
+
+#define INDEX_ADDR  (0x00)
+#define INDEX_MAGIC (0xAA55AA55)
+
+typedef struct _recordindex
+{
+		uint32_t  magic;
+    uint32_t  start_addr; 
+		uint32_t  next_addr; 
+    uint16_t  num;
+		uint16_t  max_num;
+		uint16_t  crc;
+}record_index; 
+
+static record_index g_recordindex;
+static uint8_t wait_time = 0;
+static uint8_t will_deletecount = 0;
+
+//uint16_t g_maxRecordNum = MAX_RECORD_NUM;
+//uint32_t g_start_addr = DEFAULT_START_ADDR;
+//uint16_t g_Record_Num = 0;
+//uint32_t g_next_addr = DEFAULT_START_ADDR;
+
+static void update_index(void);
+static uint8_t read_recordindex(void);
+
+void Storage_Init(void)
+{
+		wait_time=0;
+	  will_deletecount = 0;
+	
+		W25Q64_Init();
+	
+		read_recordindex();
+	
+		printf("Storage_Init: num:%d \r\n", g_recordindex.num);
+
+}
+
+uint16_t Storage_GetItemNum(void)
+{
+	return g_recordindex.num;
+}
+
+void Storage_AddItem(uint8_t itemtype, uint8_t eventtype)
+{
+		DataItem item;
+		uint8_t i=0;
+		uint8_t* pItem = (uint8_t*)&item;
+		item.magic = ITEM_MAGIC;
+		item.itemtype = itemtype;
+		item.eventtype = eventtype;
+		
+		//timestamp 
+		item.timestamp[0] = g_dateTime.year;
+		item.timestamp[1] = g_dateTime.month;
+		item.timestamp[2] = g_dateTime.day;
+		item.timestamp[3] = g_dateTime.hour;
+		item.timestamp[4] = g_dateTime.minute;
+		item.timestamp[5] = g_dateTime.second;
+	
+		//for(i=0; i<6; i++){
+		//	item.timestamp[i] = 0x00;
+		//}
+		item.crc = 0x00;
+		
+		printf("Storage_AddItem: itemtype:%d, eventtype:%d \r\n", itemtype, eventtype);
+		
+		if(0 == g_recordindex.next_addr%SECTOR_SIZE){ //新的 sector 需要先擦除
+			printf("Storage_AddItem: erssector nextaddr:0x%x \r\n", g_recordindex.next_addr);
+			W25Q64_ErsSector(g_recordindex.next_addr, 1);//擦除1个扇区4KB
+		}
+		
+		//printf("Storage_AddItem: write start \r\n");
+		
+		W25Q64_WriteBytes(g_recordindex.next_addr, pItem, sizeof(DataItem));
+		g_recordindex.num++;
+		g_recordindex.next_addr += PAGE_SIZE;
+		
+		//printf("Storage_AddItem: write ok \r\n");
+		
+		if(g_recordindex.next_addr >= (g_recordindex.start_addr+MAX_STORAGE_SPACE)){
+				g_recordindex.next_addr = g_recordindex.start_addr;
+		}
+		
+		if(g_recordindex.num > MAX_RECORD_NUM){
+				g_recordindex.num = MAX_RECORD_NUM;
+		}
+		
+		update_index();
+		
+}
+
+
+//读取一条记录,从最老的开始
+// return 0 ,成功 , 非0 失败 
+uint8_t Storage_GetItemFromOldest(DataItem* pitem)
+{
+	uint32_t item_addr = 0;
+
+	if(0 == g_recordindex.num ){
+		return 1;
+	}
+	
+	if(g_recordindex.start_addr+g_recordindex.num*PAGE_SIZE <= g_recordindex.next_addr){
+		item_addr = g_recordindex.next_addr - g_recordindex.num*PAGE_SIZE;
+	}else{
+		item_addr = g_recordindex.next_addr+MAX_STORAGE_SPACE-g_recordindex.num*PAGE_SIZE;
+	}
+	
+	
+	W25Q64_ReadBytes(item_addr, (uint8_t *)pitem, sizeof(DataItem));
+	
+	g_recordindex.num--;
+	
+	return 0;
+
+}
+
+//读取第read_id条记录,从最老的开始
+// return 0 ,成功 , 非0 失败 , 读取并不删除 
+uint8_t Storage_GetItemFromOldest2(uint8_t read_id, DataItem* pitem)
+{
+	uint32_t item_addr = 0;
+
+	if(read_id > g_recordindex.num-1 ){
+		return 1;
+	}
+	
+	if(g_recordindex.start_addr+g_recordindex.num*PAGE_SIZE <= g_recordindex.next_addr){
+		item_addr = g_recordindex.next_addr - (g_recordindex.num-read_id)*PAGE_SIZE;
+	}else{
+		item_addr = g_recordindex.next_addr+MAX_STORAGE_SPACE-(g_recordindex.num-read_id)*PAGE_SIZE;
+	}
+	
+	
+	W25Q64_ReadBytes(item_addr, (uint8_t *)pitem, sizeof(DataItem));
+	
+	//g_recordindex.num--;
+	
+	return 0;
+}
+
+void Storage_WaitDelete(uint8_t num)
+{
+	wait_time = 5;
+	if(num > g_recordindex.num){
+		will_deletecount = g_recordindex.num;
+	}else{
+		will_deletecount = num;
+	}
+	
+}
+void Storage_DeleteConfirm(void)
+{
+		g_recordindex.num -= will_deletecount;
+		update_index();
+}
+
+//每秒执行一次
+void Storage_CountReduce(void)
+{
+	
+	if(wait_time > 0){
+		 wait_time--;
+		if(0 == wait_time){
+			will_deletecount=0;
+		}
+	
+	}
+
+}
+
+
+uint8_t read_recordindex(void)
+{
+	
+		W25Q64_ReadBytes(INDEX_ADDR, (uint8_t *)&g_recordindex, sizeof(record_index));
+		
+		if(INDEX_MAGIC == g_recordindex.magic){
+			
+			
+		}else{
+			
+			g_recordindex.magic = INDEX_MAGIC;
+			g_recordindex.max_num = MAX_RECORD_NUM;
+			g_recordindex.num = 0;
+			g_recordindex.start_addr = DEFAULT_START_ADDR;
+			g_recordindex.next_addr = DEFAULT_START_ADDR;
+		}
+		
+		return 0;
+}
+
+void update_index(void)
+{
+	/*擦除数据.*/
+	//printf("update_index 111 \r\n");
+	W25Q64_ErsSector(INDEX_ADDR, 1);//擦除1个扇区4KB
+	
+	//printf("update_index 222 \r\n");
+	W25Q64_WriteBytes(INDEX_ADDR, (uint8_t *)&g_recordindex, sizeof(record_index));
+	
+	printf("update_index 333 \r\n");
+
+}
+
+void Storage_Save(void)
+{
+	update_index();
+}
+
+

+ 97 - 0
User/storage.h

@@ -0,0 +1,97 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("AutoChips Software") are
+ * protected under relevant copyright laws. The information contained herein is
+ * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
+ * the prior written permission of AutoChips inc. and/or its licensors, any
+ * reproduction, modification, use or disclosure of AutoChips Software, and
+ * information contained herein, in whole or in part, shall be strictly
+ * prohibited.
+ *
+ * AutoChips Inc. (C) 2016. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
+ * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
+ * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
+ * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
+ * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
+ * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
+ * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
+ * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
+ * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
+ * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
+ * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
+ * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
+ * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
+ * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
+ * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
+ */
+ 
+
+#ifndef STORAGE_H
+#define STORAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*************<include>****************/
+#include "W25Q64.h"
+
+/*************<extern>*****************/	
+#define DEFAULT_START_ADDR  (0x10000)   //从block1 开始
+#define MAX_STORAGE_SPACE   (0x100000)  //1MB 
+#define MAX_RECORD_NUM      (200)
+
+//#define RECORD_SIZE				(256)	/**/
+#define ITEM_MAGIC				(0xA5A5)
+#define ITEM_LOG					(0x01)
+#define ITEM_RECORD				(0x02)
+
+
+enum _eventtype
+{ 
+		EVENT_MANUAL_UNLOCK = 1, 
+		EVENT_MANUAL_LOCK, 
+		EVENT_OPENCOVER
+};
+
+typedef struct 
+{
+		uint16_t magic;
+    uint8_t  itemtype;
+		uint8_t  eventtype;
+    uint8_t  timestamp[6];
+		uint16_t crc;
+
+}DataItem; 
+
+
+void Storage_Init(void);
+void Storage_Save(void);
+uint16_t Storage_GetItemNum(void);
+void Storage_AddItem(uint8_t itemtype, uint8_t eventtype);
+//读取一条记录,从最老的开始
+// return 0 ,成功 , 非0 失败  读取成功就删除 
+uint8_t Storage_GetItemFromOldest(DataItem* pitem);
+
+//读取第read_id条记录,从最老的开始
+// return 0 ,成功 , 非0 失败 , 读取并不删除 
+uint8_t Storage_GetItemFromOldest2(uint8_t read_id, DataItem* pitem);
+void Storage_WaitDelete(uint8_t num);
+void Storage_DeleteConfirm(void);
+
+//每秒执行一次
+void Storage_CountReduce(void);
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STORAGE_H */
+
+