Quellcode durchsuchen

增加SPI,MLX90614红外测温,RC522RFID模块,更新部分旧内容

woshiashuai vor 2 Jahren
Ursprung
Commit
d7ed7604c3
76 geänderte Dateien mit 1746 neuen und 2394 gelöschten Zeilen
  1. 0 0
      module_Template/ADXL345三轴传感器/ADXL345.c
  2. 0 0
      module_Template/ADXL345三轴传感器/ADXL345.h
  3. 0 0
      module_Template/ADXL345三轴传感器/ADXL345中文PDF.pdf
  4. 0 0
      module_Template/ADXL345三轴传感器/ADXL345接口图.jpg
  5. 0 0
      module_Template/ADXL345三轴传感器/IIC.c
  6. 0 0
      module_Template/ADXL345三轴传感器/IIC.h
  7. 0 0
      module_Template/ADXL345三轴传感器/README.txt
  8. 0 0
      module_Template/ASR_CI1122语音识别/ASR_usart.c
  9. 0 0
      module_Template/ASR_CI1122语音识别/ASR_usart.h
  10. 0 0
      module_Template/ASR_CI1122语音识别/启英泰伦CI1122离线语音模组.txt
  11. 0 0
      module_Template/ASR_CI1122语音识别/语音串口协议.txt
  12. 0 0
      module_Template/BY9301语音播报模块/BY9301-16P语音模块使用说明书V1.0.pdf
  13. 69 46
      module_Template/BY9301语音播报模块/BY9301.c
  14. 5 4
      module_Template/BY9301语音播报模块/BY9301.h
  15. 0 0
      module_Template/BY9301语音播报模块/BY9301接口图.jpg
  16. 0 0
      module_Template/DHT11温湿度模块/DHT11.c
  17. 0 0
      module_Template/DHT11温湿度模块/DHT11.h
  18. 0 0
      module_Template/DHT11温湿度模块/DHT11接口图.jpg
  19. 0 0
      module_Template/DHT11温湿度模块/README.txt
  20. 0 0
      module_Template/DS1302时钟模块/DS1302.c
  21. 0 0
      module_Template/DS1302时钟模块/DS1302.h
  22. 0 0
      module_Template/DS1302时钟模块/DS1302接口图.jpg
  23. 0 0
      module_Template/DS1302时钟模块/README.txt
  24. 0 0
      module_Template/DS18B20温度传感器/DS18B20.c
  25. 0 0
      module_Template/DS18B20温度传感器/DS18B20.h
  26. 0 0
      module_Template/DS18B20温度传感器/README.txt
  27. 0 0
      module_Template/MEMS_CH2O甲醛传感器/IIC.c
  28. 0 0
      module_Template/MEMS_CH2O甲醛传感器/IIC.h
  29. 0 0
      module_Template/MEMS_CH2O甲醛传感器/MEMS_CH2O.c
  30. 0 0
      module_Template/MEMS_CH2O甲醛传感器/MEMS_CH2O.h
  31. 0 0
      module_Template/MEMS_CH2O甲醛传感器/MEMS数字甲醛传感器JED116-001.docx
  32. 0 0
      module_Template/MEMS_CH2O甲醛传感器/MEMS甲醛接口图.jpg
  33. 0 0
      module_Template/MEMS_CH2O甲醛传感器/淘宝链接.txt
  34. BIN
      module_Template/MLX90614红外测温/BCC-MLX90614的通信资料.pdf
  35. BIN
      module_Template/MLX90614红外测温/MLX9014红外测温接口图.jpg
  36. 295 0
      module_Template/MLX90614红外测温/MLX90614.c
  37. 19 0
      module_Template/MLX90614红外测温/MLX90614.h
  38. 2 0
      module_Template/MLX90614红外测温/淘宝链接.txt
  39. 0 0
      module_Template/PM2.5检测模块/DST02-N_JTS-GG-2019-001N承认书V1.0 (2).pdf
  40. 0 0
      module_Template/PM2.5检测模块/PM2.5接口图.jpg
  41. 0 0
      module_Template/PM2.5检测模块/PM2.5模拟量驱动与算法.txt
  42. 0 0
      module_Template/PM2.5检测模块/淘宝链接.txt
  43. BIN
      module_Template/RC522-RFID模块/MFRC522.pdf
  44. 321 0
      module_Template/RC522-RFID模块/RC522.c
  45. 140 0
      module_Template/RC522-RFID模块/RC522.h
  46. BIN
      module_Template/RC522-RFID模块/RFID模块-RC522接口图.jpg
  47. 152 0
      module_Template/RC522-RFID模块/SPI.c
  48. 15 0
      module_Template/RC522-RFID模块/SPI.h
  49. 2 0
      module_Template/RC522-RFID模块/淘宝链接.txt
  50. 0 52
      module_Template/SG90/SG90.c
  51. 66 0
      module_Template/SG90舵机/SG90.c
  52. 1 4
      module_Template/SG90舵机/SG90.h
  53. 0 0
      module_Template/SG90舵机/舵机接口图.jpg
  54. 1 1
      module_Template/SIM900A短信模块/GSM_config.c
  55. 0 0
      module_Template/SIM900A短信模块/GSM_config.h
  56. 0 0
      module_Template/SIM900A短信模块/GSM_func.c
  57. 0 0
      module_Template/SIM900A短信模块/GSM_func.h
  58. 0 0
      module_Template/SIM900A短信模块/README.txt
  59. 0 0
      module_Template/SIM900A短信模块/SIM900A_AT命令手册_V1.05.pdf
  60. 0 200
      project_Template/Drive/MultiButton.c
  61. 0 61
      project_Template/Drive/MultiButton.h
  62. 245 0
      project_Template/Drive/TimeScheduleSystem.c
  63. 43 0
      project_Template/Drive/TimeScheduleSystem.h
  64. 1 1
      project_Template/Project/Objects/myProject.lnp
  65. 145 145
      project_Template/Project/myProject.uvguix.AS
  66. 0 1801
      project_Template/Project/myProject.uvguix.ch
  67. 11 11
      project_Template/Project/myProject.uvoptx
  68. 7 5
      project_Template/Project/myProject.uvprojx
  69. 5 0
      project_Template/System/USART.c
  70. 0 42
      project_Template/System/WDOG.c
  71. 0 13
      project_Template/System/WDOG.h
  72. 26 6
      project_Template/User/handle.c
  73. 1 2
      project_Template/User/main.h
  74. 154 0
      system_Template/SPI.c
  75. 15 0
      system_Template/SPI.h
  76. 5 0
      system_Template/USART.c

+ 0 - 0
module_Template/ADXL345/ADXL345.c → module_Template/ADXL345三轴传感器/ADXL345.c


+ 0 - 0
module_Template/ADXL345/ADXL345.h → module_Template/ADXL345三轴传感器/ADXL345.h


+ 0 - 0
module_Template/ADXL345/ADXL345中文PDF.pdf → module_Template/ADXL345三轴传感器/ADXL345中文PDF.pdf


+ 0 - 0
module_Template/ADXL345/ADXL345接口图.jpg → module_Template/ADXL345三轴传感器/ADXL345接口图.jpg


+ 0 - 0
module_Template/ADXL345/IIC.c → module_Template/ADXL345三轴传感器/IIC.c


+ 0 - 0
module_Template/ADXL345/IIC.h → module_Template/ADXL345三轴传感器/IIC.h


+ 0 - 0
module_Template/ADXL345/README.txt → module_Template/ADXL345三轴传感器/README.txt


+ 0 - 0
module_Template/ASR_CI1122/ASR_usart.c → module_Template/ASR_CI1122语音识别/ASR_usart.c


+ 0 - 0
module_Template/ASR_CI1122/ASR_usart.h → module_Template/ASR_CI1122语音识别/ASR_usart.h


+ 0 - 0
module_Template/ASR_CI1122/启英泰伦CI1122离线语音模组.txt → module_Template/ASR_CI1122语音识别/启英泰伦CI1122离线语音模组.txt


+ 0 - 0
module_Template/ASR_CI1122/语音串口协议.txt → module_Template/ASR_CI1122语音识别/语音串口协议.txt


+ 0 - 0
module_Template/BY9301/BY9301-16P语音模块使用说明书V1.0.pdf → module_Template/BY9301语音播报模块/BY9301-16P语音模块使用说明书V1.0.pdf


+ 69 - 46
module_Template/BY9301/BY9301.c → module_Template/BY9301语音播报模块/BY9301.c

@@ -6,17 +6,20 @@ BY9301
 void BY9301_USART_Init(uint32_t baudRate);
 static void BY9301_SendString(uint8_t *str);
 static void BY9301_Say(uint8_t NOx);
+static void BY9301_setVolume(uint8_t volume);
+static void BY9301_playPause(uint8_t playPause);
 static uint8_t BY9301_Busy(void);
 
 BY9301ClassStruct BY9301Class = {
-	.Init = BY9301_USART_Init,
-	.Send = BY9301_SendString,
-	.Say = BY9301_Say,
-	.Busy = BY9301_Busy
+	.init = BY9301_USART_Init,
+	.sayFileID = BY9301_Say,
+	.isBusy = BY9301_Busy,
+	.setVolume = BY9301_setVolume,
+	.playPause = BY9301_playPause
 };
 
 // VOICE USART define
-#if	0
+#if	1
 #define  BY9301_USARTx_PORT               USART1
 #define  BY9301_USARTx_CLK                RCC_APB2Periph_USART1
 #define  BY9301_USARTx_APBxClkCmd         RCC_APB2PeriphClockCmd
