Просмотр исходного кода

增加use_example,MPU6050模块,IICs;更新readme和部分旧内容

woshiashuai 2 лет назад
Родитель
Сommit
a634d00a66
57 измененных файлов с 1644 добавлено и 16 удалено
  1. 61 1
      README.md
  2. 3 1
      module_Template/ADXL345三轴传感器/ADXL345.c
  3. 13 0
      module_Template/ADXL345三轴传感器/use_example.c
  4. 10 0
      module_Template/BY9301语音播报模块/use_example.c
  5. 12 0
      module_Template/DHT11温湿度模块/use_example.c
  6. 16 0
      module_Template/DS1302时钟模块/use_example.c
  7. 13 0
      module_Template/DS18B20温度传感器/use_example.c
  8. 0 0
      module_Template/MEMS数字气体传感器(单个)/IIC.c
  9. 0 0
      module_Template/MEMS数字气体传感器(单个)/IIC.h
  10. 1 1
      module_Template/MEMS数字气体传感器(单个)/MEMS.c
  11. 2 2
      module_Template/MEMS数字气体传感器(单个)/MEMS.h
  12. 0 0
      module_Template/MEMS数字气体传感器(单个)/MEMS数字型气体传感器使用手册.docx
  13. 0 0
      module_Template/MEMS数字气体传感器(单个)/MEMS甲醛接口图.jpg
  14. 1 0
      module_Template/MEMS数字气体传感器(单个)/readme.txt
  15. 13 0
      module_Template/MEMS数字气体传感器(单个)/use_example.c
  16. 0 0
      module_Template/MEMS数字气体传感器(单个)/淘宝链接.txt
  17. 209 0
      module_Template/MEMS数字气体传感器(多个)/IICs.c
  18. 21 0
      module_Template/MEMS数字气体传感器(多个)/IICs.h
  19. 43 0
      module_Template/MEMS数字气体传感器(多个)/MEMS.c
  20. 12 0
      module_Template/MEMS数字气体传感器(多个)/MEMS.h
  21. BIN
      module_Template/MEMS数字气体传感器(多个)/MEMS数字型气体传感器使用手册.docx
  22. BIN
      module_Template/MEMS数字气体传感器(多个)/MEMS通用接口图.jpg
  23. 1 0
      module_Template/MEMS数字气体传感器(多个)/readme.txt
  24. 15 0
      module_Template/MEMS数字气体传感器(多个)/use_example.c
  25. 2 0
      module_Template/MEMS数字气体传感器(多个)/淘宝链接.txt
  26. 13 0
      module_Template/MLX90614红外测温/use_example.c
  27. 247 0
      module_Template/MPU6050三轴传感器/IIC.c
  28. 15 0
      module_Template/MPU6050三轴传感器/IIC.h
  29. 144 0
      module_Template/MPU6050三轴传感器/MPU6050.c
  30. 388 0
      module_Template/MPU6050三轴传感器/MPU6050.h
  31. BIN
      module_Template/MPU6050三轴传感器/MPU6050接口图.jpg
  32. 1 0
      module_Template/MPU6050三轴传感器/README.txt
  33. BIN
      module_Template/MPU6050三轴传感器/RM-MPU-6000A.pdf
  34. 15 0
      module_Template/MPU6050三轴传感器/use_example.c
  35. 0 0
      module_Template/MultiButton按键驱动/BUTTON.c
  36. 0 0
      module_Template/MultiButton按键驱动/BUTTON.h
  37. 0 0
      module_Template/MultiButton按键驱动/MultiButton.c
  38. 0 0
      module_Template/MultiButton按键驱动/MultiButton.h
  39. 0 0
      module_Template/MultiButton按键驱动/MultiButtonTips.md
  40. 13 0
      module_Template/MultiButton按键驱动/use_example.c
  41. 0 0
      module_Template/OLED屏幕0.96/0.96OLED接口图.jpg
  42. 0 0
      module_Template/OLED屏幕0.96/0.96OLED文字取模配置.png
  43. 0 0
      module_Template/OLED屏幕0.96/0.96寸OLED使用文档新手必看V3.0.pdf
  44. 0 0
      module_Template/OLED屏幕0.96/OLED.c
  45. 0 0
      module_Template/OLED屏幕0.96/OLED.h
  46. 0 0
      module_Template/OLED屏幕0.96/OLEDFont.h
  47. 20 0
      module_Template/OLED屏幕0.96/use_example.c
  48. 17 0
      module_Template/RC522-RFID模块/use_example.c
  49. 41 9
      module_Template/SG90舵机/SG90.c
  50. 1 0
      module_Template/SG90舵机/SG90.h
  51. 15 0
      module_Template/SG90舵机/use_example.c
  52. 17 0
      module_Template/SIM900A短信模块/use_example.c
  53. 13 0
      module_Template/SR04超声波/use_example.c
  54. 4 2
      module_Template/分时调度系统/use_example.c
  55. 2 0
      module_Template/智能健康检测模块/淘宝链接.txt
  56. 209 0
      system_Template/IICs.c
  57. 21 0
      system_Template/IICs.h

+ 61 - 1
README.md

@@ -1,2 +1,62 @@
-# STM32F1x系列工程模板、模块模板、外设模板
+# STM32F1x系列模板
+
+开发平台:KEIL MDK5
+
+MCU型号:STM32F103C8T6
+
+文件夹描述:
+
+module_Template:模块模板
+
+project_Template:工程模板
+
+system_Template:外设模板
+
+模块模板有以下内容:
+
+1. ADXL345三轴传感器
+2. ASR_CI1122语音识别
+3. BY9301语音播报模块
+4. DHT11温湿度模块
+5. DS18B20温度传感器
+6. DS1302时钟模块
+7. FIFO缓冲区1
+8. FIFO缓冲区2
+9. MEMS数字气体传感器(单个)
+10. MEMS数字气体传感器(多个)
+11. MLX90614红外测温
+12. MPU6050三轴传感器
+13. MultiButton按键驱动
+14. OLED屏幕0.96
+15. OneNET
+16. PM2.5检测模块
+17. RC522-RFID模块
+18. SG90舵机
+19. SIM900A短信模块
+20. SR04超声波
+21. USART&TIM
+22. WIFIGetAPI
+23. 单向链表
+24. 分时调度系统
+25. 智能健康检测模块
+
+
+
+外设模板有以下内容:
+
+1. ADC.c.h
+2. CAN.c.h
+3. DELAY.c.h
+4. EXTI.c.h
+5. FLASH.c.h
+6. GPIO.c.h
+7. IIC.c.h
+8. IICs.c.h
+9. NVIC.c.h
+10. Pvd.c.h
+11. RCC.c.h
+12. SPI.c.h
+13. TIM.c.h
+14. USART.c.h
+15. WDOG.c.h
 

+ 3 - 1
module_Template/ADXL345三轴传感器/ADXL345.c

@@ -1,7 +1,8 @@
 /*
 ADXL345三轴倾斜度模块
 */