@@ -41,31 +44,10 @@ BY9301ClassStruct BY9301Class = {
 #define  BY9301_USARTx_IRQ                USART2_IRQn
 #define  BY9301_USARTx_IRQHandler         USART2_IRQHandler
 #endif
-#define BUSY_GPIO_PORT    								GPIOA			              /* GPIO端口 */
-#define BUSY_GPIO_CLK 	    							RCC_APB2Periph_GPIOA		/* GPIO端口时钟 */
-#define BUSY_GPIO_PIN											GPIO_Pin_4			        /* 连接到SCL时钟线的GPIO */
+#define BUSY_GPIO_PORT    					GPIOB			              /* GPIO端口 */
+#define BUSY_GPIO_CLK 	    				RCC_APB2Periph_GPIOB		/* GPIO端口时钟 */
+#define BUSY_GPIO_PIN						GPIO_Pin_12			        /* 连接到SCL时钟线的GPIO */
 
-// BY9301TTS播报串口协议
-uint8_t BY9301Data[][8] = {
-{0x7e,0x04,0x31,0x1e,0x2b,0xef,'\n'}, // 设置音量30最大
-{0x7e,0x05,0x41,0x00,0x01,0x45,0xef,'\n'}, // 0001
-{0x7e,0x05,0x41,0x00,0x02,0x46,0xef,'\n'}, // 0002
-{0x7e,0x05,0x41,0x00,0x03,0x47,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x04,0x40,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x05,0x41,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x06,0x42,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x07,0x43,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x08,0x4c,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x09,0x4d,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x0a,0x4e,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x0b,0x4f,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x0c,0x48,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x0d,0x49,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x0e,0x4a,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x0f,0x4b,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x10,0x54,0xef,'\n'},
-{0x7e,0x05,0x41,0x00,0x11,0x55,0xef,'\n'}, // 0017
-};
 
 void BY9301_USARTx_IRQHandler(void)
 {
@@ -122,36 +104,77 @@ static void BY9301_USART_Init(uint32_t baudRate)
 	NVIC_Init(&NVIC_InitStructure); // NVIC初始化
 }
 /**
-	* @brief  语音串口发送 具体协议参见手册 最后一个字节以\0结尾
+	* @brief  语音串口发送 具体协议参见手册
 	* @param  str: 要发送的内容
   * @retval None
   */
 static void BY9301_SendString(uint8_t *str)
 {
-	unsigned int k=0;
-  do 
-  {
-      USART_SendData(BY9301_USARTx_PORT, *(str + k) );
-			/* 等待发送数据寄存器为空 */
-			while (USART_GetFlagStatus(BY9301_USARTx_PORT, USART_FLAG_TXE) == RESET){}
-      k++;
-  }while(*(str + k)!= '\n');
-  /* 等待发送完成 */
-  while(USART_GetFlagStatus(BY9301_USARTx_PORT, USART_FLAG_TC) == RESET){}
+	if(str[1] == 0) return;
+	uint8_t i;
+	for(i = 0; i < str[1] + 2; i++) {
+		USART_SendData(BY9301_USARTx_PORT, str[i]);
+		while (USART_GetFlagStatus(BY9301_USARTx_PORT, USART_FLAG_TXE) == RESET){}
+	}
+	while(USART_GetFlagStatus(BY9301_USARTx_PORT, USART_FLAG_TC) == RESET){}
 }
 /**
-	* @brief  指定序号播报
-	* @param  NOx: mp3文件序号
+  * @brief  指定序号播报
+  * @param  NOx: mp3文件序号
   * @retval None
   */
 static void BY9301_Say(uint8_t NOx)
 {
-	BY9301_SendString(BY9301Data[NOx]);
+	uint8_t arr[8] = {0};
+	arr[0] = 0x7E;
+	arr[1] = 0x05;
+	arr[2] = 0x41;
+	arr[3] = 0x00;
+	arr[4] = NOx;
+	arr[5] = arr[1]^arr[2]^arr[3]^arr[4];
+	arr[6] = 0xEF;
+	BY9301_SendString(arr);
+}
+/**
+  * @brief  设置音量
+  * @param  volume: 0-30
+  * @retval None
+  */
+static void BY9301_setVolume(uint8_t volume)
+{
+	if(volume > 30) volume = 30;
+    uint8_t arr[7];
+    arr[0] = 0x7E;
+    arr[1] = 0x04;
+    arr[2] = 0x31;
+    arr[3] = volume;
+    arr[4] = arr[1]^arr[2]^arr[3];
+    arr[5] = 0xEF;
+    BY9301_SendString(arr);
+}
+/**
+  * @brief  设置播放暂停
+  * @param  playPause: 0:pause 1:play
+  * @retval None
+  */
+static void BY9301_playPause(uint8_t playPause)
+{
+	uint8_t arr[6];
+	arr[0] = 0x7E;
+	arr[1] = 0x03;
+	if(playPause) {
+		arr[2] = 0x01;
+	} else {
+		arr[2] = 0x02;
+	}
+	arr[3] = arr[1]^arr[2];
+	arr[4] = 0xEF;
+	BY9301_SendString(arr);
 }
 /**
-	* @brief  Busy引脚状态
-	* @param  None
-  * @retval 返回Busy引脚电平状态
+  * @brief  Busy引脚状态
+  * @param  None
+  * @retval 返回Busy引脚电平状态 1:busy 0:idle
   */
 static uint8_t BY9301_Busy(void)
 {

+ 5 - 4
module_Template/BY9301/BY9301.h → module_Template/BY9301语音播报模块/BY9301.h

@@ -4,10 +4,11 @@
 #include "main.h"
 
 typedef struct {
-	void (* Init)(uint32_t baudRate);
-	void (* Send)(uint8_t *str);
-	void (* Say)(uint8_t NOx);
-	uint8_t (* Busy)(void);
+	void (* init)(uint32_t);
+	void (* sayFileID)(uint8_t);
+	void (* setVolume)(uint8_t);
+	void (* playPause)(uint8_t);
+	uint8_t (* isBusy)(void);
 } BY9301ClassStruct;
 
 extern BY9301ClassStruct BY9301Class;

+ 0 - 0
module_Template/BY9301/BY9301接口图.jpg → module_Template/BY9301语音播报模块/BY9301接口图.jpg


+ 0 - 0
module_Template/DHT11/DHT11.c → module_Template/DHT11温湿度模块/DHT11.c


+ 0 - 0
module_Template/DHT11/DHT11.h → module_Template/DHT11温湿度模块/DHT11.h


+ 0 - 0
module_Template/DHT11/DHT11接口图.jpg → module_Template/DHT11温湿度模块/DHT11接口图.jpg


+ 0 - 0
module_Template/DHT11/README.txt → module_Template/DHT11温湿度模块/README.txt


+ 0 - 0
module_Template/DS1302/DS1302.c → module_Template/DS1302时钟模块/DS1302.c


+ 0 - 0
module_Template/DS1302/DS1302.h → module_Template/DS1302时钟模块/DS1302.h


+ 0 - 0
module_Template/DS1302/DS1302接口图.jpg → module_Template/DS1302时钟模块/DS1302接口图.jpg


+ 0 - 0
module_Template/DS1302/README.txt → module_Template/DS1302时钟模块/README.txt


+ 0 - 0
module_Template/DS18B20/DS18B20.c → module_Template/DS18B20温度传感器/DS18B20.c


+ 0 - 0
module_Template/DS18B20/DS18B20.h → module_Template/DS18B20温度传感器/DS18B20.h


+ 0 - 0
module_Template/DS18B20/README.txt → module_Template/DS18B20温度传感器/README.txt


+ 0 - 0
module_Template/MEMS_CH2O甲醛/IIC.c → module_Template/MEMS_CH2O甲醛传感器/IIC.c


+ 0 - 0
module_Template/MEMS_CH2O甲醛/IIC.h → module_Template/MEMS_CH2O甲醛传感器/IIC.h


+ 0 - 0
module_Template/MEMS_CH2O甲醛/MEMS_CH2O.c → module_Template/MEMS_CH2O甲醛传感器/MEMS_CH2O.c


+ 0 - 0
module_Template/MEMS_CH2O甲醛/MEMS_CH2O.h → module_Template/MEMS_CH2O甲醛传感器/MEMS_CH2O.h


+ 0 - 0
module_Template/MEMS_CH2O甲醛/MEMS数字甲醛传感器JED116-001.docx → module_Template/MEMS_CH2O甲醛传感器/MEMS数字甲醛传感器JED116-001.docx


+ 0 - 0
module_Template/MEMS_CH2O甲醛/MEMS甲醛接口图.jpg → module_Template/MEMS_CH2O甲醛传感器/MEMS甲醛接口图.jpg


+ 0 - 0
module_Template/MEMS_CH2O甲醛/淘宝链接.txt → module_Template/MEMS_CH2O甲醛传感器/淘宝链接.txt


BIN
module_Template/MLX90614红外测温/BCC-MLX90614的通信资料.pdf


BIN
module_Template/MLX90614红外测温/MLX9014红外测温接口图.jpg


+ 295 - 0
module_Template/MLX90614红外测温/MLX90614.c

@@ -0,0 +1,295 @@
+#include "MLX90614.h"
+
+
+#define ACK         0
+#define NACK        1
+#define SA                        0x00 
+#define RAM_ACCESS                0x00 
+#define EEPROM_ACCESS             0x20 
+#define RAM_TOBJ1                 0x07 
+
+#define SMBUS_PORT               GPIOB
+#define SMBUS_SCK                GPIO_Pin_7
+#define SMBUS_SDA                GPIO_Pin_6
+
+#define RCC_APB2Periph_SMBUS_PORT                RCC_APB2Periph_GPIOB
+
+#define SMBUS_SCK_H()            SMBUS_PORT->BSRR = SMBUS_SCK
+#define SMBUS_SCK_L()            SMBUS_PORT->BRR = SMBUS_SCK
+#define SMBUS_SDA_H()            SMBUS_PORT->BSRR = SMBUS_SDA
+#define SMBUS_SDA_L()            SMBUS_PORT->BRR = SMBUS_SDA
+
+#define SMBUS_SDA_PIN()            SMBUS_PORT->IDR & SMBUS_SDA 
+
+void SMBus_StartBit(void)
+{
+    SMBUS_SDA_H();                // Set SDA line
+    SMBus_Delay(8);            // Wait a few microseconds
+    SMBUS_SCK_H();                // Set SCL line
+    SMBus_Delay(8);            // Generate bus free time between Stop
+    SMBUS_SDA_L();                // Clear SDA line
+    SMBus_Delay(8);            // Hold time after (Repeated) Start
+    // Condition. After this period, the first clock is generated.
+    //(Thd:sta=4.0us min)
+    SMBUS_SCK_L();            // Clear SCL line
+    SMBus_Delay(8);            // Wait a few microseconds
+}
+
+void SMBus_StopBit(void)
+{
+    SMBUS_SCK_L();                // Clear SCL line
+    SMBus_Delay(8);            // Wait a few microseconds
+    SMBUS_SDA_L();                // Clear SDA line
+    SMBus_Delay(8);            // Wait a few microseconds
+    SMBUS_SCK_H();                // Set SCL line
+    SMBus_Delay(8);            // Stop condition setup time(Tsu:sto=4.0us min)
+    SMBUS_SDA_H();                // Set SDA line
+}
+
+u8 SMBus_SendByte(u8 Tx_buffer)
+{
+    u8        Bit_counter;
+    u8        Ack_bit;
+    u8        bit_out;
+
+    for(Bit_counter=8; Bit_counter; Bit_counter--)
+    {
+        if (Tx_buffer&0x80)
+        {
+            bit_out=1;   // If the current bit of Tx_buffer is 1 set bit_out
+        }
+        else
+        {
+            bit_out=0;  // else clear bit_out
+        }
+        SMBus_SendBit(bit_out);                // Send the current bit on SDA
+        Tx_buffer<<=1;                                // Get next bit for checking
+    }
+
+    Ack_bit=SMBus_ReceiveBit();                // Get acknowledgment bit
+    return        Ack_bit;
+}
+
+void SMBus_SendBit(u8 bit_out)
+{
+    if(bit_out==0)
+    {
+        SMBUS_SDA_L();
+    }
+    else
+    {
+        SMBUS_SDA_H();
+    }
+    SMBus_Delay(6);                                        // Tsu:dat = 250ns minimum
+    SMBUS_SCK_H();                                        // Set SCL line
+    SMBus_Delay(8);                                        // High Level of Clock Pulse
+    SMBUS_SCK_L();                                        // Clear SCL line
+    SMBus_Delay(8);                                        // Low Level of Clock Pulse
+    return;
+}
+
+u8 SMBus_ReceiveBit(void)
+{
+    u8 Ack_bit;
+
+    SMBUS_SDA_H();          
+        SMBus_Delay(6);                        // High Level of Clock Pulse
+    SMBUS_SCK_H();                        // Set SCL line
+    SMBus_Delay(8);                        // High Level of Clock Pulse
+    if (SMBUS_SDA_PIN())
+    {
+        Ack_bit=1;
+    }
+    else
+    {
+        Ack_bit=0;
+    }
+    SMBUS_SCK_L();                        // Clear SCL line
+    SMBus_Delay(8);                        // Low Level of Clock Pulse
+
+    return        Ack_bit;
+}
+
+u8 SMBus_ReceiveByte(u8 ack_nack)
+{
+    u8         RX_buffer;
+    u8        Bit_Counter;
+
+    for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
+    {
+        if(SMBus_ReceiveBit())                        // Get a bit from the SDA line
+        {
+            RX_buffer <<= 1;                        // If the bit is HIGH save 1  in RX_buffer
+            RX_buffer |=0x01;
+        }
+        else
+        {
+            RX_buffer <<= 1;                        // If the bit is LOW save 0 in RX_buffer
+            RX_buffer &=0xfe;
+        }
+    }
+    SMBus_SendBit(ack_nack);                        // Sends acknowledgment bit
+    return RX_buffer;
+}
+
+void SMBus_Delay(u16 time)
+{
+    u16 i, j;
+    for (i=0; i<5; i++)
+    {
+        for (j=0; j<time; j++);
+    }
+}
+
+void SMBus_Init()
+{
+    GPIO_InitTypeDef    GPIO_InitStructure;
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SMBUS_PORT, ENABLE);
+
+    GPIO_InitStructure.GPIO_Pin = SMBUS_SCK | SMBUS_SDA;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_Init(SMBUS_PORT, &GPIO_InitStructure);
+
+    SMBUS_SCK_H();
+    SMBUS_SDA_H();
+}
+
+u16 SMBus_ReadMemory(u8 slaveAddress, u8 command)
+{
+    u16 data;                        // Data storage (DataH:DataL)
+    u8 Pec;                                // PEC byte storage
+    u8 DataL=0;                        // Low data byte storage
+    u8 DataH=0;                        // High data byte storage
+    u8 arr[6];                        // Buffer for the sent bytes
+    u8 PecReg;                        // Calculated PEC byte storage
+    u8 ErrorCounter;        // Defines the number of the attempts for communication with MLX90614
+
+    ErrorCounter=0x00;                                // Initialising of ErrorCounter
+        slaveAddress <<= 1;        //2-7???????
+        
+    do
+    {
+repeat:
+        SMBus_StopBit();                            //If slave send NACK stop comunication
+        --ErrorCounter;                                    //Pre-decrement ErrorCounter
+        if(!ErrorCounter)                             //ErrorCounter=0?
+        {
+            break;                                            //Yes,go out from do-while{}
+        }
+
+        SMBus_StartBit();                                //Start condition
+        if(SMBus_SendByte(slaveAddress))//Send SlaveAddress ???Wr=0????????
+        {
+            goto        repeat;                            //Repeat comunication again
+        }
+        if(SMBus_SendByte(command))            //Send command
+        {
+            goto        repeat;                            //Repeat comunication again
+        }
+
+        SMBus_StartBit();                                        //Repeated Start condition
+        if(SMBus_SendByte(slaveAddress+1))        //Send SlaveAddress ???Rd=1????????
+        {
+            goto        repeat;                     //Repeat comunication again
+        }
+
+        DataL = SMBus_ReceiveByte(ACK);        //Read low data,master must send ACK
+        DataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACK
+        Pec = SMBus_ReceiveByte(NACK);        //Read PEC byte, master must send NACK
+        SMBus_StopBit();                                //Stop condition
+
+        arr[5] = slaveAddress;                //
+        arr[4] = command;                        //
+        arr[3] = slaveAddress+1;        //Load array arr
+        arr[2] = DataL;                                //
+        arr[1] = DataH;                                //
+        arr[0] = 0;                                        //
+        PecReg=PEC_Calculation(arr);//Calculate CRC
+    }
+    while(PecReg != Pec);                //If received and calculated CRC are equal go out from do-while{}
+
+        data = (DataH<<8) | DataL;        //data=DataH:DataL
+    return data;
+}
+
+u8 PEC_Calculation(u8 pec[])
+{
+    u8         crc[6];
+    u8        BitPosition=47;
+    u8        shift;
+    u8        i;
+    u8        j;
+    u8        temp;
+
+    do
+    {
+        /*Load pattern value 0x000000000107*/
+        crc[5]=0;
+        crc[4]=0;
+        crc[3]=0;
+        crc[2]=0;
+        crc[1]=0x01;
+        crc[0]=0x07;
+
+        /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
+        BitPosition=47;
+
+        /*Set shift position at 0*/
+        shift=0;
+
+        /*Find first "1" in the transmited message beginning from the MSByte byte5*/
+        i=5;
+        j=0;
+        while((pec[i]&(0x80>>j))==0 && i>0)
+        {
+            BitPosition--;
+            if(j<7)
+            {
+                j++;
+            }
+            else
+            {
+                j=0x00;
+                i--;
+            }
+        }/*End of while */
+
+        /*Get shift value for pattern value*/
+        shift=BitPosition-8;
+
+        /*Shift pattern value */
+        while(shift)
+        {
+            for(i=5; i<0xFF; i--)
+            {
+                if((crc[i-1]&0x80) && (i>0))
+                {
+                    temp=1;
+                }
+                else
+                {
+                    temp=0;
+                }
+                crc[i]<<=1;
+                crc[i]+=temp;
+            }/*End of for*/
+            shift--;
+        }/*End of while*/
+
+        /*Exclusive OR between pec and crc*/
+        for(i=0; i<=5; i++)
+        {
+            pec[i] ^=crc[i];
+        }/*End of for*/
+    }
+    while(BitPosition>8); /*End of do-while*/
+
+    return pec[0];
+}
+
+float SMBus_ReadTemp(void)
+{   
+	return (SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1)*0.02-273.15);
+}

+ 19 - 0
module_Template/MLX90614红外测温/MLX90614.h

@@ -0,0 +1,19 @@
+#ifndef __MLX90614_AS_H
+#define __MLX90614_AS_H
+
+#include "main.h"
+
+
+void SMBus_StartBit(void);
+void SMBus_StopBit(void);
+void SMBus_SendBit(u8);
+u8 SMBus_SendByte(u8);
+u8 SMBus_ReceiveBit(void);
+u8 SMBus_ReceiveByte(u8);
+void SMBus_Delay(u16);
+void SMBus_Init(void);
+u16 SMBus_ReadMemory(u8, u8);
+u8 PEC_Calculation(u8*);
+float SMBus_ReadTemp(void); //»ñȡζÈÖµ
+
+#endif

+ 2 - 0
module_Template/MLX90614红外测温/淘宝链接.txt

@@ -0,0 +1,2 @@
+【淘宝】https://m.tb.cn/h.UJZIwh1?tk=OAYjdj7ziad CZ3457 「GY-906 MLX90614ESF BAA BCC DCI IR红外测温传感器模块温度采器」
+点击链接直接打开 或者 淘宝搜索直接打开

+ 0 - 0
module_Template/PM2.5/DST02-N_JTS-GG-2019-001N承认书V1.0 (2).pdf → module_Template/PM2.5检测模块/DST02-N_JTS-GG-2019-001N承认书V1.0 (2).pdf


+ 0 - 0
module_Template/PM2.5/PM2.5接口图.jpg → module_Template/PM2.5检测模块/PM2.5接口图.jpg


+ 0 - 0
module_Template/PM2.5/PM2.5模拟量驱动与算法.txt → module_Template/PM2.5检测模块/PM2.5模拟量驱动与算法.txt


+ 0 - 0
module_Template/PM2.5/淘宝链接.txt → module_Template/PM2.5检测模块/淘宝链接.txt


BIN
module_Template/RC522-RFID模块/MFRC522.pdf


+ 321 - 0
module_Template/RC522-RFID模块/RC522.c