-#include "main.h"
+#include "ADXL345.h"
+#include "IIC.h"
 
 /**
   * @brief  ADXL345初始化
@@ -10,6 +11,7 @@ ADXL345
   */
 uint8_t ADXL345_init(void)
 {
+	IIC_init();
 	if(ADXL345_read_reg(DEVICE_ID) == 0xE5)
 	{
 		ADXL345_write_reg(DATA_FORMAT,0X0B); // 低电平中断输出,13位全分辨率,输出数据右对齐,16g量程 

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

@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "ADXL345.h"
+
+int main()
+{
+	float angleX, angleY, angleZ;
+	ADXL345_init(); // 初始化
+	while(1) {
+		delayMs(1000);
+		get_angle(&angleX, &angleY, &angleZ); // 获取三轴偏移角度
+		printf("angle X:%f  Y:%f  Z:%f\n", angleX, angleY, angleZ);
+	}
+}

+ 10 - 0
module_Template/BY9301语音播报模块/use_example.c

@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include "BY9301.h"
+
+int main()
+{
+	BY9301Class.init(9600); // 初始化
+	BY9301Class.setVolume(30); // 音量30
+	BY9301Class.sayFileID(1); // 播放序号为1的mp3文件
+	while(1) {}
+}

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

@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include "DHT11.h"
+
+int main()
+{
+	DHT11Class.Init(); // 初始化
+	while(1) {
+		DHT11Class.Read(&DHT11Data); // 获取温湿度
+		printf("tem:%d  hum:%d\n", DHT11Data.temp_int, DHT11Data.humi_int);
+		delayMs(1000);
+	}
+}

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

@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include "DS1302.h"
+
+int main()
+{
+	// 2023年4月9日9点0分0秒星期日
+	uint8_t initTime[8] = {0x20, 0x23, 0x04, 0x09, 0x09, 0x00, 0x00, 0x07};
+	DS1302TimeStruct getTime;
+	DS1302Class.Init(); // 初始化
+	DS1302Class.SetTime(initTime); // 写入时间
+	while(1) {
+		DS1302Class.GetTime(&getTime); // 获取时间
+		printf("%d-%d-%d %d:%d:%d\n", getTime.year, getTime.month, getTime.day, getTime.hour, getTime.minute, getTime.second);
+		delayMs(1000);
+	}
+}

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

@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "DS18B20.h"
+
+int main()
+{
+	float tem;
+	DS18B20.Init(); // 初始化
+	while(1) {
+		tem = DS18B20.GetTemp_SkipRom(); // 获取温湿度
+		printf("tem:%f\n", tem);
+		delayMs(1000);
+	}
+}

+ 0 - 0
module_Template/MEMS_CH2O甲醛传感器/IIC.c → module_Template/MEMS数字气体传感器(单个)/IIC.c


+ 0 - 0
module_Template/MEMS_CH2O甲醛传感器/IIC.h → module_Template/MEMS数字气体传感器(单个)/IIC.h


+ 1 - 1
module_Template/MEMS_CH2O甲醛传感器/MEMS_CH2O.c → module_Template/MEMS数字气体传感器(单个)/MEMS.c

@@ -1,4 +1,4 @@
-#include "MEMS_CH2O.h"
+#include "MEMS.h"
 #include "IIC.h"
 
 

+ 2 - 2
module_Template/MEMS_CH2O甲醛传感器/MEMS_CH2O.h → module_Template/MEMS数字气体传感器(单个)/MEMS.h

@@ -1,5 +1,5 @@
-#ifndef __MEMS_CH2O_H
-#define __MEMS_CH2O_H
+#ifndef __MEMS_H
+#define __MEMS_H
 
 #include "main.h"
 

+ 0 - 0
module_Template/MEMS_CH2O甲醛传感器/MEMS数字甲醛传感器JED116-001.docx → module_Template/MEMS数字气体传感器(单个)/MEMS数字型气体传感器使用手册.docx


+ 0 - 0
module_Template/MEMS_CH2O甲醛传感器/MEMS甲醛接口图.jpg → module_Template/MEMS数字气体传感器(单个)/MEMS甲醛接口图.jpg


+ 1 - 0
module_Template/MEMS数字气体传感器(单个)/readme.txt

@@ -0,0 +1 @@
+精讯畅通的MEMS数字传感器各系列的IIC地址和寄存器地址均一致,故驱动通用

+ 13 - 0
module_Template/MEMS数字气体传感器(单个)/use_example.c

@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "MEMS.h"
+
+int main()
+{
+	uint16_t mems_val;
+	MEMS_CH2O_init(); // 初始化
+	while(1) {
+		mems_val = MEMS_CH2O_read(); // 读取
+		printf("mems read ppm:%d\n", mems_val);
+		delayMs(1000);
+	}
+}

+ 0 - 0
module_Template/MEMS_CH2O甲醛传感器/淘宝链接.txt → module_Template/MEMS数字气体传感器(单个)/淘宝链接.txt


+ 209 - 0
module_Template/MEMS数字气体传感器(多个)/IICs.c

@@ -0,0 +1,209 @@
+#include "IICs.h"
+
+
+#define IIC_SCL_OUT_1(port, pin)		(port->BSRR = (uint32_t)pin) // 置1
+#define IIC_SCL_OUT_0(port, pin)		(port->BRR = (uint32_t)pin)
+#define IIC_SDA_OUT_1(port, pin)		(port->BSRR = (uint32_t)pin) // 置1
+#define IIC_SDA_OUT_0(port, pin)		(port->BRR = (uint32_t)pin)
+#define IIC_SDA_IN(port, pin)			((port->IDR & pin) != 0)
+
+struct IIC_CONFIG {
+	uint32_t IIC_SDA_CLK;
+	GPIO_TypeDef* IIC_SDA_PORT;
+	uint16_t IIC_SDA_PIN;
+	uint32_t IIC_SCL_CLK;
+	GPIO_TypeDef* IIC_SCL_PORT;
+	uint16_t IIC_SCL_PIN;
+} iic_config[] = {
+	{RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_0, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_1},
+	{RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_6, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_7}
+};
+
+/**
+  * @brief  IIC延时
+  * @param  None
+  * @retval None
+  */
+static void IIC_Delay(uint8_t iicNo)
+{
+	static uint16_t delayTime[] = {400, 400};
+	uint16_t i;
+	/* 
+	 	下面的时间是通过逻辑分析仪测试得到的。
+    工作条件:CPU主频72MHz ,MDK编译环境,1级优化
+  
+		循环次数为10时,SCL频率 = 205KHz 
+		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
+	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
+	*/
+	for (i = 0; i < delayTime[iicNo]; i++);
+}
+/**
+  * @brief  SDA输出方向配置
+  * @param  None
+  * @retval None
+  */
+void Set_IIC_SDA_OUT(uint8_t iicNo)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;	
+	RCC_APB2PeriphClockCmd(iic_config[iicNo].IIC_SDA_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin=iic_config[iicNo].IIC_SDA_PIN;
+	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
+	GPIO_Init(iic_config[iicNo].IIC_SDA_PORT,&GPIO_InitStructure); 						
+}
+/**
+  * @brief  SDA输入方向配置
+  * @param  None
+  * @retval None
+  */
+void Set_IIC_SDA_IN(uint8_t iicNo)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;	
+	RCC_APB2PeriphClockCmd(iic_config[iicNo].IIC_SDA_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin=iic_config[iicNo].IIC_SDA_PIN;
+	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
+	GPIO_Init(iic_config[iicNo].IIC_SDA_PORT,&GPIO_InitStructure);
+}
+/**
+  * @brief  模拟IIC初始化
+  * @param  None
+  * @retval None
+  */
+void IIC_init(uint8_t iicNo)
+{
+	GPIO_InitTypeDef  GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(iic_config[iicNo].IIC_SDA_CLK | iic_config[iicNo].IIC_SCL_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = iic_config[iicNo].IIC_SDA_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 		
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
+	GPIO_Init(iic_config[iicNo].IIC_SDA_PORT, &GPIO_InitStructure);	
+	GPIO_InitStructure.GPIO_Pin = iic_config[iicNo].IIC_SCL_PIN;
+	GPIO_Init(iic_config[iicNo].IIC_SCL_PORT, &GPIO_InitStructure);	
+	IIC_stop(iicNo);
+}
+/**
+  * @brief  模拟IIC起始信号
+  * @param  None
+  * @retval None
+  */
+void IIC_start(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+}
+/**
+  * @brief  模拟IIC停止信号
+  * @param  None
+  * @retval None
+  */
+void IIC_stop(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+}
+/**
+  * @brief  模拟IIC主机应答
+  * @param  None
+  * @retval None
+  */
+void IIC_ack(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);	
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+}
+/**
+  * @brief  模拟IIC主机不应答
+  * @param  None
+  * @retval None
+  */
+void IIC_noack(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+}
+/**
+  * @brief  模拟IIC等待从机应答
+  * @param  None
+  * @retval 1: 接收应答失败 0: 接收应答成功
+  */
+uint8_t IIC_wait_ack(uint8_t iicNo)
+{
+	uint8_t rec = 0;
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	Set_IIC_SDA_IN(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	rec = IIC_SDA_IN(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	
+	return rec;
+}
+/**
+  * @brief  模拟IIC发送一个字节
+  * @param  None
+  * @retval None
+  */
+void IIC_send_byte(uint8_t iicNo, uint8_t txd)
+{
+	uint8_t i=0;
+	Set_IIC_SDA_OUT(iicNo);
+	for(i=0;i<8;i++)
+	{
+		if(txd&0x80) IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+		else IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+		IIC_Delay(iicNo);
+		IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		IIC_Delay(iicNo); // 发送数据
+		IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		if(i == 7) IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN); // 最后一位数据发送完要释放SDA总线
+		txd <<= 1;
+		IIC_Delay(iicNo);
+	}
+}
+/**
+  * @brief  模拟IIC读取一个字节
+  * @param  ack: 0,读完不产生应答 1,读完产生应答
+  * @retval 返回读取到的字节
+  */
+uint8_t IIC_read_byte(uint8_t iicNo, uint8_t ack)
+{
+	uint8_t i,receive=0;
+	Set_IIC_SDA_IN(iicNo);
+	for(i=0;i<8;i++)
+	{
+		receive <<= 1;
+		IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		IIC_Delay(iicNo);
+		if(IIC_SDA_IN(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN)) receive++; // 连续读取八位
+		IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		IIC_Delay(iicNo);	
+	}
+	if(!ack) IIC_noack(iicNo);
+	else IIC_ack(iicNo);
+
+	return receive; // 返回读取到的字节
+}

+ 21 - 0
module_Template/MEMS数字气体传感器(多个)/IICs.h

@@ -0,0 +1,21 @@
+#ifndef __IICS_H
+#define __IICS_H
+
+#include "main.h"
+
+typedef enum {
+	IIC_MEMS_NH3 = 0,
+	IIC_MEMS_H2S
+} IIC_NO;
+
+void Set_IIC_SDA_OUT(uint8_t iicNo);
+void Set_IIC_SDA_IN(uint8_t iicNo);
+void IIC_init(uint8_t iicNo);
+void IIC_start(uint8_t iicNo);
+void IIC_stop(uint8_t iicNo);
+void IIC_ack(uint8_t iicNo);
+void IIC_noack(uint8_t iicNo);
+uint8_t IIC_wait_ack(uint8_t iicNo);
+void IIC_send_byte(uint8_t iicNo, uint8_t txd);
+uint8_t IIC_read_byte(uint8_t iicNo, uint8_t ack);
+#endif

+ 43 - 0
module_Template/MEMS数字气体传感器(多个)/MEMS.c

@@ -0,0 +1,43 @@
+#include "MEMS.h"
+#include "IICs.h"
+
+
+/**
+  * @brief  MEMS数字型气体传感器IIC端口初始化
+  * @param  None
+  * @retval	None
+  */
+void MEMS_init(uint8_t iicNo)
+{
+	IIC_init(iicNo); // iic延时计数400
+}
+/**
+  * @brief  读取MEMS数字型气体传感器检测浓度
+  * @param  None
+  * @retval 返回读取到的数据 2字节
+  */
+uint16_t MEMS_read(uint8_t iicNo)
+{
+	uint8_t recHigh = 0,recLow = 0;
+	IIC_start(iicNo);
+	IIC_send_byte(iicNo, MEMS_wrAddr); // slave address + write cmd
+	if(IIC_wait_ack(iicNo)) {
+		IIC_stop(iicNo);
+		return 0xFFFF;
+	}
+	IIC_send_byte(iicNo, 0xA1); // read cmd
+	if(IIC_wait_ack(iicNo)) {
+		IIC_stop(iicNo);
+		return 0xFFFE;
+	}
+	IIC_start(iicNo);
+	IIC_send_byte(iicNo, MEMS_rdAddr); // slave address + read cmd
+	if(IIC_wait_ack(iicNo)) {
+		IIC_stop(iicNo);
+		return 0xFFFD;
+	}
+	recHigh = IIC_read_byte(iicNo, 1);
+	recLow = IIC_read_byte(iicNo, 0);
+	IIC_stop(iicNo);
+	return (uint16_t)recHigh << 8 | recLow;
+}

+ 12 - 0
module_Template/MEMS数字气体传感器(多个)/MEMS.h

@@ -0,0 +1,12 @@
+#ifndef __MEMS_H
+#define __MEMS_H
+
+#include "main.h"
+
+#define MEMS_wrAddr	0x54
+#define MEMS_rdAddr	0x55
+
+void MEMS_init(uint8_t iicNo);
+uint16_t MEMS_read(uint8_t iicNo);
+
+#endif

BIN
module_Template/MEMS数字气体传感器(多个)/MEMS数字型气体传感器使用手册.docx


BIN
module_Template/MEMS数字气体传感器(多个)/MEMS通用接口图.jpg


+ 1 - 0
module_Template/MEMS数字气体传感器(多个)/readme.txt

@@ -0,0 +1 @@
+精讯畅通的MEMS数字传感器各系列的IIC地址和寄存器地址均一致,故驱动通用

+ 15 - 0
module_Template/MEMS数字气体传感器(多个)/use_example.c

@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include "MEMS.h"
+
+int main()
+{
+	uint16_t NH3_val, H2S_val;
+	MEMS_init(IIC_MEMS_NH3); // 初始化
+	MEMS_init(IIC_MEMS_H2S); // 初始化
+	while(1) {
+		NH3_val = MEMS_read(IIC_MEMS_NH3); // 读取
+		H2S_val = MEMS_read(IIC_MEMS_H2S); // 读取
+		printf("NH3 ppm:%d, H2S ppm:%d\n", NH3_val, H2S_val);
+		delayMs(1000);
+	}
+}

+ 2 - 0
module_Template/MEMS数字气体传感器(多个)/淘宝链接.txt

@@ -0,0 +1,2 @@
+【淘宝】https://m.tb.cn/h.UpzPxRE?tk=f39fd82gKed CZ3457 「MEMS气体探头可燃气VOC氢气氨气硫化氢氟利昂乙醇空气质量传感器」
+点击链接直接打开 或者 淘宝搜索直接打开

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

@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "MLX90614.h"
+
+int main()
+{
+	float tem;
+	SMBus_Init(); // 初始化
+	while(1) {
+		tem = SMBus_ReadTemp(); // 读取温度
+		printf("tem:%f\n", tem);
+		delayMs(1000);
+	}
+}

+ 247 - 0
module_Template/MPU6050三轴传感器/IIC.c

@@ -0,0 +1,247 @@
+#include "IIC.h"
+
+
+#define GPIO_PORT_I2C	GPIOB					/* GPIO端口 */
+#define RCC_I2C_PORT 	RCC_APB2Periph_GPIOB	/* GPIO端口时钟 */
+#define I2C_SCL_PIN		GPIO_Pin_1				/* 连接到SCL时钟线的GPIO */
+#define I2C_SDA_PIN		GPIO_Pin_0				/* 连接到SDA数据线的GPIO */
+
+/* 定义读写SCL和SDA的宏,已增加代码的可移植性和可阅读性 */
+#if 0	/* 条件编译: 1 选择GPIO的库函数实现IO读写 */
+	#define I2C_SCL_1()  GPIO_SetBits(GPIO_PORT_I2C, I2C_SCL_PIN)		/* SCL = 1 */
+	#define I2C_SCL_0()  GPIO_ResetBits(GPIO_PORT_I2C, I2C_SCL_PIN)		/* SCL = 0 */
+	
+	#define I2C_SDA_1()  GPIO_SetBits(GPIO_PORT_I2C, I2C_SDA_PIN)		/* SDA = 1 */
+	#define I2C_SDA_0()  GPIO_ResetBits(GPIO_PORT_I2C, I2C_SDA_PIN)		/* SDA = 0 */
+	
+	#define I2C_SDA_READ()  GPIO_ReadInputDataBit(GPIO_PORT_I2C, I2C_SDA_PIN)	/* 读SDA口线状态 */
+#else	/* 这个分支选择直接寄存器操作实现IO读写 */
+    /* 注意:如下写法,在IAR最高级别优化时,会被编译器错误优化 */
+	#define I2C_SCL_1()  GPIO_PORT_I2C->BSRR = I2C_SCL_PIN				/* SCL = 1 */
+	#define I2C_SCL_0()  GPIO_PORT_I2C->BRR = I2C_SCL_PIN				/* SCL = 0 */
+	
+	#define I2C_SDA_1()  GPIO_PORT_I2C->BSRR = I2C_SDA_PIN				/* SDA = 1 */
+	#define I2C_SDA_0()  GPIO_PORT_I2C->BRR = I2C_SDA_PIN				/* SDA = 0 */
+	
+	#define I2C_SDA_READ()  ((GPIO_PORT_I2C->IDR & I2C_SDA_PIN) != 0)	/* 读SDA口线状态 */
+#endif
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_delay
+*	功能说明: I2C总线位延迟,最快400KHz
+*	形    参:无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+static void IIC_delay(void)
+{
+	uint8_t i;
+
+	/* 
+	 	下面的时间是通过安富莱AX-Pro逻辑分析仪测试得到的。
+		CPU主频72MHz时,在内部Flash运行, MDK工程不优化
+		循环次数为10时,SCL频率 = 205KHz 
+		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
+	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
+        
+    IAR工程编译效率高,不能设置为7
+	*/
+	for (i = 0; i < 10; i++);
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_start
+*	功能说明: CPU发起I2C总线启动信号
+*	形    参:无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void IIC_start(void)
+{
+	/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
+	I2C_SDA_1();
+	I2C_SCL_1();
+	IIC_delay();
+	I2C_SDA_0();
+	IIC_delay();
+	I2C_SCL_0();
+	IIC_delay();
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_start
+*	功能说明: CPU发起I2C总线停止信号
+*	形    参:无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void IIC_stop(void)
+{
+	/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */
+	I2C_SDA_0();
+	I2C_SCL_1();
+	IIC_delay();
+	I2C_SDA_1();
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_send_byte
+*	功能说明: CPU向I2C总线设备发送8bit数据
+*	形    参:_ucByte : 等待发送的字节
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void IIC_send_byte(uint8_t _ucByte)
+{
+	uint8_t i;
+
+	/* 先发送字节的高位bit7 */
+	for (i = 0; i < 8; i++)
+	{		
+		if (_ucByte & 0x80)
+		{
+			I2C_SDA_1();
+		}
+		else
+		{
+			I2C_SDA_0();
+		}
+		IIC_delay();
+		I2C_SCL_1();
+		IIC_delay();	
+		I2C_SCL_0();
+		if (i == 7)
+		{
+			 I2C_SDA_1(); // 释放总线
+		}
+		_ucByte <<= 1;	/* 左移一个bit */
+		IIC_delay();
+	}
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_read_byte
+*	功能说明: CPU从I2C总线设备读取8bit数据
+*	形    参:无
+*	返 回 值: 读到的数据
+*********************************************************************************************************
+*/
+uint8_t IIC_read_byte(u8 ack)
+{
+	uint8_t i;
+	uint8_t value;
+
+	/* 读到第1个bit为数据的bit7 */
+	value = 0;
+	for (i = 0; i < 8; i++)
+	{
+		value <<= 1;
+		I2C_SCL_1();
+		IIC_delay();
+		if (I2C_SDA_READ())
+		{
+			value++;
+		}
+		I2C_SCL_0();
+		IIC_delay();
+	}
+	if(ack==0)
+		IIC_nack();
+	else
+		IIC_ack();
+	return value;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_wait_ack
+*	功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
+*	形    参:无
+*	返 回 值: 返回0表示正确应答,1表示无器件响应
+*********************************************************************************************************
+*/
+uint8_t IIC_wait_ack(void)
+{
+	uint8_t re;
+
+	I2C_SDA_1();	/* CPU释放SDA总线 */
+	IIC_delay();
+	I2C_SCL_1();	/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
+	IIC_delay();
+	if (I2C_SDA_READ())	/* CPU读取SDA口线状态 */
+	{
+		re = 1;
+	}
+	else
+	{
+		re = 0;
+	}
+	I2C_SCL_0();
+	IIC_delay();
+	return re;
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_ack
+*	功能说明: CPU产生一个ACK信号
+*	形    参:无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void IIC_ack(void)
+{
+	I2C_SDA_0();	/* CPU驱动SDA = 0 */
+	IIC_delay();
+	I2C_SCL_1();	/* CPU产生1个时钟 */
+	IIC_delay();
+	I2C_SCL_0();
+	IIC_delay();
+	I2C_SDA_1();	/* CPU释放SDA总线 */
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: IIC_nack
+*	功能说明: CPU产生1个NACK信号
+*	形    参:无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void IIC_nack(void)
+{
+	I2C_SDA_1();	/* CPU驱动SDA = 1 */
+	IIC_delay();
+	I2C_SCL_1();	/* CPU产生1个时钟 */
+	IIC_delay();
+	I2C_SCL_0();
+	IIC_delay();	
+}
+
+/*
+*********************************************************************************************************
+*	函 数 名: i2c_GPIO_Config
+*	功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
+*	形    参:无
+*	返 回 值: 无
+*********************************************************************************************************
+*/
+void IIC_init(void)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;
+
+	RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE);	/* 打开GPIO时钟 */
+
+	GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  	/* 开漏输出 */
+	GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);
+
+	/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
+	IIC_stop();
+}

+ 15 - 0
module_Template/MPU6050三轴传感器/IIC.h

@@ -0,0 +1,15 @@
+#ifndef __I2C_H
+#define __I2C_H
+
+#include "main.h"
+
+void IIC_start(void);
+void IIC_stop(void);
+void IIC_send_byte(uint8_t _ucByte);
+uint8_t IIC_read_byte(uint8_t ack);
+uint8_t IIC_wait_ack(void);
+void IIC_ack(void);
+void IIC_nack(void);
+void IIC_init(void);
+
+#endif

+ 144 - 0
module_Template/MPU6050三轴传感器/MPU6050.c

@@ -0,0 +1,144 @@
+#include "MPU6050.h"
+#include "IIC.h"
+
+
+/**
+  * @brief   写数据到MPU6050寄存器
+  * @param   
+  * @retval  
+  */
+void MPU6050_WriteReg(u8 reg_add,u8 reg_dat)
+{
+	IIC_start();
+	IIC_send_byte(MPU6050_WriteAddr);
+	IIC_wait_ack();
+	IIC_send_byte(reg_add);
+	IIC_wait_ack();
+	IIC_send_byte(reg_dat);
+	IIC_wait_ack();
+	IIC_stop();
+}
+/**
+  * @brief   从MPU6050寄存器读取数据
+  * @param   
+  * @retval  
+  */
+void MPU6050_ReadData(u8 reg_add,unsigned char*Read,u8 num)
+{
+	unsigned char i;
+	
+	IIC_start();
+	IIC_send_byte(MPU6050_WriteAddr);
+	IIC_wait_ack();
+	IIC_send_byte(reg_add);
+	IIC_wait_ack();
+	
+	IIC_start();
+	IIC_send_byte(MPU6050_ReadAddr);
+	IIC_wait_ack();
+	
+	for(i=0;i<(num-1);i++){
+		*Read=IIC_read_byte(1);
+		Read++;
+	}
+	*Read=IIC_read_byte(0);
+	IIC_stop();
+}
+
+
+/**
+  * @brief   初始化MPU6050芯片
+  * @param   
+  * @retval  
+  */
+void MPU6050_Init(void)
+{
+	IIC_init();
+	//在初始化之前要延时一段时间,若没有延时,则断电后再上电数据可能会出错
+	DELAYClass.DelayMs(1000);
+	MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);	    //解除休眠状态
+	MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);	    //陀螺仪采样率,1KHz
+	MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);	        //低通滤波器的设置,截止频率是1K,带宽是5K
+	MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);	  //配置加速度传感器工作在2G模式,不自检
+	MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
+	MPU6050ReadID();
+}
+
+/**
+  * @brief   读取MPU6050的ID
+  * @param   
+  * @retval  
+  */
+uint8_t MPU6050ReadID(void)
+{
+	unsigned char Re = 0;
+    MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //读器件地址
+	if(Re != 0x68)
+	{
+		printf("MPU6050 dectected error!\n");
+		return 0;
+	}
+	else
+	{
+		printf("MPU6050 ID = 0x%02X\n",Re);
+		return 1;
+	}
+		
+}
+/**
+  * @brief   读取MPU6050的加速度数据
+  * @param   
+  * @retval  
+  */
+void MPU6050ReadAcc(short *accData)
+{
+    u8 buf[6];
+    MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6);
+    accData[0] = (buf[0] << 8) | buf[1];
+    accData[1] = (buf[2] << 8) | buf[3];
+    accData[2] = (buf[4] << 8) | buf[5];
+}
+
+/**
+  * @brief   读取MPU6050的角加速度数据
+  * @param   
+  * @retval  
+  */
+void MPU6050ReadGyro(short *gyroData)
+{
+    u8 buf[6];
+    MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
+    gyroData[0] = (buf[0] << 8) | buf[1];
+    gyroData[1] = (buf[2] << 8) | buf[3];
+    gyroData[2] = (buf[4] << 8) | buf[5];
+}
+
+
+/**
+  * @brief   读取MPU6050的原始温度数据
+  * @param   
+  * @retval  
+  */
+void MPU6050ReadTemp(short *tempData)
+{
+	u8 buf[2];
+    MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
+    *tempData = (buf[0] << 8) | buf[1];
+}
+
+
+/**
+  * @brief   读取MPU6050的温度数据,转化成摄氏度
+  * @param   
+  * @retval  
+  */
+void MPU6050_ReturnTemp(float *Temperature)
+{
+	short temp3;
+	u8 buf[2];
+	
+	MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
+  temp3= (buf[0] << 8) | buf[1];	
+	*Temperature=((double) temp3/340.0)+36.53;
+
+}

+ 388 - 0
module_Template/MPU6050三轴传感器/MPU6050.h

@@ -0,0 +1,388 @@
+#ifndef __MPU6050_H
+#define __MPU6050_H
+
+#include "main.h"
+
+
+
+//模块的A0引脚接GND,IIC的7位地址为0x68,若接到VCC,需要改为0x69
+#define MPU6050_SLAVE_ADDRESS  	0x68
+#define MPU6050_ReadAddr		0xD1
+#define MPU6050_WriteAddr		0xD0
+
+
+#define MPU6050_WHO_AM_I        0x75
+#define MPU6050_SMPLRT_DIV      0  //8000Hz
+#define MPU6050_DLPF_CFG        0
+#define MPU6050_GYRO_OUT        0x43     //MPU6050陀螺仪数据寄存器地址
+#define MPU6050_ACC_OUT         0x3B     //MPU6050加速度数据寄存器地址
+
+
+
+#define MPU6050_ADDRESS_AD0_LOW     0x68 // address pin low (GND), default for InvenSense evaluation board
+#define MPU6050_ADDRESS_AD0_HIGH    0x69 // address pin high (VCC)
+#define MPU6050_DEFAULT_ADDRESS     MPU6050_ADDRESS_AD0_LOW
+
+#define MPU6050_RA_XG_OFFS_TC       0x00 //[7] PWR_MODE, [6:1] XG_OFFS_TC, [0] OTP_BNK_VLD
+#define MPU6050_RA_YG_OFFS_TC       0x01 //[7] PWR_MODE, [6:1] YG_OFFS_TC, [0] OTP_BNK_VLD
+#define MPU6050_RA_ZG_OFFS_TC       0x02 //[7] PWR_MODE, [6:1] ZG_OFFS_TC, [0] OTP_BNK_VLD
+#define MPU6050_RA_X_FINE_GAIN      0x03 //[7:0] X_FINE_GAIN
+#define MPU6050_RA_Y_FINE_GAIN      0x04 //[7:0] Y_FINE_GAIN
+#define MPU6050_RA_Z_FINE_GAIN      0x05 //[7:0] Z_FINE_GAIN
+#define MPU6050_RA_XA_OFFS_H        0x06 //[15:0] XA_OFFS
+#define MPU6050_RA_XA_OFFS_L_TC     0x07
+#define MPU6050_RA_YA_OFFS_H        0x08 //[15:0] YA_OFFS
+#define MPU6050_RA_YA_OFFS_L_TC     0x09
+#define MPU6050_RA_ZA_OFFS_H        0x0A //[15:0] ZA_OFFS
+#define MPU6050_RA_ZA_OFFS_L_TC     0x0B
+#define MPU6050_RA_XG_OFFS_USRH     0x13 //[15:0] XG_OFFS_USR
+#define MPU6050_RA_XG_OFFS_USRL     0x14
+#define MPU6050_RA_YG_OFFS_USRH     0x15 //[15:0] YG_OFFS_USR
+#define MPU6050_RA_YG_OFFS_USRL     0x16
+#define MPU6050_RA_ZG_OFFS_USRH     0x17 //[15:0] ZG_OFFS_USR
+#define MPU6050_RA_ZG_OFFS_USRL     0x18
+#define MPU6050_RA_SMPLRT_DIV       0x19
+#define MPU6050_RA_CONFIG           0x1A
+#define MPU6050_RA_GYRO_CONFIG      0x1B
+#define MPU6050_RA_ACCEL_CONFIG     0x1C
+#define MPU6050_RA_FF_THR           0x1D
+#define MPU6050_RA_FF_DUR           0x1E
+#define MPU6050_RA_MOT_THR          0x1F
+#define MPU6050_RA_MOT_DUR          0x20
+#define MPU6050_RA_ZRMOT_THR        0x21
+#define MPU6050_RA_ZRMOT_DUR        0x22
+#define MPU6050_RA_FIFO_EN          0x23
+#define MPU6050_RA_I2C_MST_CTRL     0x24
+#define MPU6050_RA_I2C_SLV0_ADDR    0x25
+#define MPU6050_RA_I2C_SLV0_REG     0x26
+#define MPU6050_RA_I2C_SLV0_CTRL    0x27
+#define MPU6050_RA_I2C_SLV1_ADDR    0x28
+#define MPU6050_RA_I2C_SLV1_REG     0x29
+#define MPU6050_RA_I2C_SLV1_CTRL    0x2A
+#define MPU6050_RA_I2C_SLV2_ADDR    0x2B
+#define MPU6050_RA_I2C_SLV2_REG     0x2C
+#define MPU6050_RA_I2C_SLV2_CTRL    0x2D
+#define MPU6050_RA_I2C_SLV3_ADDR    0x2E
+#define MPU6050_RA_I2C_SLV3_REG     0x2F
+#define MPU6050_RA_I2C_SLV3_CTRL    0x30
+#define MPU6050_RA_I2C_SLV4_ADDR    0x31
+#define MPU6050_RA_I2C_SLV4_REG     0x32
+#define MPU6050_RA_I2C_SLV4_DO      0x33
+#define MPU6050_RA_I2C_SLV4_CTRL    0x34
+#define MPU6050_RA_I2C_SLV4_DI      0x35
+#define MPU6050_RA_I2C_MST_STATUS   0x36
+#define MPU6050_RA_INT_PIN_CFG      0x37
+#define MPU6050_RA_INT_ENABLE       0x38
+#define MPU6050_RA_DMP_INT_STATUS   0x39
+#define MPU6050_RA_INT_STATUS       0x3A
+#define MPU6050_RA_ACCEL_XOUT_H     0x3B
+#define MPU6050_RA_ACCEL_XOUT_L     0x3C
+#define MPU6050_RA_ACCEL_YOUT_H     0x3D
+#define MPU6050_RA_ACCEL_YOUT_L     0x3E
+#define MPU6050_RA_ACCEL_ZOUT_H     0x3F
+#define MPU6050_RA_ACCEL_ZOUT_L     0x40
+#define MPU6050_RA_TEMP_OUT_H       0x41
+#define MPU6050_RA_TEMP_OUT_L       0x42
+#define MPU6050_RA_GYRO_XOUT_H      0x43
+#define MPU6050_RA_GYRO_XOUT_L      0x44
+#define MPU6050_RA_GYRO_YOUT_H      0x45
+#define MPU6050_RA_GYRO_YOUT_L      0x46
+#define MPU6050_RA_GYRO_ZOUT_H      0x47
+#define MPU6050_RA_GYRO_ZOUT_L      0x48
+#define MPU6050_RA_EXT_SENS_DATA_00 0x49
+#define MPU6050_RA_EXT_SENS_DATA_01 0x4A
+#define MPU6050_RA_EXT_SENS_DATA_02 0x4B
+#define MPU6050_RA_EXT_SENS_DATA_03 0x4C
+#define MPU6050_RA_EXT_SENS_DATA_04 0x4D
+#define MPU6050_RA_EXT_SENS_DATA_05 0x4E
+#define MPU6050_RA_EXT_SENS_DATA_06 0x4F
+#define MPU6050_RA_EXT_SENS_DATA_07 0x50
+#define MPU6050_RA_EXT_SENS_DATA_08 0x51
+#define MPU6050_RA_EXT_SENS_DATA_09 0x52
+#define MPU6050_RA_EXT_SENS_DATA_10 0x53
+#define MPU6050_RA_EXT_SENS_DATA_11 0x54
+#define MPU6050_RA_EXT_SENS_DATA_12 0x55
+#define MPU6050_RA_EXT_SENS_DATA_13 0x56
+#define MPU6050_RA_EXT_SENS_DATA_14 0x57
+#define MPU6050_RA_EXT_SENS_DATA_15 0x58
+#define MPU6050_RA_EXT_SENS_DATA_16 0x59
+#define MPU6050_RA_EXT_SENS_DATA_17 0x5A
+#define MPU6050_RA_EXT_SENS_DATA_18 0x5B
+#define MPU6050_RA_EXT_SENS_DATA_19 0x5C
+#define MPU6050_RA_EXT_SENS_DATA_20 0x5D
+#define MPU6050_RA_EXT_SENS_DATA_21 0x5E
+#define MPU6050_RA_EXT_SENS_DATA_22 0x5F
+#define MPU6050_RA_EXT_SENS_DATA_23 0x60
+#define MPU6050_RA_MOT_DETECT_STATUS    0x61
+#define MPU6050_RA_I2C_SLV0_DO      0x63
+#define MPU6050_RA_I2C_SLV1_DO      0x64
+#define MPU6050_RA_I2C_SLV2_DO      0x65
+#define MPU6050_RA_I2C_SLV3_DO      0x66
+#define MPU6050_RA_I2C_MST_DELAY_CTRL   0x67
+#define MPU6050_RA_SIGNAL_PATH_RESET    0x68
+#define MPU6050_RA_MOT_DETECT_CTRL      0x69
+#define MPU6050_RA_USER_CTRL        0x6A
+#define MPU6050_RA_PWR_MGMT_1       0x6B
+#define MPU6050_RA_PWR_MGMT_2       0x6C
+#define MPU6050_RA_BANK_SEL         0x6D
+#define MPU6050_RA_MEM_START_ADDR   0x6E
+#define MPU6050_RA_MEM_R_W          0x6F
+#define MPU6050_RA_DMP_CFG_1        0x70
+#define MPU6050_RA_DMP_CFG_2        0x71
+#define MPU6050_RA_FIFO_COUNTH      0x72
+#define MPU6050_RA_FIFO_COUNTL      0x73
+#define MPU6050_RA_FIFO_R_W         0x74
+#define MPU6050_RA_WHO_AM_I         0x75
+
+#define MPU6050_TC_PWR_MODE_BIT     7
+#define MPU6050_TC_OFFSET_BIT       6
+#define MPU6050_TC_OFFSET_LENGTH    6
+#define MPU6050_TC_OTP_BNK_VLD_BIT  0
+
+#define MPU6050_VDDIO_LEVEL_VLOGIC  0
+#define MPU6050_VDDIO_LEVEL_VDD     1
+
+#define MPU6050_CFG_EXT_SYNC_SET_BIT    5
+#define MPU6050_CFG_EXT_SYNC_SET_LENGTH 3
+#define MPU6050_CFG_DLPF_CFG_BIT    2
+#define MPU6050_CFG_DLPF_CFG_LENGTH 3
+
+#define MPU6050_EXT_SYNC_DISABLED       0x0
+#define MPU6050_EXT_SYNC_TEMP_OUT_L     0x1
+#define MPU6050_EXT_SYNC_GYRO_XOUT_L    0x2
+#define MPU6050_EXT_SYNC_GYRO_YOUT_L    0x3
+#define MPU6050_EXT_SYNC_GYRO_ZOUT_L    0x4
+#define MPU6050_EXT_SYNC_ACCEL_XOUT_L   0x5
+#define MPU6050_EXT_SYNC_ACCEL_YOUT_L   0x6
+#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L   0x7
+
+#define MPU6050_DLPF_BW_256         0x00
+#define MPU6050_DLPF_BW_188         0x01
+#define MPU6050_DLPF_BW_98          0x02
+#define MPU6050_DLPF_BW_42          0x03
+#define MPU6050_DLPF_BW_20          0x04
+#define MPU6050_DLPF_BW_10          0x05
+#define MPU6050_DLPF_BW_5           0x06
+
+#define MPU6050_GCONFIG_FS_SEL_BIT      4
+#define MPU6050_GCONFIG_FS_SEL_LENGTH   2
+
+#define MPU6050_GYRO_FS_250         0x00
+#define MPU6050_GYRO_FS_500         0x01
+#define MPU6050_GYRO_FS_1000        0x02
+#define MPU6050_GYRO_FS_2000        0x03
+
+#define MPU6050_ACONFIG_XA_ST_BIT           7
+#define MPU6050_ACONFIG_YA_ST_BIT           6
+#define MPU6050_ACONFIG_ZA_ST_BIT           5
+#define MPU6050_ACONFIG_AFS_SEL_BIT         4
+#define MPU6050_ACONFIG_AFS_SEL_LENGTH      2
+#define MPU6050_ACONFIG_ACCEL_HPF_BIT       2
+#define MPU6050_ACONFIG_ACCEL_HPF_LENGTH    3
+
+#define MPU6050_ACCEL_FS_2          0x00
+#define MPU6050_ACCEL_FS_4          0x01
+#define MPU6050_ACCEL_FS_8          0x02
+#define MPU6050_ACCEL_FS_16         0x03
+
+#define MPU6050_DHPF_RESET          0x00
+#define MPU6050_DHPF_5              0x01
+#define MPU6050_DHPF_2P5            0x02
+#define MPU6050_DHPF_1P25           0x03
+#define MPU6050_DHPF_0P63           0x04
+#define MPU6050_DHPF_HOLD           0x07
+
+#define MPU6050_TEMP_FIFO_EN_BIT    7
+#define MPU6050_XG_FIFO_EN_BIT      6
+#define MPU6050_YG_FIFO_EN_BIT      5
+#define MPU6050_ZG_FIFO_EN_BIT      4
+#define MPU6050_ACCEL_FIFO_EN_BIT   3
+#define MPU6050_SLV2_FIFO_EN_BIT    2
+#define MPU6050_SLV1_FIFO_EN_BIT    1
+#define MPU6050_SLV0_FIFO_EN_BIT    0
+
+#define MPU6050_MULT_MST_EN_BIT     7
+#define MPU6050_WAIT_FOR_ES_BIT     6
+#define MPU6050_SLV_3_FIFO_EN_BIT   5
+#define MPU6050_I2C_MST_P_NSR_BIT   4
+#define MPU6050_I2C_MST_CLK_BIT     3
+#define MPU6050_I2C_MST_CLK_LENGTH  4
+
+#define MPU6050_CLOCK_DIV_348       0x0
+#define MPU6050_CLOCK_DIV_333       0x1
+#define MPU6050_CLOCK_DIV_320       0x2
+#define MPU6050_CLOCK_DIV_308       0x3
+#define MPU6050_CLOCK_DIV_296       0x4
+#define MPU6050_CLOCK_DIV_286       0x5
+#define MPU6050_CLOCK_DIV_276       0x6
+#define MPU6050_CLOCK_DIV_267       0x7
+#define MPU6050_CLOCK_DIV_258       0x8
+#define MPU6050_CLOCK_DIV_500       0x9
+#define MPU6050_CLOCK_DIV_471       0xA
+#define MPU6050_CLOCK_DIV_444       0xB
+#define MPU6050_CLOCK_DIV_421       0xC
+#define MPU6050_CLOCK_DIV_400       0xD
+#define MPU6050_CLOCK_DIV_381       0xE
+#define MPU6050_CLOCK_DIV_364       0xF
+
+#define MPU6050_I2C_SLV_RW_BIT      7
+#define MPU6050_I2C_SLV_ADDR_BIT    6
+#define MPU6050_I2C_SLV_ADDR_LENGTH 7
+#define MPU6050_I2C_SLV_EN_BIT      7
+#define MPU6050_I2C_SLV_BYTE_SW_BIT 6
+#define MPU6050_I2C_SLV_REG_DIS_BIT 5
+#define MPU6050_I2C_SLV_GRP_BIT     4
+#define MPU6050_I2C_SLV_LEN_BIT     3
+#define MPU6050_I2C_SLV_LEN_LENGTH  4
+
+#define MPU6050_I2C_SLV4_RW_BIT         7
+#define MPU6050_I2C_SLV4_ADDR_BIT       6
+#define MPU6050_I2C_SLV4_ADDR_LENGTH    7
+#define MPU6050_I2C_SLV4_EN_BIT         7
+#define MPU6050_I2C_SLV4_INT_EN_BIT     6
+#define MPU6050_I2C_SLV4_REG_DIS_BIT    5
+#define MPU6050_I2C_SLV4_MST_DLY_BIT    4
+#define MPU6050_I2C_SLV4_MST_DLY_LENGTH 5
+
+#define MPU6050_MST_PASS_THROUGH_BIT    7
+#define MPU6050_MST_I2C_SLV4_DONE_BIT   6
+#define MPU6050_MST_I2C_LOST_ARB_BIT    5
+#define MPU6050_MST_I2C_SLV4_NACK_BIT   4
+#define MPU6050_MST_I2C_SLV3_NACK_BIT   3
+#define MPU6050_MST_I2C_SLV2_NACK_BIT   2
+#define MPU6050_MST_I2C_SLV1_NACK_BIT   1
+#define MPU6050_MST_I2C_SLV0_NACK_BIT   0
+
+#define MPU6050_INTCFG_INT_LEVEL_BIT        7
+#define MPU6050_INTCFG_INT_OPEN_BIT         6
+#define MPU6050_INTCFG_LATCH_INT_EN_BIT     5
+#define MPU6050_INTCFG_INT_RD_CLEAR_BIT     4
+#define MPU6050_INTCFG_FSYNC_INT_LEVEL_BIT  3
+#define MPU6050_INTCFG_FSYNC_INT_EN_BIT     2
+#define MPU6050_INTCFG_I2C_BYPASS_EN_BIT    1
+#define MPU6050_INTCFG_CLKOUT_EN_BIT        0
+
+#define MPU6050_INTMODE_ACTIVEHIGH  0x00
+#define MPU6050_INTMODE_ACTIVELOW   0x01
+
+#define MPU6050_INTDRV_PUSHPULL     0x00
+#define MPU6050_INTDRV_OPENDRAIN    0x01
+
+#define MPU6050_INTLATCH_50USPULSE  0x00
+#define MPU6050_INTLATCH_WAITCLEAR  0x01
+
+#define MPU6050_INTCLEAR_STATUSREAD 0x00
+#define MPU6050_INTCLEAR_ANYREAD    0x01
+
+#define MPU6050_INTERRUPT_FF_BIT            7
+#define MPU6050_INTERRUPT_MOT_BIT           6
+#define MPU6050_INTERRUPT_ZMOT_BIT          5
+#define MPU6050_INTERRUPT_FIFO_OFLOW_BIT    4
+#define MPU6050_INTERRUPT_I2C_MST_INT_BIT   3
+#define MPU6050_INTERRUPT_PLL_RDY_INT_BIT   2
+#define MPU6050_INTERRUPT_DMP_INT_BIT       1
+#define MPU6050_INTERRUPT_DATA_RDY_BIT      0
+
+// TODO: figure out what these actually do
+// UMPL source code is not very obivous
+#define MPU6050_DMPINT_5_BIT            5
+#define MPU6050_DMPINT_4_BIT            4
+#define MPU6050_DMPINT_3_BIT            3
+#define MPU6050_DMPINT_2_BIT            2
+#define MPU6050_DMPINT_1_BIT            1
+#define MPU6050_DMPINT_0_BIT            0
+
+#define MPU6050_MOTION_MOT_XNEG_BIT     7
+#define MPU6050_MOTION_MOT_XPOS_BIT     6
+#define MPU6050_MOTION_MOT_YNEG_BIT     5
+#define MPU6050_MOTION_MOT_YPOS_BIT     4
+#define MPU6050_MOTION_MOT_ZNEG_BIT     3
+#define MPU6050_MOTION_MOT_ZPOS_BIT     2
+#define MPU6050_MOTION_MOT_ZRMOT_BIT    0
+
+#define MPU6050_DELAYCTRL_DELAY_ES_SHADOW_BIT   7
+#define MPU6050_DELAYCTRL_I2C_SLV4_DLY_EN_BIT   4
+#define MPU6050_DELAYCTRL_I2C_SLV3_DLY_EN_BIT   3
+#define MPU6050_DELAYCTRL_I2C_SLV2_DLY_EN_BIT   2
+#define MPU6050_DELAYCTRL_I2C_SLV1_DLY_EN_BIT   1
+#define MPU6050_DELAYCTRL_I2C_SLV0_DLY_EN_BIT   0
+
+#define MPU6050_PATHRESET_GYRO_RESET_BIT    2
+#define MPU6050_PATHRESET_ACCEL_RESET_BIT   1
+#define MPU6050_PATHRESET_TEMP_RESET_BIT    0
+
+#define MPU6050_DETECT_ACCEL_ON_DELAY_BIT       5
+#define MPU6050_DETECT_ACCEL_ON_DELAY_LENGTH    2
+#define MPU6050_DETECT_FF_COUNT_BIT             3
+#define MPU6050_DETECT_FF_COUNT_LENGTH          2
+#define MPU6050_DETECT_MOT_COUNT_BIT            1
+#define MPU6050_DETECT_MOT_COUNT_LENGTH         2
+
+#define MPU6050_DETECT_DECREMENT_RESET  0x0
+#define MPU6050_DETECT_DECREMENT_1      0x1
+#define MPU6050_DETECT_DECREMENT_2      0x2
+#define MPU6050_DETECT_DECREMENT_4      0x3
+
+#define MPU6050_USERCTRL_DMP_EN_BIT             7
+#define MPU6050_USERCTRL_FIFO_EN_BIT            6
+#define MPU6050_USERCTRL_I2C_MST_EN_BIT         5
+#define MPU6050_USERCTRL_I2C_IF_DIS_BIT         4
+#define MPU6050_USERCTRL_DMP_RESET_BIT          3
+#define MPU6050_USERCTRL_FIFO_RESET_BIT         2
+#define MPU6050_USERCTRL_I2C_MST_RESET_BIT      1
+#define MPU6050_USERCTRL_SIG_COND_RESET_BIT     0
+
+#define MPU6050_PWR1_DEVICE_RESET_BIT   7
+#define MPU6050_PWR1_SLEEP_BIT          6
+#define MPU6050_PWR1_CYCLE_BIT          5
+#define MPU6050_PWR1_TEMP_DIS_BIT       3
+#define MPU6050_PWR1_CLKSEL_BIT         2
+#define MPU6050_PWR1_CLKSEL_LENGTH      3
+
+#define MPU6050_CLOCK_INTERNAL          0x00
+#define MPU6050_CLOCK_PLL_XGYRO         0x01
+#define MPU6050_CLOCK_PLL_YGYRO         0x02
+#define MPU6050_CLOCK_PLL_ZGYRO         0x03
+#define MPU6050_CLOCK_PLL_EXT32K        0x04
+#define MPU6050_CLOCK_PLL_EXT19M        0x05
+#define MPU6050_CLOCK_KEEP_RESET        0x07
+
+#define MPU6050_PWR2_LP_WAKE_CTRL_BIT       7
+#define MPU6050_PWR2_LP_WAKE_CTRL_LENGTH    2
+#define MPU6050_PWR2_STBY_XA_BIT            5
+#define MPU6050_PWR2_STBY_YA_BIT            4
+#define MPU6050_PWR2_STBY_ZA_BIT            3
+#define MPU6050_PWR2_STBY_XG_BIT            2
+#define MPU6050_PWR2_STBY_YG_BIT            1
+#define MPU6050_PWR2_STBY_ZG_BIT            0
+
+#define MPU6050_WAKE_FREQ_1P25      0x0
+#define MPU6050_WAKE_FREQ_2P5       0x1
+#define MPU6050_WAKE_FREQ_5         0x2
+#define MPU6050_WAKE_FREQ_10        0x3
+
+#define MPU6050_BANKSEL_PRFTCH_EN_BIT       6
+#define MPU6050_BANKSEL_CFG_USER_BANK_BIT   5
+#define MPU6050_BANKSEL_MEM_SEL_BIT         4
+#define MPU6050_BANKSEL_MEM_SEL_LENGTH      5
+
+#define MPU6050_WHO_AM_I_BIT        6
+#define MPU6050_WHO_AM_I_LENGTH     6
+
+#define MPU6050_DMP_MEMORY_BANKS        8
+#define MPU6050_DMP_MEMORY_BANK_SIZE    256
+#define MPU6050_DMP_MEMORY_CHUNK_SIZE   16
+
+void MPU6050ReadTemp(short *tempData);
+void MPU6050ReadGyro(short *gyroData);
+void MPU6050ReadAcc(short *accData);
+void MPU6050_ReturnTemp(float *Temperature);
+void MPU6050_Init(void);
+uint8_t MPU6050ReadID(void);
+void PMU6050_ReadData(u8 reg_add,unsigned char*Read,u8 num);
+void PMU6050_WriteReg(u8 reg_add,u8 reg_dat);
+
+void MPU6050_PWR_MGMT_1_INIT(void);
+
+
+#endif  /*__MPU6050*/

BIN
module_Template/MPU6050三轴传感器/MPU6050接口图.jpg


+ 1 - 0
module_Template/MPU6050三轴传感器/README.txt

@@ -0,0 +1 @@
+MPU6050三轴加速度,陀螺仪模块

BIN
module_Template/MPU6050三轴传感器/RM-MPU-6000A.pdf


+ 15 - 0
module_Template/MPU6050三轴传感器/use_example.c

@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include "MPU6050.h"
+
+int main()
+{
+	short gyro[3]; // 陀螺仪xyz
+	short acce[3]; // 加速度xyz
+	MPU6050_Init(); // 初始化
+	while(1) {
+		MPU6050ReadGyro(gyro); // 读取三轴陀螺仪
+		MPU6050ReadAcc(acce); // 读取三轴加速度
+		printf("gyro x:%d y:%d z:%d, acce x:%d y:%d z:%d\n", gyro[0], gyro[1], gyro[2], acce[0], acce[1], acce[2]);
+		delayMs(1000);
+	}
+}

+ 0 - 0
module_Template/MultiButton/BUTTON.c → module_Template/MultiButton按键驱动/BUTTON.c


+ 0 - 0
module_Template/MultiButton/BUTTON.h → module_Template/MultiButton按键驱动/BUTTON.h


+ 0 - 0
module_Template/MultiButton/MultiButton.c → module_Template/MultiButton按键驱动/MultiButton.c


+ 0 - 0
module_Template/MultiButton/MultiButton.h → module_Template/MultiButton按键驱动/MultiButton.h


+ 0 - 0
module_Template/MultiButton/MultiButtonTips.md → module_Template/MultiButton按键驱动/MultiButtonTips.md


+ 13 - 0
module_Template/MultiButton按键驱动/use_example.c

@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "BUTTON.h"
+
+int main()
+{
+	KEYClass.Init(); // 初始化
+	while(1) {}
+}
+// 将扫描函数加入MultiButton.h文件内TICKS_INTERVAL宏定义的周期的定时器内进行扫描
+void TIM_5msIRQHandle()
+{
+	KEYClass.Scan();
+}

+ 0 - 0
module_Template/OLED0.96/0.96OLED接口图.jpg → module_Template/OLED屏幕0.96/0.96OLED接口图.jpg


+ 0 - 0
module_Template/OLED0.96/0.96OLED文字取模配置.png → module_Template/OLED屏幕0.96/0.96OLED文字取模配置.png


+ 0 - 0
module_Template/OLED0.96/0.96寸OLED使用文档新手必看V3.0.pdf → module_Template/OLED屏幕0.96/0.96寸OLED使用文档新手必看V3.0.pdf


+ 0 - 0
module_Template/OLED0.96/OLED.c → module_Template/OLED屏幕0.96/OLED.c


+ 0 - 0
module_Template/OLED0.96/OLED.h → module_Template/OLED屏幕0.96/OLED.h


+ 0 - 0
module_Template/OLED0.96/OLEDFont.h → module_Template/OLED屏幕0.96/OLEDFont.h


+ 20 - 0
module_Template/OLED屏幕0.96/use_example.c

@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include "OLED.h"
+
+int main()
+{
+	OLED_Init(); // 初始化
+	OLED_Clear(); // 清屏
+	while(1) {
+		OLED_ShowNum(0, 0, 123456, 6, 16); // 第一行
+		OLED_ShowChar(0, 2, '?', 16); // 第二行
+		OLED_ShowString(0, 4, "abcd", 16); // 第三行
+		OLED_ShowCHinese(0, 6, 0); // 第四行
+		/* 汉字大小16*16 数字和字符大小8*16 128*64OLED最多四行
+		123456
+		?
+		abcd
+		智
+		*/
+	}
+}

+ 17 - 0
module_Template/RC522-RFID模块/use_example.c

@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include "SPI.h"
+#include "RC522.h"
+
+int main()
+{
+	uint8_t cardID[4] = {0};
+	SPIClass.SPI1_Init(); // SPI初始化
+	MFRC522_Init(); // RC522初始化
+	while(1) {
+		if(!RC522_cardScan(cardID)) {
+			printf("card scan success, id:0x%02X%02X%02X%02X\n", cardID[0], cardID[1], cardID[2], cardID[3]);
+		} else {
+			printf("card scan failure\n");
+		}
+	}
+}

+ 41 - 9
module_Template/SG90舵机/SG90.c

@@ -1,29 +1,44 @@
 #include "main.h"
 
-static void SG90_TIM3_Init(void);
+static void SG90_TIM_Init(void);
 static void SG90_Angle(float angle);
+static void SG90_Angle2(float angle);
 
 SG90ClassStruct SG90Class = {
-	SG90_TIM3_Init,
-	SG90_Angle
+	SG90_TIM_Init,
+	SG90_Angle,
+	SG90_Angle2
 };
+// 使用哪个通道
+#define USE_TIM_CH1
+#define USE_TIM_CH2
 
-#if 1
+#if 0
 #define SG90_TIM						TIM2
 #define SG90_TIM_CLK					RCC_APB1Periph_TIM2
 #define SG90_GPIO_PORT    				GPIOA
 #define SG90_GPIO_CLK 	    			RCC_APB2Periph_GPIOA
+#ifdef USE_TIM_CH1
 #define SG90_GPIO_PIN					GPIO_Pin_0
+#endif
+#ifdef USE_TIM_CH2
+#define SG90_GPIO_PIN2					GPIO_Pin_1
+#endif
 #else
 #define SG90_TIM						TIM3
 #define SG90_TIM_CLK					RCC_APB1Periph_TIM3
 #define SG90_GPIO_PORT    				GPIOA
 #define SG90_GPIO_CLK 	    			RCC_APB2Periph_GPIOA
+#ifdef USE_TIM_CH1
 #define SG90_GPIO_PIN					GPIO_Pin_6
 #endif
+#ifdef USE_TIM_CH2
+#define SG90_GPIO_PIN2					GPIO_Pin_7
+#endif
+#endif
 
 // PWM初始化 10000-1,144-1
-static void SG90_TIM3_Init(void)
+static void SG90_TIM_Init(void)
 {
 	GPIO_InitTypeDef GPIO_InitStructure;
 	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
@@ -34,10 +49,16 @@ static void SG90_TIM3_Init(void)
 	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;
+#ifdef USE_TIM_CH1
+	GPIO_InitStructure.GPIO_Pin = SG90_GPIO_PIN;
+	GPIO_Init(SG90_GPIO_PORT, &GPIO_InitStructure);
+#endif
+#ifdef USE_TIM_CH2
+	GPIO_InitStructure.GPIO_Pin = SG90_GPIO_PIN2;
 	GPIO_Init(SG90_GPIO_PORT, &GPIO_InitStructure);
+#endif
 	
 	//定时器初始化
 	TIM_TimeBaseStructure.TIM_Period = 10000-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
@@ -51,16 +72,27 @@ static void SG90_TIM3_Init(void)
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
 	TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
 	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
+#ifdef USE_TIM_CH1
 	TIM_OC1Init(SG90_TIM, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
-	
-	TIM_OC1PreloadConfig(SG90_TIM, TIM_OCPreload_Enable);  	//CH1预装载使能    
+	TIM_OC1PreloadConfig(SG90_TIM, TIM_OCPreload_Enable);  	//CH1预装载使能   
+#endif	
+#ifdef USE_TIM_CH2
+	TIM_OC2Init(SG90_TIM, &TIM_OCInitStructure);
+	TIM_OC2PreloadConfig(SG90_TIM, TIM_OCPreload_Enable);
+#endif
 	TIM_ARRPreloadConfig(SG90_TIM, ENABLE); //使能TIMx在ARR上的预装载寄存器
 	TIM_Cmd(SG90_TIM, ENABLE);  //使能TIMx
 	TIM_CtrlPWMOutputs(SG90_TIM,ENABLE);  //MOE 主输出使能				 
 }
-
+// CH1舵机角度
 static void SG90_Angle(float angle)
 {
 	angle = (uint16_t)(50.0 * angle / 9.0 + 250.0);
 	TIM_SetCompare1(SG90_TIM, angle);
 }
+// CH2舵机角度
+static void SG90_Angle2(float angle)
+{
+	angle = (uint16_t)(50.0 * angle / 9.0 + 250.0);
+	TIM_SetCompare2(SG90_TIM, angle);
+}

+ 1 - 0
module_Template/SG90舵机/SG90.h

@@ -6,6 +6,7 @@
 typedef struct {
 	void (* Init)(void);
 	void (* Angle)(float angle);
+	void (* Angle2)(float angle);
 } SG90ClassStruct;
 
 extern SG90ClassStruct SG90Class;

+ 15 - 0
module_Template/SG90舵机/use_example.c

@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include "SG90.h"
+
+int main()
+{
+	SG90Class.Init(); // 初始化
+	while(1) {
+		SG90Class.Angle(0); // 旋转0度
+		SG90Class.Angle2(0); // if you use TIM_CH2
+		delayMs(1000);
+		SG90Class.Angle(45); // 旋转45度
+		SG90Class.Angle2(180); // if you use TIM_CH2
+		delayMs(1000);
+	}
+}

+ 17 - 0
module_Template/SIM900A短信模块/use_example.c

@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include "GSM_func.h"
+
+int main()
+{
+	char mes[] = "this is message";
+	uint8_t recMesID = 0;
+	GSM_Init(); // 初始化
+	GSM_sendMessage(mes);
+	while(1) {
+		// 接收到短信send:1
+		if((recMesID = GSM_waitMessage()) != 0) {
+			char val = GSM_readMessage(recMesID); // val = 1
+			printf("rec mes val:%c\n", val);
+		}
+	}
+}

+ 13 - 0
module_Template/SR04超声波/use_example.c

@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include "SR04.h"
+
+int main()
+{
+	uint16_t distance = 0;
+	SR04.Init(); // 初始化
+	while(1) {
+		distance = SR04.Read(); // 读取距离cm
+		printf("sr04 distance:%d\n", distance);
+		delayMs(100);
+	}
+}

+ 4 - 2
module_Template/分时调度系统/main.c → module_Template/分时调度系统/use_example.c

@@ -1,5 +1,7 @@
 #include <stdio.h>
 #include "TimeScheduleSystem.h"
+// 事件调度定时器周期ms
+#define TIMER_PERIOD_MS	5
 
 TSS_t myTSS1; // 事件结构体实例
 TSS_t myTSS2;
@@ -19,13 +21,13 @@ int main()
 {
     int ret = 0;
     // 1.初始化事件
-    ret = TSS_init(&myTSS1, 100, myTSS1_callback); // 100 * 5ms = 500ms周期
+    ret = TSS_init(&myTSS1, 500/TIMER_PERIOD_MS, myTSS1_callback); // 500ms
     if(!ret) {
         TSS_start(&myTSS1);
         printf("myTSS1 init success\n");
     }
     else printf("myTSS1 init fail : %d\n", ret);
-    ret = TSS_init(&myTSS2, 200, myTSS2_callback); // 200 * 5ms = 1000ms周期
+    ret = TSS_init(&myTSS2, 1000/TIMER_PERIOD_MS, myTSS2_callback); // 1000ms
     if(!ret) {
         TSS_start(&myTSS2);
         printf("myTSS2 init success\n");

+ 2 - 0
module_Template/智能健康检测模块/淘宝链接.txt

@@ -0,0 +1,2 @@
+【淘宝】https://m.tb.cn/h.UIle2pn?tk=eNW0dPU3PjM CZ0001 「生命体征监测模块,实时检测血压、血氧、心率、微循环,手环可用」
+点击链接直接打开 或者 淘宝搜索直接打开

+ 209 - 0
system_Template/IICs.c

@@ -0,0 +1,209 @@
+#include "IICs.h"
+
+
+#define IIC_SCL_OUT_1(port, pin)		(port->BSRR = (uint32_t)pin) // 置1
+#define IIC_SCL_OUT_0(port, pin)		(port->BRR = (uint32_t)pin)
+#define IIC_SDA_OUT_1(port, pin)		(port->BSRR = (uint32_t)pin) // 置1
+#define IIC_SDA_OUT_0(port, pin)		(port->BRR = (uint32_t)pin)
+#define IIC_SDA_IN(port, pin)			((port->IDR & pin) != 0)
+
+struct IIC_CONFIG {
+	uint32_t IIC_SDA_CLK;
+	GPIO_TypeDef* IIC_SDA_PORT;
+	uint16_t IIC_SDA_PIN;
+	uint32_t IIC_SCL_CLK;
+	GPIO_TypeDef* IIC_SCL_PORT;
+	uint16_t IIC_SCL_PIN;
+} iic_config[] = {
+	{RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_0, RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_1},
+	{RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_6, RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_7}
+};
+
+/**
+  * @brief  IIC延时
+  * @param  None
+  * @retval None
+  */
+static void IIC_Delay(uint8_t iicNo)
+{
+	static uint16_t delayTime[] = {400, 400};
+	uint16_t i;
+	/* 
+	 	下面的时间是通过逻辑分析仪测试得到的。
+    工作条件:CPU主频72MHz ,MDK编译环境,1级优化
+  
+		循环次数为10时,SCL频率 = 205KHz 
+		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
+	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
+	*/
+	for (i = 0; i < delayTime[iicNo]; i++);
+}
+/**
+  * @brief  SDA输出方向配置
+  * @param  None
+  * @retval None
+  */
+void Set_IIC_SDA_OUT(uint8_t iicNo)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;	
+	RCC_APB2PeriphClockCmd(iic_config[iicNo].IIC_SDA_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin=iic_config[iicNo].IIC_SDA_PIN;
+	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
+	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
+	GPIO_Init(iic_config[iicNo].IIC_SDA_PORT,&GPIO_InitStructure); 						
+}
+/**
+  * @brief  SDA输入方向配置
+  * @param  None
+  * @retval None
+  */
+void Set_IIC_SDA_IN(uint8_t iicNo)
+{
+	GPIO_InitTypeDef GPIO_InitStructure;	
+	RCC_APB2PeriphClockCmd(iic_config[iicNo].IIC_SDA_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin=iic_config[iicNo].IIC_SDA_PIN;
+	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
+	GPIO_Init(iic_config[iicNo].IIC_SDA_PORT,&GPIO_InitStructure);
+}
+/**
+  * @brief  模拟IIC初始化
+  * @param  None
+  * @retval None
+  */
+void IIC_init(uint8_t iicNo)
+{
+	GPIO_InitTypeDef  GPIO_InitStructure;
+	RCC_APB2PeriphClockCmd(iic_config[iicNo].IIC_SDA_CLK | iic_config[iicNo].IIC_SCL_CLK, ENABLE);
+	GPIO_InitStructure.GPIO_Pin = iic_config[iicNo].IIC_SDA_PIN;
+	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; 		
+	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
+	GPIO_Init(iic_config[iicNo].IIC_SDA_PORT, &GPIO_InitStructure);	
+	GPIO_InitStructure.GPIO_Pin = iic_config[iicNo].IIC_SCL_PIN;
+	GPIO_Init(iic_config[iicNo].IIC_SCL_PORT, &GPIO_InitStructure);	
+	IIC_stop(iicNo);
+}
+/**
+  * @brief  模拟IIC起始信号
+  * @param  None
+  * @retval None
+  */
+void IIC_start(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+}
+/**
+  * @brief  模拟IIC停止信号
+  * @param  None
+  * @retval None
+  */
+void IIC_stop(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+}
+/**
+  * @brief  模拟IIC主机应答
+  * @param  None
+  * @retval None
+  */
+void IIC_ack(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);	
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+}
+/**
+  * @brief  模拟IIC主机不应答
+  * @param  None
+  * @retval None
+  */
+void IIC_noack(uint8_t iicNo)
+{
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+}
+/**
+  * @brief  模拟IIC等待从机应答
+  * @param  None
+  * @retval 1: 接收应答失败 0: 接收应答成功
+  */
+uint8_t IIC_wait_ack(uint8_t iicNo)
+{
+	uint8_t rec = 0;
+	Set_IIC_SDA_OUT(iicNo);
+	IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_Delay(iicNo);
+	Set_IIC_SDA_IN(iicNo);
+	IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	rec = IIC_SDA_IN(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+	IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+	IIC_Delay(iicNo);
+	
+	return rec;
+}
+/**
+  * @brief  模拟IIC发送一个字节
+  * @param  None
+  * @retval None
+  */
+void IIC_send_byte(uint8_t iicNo, uint8_t txd)
+{
+	uint8_t i=0;
+	Set_IIC_SDA_OUT(iicNo);
+	for(i=0;i<8;i++)
+	{
+		if(txd&0x80) IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+		else IIC_SDA_OUT_0(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN);
+		IIC_Delay(iicNo);
+		IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		IIC_Delay(iicNo); // 发送数据
+		IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		if(i == 7) IIC_SDA_OUT_1(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN); // 最后一位数据发送完要释放SDA总线
+		txd <<= 1;
+		IIC_Delay(iicNo);
+	}
+}
+/**
+  * @brief  模拟IIC读取一个字节
+  * @param  ack: 0,读完不产生应答 1,读完产生应答
+  * @retval 返回读取到的字节
+  */
+uint8_t IIC_read_byte(uint8_t iicNo, uint8_t ack)
+{
+	uint8_t i,receive=0;
+	Set_IIC_SDA_IN(iicNo);
+	for(i=0;i<8;i++)
+	{
+		receive <<= 1;
+		IIC_SCL_OUT_1(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		IIC_Delay(iicNo);
+		if(IIC_SDA_IN(iic_config[iicNo].IIC_SDA_PORT, iic_config[iicNo].IIC_SDA_PIN)) receive++; // 连续读取八位
+		IIC_SCL_OUT_0(iic_config[iicNo].IIC_SCL_PORT, iic_config[iicNo].IIC_SCL_PIN);
+		IIC_Delay(iicNo);	
+	}
+	if(!ack) IIC_noack(iicNo);
+	else IIC_ack(iicNo);
+
+	return receive; // 返回读取到的字节
+}

+ 21 - 0
system_Template/IICs.h

@@ -0,0 +1,21 @@
+#ifndef __IICS_H
+#define __IICS_H
+
+#include "main.h"
+
+typedef enum {
+	IIC_MEMS_NH3 = 0,
+	IIC_MEMS_H2S
+} IIC_NO;
+
+void Set_IIC_SDA_OUT(uint8_t iicNo);
+void Set_IIC_SDA_IN(uint8_t iicNo);
+void IIC_init(uint8_t iicNo);
+void IIC_start(uint8_t iicNo);
+void IIC_stop(uint8_t iicNo);
+void IIC_ack(uint8_t iicNo);
+void IIC_noack(uint8_t iicNo);
+uint8_t IIC_wait_ack(uint8_t iicNo);
+void IIC_send_byte(uint8_t iicNo, uint8_t txd);
+uint8_t IIC_read_byte(uint8_t iicNo, uint8_t ack);
+#endif