@@ -0,0 +1,321 @@
+// Mifare RC522 RFID Card reader 13.56 MHz
+
+// MFRC522		STM32F103		DESCRIPTION
+// CS (SDA)		PB0				SPI1_NSS	Chip select for SPI
+// SCK			PA5				SPI1_SCK	Serial Clock for SPI
+// MOSI			PA7 			SPI1_MOSI	Master In Slave Out for SPI
+// MISO			PA6				SPI1_MISO	Master Out Slave In for SPI
+// IRQ			-				Irq
+// GND			GND				Ground
+// RST			3.3V			Reset pin (3.3V)
+// VCC			3.3V			3.3V power
+#include "RC522.h"
+
+/******template******/
+// 0-255数字转换为字符  0xFF--"FF"
+void char_to_hex(uint8_t data, uint8_t *retStr) {
+	uint8_t digits[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+	
+	if (data < 16) {
+		retStr[0] = '0';
+		retStr[1] = digits[data];
+	} else {
+		retStr[0] = digits[(data & 0xF0)>>4];
+		retStr[1] = digits[(data & 0x0F)];
+	}
+}
+/**
+  * @brief  扫描RFID卡
+  * @param  cardID 四字节数组
+  * @retval 0扫描到RFID卡
+  */
+uint8_t RC522_cardScan(uint8_t *cardID)
+{
+	if(!MFRC522_Request(PICC_REQIDL, cardID)) {
+		if(!MFRC522_Anticoll(cardID)) {
+			
+#ifdef DEBUG_printf
+			uint8_t cardIDString[8] = {0};
+			for(uint8_t i = 0; i < 4; i++) {
+				char_to_hex(cardID[i], cardIDString+i*2);
+			}
+			printf("card id:%s\n", cardIDString);
+#endif
+			return 0;
+		}
+	}
+	return 1;
+}
+/********************/
+
+
+void SPI1_WriteReg(uint8_t address, uint8_t value) {
+	cs_reset();
+	SPISendByte(address);
+	SPISendByte(value);
+	cs_set();
+}
+
+uint8_t SPI1_ReadReg(uint8_t address) {
+	uint8_t	val;
+
+	cs_reset();
+	SPISendByte(address);
+	val = SPISendByte(0x00);
+	cs_set();
+	return val;
+}
+
+void MFRC522_WriteRegister(uint8_t addr, uint8_t val) {
+	addr = (addr << 1) & 0x7E;															// Address format: 0XXXXXX0
+  SPI1_WriteReg(addr, val);
+}
+
+uint8_t MFRC522_ReadRegister(uint8_t addr) {
+	uint8_t val;
+
+	addr = ((addr << 1) & 0x7E) | 0x80;
+	val = SPI1_ReadReg(addr);
+	return val;	
+}
+
+uint8_t MFRC522_Check(uint8_t* id) {
+	uint8_t status;
+	status = MFRC522_Request(PICC_REQIDL, id);							// Find cards, return card type
+	if (status == MI_OK) status = MFRC522_Anticoll(id);			// Card detected. Anti-collision, return card serial number 4 bytes
+	MFRC522_Halt();																					// Command card into hibernation 
+	return status;
+}
+
+uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID) {
+	uint8_t i;
+	for (i = 0; i < 5; i++) {
+		if (CardID[i] != CompareID[i]) return MI_ERR;
+	}
+	return MI_OK;
+}
+
+void MFRC522_SetBitMask(uint8_t reg, uint8_t mask) {
+	MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) | mask);
+}
+
+void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask){
+	MFRC522_WriteRegister(reg, MFRC522_ReadRegister(reg) & (~mask));
+}
+
+uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType) {
+	uint8_t status;  
+	uint16_t backBits;																			// The received data bits
+
+	MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07);		// TxLastBists = BitFramingReg[2..0]
+	TagType[0] = reqMode;
+	status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
+	if ((status != MI_OK) || (backBits != 0x10)) status = MI_ERR;
+	return status;
+}
+
+uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) {
+	uint8_t status = MI_ERR;
+	uint8_t irqEn = 0x00;
+	uint8_t waitIRq = 0x00;
+	uint8_t lastBits;
+	uint8_t n;
+	uint16_t i;
+
+	switch (command) {
+		case PCD_AUTHENT: {
+			irqEn = 0x12;
+			waitIRq = 0x10;
+			break;
+		}
+		case PCD_TRANSCEIVE: {
+			irqEn = 0x77;
+			waitIRq = 0x30;
+			break;
+		}
+		default:
+		break;
+	}
+
+	MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
+	MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
+	MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
+	MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);
+
+	// Writing data to the FIFO
+	for (i = 0; i < sendLen; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);
+
+	// Execute the command
+	MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
+	if (command == PCD_TRANSCEIVE) MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);		// StartSend=1,transmission of data starts 
+
+	// Waiting to receive data to complete
+	i = 2000;	// i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms
+	do {
+		// CommIrqReg[7..0]
+		// Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
+		n = MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
+		i--;
+	} while ((i!=0) && !(n&0x01) && !(n&waitIRq));
+
+	MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);																// StartSend=0
+
+	if (i != 0)  {
+		if (!(MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
+			status = MI_OK;
+			if (n & irqEn & 0x01) status = MI_NOTAGERR;
+			if (command == PCD_TRANSCEIVE) {
+				n = MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
+				lastBits = MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
+				if (lastBits) *backLen = (n-1)*8+lastBits; else *backLen = n*8;
+				if (n == 0) n = 1;
+				if (n > MFRC522_MAX_LEN) n = MFRC522_MAX_LEN;
+				for (i = 0; i < n; i++) backData[i] = MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA);		// Reading the received data in FIFO
+			}
+		} else status = MI_ERR;
+	}
+	return status;
+}
+
+uint8_t MFRC522_Anticoll(uint8_t* serNum) {
+	uint8_t status;
+	uint8_t i;
+	uint8_t serNumCheck = 0;
+	uint16_t unLen;
+
+	MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x00);												// TxLastBists = BitFramingReg[2..0]
+	serNum[0] = PICC_ANTICOLL;
+	serNum[1] = 0x20;
+	status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
+	if (status == MI_OK) {
+		// Check card serial number
+		for (i = 0; i < 4; i++) serNumCheck ^= serNum[i];
+		if (serNumCheck != serNum[i]) status = MI_ERR;
+	}
+	return status;
+} 
+
+void MFRC522_CalculateCRC(uint8_t*  pIndata, uint8_t len, uint8_t* pOutData) {
+	uint8_t i, n;
+
+	MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04);													// CRCIrq = 0
+	MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);													// Clear the FIFO pointer
+	// Write_MFRC522(CommandReg, PCD_IDLE);
+
+	// Writing data to the FIFO	
+	for (i = 0; i < len; i++) MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, *(pIndata+i));
+	MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_CALCCRC);
+
+	// Wait CRC calculation is complete
+	i = 0xFF;
+	do {
+		n = MFRC522_ReadRegister(MFRC522_REG_DIV_IRQ);
+		i--;
+	} while ((i!=0) && !(n&0x04));																						// CRCIrq = 1
+
+	// Read CRC calculation result
+	pOutData[0] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_L);
+	pOutData[1] = MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_M);
+}
+
+uint8_t MFRC522_SelectTag(uint8_t* serNum) {
+	uint8_t i;
+	uint8_t status;
+	uint8_t size;
+	uint16_t recvBits;
+	uint8_t buffer[9]; 
+
+	buffer[0] = PICC_SElECTTAG;
+	buffer[1] = 0x70;
+	for (i = 0; i < 5; i++) buffer[i+2] = *(serNum+i);
+	MFRC522_CalculateCRC(buffer, 7, &buffer[7]);		//??
+	status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
+	if ((status == MI_OK) && (recvBits == 0x18)) size = buffer[0]; else size = 0;
+	return size;
+}
+
+uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
+	uint8_t status;
+	uint16_t recvBits;
+	uint8_t i;
+	uint8_t buff[12]; 
+
+	// Verify the command block address + sector + password + card serial number
+	buff[0] = authMode;
+	buff[1] = BlockAddr;
+	for (i = 0; i < 6; i++) buff[i+2] = *(Sectorkey+i);
+	for (i=0; i<4; i++) buff[i+8] = *(serNum+i);
+	status = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
+	if ((status != MI_OK) || (!(MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) status = MI_ERR;
+	return status;
+}
+
+uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData) {
+	uint8_t status;
+	uint16_t unLen;
+
+	recvData[0] = PICC_READ;
+	recvData[1] = blockAddr;
+	MFRC522_CalculateCRC(recvData,2, &recvData[2]);
+	status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);
+	if ((status != MI_OK) || (unLen != 0x90)) status = MI_ERR;
+	return status;
+}
+
+uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData) {
+	uint8_t status;
+	uint16_t recvBits;
+	uint8_t i;
+	uint8_t buff[18]; 
+
+	buff[0] = PICC_WRITE;
+	buff[1] = blockAddr;
+	MFRC522_CalculateCRC(buff, 2, &buff[2]);
+	status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);
+	if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
+	if (status == MI_OK) {
+		// Data to the FIFO write 16Byte
+		for (i = 0; i < 16; i++) buff[i] = *(writeData+i);
+		MFRC522_CalculateCRC(buff, 16, &buff[16]);
+		status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
+		if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) status = MI_ERR;
+	}
+	return status;
+}
+
+void MFRC522_Init(void) {
+	MFRC522_Reset();
+	MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
+	MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
+	MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);           
+	MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);
+	MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70);				// 48dB gain	
+	MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
+	MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);
+	MFRC522_AntennaOn();																		// Open the antenna
+}
+
+void MFRC522_Reset(void) {
+	MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_RESETPHASE);
+}
+
+void MFRC522_AntennaOn(void) {
+	uint8_t temp;
+
+	temp = MFRC522_ReadRegister(MFRC522_REG_TX_CONTROL);
+	if (!(temp & 0x03)) MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
+}
+
+void MFRC522_AntennaOff(void) {
+	MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
+}
+
+void MFRC522_Halt(void) {
+	uint16_t unLen;
+	uint8_t buff[4]; 
+
+	buff[0] = PICC_HALT;
+	buff[1] = 0;
+	MFRC522_CalculateCRC(buff, 2, &buff[2]);
+	MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
+}

+ 140 - 0
module_Template/RC522-RFID模块/RC522.h

@@ -0,0 +1,140 @@
+#ifndef __RC522_H
+#define __RC522_H
+
+#include "main.h"
+
+// RC522 use SPIx define
+#define RC522_SPI					SPI1
+// SPI write read define
+#define SPISendByte(data)			SPIClass.WriteRead(RC522_SPI, data, 1000)
+// SPI CS define
+#define cs_reset() 					SPIClass.WriteCSPin(RC522_SPI, Bit_RESET)
+#define cs_set() 					SPIClass.WriteCSPin(RC522_SPI, Bit_SET)
+
+// Status enumeration, Used with most functions
+#define MI_OK											0
+#define MI_NOTAGERR										1
+#define MI_ERR											2
+
+// MFRC522 Commands
+#define PCD_IDLE										0x00	// NO action; Cancel the current command
+#define PCD_AUTHENT										0x0E  	// Authentication Key
+#define PCD_RECEIVE										0x08   	// Receive Data
+#define PCD_TRANSMIT									0x04   	// Transmit data
+#define PCD_TRANSCEIVE									0x0C   	// Transmit and receive data,
+#define PCD_RESETPHASE									0x0F   	// Reset
+#define PCD_CALCCRC										0x03   	// CRC Calculate
+
+// Mifare_One card command word
+#define PICC_REQIDL										0x26   	// find the antenna area does not enter hibernation
+#define PICC_REQALL										0x52   	// find all the cards antenna area
+#define PICC_ANTICOLL									0x93   	// anti-collision
+#define PICC_SElECTTAG									0x93   	// election card
+#define PICC_AUTHENT1A									0x60   	// authentication key A
+#define PICC_AUTHENT1B									0x61   	// authentication key B
+#define PICC_READ										0x30   	// Read Block
+#define PICC_WRITE										0xA0   	// write block
+#define PICC_DECREMENT									0xC0   	// debit
+#define PICC_INCREMENT									0xC1   	// recharge
+#define PICC_RESTORE									0xC2   	// transfer block data to the buffer
+#define PICC_TRANSFER									0xB0   	// save the data in the buffer
+#define PICC_HALT										0x50   	// Sleep
+
+// MFRC522 Registers
+// Page 0: Command and Status
+#define MFRC522_REG_RESERVED00					0x00
+#define MFRC522_REG_COMMAND						0x01
+#define MFRC522_REG_COMM_IE_N					0x02
+#define MFRC522_REG_DIV1_EN						0x03
+#define MFRC522_REG_COMM_IRQ					0x04
+#define MFRC522_REG_DIV_IRQ						0x05
+#define MFRC522_REG_ERROR						0x06
+#define MFRC522_REG_STATUS1						0x07
+#define MFRC522_REG_STATUS2						0x08
+#define MFRC522_REG_FIFO_DATA					0x09
+#define MFRC522_REG_FIFO_LEVEL					0x0A
+#define MFRC522_REG_WATER_LEVEL					0x0B
+#define MFRC522_REG_CONTROL						0x0C
+#define MFRC522_REG_BIT_FRAMING					0x0D
+#define MFRC522_REG_COLL						0x0E
+#define MFRC522_REG_RESERVED01					0x0F
+// Page 1: Command
+#define MFRC522_REG_RESERVED10					0x10
+#define MFRC522_REG_MODE						0x11
+#define MFRC522_REG_TX_MODE						0x12
+#define MFRC522_REG_RX_MODE						0x13
+#define MFRC522_REG_TX_CONTROL					0x14
+#define MFRC522_REG_TX_AUTO						0x15
+#define MFRC522_REG_TX_SELL						0x16
+#define MFRC522_REG_RX_SELL						0x17
+#define MFRC522_REG_RX_THRESHOLD				0x18
+#define MFRC522_REG_DEMOD						0x19
+#define MFRC522_REG_RESERVED11					0x1A
+#define MFRC522_REG_RESERVED12					0x1B
+#define MFRC522_REG_MIFARE						0x1C
+#define MFRC522_REG_RESERVED13					0x1D
+#define MFRC522_REG_RESERVED14					0x1E
+#define MFRC522_REG_SERIALSPEED					0x1F
+// Page 2: CFG
+#define MFRC522_REG_RESERVED20					0x20
+#define MFRC522_REG_CRC_RESULT_M				0x21
+#define MFRC522_REG_CRC_RESULT_L				0x22
+#define MFRC522_REG_RESERVED21					0x23
+#define MFRC522_REG_MOD_WIDTH					0x24
+#define MFRC522_REG_RESERVED22					0x25
+#define MFRC522_REG_RF_CFG						0x26
+#define MFRC522_REG_GS_N						0x27
+#define MFRC522_REG_CWGS_PREG					0x28
+#define MFRC522_REG__MODGS_PREG					0x29
+#define MFRC522_REG_T_MODE						0x2A
+#define MFRC522_REG_T_PRESCALER					0x2B
+#define MFRC522_REG_T_RELOAD_H					0x2C
+#define MFRC522_REG_T_RELOAD_L					0x2D
+#define MFRC522_REG_T_COUNTER_VALUE_H			0x2E
+#define MFRC522_REG_T_COUNTER_VALUE_L			0x2F
+// Page 3:TestRegister
+#define MFRC522_REG_RESERVED30					0x30
+#define MFRC522_REG_TEST_SEL1					0x31
+#define MFRC522_REG_TEST_SEL2					0x32
+#define MFRC522_REG_TEST_PIN_EN					0x33
+#define MFRC522_REG_TEST_PIN_VALUE				0x34
+#define MFRC522_REG_TEST_BUS					0x35
+#define MFRC522_REG_AUTO_TEST					0x36
+#define MFRC522_REG_VERSION						0x37
+#define MFRC522_REG_ANALOG_TEST					0x38
+#define MFRC522_REG_TEST_ADC1					0x39
+#define MFRC522_REG_TEST_ADC2					0x3A
+#define MFRC522_REG_TEST_ADC0					0x3B
+#define MFRC522_REG_RESERVED31					0x3C
+#define MFRC522_REG_RESERVED32					0x3D
+#define MFRC522_REG_RESERVED33					0x3E
+#define MFRC522_REG_RESERVED34					0x3F
+
+#define MFRC522_DUMMY							0x00		// Dummy byte
+#define MFRC522_MAX_LEN							16			// Buf len byte
+
+// RC522
+uint8_t MFRC522_Check(uint8_t* id);
+uint8_t MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID);
+void MFRC522_WriteRegister(uint8_t addr, uint8_t val);
+uint8_t MFRC522_ReadRegister(uint8_t addr);
+void MFRC522_SetBitMask(uint8_t reg, uint8_t mask);
+void MFRC522_ClearBitMask(uint8_t reg, uint8_t mask);
+uint8_t MFRC522_Request(uint8_t reqMode, uint8_t* TagType);
+uint8_t MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);
+uint8_t MFRC522_Anticoll(uint8_t* serNum);
+void MFRC522_CalulateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData);
+uint8_t MFRC522_SelectTag(uint8_t* serNum);
+uint8_t MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum);
+uint8_t MFRC522_Read(uint8_t blockAddr, uint8_t* recvData);
+uint8_t MFRC522_Write(uint8_t blockAddr, uint8_t* writeData);
+void MFRC522_Init(void);
+void MFRC522_Reset(void);
+void MFRC522_AntennaOn(void);
+void MFRC522_AntennaOff(void);
+void MFRC522_Halt(void);
+
+// user template
+uint8_t RC522_cardScan(uint8_t *cardID);
+
+#endif

BIN
module_Template/RC522-RFID模块/RFID模块-RC522接口图.jpg


+ 152 - 0
module_Template/RC522-RFID模块/SPI.c

@@ -0,0 +1,152 @@
+#include "main.h"
+
+static void SPI1_Init(void);
+static void SPI2_Init(void);
+static uint8_t SPI_WriteRead(SPI_TypeDef* SPIx, uint8_t data, uint32_t timeout);
+static void SPI_CS_WritePin(SPI_TypeDef* SPIx, BitAction bitVal);
+
+SPIClassStruct SPIClass = {
+	.SPI1_Init = SPI1_Init,
+	.SPI2_Init = SPI2_Init,
+	.WriteRead = SPI_WriteRead,
+	.WriteCSPin = SPI_CS_WritePin
+};
+// SPI1 CS
+#define SPI1_CS_GPIO_PORT    		GPIOB
+#define SPI1_CS_GPIO_CLK 	    	RCC_APB2Periph_GPIOB
+#define SPI1_CS_GPIO_PIN			GPIO_Pin_0
+// SPI2 CS
+#define SPI2_CS_GPIO_PORT    		GPIOA
+#define SPI2_CS_GPIO_CLK 	    	RCC_APB2Periph_GPIOA
+#define SPI2_CS_GPIO_PIN			GPIO_Pin_0
+
+/**
+  * @brief  SPI1初始化
+  * @param  None
+  * @retval None
+  */
+static void SPI1_Init(void)
+{
+	GPIO_InitTypeDef  GPIO_InitStructure;
+	SPI_InitTypeDef  SPI_InitStructure;
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+	// SPI1 SCK-PA5  MOSI-PA7
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	// SPI1 MISO-PA6
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	// software CS user write
+	RCC_APB2PeriphClockCmd(SPI1_CS_GPIO_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = SPI1_CS_GPIO_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_Init(SPI1_CS_GPIO_PORT, &GPIO_InitStructure);
+	GPIO_WriteBit(SPI1_CS_GPIO_PORT, SPI1_CS_GPIO_PIN, Bit_SET); // 拉高片选引脚
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1时钟使能
+
+	SPI_Cmd(SPI1, DISABLE);
+	SPI_I2S_DeInit(SPI1);
+	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为双线全双工
+	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI为主模式
+	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
+	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI时钟空闲时为低电平
+	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采样数据
+	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS信号由软件管理
+	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // SPI波特率预分频值 72M / Prescaler
+	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始
+	SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
+
+	SPI_Init(SPI1, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPI寄存器
+	SPI_Cmd(SPI1, ENABLE); // 使能SPI
+}
+
+/**
+  * @brief  SPI2初始化
+  * @param  None
+  * @retval None
+  */
+static void SPI2_Init(void)
+{
+	GPIO_InitTypeDef  GPIO_InitStructure;
+	SPI_InitTypeDef  SPI_InitStructure;
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+	// SPI1 SCK-PB13  MOSI-PB15
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_Init(GPIOB, &GPIO_InitStructure);
+	// SPI1 MISO-PB14
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+	GPIO_Init(GPIOB, &GPIO_InitStructure);
+	// software CS user write
+	RCC_APB2PeriphClockCmd(SPI2_CS_GPIO_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = SPI2_CS_GPIO_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_Init(SPI2_CS_GPIO_PORT, &GPIO_InitStructure);
+	GPIO_WriteBit(SPI2_CS_GPIO_PORT, SPI2_CS_GPIO_PIN, Bit_SET); // 拉高片选引脚
+	
+	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // SPI2时钟使能
+
+	SPI_Cmd(SPI2, DISABLE);
+	SPI_I2S_DeInit(SPI2);
+	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为双线全双工
+	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI为主模式
+	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
+	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI时钟空闲时为低电平
+	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采样数据
+	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS信号由软件管理
+	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // SPI波特率预分频值 36M / Prescaler
+	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始
+	SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
+
+	SPI_Init(SPI2, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPI寄存器
+	SPI_Cmd(SPI2, ENABLE); // 使能SPI
+}
+/**
+  * @brief  SPI读写函数
+  * @param  None
+  * @retval 0-超时 
+  */
+static uint8_t SPI_WriteRead(SPI_TypeDef* SPIx, uint8_t data, uint32_t timeout)
+{
+	uint32_t retry = 0;				 	
+	/* Loop while DR register in not emplty */
+	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET) // 发送缓存标志位为空
+	{
+		retry++;
+		if(retry > timeout) return 0;
+	}			  
+	SPI_I2S_SendData(SPIx, data); // 通过外设SPI2发送一个数据
+	retry = 0;
+	/* Wait to receive a byte */
+	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET) // 接收缓存标志位不为空
+	{
+		retry++;
+		if(retry > timeout) return 0;
+	}	  						    
+	/* Return the byte read from the SPI bus */
+	return SPI_I2S_ReceiveData(SPIx); // 通过SPI2返回接收数据	
+}
+/**
+  * @brief  SPI读写函数
+  * @param  None
+  * @retval 0-成功
+  */
+static void SPI_CS_WritePin(SPI_TypeDef* SPIx, BitAction bitVal)
+{
+	if(SPIx == SPI1) {
+		GPIO_WriteBit(SPI1_CS_GPIO_PORT, SPI1_CS_GPIO_PIN, bitVal);
+	} else if(SPIx == SPI2) {
+		GPIO_WriteBit(SPI2_CS_GPIO_PORT, SPI2_CS_GPIO_PIN, bitVal);
+	}
+}
+
+
+

+ 15 - 0
module_Template/RC522-RFID模块/SPI.h

@@ -0,0 +1,15 @@
+#ifndef __SPI_AS_H
+#define __SPI_AS_H
+
+#include "main.h"
+
+typedef struct {
+	void (* SPI1_Init)(void);
+	void (* SPI2_Init)(void);
+	uint8_t (* WriteRead)(SPI_TypeDef *, uint8_t, uint32_t);
+	void (* WriteCSPin)(SPI_TypeDef *, BitAction);
+} SPIClassStruct;
+
+extern SPIClassStruct SPIClass;
+
+#endif

+ 2 - 0
module_Template/RC522-RFID模块/淘宝链接.txt

@@ -0,0 +1,2 @@
+【淘宝】https://m.tb.cn/h.UJZseAF?tk=pHUedj7BdKN CZ3457 「MFRC-522 RC522 RFID射频 IC卡感应模块 送S50复旦卡PN532 PN5180」
+点击链接直接打开 或者 淘宝搜索直接打开

+ 0 - 52
module_Template/SG90/SG90.c

@@ -1,52 +0,0 @@
-#include "main.h"
-
-static void SG90_TIM3_Init(u16 arr,u16 psc);
-static void SG90_Angle(float angle);
-
-SG90ClassStruct SG90Class = {
-	SG90_TIM3_Init,
-	SG90_Angle
-};
-
-// PWM初始化 1000-1,1440-1
-static void SG90_TIM3_Init(u16 arr,u16 psc)
-{
-  GPIO_InitTypeDef GPIO_InitStructure;
-	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
-	TIM_OCInitTypeDef  TIM_OCInitStructure;
-
-	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIO外设时钟使能
-	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
-	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
-	
-	//设置该引脚为复用输出功能,输出TIM3 CH1的PWM脉冲波形
-	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM3_CH1
-	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
-	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-	GPIO_Init(GPIOA, &GPIO_InitStructure);
-	
-	//定时器TIM3初始化
-	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
-	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
-	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
-	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
-	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
-	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
- 
-	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
-  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
-  TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
-  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
-  TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
-	
-  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  	//CH1预装载使能    
-  TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
-  TIM_Cmd(TIM3, ENABLE);  //使能TIMx
-	TIM_CtrlPWMOutputs(TIM3,ENABLE);  //MOE 主输出使能				 
-}
-
-static void SG90_Angle(float angle)
-{
-	angle = (uint16_t)(50.0 * angle / 9.0 + 250.0);
-	TIM_SetCompare1(TIM3, angle);
-}

+ 66 - 0
module_Template/SG90舵机/SG90.c

@@ -0,0 +1,66 @@
+#include "main.h"
+
+static void SG90_TIM3_Init(void);
+static void SG90_Angle(float angle);
+
+SG90ClassStruct SG90Class = {
+	SG90_TIM3_Init,
+	SG90_Angle
+};
+
+#if 1
+#define SG90_TIM						TIM2
+#define SG90_TIM_CLK					RCC_APB1Periph_TIM2
+#define SG90_GPIO_PORT    				GPIOA
+#define SG90_GPIO_CLK 	    			RCC_APB2Periph_GPIOA
+#define SG90_GPIO_PIN					GPIO_Pin_0
+#else
+#define SG90_TIM						TIM3
+#define SG90_TIM_CLK					RCC_APB1Periph_TIM3
+#define SG90_GPIO_PORT    				GPIOA
+#define SG90_GPIO_CLK 	    			RCC_APB2Periph_GPIOA
+#define SG90_GPIO_PIN					GPIO_Pin_6
+#endif
+
+// PWM初始化 10000-1,144-1
+static void SG90_TIM3_Init(void)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;
+	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
+	TIM_OCInitTypeDef  TIM_OCInitStructure;
+
+	RCC_APB2PeriphClockCmd(SG90_GPIO_CLK, ENABLE);  //使能GPIO外设时钟使能
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
+	RCC_APB1PeriphClockCmd(SG90_TIM_CLK, ENABLE); //时钟使能
+	
+	//设置该引脚为复用输出功能,输出PWM脉冲波形
+	GPIO_InitStructure.GPIO_Pin = SG90_GPIO_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_Init(SG90_GPIO_PORT, &GPIO_InitStructure);
+	
+	//定时器初始化
+	TIM_TimeBaseStructure.TIM_Period = 10000-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
+	TIM_TimeBaseStructure.TIM_Prescaler = 144-1; //设置用来作为TIMx时钟频率除数的预分频值
+	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
+	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
+	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
+	TIM_TimeBaseInit(SG90_TIM, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
+ 
+	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
+	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
+	TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
+	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
+	TIM_OC1Init(SG90_TIM, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
+	
+	TIM_OC1PreloadConfig(SG90_TIM, TIM_OCPreload_Enable);  	//CH1预装载使能    
+	TIM_ARRPreloadConfig(SG90_TIM, ENABLE); //使能TIMx在ARR上的预装载寄存器
+	TIM_Cmd(SG90_TIM, ENABLE);  //使能TIMx
+	TIM_CtrlPWMOutputs(SG90_TIM,ENABLE);  //MOE 主输出使能				 
+}
+
+static void SG90_Angle(float angle)
+{
+	angle = (uint16_t)(50.0 * angle / 9.0 + 250.0);
+	TIM_SetCompare1(SG90_TIM, angle);
+}

+ 1 - 4
module_Template/SG90/SG90.h → module_Template/SG90舵机/SG90.h

@@ -4,13 +4,10 @@
 #include "main.h"
 
 typedef struct {
-	void (* Init)(u16 arr,u16 psc);
+	void (* Init)(void);
 	void (* Angle)(float angle);
 } SG90ClassStruct;
 
 extern SG90ClassStruct SG90Class;
 
-void MG90S_TIM3_Init(u16 arr,u16 psc);
-void TIM_Angle(float angle);
-
 #endif

+ 0 - 0
module_Template/SG90/舵机接口图.jpg → module_Template/SG90舵机/舵机接口图.jpg


+ 1 - 1
module_Template/SIM900A/GSM_config.c → module_Template/SIM900A短信模块/GSM_config.c

@@ -44,7 +44,7 @@ char GSM_USART_TX_BUF[GSM_USART_MAX_SEND_LEN];
 volatile uint16_t GSM_USART_RX_STA = 0;   	
 
 // GSM´®¿ÚÖжϴ¦Àí
-void USART2_IRQHandler(void)
+void GSM_USART_IRQHandler(void)
 {
 	uint8_t res;	      
 	if(USART_GetITStatus(GSM_USARTx, USART_IT_RXNE) != RESET)

+ 0 - 0
module_Template/SIM900A/GSM_config.h → module_Template/SIM900A短信模块/GSM_config.h


+ 0 - 0
module_Template/SIM900A/GSM_func.c → module_Template/SIM900A短信模块/GSM_func.c


+ 0 - 0
module_Template/SIM900A/GSM_func.h → module_Template/SIM900A短信模块/GSM_func.h


+ 0 - 0
module_Template/SIM900A/README.txt → module_Template/SIM900A短信模块/README.txt


+ 0 - 0
module_Template/SIM900A/SIM900A_AT命令手册_V1.05.pdf → module_Template/SIM900A短信模块/SIM900A_AT命令手册_V1.05.pdf


+ 0 - 200
project_Template/Drive/MultiButton.c

@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
- * All rights reserved
- */
-
-#include "MultiButton.h"
-
-#define EVENT_CB(ev)   if(handle->cb[ev])handle->cb[ev]((Button*)handle)
-
-//button handle list head.
-static struct Button* head_handle = NULL;
-
-/**
-  * @brief  Initializes the button struct handle.
-  * @param  handle: the button handle strcut.
-  * @param  pin_level: read the HAL GPIO of the connet button level.
-  * @param  active_level: pressed GPIO level.
-  * @retval None
-  */
-void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level)
-{
-	memset(handle, 0, sizeof(struct Button));
-	handle->event = (uint8_t)NONE_PRESS;
-	handle->hal_button_Level = pin_level;
-	handle->button_level = handle->hal_button_Level();
-	handle->active_level = active_level;
-}
-
-/**
-  * @brief  Attach the button event callback function.
-  * @param  handle: the button handle strcut.
-  * @param  event: trigger event type.
-  * @param  cb: callback function.
-  * @retval None
-  */
-void button_attach(struct Button* handle, PressEvent event, BtnCallback cb)
-{
-	handle->cb[event] = cb;
-}
-
-/**
-  * @brief  Inquire the button event happen.
-  * @param  handle: the button handle strcut.
-  * @retval button event.
-  */
-PressEvent get_button_event(struct Button* handle)
-{
-	return (PressEvent)(handle->event);
-}
-
-/**
-  * @brief  Button driver core function, driver state machine.
-  * @param  handle: the button handle strcut.
-  * @retval None
-  */
-void button_handler(struct Button* handle)
-{
-	uint8_t read_gpio_level = handle->hal_button_Level();
-
-	//ticks counter working..
-	if((handle->state) > 0) handle->ticks++;
-
-	/*------------button debounce handle---------------*/
-	if(read_gpio_level != handle->button_level) { //not equal to prev one
-		//continue read 3 times same new level change
-		if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) {
-			handle->button_level = read_gpio_level;
-			handle->debounce_cnt = 0;
-		}
-	} else { //leved not change ,counter reset.
-		handle->debounce_cnt = 0;
-	}
-
-	/*-----------------State machine-------------------*/
-	switch (handle->state) {
-	case 0:
-		if(handle->button_level == handle->active_level) {	//start press down
-			handle->event = (uint8_t)PRESS_DOWN;
-			EVENT_CB(PRESS_DOWN);
-			handle->ticks = 0;
-			handle->repeat = 1;
-			handle->state = 1;
-		} else {
-			handle->event = (uint8_t)NONE_PRESS;
-		}
-		break;
-
-	case 1:
-		if(handle->button_level != handle->active_level) { //released press up
-			handle->event = (uint8_t)PRESS_UP;
-			EVENT_CB(PRESS_UP);
-			handle->ticks = 0;
-			handle->state = 2;
-
-		} else if(handle->ticks > LONG_TICKS) {
-			handle->event = (uint8_t)LONG_PRESS_START;
-			EVENT_CB(LONG_PRESS_START);
-			handle->state = 5;
-		}
-		break;
-
-	case 2:
-		if(handle->button_level == handle->active_level) { //press down again
-			handle->event = (uint8_t)PRESS_DOWN;
-			EVENT_CB(PRESS_DOWN);
-			handle->repeat++;
-			EVENT_CB(PRESS_REPEAT); // repeat hit
-			handle->ticks = 0;
-			handle->state = 3;
-		} else if(handle->ticks > SHORT_TICKS) { //released timeout
-			if(handle->repeat == 1) {
-				handle->event = (uint8_t)SINGLE_CLICK;
-				EVENT_CB(SINGLE_CLICK);
-			} else if(handle->repeat == 2) {
-				handle->event = (uint8_t)DOUBLE_CLICK;
-				EVENT_CB(DOUBLE_CLICK); // repeat hit
-			}
-			handle->state = 0;
-		}
-		break;
-
-	case 3:
-		if(handle->button_level != handle->active_level) { //released press up
-			handle->event = (uint8_t)PRESS_UP;
-			EVENT_CB(PRESS_UP);
-			if(handle->ticks < SHORT_TICKS) {
-				handle->ticks = 0;
-				handle->state = 2; //repeat press
-			} else {
-				handle->state = 0;
-			}
-		}else if(handle->ticks > SHORT_TICKS){ // long press up
-			handle->state = 0;
-		}
-		break;
-
-	case 5:
-		if(handle->button_level == handle->active_level) {
-			//continue hold trigger
-			handle->event = (uint8_t)LONG_PRESS_HOLD;
-			EVENT_CB(LONG_PRESS_HOLD);
-
-		} else { //releasd
-			handle->event = (uint8_t)PRESS_UP;
-			EVENT_CB(PRESS_UP);
-			handle->state = 0; //reset
-		}
-		break;
-	}
-}
-
-/**
-  * @brief  Start the button work, add the handle into work list.
-  * @param  handle: target handle strcut.
-  * @retval 0: succeed. -1: already exist.
-  */
-int button_start(struct Button* handle)
-{
-	struct Button* target = head_handle;
-	while(target) {
-		if(target == handle) return -1;	//already exist.
-		target = target->next;
-	}
-	handle->next = head_handle;
-	head_handle = handle;
-	return 0;
-}
-
-/**
-  * @brief  Stop the button work, remove the handle off work list.
-  * @param  handle: target handle strcut.
-  * @retval None
-  */
-void button_stop(struct Button* handle)
-{
-	struct Button** curr;
-	for(curr = &head_handle; *curr; ) {
-		struct Button* entry = *curr;
-		if (entry == handle) {
-			*curr = entry->next;
-//			free(entry);
-			return;//glacier add 2021-8-18
-		} else
-			curr = &entry->next;
-	}
-}
-
-/**
-  * @brief  background ticks, timer repeat invoking interval 5ms.
-  * @param  None.
-  * @retval None
-  */
-void button_ticks()
-{
-	struct Button* target;
-	for(target=head_handle; target; target=target->next) {
-		button_handler(target);
-	}
-}
-

+ 0 - 61
project_Template/Drive/MultiButton.h

@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
- * All rights reserved
- */
-
-#ifndef _MULTI_BUTTON_H_
-#define _MULTI_BUTTON_H_
-
-#include "stdint.h"
-#include "string.h"
-
-//According to your need to modify the constants.
-#define TICKS_INTERVAL    10	//ms
-#define DEBOUNCE_TICKS    3	//MAX 8
-#define SHORT_TICKS       (300 /TICKS_INTERVAL)
-#define LONG_TICKS        (1000 /TICKS_INTERVAL)
-
-
-typedef void (*BtnCallback)(void*);
-
-typedef enum {
-	PRESS_DOWN = 0,
-	PRESS_UP,
-	PRESS_REPEAT,
-	SINGLE_CLICK,
-	DOUBLE_CLICK,
-	LONG_PRESS_START,
-	LONG_PRESS_HOLD,
-	number_of_event,
-	NONE_PRESS
-}PressEvent;
-
-typedef struct Button {
-	uint16_t ticks;
-	uint8_t  repeat : 4;
-	uint8_t  event : 4;
-	uint8_t  state : 3;
-	uint8_t  debounce_cnt : 3;
-	uint8_t  active_level : 1;
-	uint8_t  button_level : 1;
-	uint8_t  (*hal_button_Level)(void);
-	BtnCallback  cb[number_of_event];
-	struct Button* next;
-}Button;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level);
-void button_attach(struct Button* handle, PressEvent event, BtnCallback cb);
-PressEvent get_button_event(struct Button* handle);
-int  button_start(struct Button* handle);
-void button_stop(struct Button* handle);
-void button_ticks(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 245 - 0
project_Template/Drive/TimeScheduleSystem.c

@@ -0,0 +1,245 @@
+/************************************/
+/* @Author: @woshiashuai            */
+/* @Version: V1.0                   */
+/* @Date: 2023-02-13 10:49:00       */
+/* @Description:                    */
+/* V1.0: create                     */
+/************************************/
+#include "TimeScheduleSystem.h"
+
+TSS_t *TSS_head = NULL; // 分时调度系统工作链表头节点
+
+/**
+  * @brief  分时调度事件初始化
+  * @note	加入到初始化中
+  * @param  TSS: 事件指针
+  * @param  targetTicks: 目标计数值 = 事件调度周期 / 调度器周期 例如: 100 = 500ms / 5ms
+  * @param  callback: 事件回调函数
+  * @retval 0: 初始化成功 1: 参数二为零 2: 参数三为空 3: 事件已存在
+  */
+unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(void))
+{
+    if(targetTicks == 0) return 1;
+    if(callback == NULL) return 2;
+    memset(TSS, 0, sizeof(TSS_t));
+    TSS->targetTicks = targetTicks;
+    TSS->callback = callback;
+    return 0;
+}
+/**
+  * @brief  分时调度事件执行(循环)处理的内部方法
+  * @note	None
+  * @param  TSS: 事件指针
+  * @retval None
+  */
+static void TSS_whileHandle(TSS_t *TSS)
+{
+    // 分时调度结果是等待中或跳过调度则退出
+    if(!TSS->result || TSS->skip) return ;
+	TSS->callback(); // 执行绑定的回调函数
+	TSS->ticks = 0; // 防止因手动切换状态导致的ticks不为0
+	TSS->result = 0; // 切换分时调度结果为等待中
+}
+/**
+  * @brief  分时调度事件执行(循环)处理
+  * @note	加入到主循环中
+  * @param  None
+  * @retval None
+  */
+void TSS_while(void)
+{
+    TSS_t *TSS_target;
+    for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) {
+        TSS_whileHandle(TSS_target);
+    }
+}
+/**
+  * @brief  分时调度事件调度处理的内部方法
+  * @note	None
+  * @param  TSS: 事件指针
+  * @retval None
+  */
+static void TSS_timerHandle(TSS_t *TSS)
+{
+    // 分时调度结果是可执行或跳过调度则退出
+    if(TSS->result || TSS->skip) return ;
+	TSS->ticks += 1; // 计数自加
+	// 计数大于等于目标计数
+	if(TSS->ticks >= TSS->targetTicks) {
+			TSS->ticks = 0; // 计数清零
+			TSS->result = 1; // 切换分时调度结果为可执行
+	}
+}
+/**
+  * @brief  分时调度事件调度处理
+  * @note	加入到调度器中
+  * @param  None
+  * @retval None
+  */
+void TSS_timer(void)
+{
+    TSS_t *TSS_target;
+    for(TSS_target = TSS_head; TSS_target; TSS_target = TSS_target->next) {
+        TSS_timerHandle(TSS_target);
+    }
+}
+
+
+/**
+  * @brief  分时调度事件挂起处理
+  * @note	主要用于将事件从工作链表中取下
+  * @param  TSS: 事件指针
+  * @retval 0: 挂起成功 1: 事件未初始化/初始化失败 2: 事件不在工作链表中(可能已被挂起)
+  */
+unsigned char TSS_pending(TSS_t *TSS)
+{
+    if((TSS->targetTicks == 0) || (TSS->callback == NULL)) return 1;
+    TSS_t *TSS_target = TSS_head;
+    TSS_t *TSS_last = NULL;
+    while(TSS_target) {
+        // 查找事件是否存在
+        if(TSS_target == TSS) {
+            // 是否在头节点
+            if(TSS_last == NULL) {
+                TSS_head = TSS_target->next; // 在头节点则将下一个节点作为新的头节点
+            } else {
+                // 不在头节点则将下一个节点链接到上一个节点
+                TSS_last->next = TSS_target->next;
+                TSS_head = TSS_last;
+            }
+            TSS->state = 0; // 退出工作链表则改变状态为不在工作链表
+            return 0;
+        }
+        TSS_last = TSS_target;
+        TSS_target = TSS_target->next;
+    }
+    return 2;
+}
+/**
+  * @brief  分时调度事件启动处理
+  * @note	主要用于将事件加入到工作链表中
+  * @param  TSS: 事件指针
+  * @retval 0: 启动成功 1: 事件未初始化/初始化失败 2: 事件已在工作链表中(可能已被恢复)
+  */
+unsigned char TSS_start(TSS_t *TSS)
+{
+    if((TSS->targetTicks == 0) || (TSS->callback == NULL)) return 1;
+    TSS_t *TSS_target = TSS_head;
+    while(TSS_target) {
+        if(TSS_target == TSS) return 2;
+        TSS_target = TSS_target->next;
+    }
+    TSS->state = 1; // 加入工作链表则改变状态为在工作链表
+    TSS->next = TSS_head;
+    TSS_head = TSS;
+    return 0;
+}
+
+
+/**
+  * @brief  分时调度事件设置计数值处理
+  * @note	None
+  * @param  TSS: 事件指针
+  * @param  ticks: 设置的计数值
+  * @retval None
+  */
+void TSS_setTicks(TSS_t *TSS, unsigned char ticks)
+{
+   TSS->ticks = ticks;
+}
+/**
+  * @brief  分时调度事件获取计数值处理
+  * @note	None
+  * @param  TSS: 事件指针
+  * @retval 事件计数值
+  */
+unsigned int TSS_getTicks(TSS_t *TSS)
+{
+    return TSS->ticks;
+}
+/**
+  * @brief  分时调度事件设置目标计数值处理
+  * @note	主要用于修改事件执行周期,若较上次改小则可能立即触发事件执行
+  * @param  TSS: 事件指针
+  * @param  result: 设置的目标计数值
+  * @retval None
+  */
+void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks)
+{
+   TSS->targetTicks = targetTicks;
+}
+/**
+  * @brief  分时调度事件获取目标计数值处理
+  * @note	主要用于查看事件执行周期
+  * @param  TSS: 事件指针
+  * @retval 事件目标计数值
+  */
+unsigned int TSS_TargetTicks(TSS_t *TSS)
+{
+    return TSS->targetTicks;
+}
+/**
+  * @brief  分时调度事件设置结果值处理
+  * @note	主要用于立即切换事件结果为1:可执行
+  * @param  TSS: 事件指针
+  * @param  result: 设置的结果值
+  * @retval None
+  */
+void TSS_setResult(TSS_t *TSS, unsigned char result)
+{
+   TSS->result = result;
+}
+/**
+  * @brief  分时调度事件获取结果值处理 
+  * @note	一般获取到的事件结果多为0:等待中,因为在事件执行后事件结果值即清零
+  * @param  TSS: 事件指针
+  * @retval 事件结果值 0: 等待中 1: 可执行
+  */
+unsigned char TSS_getResult(TSS_t *TSS)
+{
+    return TSS->result;
+}
+
+/**
+  * @brief  分时调度事件设置状态值处理
+  * @note	手动操作此函数无效,因为事件状态只与事件是否存在于工作链表中有关
+  * @param  TSS: 事件指针
+  * @param  state: 设置的状态值
+  * @retval None
+  */
+void TSS_setState(TSS_t *TSS, unsigned char state)
+{
+//   TSS->state = state;
+}
+/**
+  * @brief  分时调度事件获取状态值处理
+  * @note	主要用于查看事件是否存在于工作链表中
+  * @param  TSS: 事件指针
+  * @retval 事件的状态值 0:不在工作链表 1:在工作链表
+  */
+unsigned char TSS_getState(TSS_t *TSS)
+{
+    return TSS->state;
+}
+
+/**
+  * @brief  分时调度事件设置跳过值处理 
+  * @note	主要用于事件仍在工作链表中的启动或挂起,相较于把事件从工作链表取下和恢复,此操作更快
+  * @param  TSS: 事件指针
+  * @param  state: 设置的跳过值
+  * @retval None
+  */
+void TSS_setSkip(TSS_t *TSS, unsigned char skip)
+{
+   TSS->skip = skip;
+}
+/**
+  * @brief  分时调度事件获取跳过值处理
+  * @note	主要用于查看事件是否跳过事件调度,事件仍在工作链表中的启动或挂起
+  * @param  TSS: 事件指针
+  * @retval 事件的跳过值 0:不跳过调度 1: 跳过调度
+  */
+unsigned char TSS_getSkip(TSS_t *TSS)
+{
+    return TSS->skip;
+}

+ 43 - 0
project_Template/Drive/TimeScheduleSystem.h

@@ -0,0 +1,43 @@
+#ifndef TIMESCHEDULESYSTEM_H
+#define TIMESCHEDULESYSTEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <string.h>
+
+typedef struct TimeScheduleSystem{
+    unsigned int ticks;
+    unsigned int targetTicks;
+    unsigned char result : 1; // 0:等待中 1:可执行
+    unsigned char state : 1; // 0:不在工作链表 1:在工作链表
+		unsigned char skip : 1; // 0:不跳过调度 1:跳过调度
+    void (* callback)(void);
+    struct TimeScheduleSystem *next;
+} TSS_t;
+
+unsigned char TSS_init(TSS_t *TSS, unsigned int targetTicks, void (* callback)(void));
+void TSS_while(void);
+void TSS_timer(void);
+
+unsigned char TSS_pending(TSS_t *TSS);
+unsigned char TSS_start(TSS_t *TSS);
+
+void TSS_setTicks(TSS_t *TSS, unsigned char ticks);
+unsigned int TSS_getTicks(TSS_t *TSS);
+void TSS_setTargetTicks(TSS_t *TSS, unsigned char targetTicks);
+unsigned int TSS_TargetTicks(TSS_t *TSS);
+void TSS_setResult(TSS_t *TSS, unsigned char result);
+unsigned char TSS_getResult(TSS_t *TSS);
+void TSS_setState(TSS_t *TSS, unsigned char state);
+unsigned char TSS_getState(TSS_t *TSS);
+void TSS_setSkip(TSS_t *TSS, unsigned char skip);
+unsigned char TSS_getSkip(TSS_t *TSS);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TIMESCHEDULESYSTEM_H

+ 1 - 1
project_Template/Project/Objects/myProject.lnp

@@ -33,7 +33,7 @@
 ".\objects\rcc.o"
 ".\objects\tim.o"
 ".\objects\usart.o"
-".\objects\wdog.o"
+".\objects\timeschedulesystem.o"
 --library_type=microlib --strict --scatter ".\Objects\myProject.sct"
 --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols
 --info sizes --info totals --info unused --info veneers

Datei-Diff unterdrückt, da er zu groß ist
+ 145 - 145
project_Template/Project/myProject.uvguix.AS


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 1801
project_Template/Project/myProject.uvguix.ch


+ 11 - 11
project_Template/Project/myProject.uvoptx

@@ -622,26 +622,26 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+  </Group>
+
+  <Group>
+    <GroupName>drive</GroupName>
+    <tvExp>1</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
     <File>
-      <GroupNumber>5</GroupNumber>
+      <GroupNumber>6</GroupNumber>
       <FileNumber>35</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <bDave2>0</bDave2>
-      <PathWithFileName>..\System\WDOG.c</PathWithFileName>
-      <FilenameWithoutPath>WDOG.c</FilenameWithoutPath>
+      <PathWithFileName>..\Drive\TimeScheduleSystem.c</PathWithFileName>
+      <FilenameWithoutPath>TimeScheduleSystem.c</FilenameWithoutPath>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
   </Group>
 
-  <Group>
-    <GroupName>drive</GroupName>
-    <tvExp>1</tvExp>
-    <tvExpOptDlg>0</tvExpOptDlg>
-    <cbSel>0</cbSel>
-    <RteFlg>0</RteFlg>
-  </Group>
-
 </ProjectOpt>

+ 7 - 5
project_Template/Project/myProject.uvprojx

@@ -573,15 +573,17 @@
               <FileType>1</FileType>
               <FilePath>..\System\USART.c</FilePath>
             </File>
-            <File>
-              <FileName>WDOG.c</FileName>
-              <FileType>1</FileType>
-              <FilePath>..\System\WDOG.c</FilePath>
-            </File>
           </Files>
         </Group>
         <Group>
           <GroupName>drive</GroupName>
+          <Files>
+            <File>
+              <FileName>TimeScheduleSystem.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Drive\TimeScheduleSystem.c</FilePath>
+            </File>
+          </Files>
         </Group>
       </Groups>
     </Target>

+ 5 - 0
project_Template/System/USART.c

@@ -254,5 +254,10 @@ int fputc(int ch, FILE *f)
 		while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);		
 		return (ch);
 }
+#else
+int fputc(int ch, FILE *f)
+{
+	return (ch);
+}
 #endif
 

+ 0 - 42
project_Template/System/WDOG.c

@@ -1,42 +0,0 @@
-#include "main.h"
-
-static void WDOG_Init(void);
-static void WDOG_Feed(void);
-
-WDOGClassStruct WDOGClass = {
-	.Init = WDOG_Init,
-	.Feed = WDOG_Feed
-};
-
-/**
-  * @brief  看门狗初始化
-  * @param  None
-  * @retval None
-  */
-static void WDOG_Init(void)
-{
-	// 使能 预分频寄存器PR和重装载寄存器RLR可写
-	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
-	// 设置预分频器值
-	IWDG_SetPrescaler(IWDG_Prescaler_16); // IWDG 1s 超时溢出40k/16/2500= 1s
-	// 设置重装载寄存器值
-	IWDG_SetReload(0xfff);
-	// 把重装载寄存器的值放到计数器中
-	IWDG_ReloadCounter();
-	// 使能 IWDG
-	IWDG_Enable();    
-}
-/**
-  * @brief  重置看门狗
-  * @param  None
-  * @retval None
-  */
-static void WDOG_Feed(void)
-{
-	// 把重装载寄存器的值放到计数器中,喂狗,防止IWDG复位
-	// 当计数器的值减到0的时候会产生系统复位
-	IWDG_ReloadCounter();
-}
-
-
-

+ 0 - 13
project_Template/System/WDOG.h

@@ -1,13 +0,0 @@
-#ifndef __WDOG_AS_H
-#define __WDOG_AS_H
-
-#include "main.h"
-
-typedef struct {
-	void (* Init)(void);
-	void (* Feed)(void);
-} WDOGClassStruct;
-
-extern WDOGClassStruct WDOGClass;
-
-#endif

+ 26 - 6
project_Template/User/handle.c

@@ -4,6 +4,12 @@ AllFlagStruct AllFlag = {
 
 };
 
+#define TIMER_PERIOD_MS	10
+
+
+TSS_t m_ledBlink;
+
+void TSS_ledBlink(void);
 
 /**
   * @brief  系统初始化
@@ -19,6 +25,15 @@ void SYSTEM_Init(void)
 	printf("begin\n");
 #endif
 	
+	
+	uint8_t ret = 0;
+	ret = TSS_init(&m_ledBlink, 500/TIMER_PERIOD_MS, TSS_ledBlink);
+	if(!ret) {
+		TSS_start(&m_ledBlink);
+		printf("m_ledBlink TSS init success and started\n");
+	} else {
+		printf("m_ledBlink TSS init fail:%d\n", ret);
+	}
 }
 /**
   * @brief  任务处理
@@ -27,7 +42,16 @@ void SYSTEM_Init(void)
   */
 void TASK_Schedule(void)
 {
-	
+	TSS_while();
+}
+/**
+  * @brief  运行指示灯闪烁任务
+  * @param  None
+  * @retval None
+  */
+void TSS_ledBlink(void)
+{
+	GPIOClass.Toggle(LED_Run);
 }
 /**
   * @brief  TIM2中断函数
@@ -38,11 +62,7 @@ void TIM2_IRQHandler(void)
 {
 	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 
 	{	
-		static uint16_t TIM2_Count1 = 0;
-		TIM2_Count1++;
-		if(TIM2_Count1 % 50 == 0) GPIOClass.Toggle(LED_Run);
-		
-		if(TIM2_Count1 >= 60000) TIM2_Count1 = 0;
+		TSS_timer();
 		TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);
 	}	
 }

+ 1 - 2
project_Template/User/main.h

@@ -11,12 +11,11 @@
 // system
 #include "RCC.h"
 #include "DELAY.h"
-#include "WDOG.h"
 #include "TIM.h"
 #include "USART.h"
 #include "GPIO.h"
 // drive
-
+#include "TimeScheduleSystem.h"
 // user
 #include "handle.h"
 

+ 154 - 0
system_Template/SPI.c

@@ -0,0 +1,154 @@
+#include "main.h"
+
+static void SPI1_Init(void);
+static void SPI2_Init(void);
+static uint8_t SPI_WriteRead(SPI_TypeDef* SPIx, uint8_t data, uint32_t timeout);
+static uint8_t SPI_CS_WritePin(SPI_TypeDef* SPIx, uint8_t bitVal);
+
+SPIClassStruct SPIClass = {
+	.SPI1_Init = SPI1_Init,
+	.SPI2_Init = SPI2_Init,
+	.WriteRead = SPI_WriteRead,
+	.WriteCSPin = SPI_CS_WritePin
+};
+// SPI1 CS
+#define SPI1_CS_GPIO_PORT    		GPIOB
+#define SPI1_CS_GPIO_CLK 	    	RCC_APB2Periph_GPIOB
+#define SPI1_CS_GPIO_PIN			GPIO_Pin_0
+// SPI2 CS
+#define SPI2_CS_GPIO_PORT    		GPIOA
+#define SPI2_CS_GPIO_CLK 	    	RCC_APB2Periph_GPIOA
+#define SPI2_CS_GPIO_PIN			GPIO_Pin_0
+
+/**
+  * @brief  SPI1初始化
+  * @param  None
+  * @retval None
+  */
+static void SPI1_Init(void)
+{
+	GPIO_InitTypeDef  GPIO_InitStructure;
+	SPI_InitTypeDef  SPI_InitStructure;
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+	// SPI1 SCK-PA5  MOSI-PA7
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	// SPI1 MISO-PA6
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+	GPIO_Init(GPIOA, &GPIO_InitStructure);
+	// software CS user write
+	RCC_APB2PeriphClockCmd(SPI1_CS_GPIO_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = SPI1_CS_GPIO_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_Init(SPI1_CS_GPIO_PORT, &GPIO_InitStructure);
+	GPIO_WriteBit(SPI1_CS_GPIO_PORT, SPI1_CS_GPIO_PIN, 1); // 拉高片选引脚
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // SPI1时钟使能
+
+	SPI_Cmd(SPI1, DISABLE);
+	SPI_I2S_DeInit(SPI1);
+	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为双线全双工
+	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI为主模式
+	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
+	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI时钟空闲时为低电平
+	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采样数据
+	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS信号由软件管理
+	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // SPI波特率预分频值 72M / Prescaler
+	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始
+	SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
+
+	SPI_Init(SPI1, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPI寄存器
+	SPI_Cmd(SPI1, ENABLE); // 使能SPI
+}
+
+/**
+  * @brief  SPI1初始化
+  * @param  None
+  * @retval None
+  */
+static void SPI2_Init(void)
+{
+	GPIO_InitTypeDef  GPIO_InitStructure;
+	SPI_InitTypeDef  SPI_InitStructure;
+	
+	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
+	// SPI1 SCK-PB13  MOSI-PB15
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_Init(GPIOB, &GPIO_InitStructure);
+	// SPI1 MISO-PB14
+	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
+	GPIO_Init(GPIOB, &GPIO_InitStructure);
+	// software CS user write
+	RCC_APB2PeriphClockCmd(SPI2_CS_GPIO_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = SPI2_CS_GPIO_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+	GPIO_Init(SPI2_CS_GPIO_PORT, &GPIO_InitStructure);
+	GPIO_WriteBit(SPI2_CS_GPIO_PORT, SPI2_CS_GPIO_PIN, 1); // 拉高片选引脚
+	
+	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // SPI2时钟使能
+
+	SPI_Cmd(SPI2, DISABLE);
+	SPI_I2S_DeInit(SPI2);
+	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI设置为双线全双工
+	SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI为主模式
+	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI发送接收8位帧结构
+	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // SPI时钟空闲时为低电平
+	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 第一个时钟沿开始采样数据
+	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // CS信号由软件管理
+	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // SPI波特率预分频值 36M / Prescaler
+	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 数据传输从MSB位开始
+	SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式
+
+	SPI_Init(SPI2, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPI寄存器
+	SPI_Cmd(SPI2, ENABLE); // 使能SPI
+}
+/**
+  * @brief  SPI读写函数
+  * @param  None
+  * @retval 0-超时 
+  */
+static uint8_t SPI_WriteRead(SPI_TypeDef* SPIx, uint8_t data, uint32_t timeout)
+{
+	uint32_t retry = 0;				 	
+	/* Loop while DR register in not emplty */
+	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET) // 发送缓存标志位为空
+	{
+		retry++;
+		if(retry > timeout) return 0;
+	}			  
+	SPI_I2S_SendData(SPIx, data); // 通过外设SPI2发送一个数据
+	retry = 0;
+	/* Wait to receive a byte */
+	while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) == RESET) // 接收缓存标志位不为空
+	{
+		retry++;
+		if(retry > timeout) return 0;
+	}	  						    
+	/* Return the byte read from the SPI bus */
+	return SPI_I2S_ReceiveData(SPIx); // 通过SPI2返回接收数据	
+}
+/**
+  * @brief  SPI读写函数
+  * @param  None
+  * @retval 0-成功
+  */
+static uint8_t SPI_CS_WritePin(SPI_TypeDef* SPIx, uint8_t bitVal)
+{
+	if(bitVal != RESET && bitVal != SET) return 1;
+	if(SPIx == SPI1) {
+		GPIO_WriteBit(SPI1_CS_GPIO_PORT, SPI1_CS_GPIO_PIN, bitVal);
+	} else if(SPIx == SPI2) {
+		GPIO_WriteBit(SPI2_CS_GPIO_PORT, SPI2_CS_GPIO_PIN, bitVal);
+	}
+	return 0;
+}
+
+
+

+ 15 - 0
system_Template/SPI.h

@@ -0,0 +1,15 @@
+#ifndef __SPI_AS_H
+#define __SPI_AS_H
+
+#include "main.h"
+
+typedef struct {
+	void (* SPI1_Init)(void);
+	void (* SPI2_Init)(void);
+	uint8_t (* WriteRead)(SPI_TypeDef *, uint8_t, uint32_t);
+	uint8_t (* WriteCSPin)(SPI_TypeDef *, uint8_t);
+} SPIClassStruct;
+
+extern SPIClassStruct SPIClass;
+
+#endif

+ 5 - 0
system_Template/USART.c

@@ -254,5 +254,10 @@ int fputc(int ch, FILE *f)
 		while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);		
 		return (ch);
 }
+#else
+int fputc(int ch, FILE *f)
+{
+	return (ch);
+}
 #endif
 

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.