wwwxxx国产_337p日本欧洲亚洲大胆张筱雨_免费在线看成人av_日本黄色不卡视频_国产精品成熟老女人_99视频一区_亚洲精品97久久中文字幕_免费精品视频在线_亚洲色图欧美视频_欧美一区二三区

標題: max30100血氧心率制作stm32源碼 OLED顯示 [打印本頁]

作者: 冬天的小雪    時間: 2017-10-31 12:09
標題: max30100血氧心率制作stm32源碼 OLED顯示
使用模擬iic_MAX30100,簡易血氧心率制作,可用正電原子mini板,OLED顯示。整套資料提供給大家學習。主函數部分代碼


50Hz每采集一次數據集時間0.02s,共采集800次,用時16s
脈搏每跳動一次對應一個波形的峰值,上圖共有20處峰值
計算(20/16)*60=75,可知心跳為每分鐘75次

50Hz采集心率數據:


血氧檢測數據處理:


stm32單片機源程序如下:
  1. #include "stm32f10x.h"
  2. #include "usart.h"
  3. #include "ultrasonic.h"
  4. #include "stm32f10x_gpio.h"
  5. #include "stm32f10x_i2c.h"
  6. #include "delay.h"        //延時函數 1
  7. #include "delayl.h"        //延時函數 2
  8. #include <stdio.h>
  9. #include <math.h>
  10. #include "bsp_i2c_gpio.h"
  11. #include "oled.h"

  12. #define SAMPLE_50   //如果定義此宏就是50采樣率   否則是100


  13. /*************************************************
  14. 函數: fputc(int ch, FILE *f)
  15. 功能: 重定向c庫函數printf到USART1
  16. 參數: 無
  17. 返回: 無
  18. **************************************************/
  19. int fputc(int ch, FILE *f)
  20. {
  21.         USART_SendData(USART1, (unsigned char) ch);
  22.         while (!(USART1->SR & USART_FLAG_TXE));
  23.         return (ch);
  24. }


  25. #define USR_I2C_USED I2C1

  26. void I2C1_Configuration(void)
  27. {
  28.         I2C_InitTypeDef  I2C_InitStructure;
  29.         GPIO_InitTypeDef  GPIO_InitStructure;

  30.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
  31.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  32.    

  33.         /* PB6,7 SCL and SDA */
  34.         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  35.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  36.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  37.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  38.         
  39.     I2C_DeInit(I2C1);
  40.     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  41.     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  42.     I2C_InitStructure.I2C_OwnAddress1 = 0x30;
  43.     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  44.     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  45.     I2C_InitStructure.I2C_ClockSpeed = 100000;//100K速度
  46.    
  47.         I2C_Cmd(I2C1, ENABLE);
  48.         I2C_Init(I2C1, &I2C_InitStructure);
  49.         /*允許1字節1應答模式*/
  50.         I2C_AcknowledgeConfig(I2C1, ENABLE);

  51.     printf("I2C1_Configuration----\n\r");
  52. }

  53. void I2C2_Configuration(void)
  54. {
  55.         I2C_InitTypeDef  I2C_InitStructure;
  56.         GPIO_InitTypeDef  GPIO_InitStructure;

  57.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
  58.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  59.    

  60.         /* PB10,11 SCL and SDA */
  61.         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
  62.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  63.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  64.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  65.         
  66.     I2C_DeInit(I2C2);
  67.     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  68.     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  69.     I2C_InitStructure.I2C_OwnAddress1 = 0x30;
  70.     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  71.     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  72.     I2C_InitStructure.I2C_ClockSpeed = 100000;//100K速度
  73.    
  74.         I2C_Cmd(I2C2, ENABLE);
  75.         I2C_Init(I2C2, &I2C_InitStructure);
  76.         /*允許1字節1應答模式*/
  77.         I2C_AcknowledgeConfig(I2C2, ENABLE);

  78.     printf("I2C2_Configuration----\n\r");
  79. }

  80. void I2C1_GPIO_Config(void)
  81. {

  82.         GPIO_InitTypeDef GPIO_InitStructure; //GPIO結構體定義
  83.         
  84.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能I2C的IO口

  85.                 /* 使能與 I2C1 有關的時鐘 */
  86.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
  87.         
  88.         /* PB6-I2C1_SCL、PB7-I2C1_SDA*/
  89.         
  90.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

  91.         
  92.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  93.         
  94.         //PIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 開漏輸出
  95.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  96.         
  97.         GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化結構體配置

  98. }

  99. /* I2C 工作模式配置 */

  100. void I2C1_Mode_config(void)
  101. {
  102.                 /*定義I2C結構體*/
  103.         I2C_InitTypeDef  I2C_InitStructure;



  104.                
  105.         /*配置為I2C模式*/
  106.         I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  107.         
  108.         /*該參數只有在I2C 工作在快速模式(時鐘工作頻率高于 100KHz)下才有意義。*/
  109.         I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  110.         
  111.         /*設置第一個設備自身地址*/
  112.         I2C_InitStructure.I2C_OwnAddress1 =0x30;
  113.         
  114.         /*使能應答*/
  115.         I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
  116.         
  117.         /*AT24C02地址為7位所以設置7位就行了*/
  118.         I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /*時鐘速率,以HZ為單位的,最高為400khz*/
  119.         
  120.         I2C_InitStructure.I2C_ClockSpeed = 20000;

  121.         /* 使能 I2C1 */
  122.         I2C_Cmd(I2C1, ENABLE);
  123.         
  124.         /* I2C1 初始化 */
  125.         I2C_Init(I2C1, &I2C_InitStructure);
  126.         
  127.         
  128. }

  129. void I2C2_GPIO_Config(void)
  130. {

  131.         GPIO_InitTypeDef GPIO_InitStructure; //GPIO結構體定義
  132.         
  133.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能I2C的IO口

  134.                 /* 使能與 I2C1 有關的時鐘 */
  135.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
  136.         
  137.         /* PB10-I2C2_SCL、PB11-I2C2_SDA*/
  138.         
  139.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;

  140.         
  141.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  142.         
  143.         //PIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 開漏輸出
  144.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  145.         
  146.         GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化結構體配置

  147. }

  148. /* I2C 工作模式配置 */

  149. void I2C2_Mode_config(void)
  150. {
  151.                 /*定義I2C結構體*/
  152.         I2C_InitTypeDef  I2C_InitStructure;

  153.         /*配置為I2C模式*/
  154.         I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  155.         
  156.         /*該參數只有在I2C 工作在快速模式(時鐘工作頻率高于 100KHz)下才有意義。*/
  157.         I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  158.         
  159.         /*設置第一個設備自身地址*/
  160.         I2C_InitStructure.I2C_OwnAddress1 =0x30;
  161.         
  162.         /*使能應答*/
  163.         I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
  164.         
  165.         /*AT24C02地址為7位所以設置7位就行了*/
  166.         I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /*時鐘速率,以HZ為單位的,最高為400khz*/
  167.         
  168.         I2C_InitStructure.I2C_ClockSpeed = 100000;

  169.         /* 使能 I2C1 */
  170.         I2C_Cmd(I2C2, ENABLE);
  171.         
  172.         /* I2C1 初始化 */
  173.         I2C_Init(I2C2, &I2C_InitStructure);
  174.         
  175.         
  176. }


  177. /*************************************************
  178. 函數: void main_init(void)
  179. 功能: main初始化
  180. 參數: 無
  181. 返回: 無
  182. **************************************************/
  183. void main_init(void)
  184. {
  185.         Usart_Init();
  186.         //I2C1_GPIO_Config();
  187.         //I2C1_Mode_config();
  188.         //I2C1_Configuration();
  189.         bsp_InitI2C();
  190.         delay_init(72);            //延時初始化
  191. }

  192. extern void test_max30100_fun(void);
  193. extern u8 max10300_Bus_Read(u8 Register_Address);
  194. extern void max10300_init(void);

  195. /*************************************************
  196. 函數: int main(void)
  197. 功能: main主函數
  198. 參數: 無
  199. 返回: 無
  200. **************************************************/
  201. int main(void)
  202. {
  203.         u8 temp_num=0;
  204.          
  205.         main_init();
  206.         
  207.         max10300_init();
  208.         printf("\r\n stm32 init runing \r\n");
  209.         
  210.         delayl_init();                     //延時函數初始化         
  211.          
  212.         OLED_Init();                        //初始化OLED     

  213.         OLED_ShowString(0,0, "SpO2:",16);  
  214.                   
  215.         OLED_ShowString(0,30,"Heart Rate:",16);  
  216.                   
  217.         OLED_Refresh_Gram();//更新顯示到OLED
  218.         
  219.         
  220.         
  221.         
  222.         
  223.         /*
  224. while(1)
  225. {
  226.         delay_ms(1000);            
  227.         max10300_init();
  228.         temp_num = max10300_Bus_Read(0x16);
  229.         printf("當前溫度 = %d\r\n",temp_num);
  230. }*/
  231.         while(1)
  232.         {        
  233.                 test_max30100_fun();
  234.                
  235.                
  236.                         
  237.                
  238.                
  239.                
  240.         }
  241. }




  242. #define max10300_WR_address 0xAE

  243. u8 max10300_Bus_Write(u8 Register_Address, u8 Word_Data)
  244. {

  245.         /* 采用串行EEPROM隨即讀取指令序列,連續讀取若干字節 */

  246.         /* 第1步:發起I2C總線啟動信號 */
  247.         i2c_Start();

  248.         /* 第2步:發起控制字節,高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  249.         i2c_SendByte(max10300_WR_address | I2C_WR);        /* 此處是寫指令 */

  250.         /* 第3步:發送ACK */
  251.         if (i2c_WaitAck() != 0)
  252.         {
  253.                 goto cmd_fail;        /* EEPROM器件無應答 */
  254.         }

  255.         /* 第4步:發送字節地址 */
  256.         i2c_SendByte(Register_Address);
  257.         if (i2c_WaitAck() != 0)
  258.         {
  259.                 goto cmd_fail;        /* EEPROM器件無應答 */
  260.         }
  261.         
  262.         /* 第5步:開始寫入數據 */
  263.         i2c_SendByte(Word_Data);

  264.         /* 第6步:發送ACK */
  265.         if (i2c_WaitAck() != 0)
  266.         {
  267.                 goto cmd_fail;        /* EEPROM器件無應答 */
  268.         }

  269.         /* 發送I2C總線停止信號 */
  270.         i2c_Stop();
  271.         return 1;        /* 執行成功 */

  272. cmd_fail: /* 命令執行失敗后,切記發送停止信號,避免影響I2C總線上其他設備 */
  273.         /* 發送I2C總線停止信號 */
  274.         i2c_Stop();
  275.         return 0;
  276. }



  277. u8 max10300_Bus_Read(u8 Register_Address)
  278. {
  279.         u8  data;


  280.         /* 第1步:發起I2C總線啟動信號 */
  281.         i2c_Start();

  282.         /* 第2步:發起控制字節,高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  283.         i2c_SendByte(max10300_WR_address | I2C_WR);        /* 此處是寫指令 */

  284.         /* 第3步:發送ACK */
  285.         if (i2c_WaitAck() != 0)
  286.         {
  287.                 goto cmd_fail;        /* EEPROM器件無應答 */
  288.         }

  289.         /* 第4步:發送字節地址, */
  290.         i2c_SendByte((uint8_t)Register_Address);
  291.         if (i2c_WaitAck() != 0)
  292.         {
  293.                 goto cmd_fail;        /* EEPROM器件無應答 */
  294.         }
  295.         

  296.         /* 第6步:重新啟動I2C總線。下面開始讀取數據 */
  297.         i2c_Start();

  298.         /* 第7步:發起控制字節,高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  299.         i2c_SendByte(max10300_WR_address | I2C_RD);        /* 此處是讀指令 */

  300.         /* 第8步:發送ACK */
  301.         if (i2c_WaitAck() != 0)
  302.         {
  303.                 goto cmd_fail;        /* EEPROM器件無應答 */
  304.         }

  305.         /* 第9步:讀取數據 */
  306.         {
  307.                 data = i2c_ReadByte();        /* 讀1個字節 */

  308.                 i2c_NAck();        /* 最后1個字節讀完后,CPU產生NACK信號(驅動SDA = 1) */
  309.         }
  310.         /* 發送I2C總線停止信號 */
  311.         i2c_Stop();
  312.         return data;        /* 執行成功 返回data值 */

  313. cmd_fail: /* 命令執行失敗后,切記發送停止信號,避免影響I2C總線上其他設備 */
  314.         /* 發送I2C總線停止信號 */
  315.         i2c_Stop();
  316.         return 0;
  317. }

  318. static void i2c_Delay(void)
  319. {
  320.         uint8_t i;

  321.         /* 
  322.                 CPU主頻168MHz時,在內部Flash運行, MDK工程不優化。用臺式示波器觀測波形。
  323.                 循環次數為5時,SCL頻率 = 1.78MHz (讀耗時: 92ms, 讀寫正常,但是用示波器探頭碰上就讀寫失敗。時序接近臨界)
  324.                 循環次數為10時,SCL頻率 = 1.1MHz (讀耗時: 138ms, 讀速度: 118724B/s)
  325.                 循環次數為30時,SCL頻率 = 440KHz, SCL高電平時間1.0us,SCL低電平時間1.2us

  326.                 上拉電阻選擇2.2K歐時,SCL上升沿時間約0.5us,如果選4.7K歐,則上升沿約1us

  327.                 實際應用選擇400KHz左右的速率即可
  328.         */
  329.         for (i = 0; i < 30; i++);
  330. }
  331. #if 1
  332. void max10300_FIFO_Read(u8 Register_Address,u16  Word_Data[][2],u8 count)
  333. {
  334.         u8 i=0;
  335.         u8 no = count;
  336.         u8 data1, data2;
  337.         /* 第1步:發起I2C總線啟動信號 */
  338.         i2c_Start();

  339.         /* 第2步:發起控制字節,高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  340.         i2c_SendByte(max10300_WR_address | I2C_WR);        /* 此處是寫指令 */

  341.         /* 第3步:發送ACK */
  342.         if (i2c_WaitAck() != 0)
  343.         {
  344.                 goto cmd_fail;        /* EEPROM器件無應答 */
  345.         }

  346.         /* 第4步:發送字節地址, */
  347.         i2c_SendByte((uint8_t)Register_Address);
  348.         if (i2c_WaitAck() != 0)
  349.         {
  350.                 goto cmd_fail;        /* EEPROM器件無應答 */
  351.         }
  352.         

  353.         /* 第6步:重新啟動I2C總線。下面開始讀取數據 */
  354.         i2c_Start();

  355.         /* 第7步:發起控制字節,高7bit是地址,bit0是讀寫控制位,0表示寫,1表示讀 */
  356.         i2c_SendByte(max10300_WR_address | I2C_RD);        /* 此處是讀指令 */

  357.         /* 第8步:發送ACK */
  358.         if (i2c_WaitAck() != 0)
  359.         {
  360.                 goto cmd_fail;        /* EEPROM器件無應答 */
  361.         }

  362.         /* 第9步:讀取數據 */
  363.         while (no)
  364.         {
  365.                 data1 = i2c_ReadByte();        
  366.                 i2c_Ack();
  367.                 data2 = i2c_ReadByte();
  368.                 i2c_Ack();
  369.                 Word_Data[i][0] = (((u16)data1 << 8) | data2);  //

  370.                
  371.                 data1 = i2c_ReadByte();        
  372.                 i2c_Ack();
  373.                 data2 = i2c_ReadByte();
  374.                 if(1==no)
  375.                         i2c_NAck();        /* 最后1個字節讀完后,CPU產生NACK信號(驅動SDA = 1) */
  376.                 else
  377.                         i2c_Ack();
  378.                 Word_Data[i][1] = (((u16)data1 << 8) | data2);

  379.                 no--;        
  380.                 i++;
  381.         }
  382.         /* 發送I2C總線停止信號 */
  383.         i2c_Stop();

  384. cmd_fail: /* 命令執行失敗后,切記發送停止信號,避免影響I2C總線上其他設備 */
  385.         /* 發送I2C總線停止信號 */
  386.         i2c_Stop();
  387. }
  388. #else

  389. void max10300_FIFO_Read(u8 Register_Address,u16  Word_Data[][2],u8 count)
  390. {
  391.         u8 i=0;
  392.         u8 no = count;
  393.         u8 data1, data2;
  394.         

  395.         while(I2C_GetFlagStatus(USR_I2C_USED, I2C_FLAG_BUSY))
  396.                 ; //調用庫函數檢測I2C器件是否處于BUSY狀態
  397.                

  398.         I2C_AcknowledgeConfig(USR_I2C_USED, ENABLE);   /*允許1字節1應答模式*/


  399.         I2C_GenerateSTART(USR_I2C_USED, ENABLE);
  400.          while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_MODE_SELECT))
  401.                  ; //清除EV5
  402.         
  403.         I2C_Send7bitAddress(USR_I2C_USED, max10300_WR_address, I2C_Direction_Transmitter);
  404.         while(!I2C_CheckEvent(USR_I2C_USED,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  405.                 ; //ADDR=1,清除EV6
  406.                
  407.         I2C_SendData(USR_I2C_USED, Register_Address);
  408.          while(! I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  409.                  ;//移位寄存器非空,數據寄存器已經空,產生EV8,發送數據到DR既可清除該事件

  410.         I2C_GenerateSTART(USR_I2C_USED, ENABLE);
  411.          while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_MODE_SELECT))
  412.                  ; //清除EV5
  413.         
  414.         I2C_Send7bitAddress(USR_I2C_USED, max10300_WR_address, I2C_Direction_Receiver);
  415.         while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


  416.          while (no)
  417.     {        
  418.         
  419.                 while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_BYTE_RECEIVED)); // EV7
  420.             data1 = I2C_ReceiveData(USR_I2C_USED);

  421.                 while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_BYTE_RECEIVED)); // EV7
  422.             data2 = I2C_ReceiveData(USR_I2C_USED);

  423.             Word_Data[i][0] = (((u16)data1 << 8) | data2);  //



  424.        while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_BYTE_RECEIVED)); // EV7
  425.                 data1 = I2C_ReceiveData(USR_I2C_USED);

  426.             if(no==1)
  427.                 {
  428.                      I2C_AcknowledgeConfig(I2C1, DISABLE);        //最后一位后要關閉應答的
  429.                     I2C_GenerateSTOP(I2C1, ENABLE);                        //發送停止位
  430.                
  431.                 }

  432.                 while(!I2C_CheckEvent(USR_I2C_USED, I2C_EVENT_MASTER_BYTE_RECEIVED)); // EV7
  433.                 data2 = I2C_ReceiveData(USR_I2C_USED);

  434.                 Word_Data[i][1] = (((u16)data1 << 8) | data2);
  435.                 i++;

  436.                
  437.             /* Decrement the read bytes counter */
  438.             no--;
  439.     }
  440.         
  441.         I2C_AcknowledgeConfig(USR_I2C_USED, ENABLE);//將應答位使能回去,等待下次通信
  442.         I2C_GenerateSTOP(I2C1, ENABLE);                        //發送停止位

  443. }

  444. #endif
  445. #define INTERRUPT_REG                                          0X00
  446. #define INTERRUPT_REG_A_FULL                          (0X01<<7)
  447. #define INTERRUPT_REG_TEMP_RDY                  (0X01<<6)
  448. #define INTERRUPT_REG_HR_RDY                          (0X01<<5)
  449. #define INTERRUPT_REG_SPO2_RDY                  (0X01<<4)
  450. #define INTERRUPT_REG_PWR_RDY                          (0X01<<0)



  451. void max10300_init()
  452. {
  453.         max10300_Bus_Write(0x06, 0x0b);  //mode configuration : temp_en[3]      MODE[2:0]=010 HR only enabled    011 SP02 enabled
  454.         //max10300_Bus_Write(0x06, 0x0a);  //MODE[2:0]=010 HR only enabled     when used is mode ,the red led is not used.
  455.         max10300_Bus_Write(0x01, 0xF0); //open all of interrupt
  456.         max10300_Bus_Write(INTERRUPT_REG, 0x00); //all interrupt clear
  457.         max10300_Bus_Write(0x09, 0x33); //r_pa=3,ir_pa=3

  458. #ifdef SAMPLE_50
  459.         max10300_Bus_Write(0x07, 0x43); //SPO2_SR[4:2]=000   50 per second    LED_PW[1:0]=11  16BITS
  460. #else
  461.         max10300_Bus_Write(0x07, 0x47); //SPO2_SR[4:2]=001  100 per second    LED_PW[1:0]=11  16BITS
  462. #endif
  463.         
  464.         max10300_Bus_Write(0x02, 0x00);   //set FIFO write Pointer reg = 0x00 for clear it
  465.         max10300_Bus_Write(0x03, 0x00);        //set Over Flow Counter  reg = 0x00 for clear it
  466.         max10300_Bus_Write(0x04, 0x0f);        //set FIFO Read Pointer  reg = 0x0f for   
  467.                                                                                         //waitting  write pointer eq read pointer   to   interrupts  INTERRUPT_REG_A_FULL
  468. }

  469. double my_floor(double x)
  470. {
  471.    double y=x;
  472.     if( (*( ( (int *) &y)+1) & 0x80000000)  != 0) //或者if(x<0)
  473.         return (float)((int)x)-1;
  474.     else
  475.         return (float)((int)x);
  476. }

  477. double my_fmod(double x, double y)
  478. {
  479.    double temp, ret;
  480.   
  481.    if (y == 0.0)
  482.       return 0.0;
  483.    temp = my_floor(x/y);
  484.    ret = x - temp * y;
  485.    if ((x < 0.0) != (y < 0.0))
  486.       ret = ret - y;
  487.    return ret;
  488. }


  489. #define XPI            (3.1415926535897932384626433832795)
  490. #define XENTRY        (100)
  491. #define XINCL        (XPI/2/XENTRY)

  492.   static const double XSinTbl[] = {
  493.         0.00000000000000000  , 0.015707317311820675 , 0.031410759078128292 , 0.047106450709642665 , 0.062790519529313374 ,
  494.         0.078459095727844944 , 0.094108313318514325 , 0.10973431109104528  , 0.12533323356430426  , 0.14090123193758267  ,
  495.         0.15643446504023087  , 0.17192910027940955  , 0.18738131458572463  , 0.20278729535651249  , 0.21814324139654256  ,
  496.         0.23344536385590542  , 0.24868988716485479  , 0.26387304996537292  , 0.27899110603922928  , 0.29404032523230400  ,
  497.         0.30901699437494740  , 0.32391741819814940  , 0.33873792024529142  , 0.35347484377925714  , 0.36812455268467797  ,
  498.         0.38268343236508978  , 0.39714789063478062  , 0.41151435860510882  , 0.42577929156507272  , 0.43993916985591514  ,
  499.         0.45399049973954680  , 0.46792981426057340  , 0.48175367410171532  , 0.49545866843240760  , 0.50904141575037132  ,
  500.         0.52249856471594880  , 0.53582679497899666  , 0.54902281799813180  , 0.56208337785213058  , 0.57500525204327857  ,
  501.         0.58778525229247314  , 0.60042022532588402  , 0.61290705365297649  , 0.62524265633570519  , 0.63742398974868975  ,
  502.         0.64944804833018377  , 0.66131186532365183  , 0.67301251350977331  , 0.68454710592868873  , 0.69591279659231442  ,
  503.         0.70710678118654757  , 0.71812629776318881  , 0.72896862742141155  , 0.73963109497860968  , 0.75011106963045959  ,
  504.         0.76040596560003104  , 0.77051324277578925  , 0.78043040733832969  , 0.79015501237569041  , 0.79968465848709058  ,
  505.         0.80901699437494745  , 0.81814971742502351  , 0.82708057427456183  , 0.83580736136827027  , 0.84432792550201508  ,
  506.         0.85264016435409218  , 0.86074202700394364  , 0.86863151443819120  , 0.87630668004386369  , 0.88376563008869347  ,
  507.         0.89100652418836779  , 0.89802757576061565  , 0.90482705246601958  , 0.91140327663544529  , 0.91775462568398114  ,
  508.         0.92387953251128674  , 0.92977648588825146  , 0.93544403082986738  , 0.94088076895422557  , 0.94608535882754530  ,
  509.         0.95105651629515353  , 0.95579301479833012  , 0.96029368567694307  , 0.96455741845779808  , 0.96858316112863108  ,
  510.         0.97236992039767667  , 0.97591676193874743  , 0.97922281062176575  , 0.98228725072868872  , 0.98510932615477398  ,
  511.         0.98768834059513777  , 0.99002365771655754  , 0.99211470131447788  , 0.99396095545517971  , 0.99556196460308000  ,
  512.         0.99691733373312796  , 0.99802672842827156  , 0.99888987496197001  , 0.99950656036573160  , 0.99987663248166059  ,
  513.         1.00000000000000000  };

  514. double XSin( double x )
  515. {
  516.     int s = 0 , n;
  517.     double dx , sx , cx;
  518.     if( x < 0 )
  519.         s = 1 , x = -x;
  520.     x = my_fmod( x , 2 * XPI );
  521.     if( x > XPI )
  522.         s = !s , x -= XPI;
  523.     if( x > XPI / 2 )
  524.         x = XPI - x;
  525.     n = (int)( x / XINCL );
  526.     dx = x - n * XINCL;
  527.     if( dx > XINCL / 2 )
  528.         ++n , dx -= XINCL;
  529.     sx = XSinTbl[n];
  530.     cx = XSinTbl[XENTRY-n];
  531.     x = sx + dx*cx - (dx*dx)*sx/2
  532.         - (dx*dx*dx)*cx/6
  533.         + (dx*dx*dx*dx)*sx/24
  534.         ;
  535.      
  536.     return s ? -x : x;
  537. }

  538. double XCos( double x )
  539. {
  540.     return XSin( x + XPI/2 );
  541. }


  542. /*********************************FFT*************************************
  543.                          快速傅里葉變換C函數
  544. 函數簡介:此函數是通用的快速傅里葉變換C語言函數,移植性強,以下部分不依
  545.           賴硬件。此函數采用聯合體的形式表示一個復數,輸入為自然順序的復
  546.           數(輸入實數是可令復數虛部為0),輸出為經過FFT變換的自然順序的
  547.           復數
  548. 使用說明:使用此函數只需更改宏定義FFT_N的值即可實現點數的改變,FFT_N的
  549.           應該為2的N次方,不滿足此條件時應在后面補0
  550. 函數調用:FFT(s);
  551. 時    間:2010-2-20
  552. 版    本:Ver1.0
  553. 參考文獻:     
  554. **********************************************************************/

  555. #define PI 3.1415926535897932384626433832795028841971               //定義圓周率值
  556. #define FFT_N 1024                                                  //定義福利葉變換的點數

  557. struct compx     //定義一個復數結構
  558.         {
  559.                 float real;
  560.                 float imag;
  561.         };                  

  562. struct compx s1[FFT_N+16];           //FFT輸入和輸出:從S[1]開始存放,根據大小自己定義
  563. struct compx s2[FFT_N+16];           //FFT輸入和輸出:從S[1]開始存放,根據大小自己定義


  564. /*******************************************************************
  565. 函數原型:struct compx EE(struct compx b1,struct compx b2)  
  566. 函數功能:對兩個復數進行乘法運算
  567. 輸入參數:兩個以聯合體定義的復數a,b
  568. 輸出參數:a和b的乘積,以聯合體的形式輸出
  569. *******************************************************************/
  570. struct compx EE(struct compx a,struct compx b)      
  571. {
  572.          struct compx c;
  573.          c.real=a.real*b.real-a.imag*b.imag;
  574.          c.imag=a.real*b.imag+a.imag*b.real;
  575.          return(c);
  576. }

  577. /*****************************************************************
  578. 函數原型:void FFT(struct compx *xin,int N)
  579. 函數功能:對輸入的復數組進行快速傅里葉變換(FFT)
  580. 輸入參數:*xin復數結構體組的首地址指針,struct型
  581. *****************************************************************/
  582. void FFT(struct compx *xin)
  583. {
  584.         int f,m,nv2,nm1,i,k,l,j=0;
  585.         struct compx u,w,t;

  586.         nv2=FFT_N/2;                  //變址運算,即把自然順序變成倒位序,采用雷德算法
  587.         nm1=FFT_N-1;  
  588.         for(i=0;i<nm1;i++)        
  589.         {
  590.                 if(i<j)                    //如果i<j,即進行變址
  591.                 {
  592.                         t=xin[j];           
  593.                         xin[j]=xin[i];
  594.                         xin[i]=t;
  595.                 }
  596.                 k=nv2;                    //求j的下一個倒位序
  597.                
  598.                 while(k<=j)               //如果k<=j,表示j的最高位為1   
  599.                 {           
  600.                         j=j-k;                 //把最高位變成0
  601.                         k=k/2;                 //k/2,比較次高位,依次類推,逐個比較,直到某個位為0
  602.                 }
  603.                
  604.                 j=j+k;                   //把0改為1
  605.         }
  606.          
  607.         {  //FFT運算核,使用蝶形運算完成FFT運算
  608.                 int le,lei,ip;                           
  609.                 f=FFT_N;
  610.                 for(l=1;(f=f/2)!=1;l++)                  //計算l的值,即計算蝶形級數
  611.                         ;
  612.                 for(m=1;m<=l;m++)                           // 控制蝶形結級數
  613.                 {                                           //m表示第m級蝶形,l為蝶形級總數l=log(2)N
  614.                         le=2<<(m-1);                            //le蝶形結距離,即第m級蝶形的蝶形結相距le點
  615.                         lei=le/2;                               //同一蝶形結中參加運算的兩點的距離
  616.                         u.real=1.0;                             //u為蝶形結運算系數,初始值為1
  617.                         u.imag=0.0;
  618.                         w.real=XCos(PI/lei);                     //w為系數商,即當前系數與前一個系數的商
  619.                         w.imag=-XSin(PI/lei);
  620.                         for(j=0;j<=lei-1;j++)                   //控制計算不同種蝶形結,即計算系數不同的蝶形結
  621.                         {
  622.                                 for(i=j;i<=FFT_N-1;i=i+le)            //控制同一蝶形結運算,即計算系數相同蝶形結
  623.                                 {
  624.                                         ip=i+lei;                           //i,ip分別表示參加蝶形運算的兩個節點
  625.                                         t=EE(xin[ip],u);                    //蝶形運算,詳見公式
  626.                                         xin[ip].real=xin[i].real-t.real;
  627.                                         xin[ip].imag=xin[i].imag-t.imag;
  628.                                         xin[i].real=xin[i].real+t.real;
  629.                                         xin[i].imag=xin[i].imag+t.imag;
  630.                                 }
  631.                                 u=EE(u,w);                           //改變系數,進行下一個蝶形運算
  632.                         }
  633.                 }
  634.         }

  635. }

  636. u16 g_fft_index=0;

  637. u16 qsqrt(u32 a)
  638. {
  639.   u32 rem = 0, root = 0, divisor = 0;
  640.   u16 i;
  641.   for(i=0; i<16; i++)
  642.   {
  643.     root <<= 1;
  644.     rem = ((rem << 2) + (a>>30));
  645.     a <<= 2;
  646.     divisor = (root << 1) + 1;
  647.     if(divisor <= rem)
  648.     {
  649.       rem -= divisor;
  650.       root++;
  651.     }
  652.   }
  653.   return root;
  654. }

  655. #define START_INDEX    10   //濾出低頻干擾
  656. u16 find_max_num_index(struct compx *data,u16 count)
  657. {
  658.         u16 i=START_INDEX;
  659.         u16 max_num_index = i;
  660.         //struct compx temp=data[i];
  661.         float temp = data[i].real;
  662.         for(i=START_INDEX;i<count;i++)
  663.         {
  664.                 if(temp < data[i].real)
  665.                 {
  666.                         temp = data[i].real;
  667.                         max_num_index = i;
  668.                 }
  669.         }
  670.         printf("max_num_index=%d\r\n",max_num_index);
  671.         return max_num_index;
  672.         
  673. }

  674. #define CORRECTED_VALUE        50   //粗略標定血液氧氣含量   ,精準數據需要大量測量

  675. void sp02_treated_fun(u16 max_index)
  676. {
  677.         float sp02_num=0;
  678.          
  679.         delayl_init();                     //延時函數初始化           
  680.         OLED_Init();                        //初始化OLED     
  681.    
  682.          printf("\r\n zhiliu s1=%f,s2=%f \r\n",s1[0].real,s2[0].real);
  683.         printf("\r\n s1=%f,s2=%f \r\n",s1[max_index].real,s2[max_index].real);
  684.         if((s1[max_index].real*s2[0].real)>(s2[max_index].real*s1[0].real))  //if   ir>red      sp02>75%
  685.         {
  686.                 sp02_num = (s2[max_index].real*s1[0].real)/(s1[max_index].real*s2[0].real);
  687.                 printf("\r\nsp02_num  : %f\r\n",sp02_num*100);
  688.                 printf("\r\n血氧含量為: %f\r\n",(1-sp02_num)*100+CORRECTED_VALUE);
  689.                
  690.                 OLED_ShowString(0,0, "SpO2:",16);
  691.                 if((1-sp02_num)*100+CORRECTED_VALUE>99)
  692.                         OLED_ShowString(40,0, "99",16);
  693.                 else
  694.                         OLED_ShowNum(40,0,(1-sp02_num)*100+CORRECTED_VALUE,4,16);

  695.                 OLED_ShowString(80,0,"%",16);
  696.                 OLED_ShowString(0,30,"Heart Rate:",12);   
  697.                 OLED_Refresh_Gram();//更新顯示到OLED         
  698.                
  699.         }
  700.         else   // sp02<75%
  701.         {
  702.                 printf("\r\n 嚴重缺氧! \r\n");
  703.                
  704.                 OLED_ShowString(0,0, "SpO2:",16);
  705.                 OLED_ShowString(40,0,"ANOXIA!",16);
  706.                 OLED_ShowString(0,30,"Heart Rate:",12);   
  707.                 OLED_Refresh_Gram();//更新顯示到OLED
  708.         }        
  709. }

  710. void test_max30100_fun(void)
  711. {
  712.         u16 temp_num=0;
  713.         u16 fifo_word_buff[15][2];
  714.         u16 Heart_Rate=0;
  715.         u16 s1_max_index=0;
  716.         u16 s2_max_index=0;
  717.         
  718. ……………………

  719. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
血氧心率.7z (4.33 MB, 下載次數: 1349)



作者: xwnc    時間: 2017-11-8 18:39
樓主太強了,學習學習
作者: 伊森Y亨特    時間: 2017-11-14 22:52
不錯啊  學習一個
作者: 伊森一亨特    時間: 2017-11-15 10:45
樓主,你有兩個I2C函數,都用了 PB6和PB7引腳,一個是復用開漏,一個是復用推挽,請問為什么這樣寫呢?謝謝
作者: liguang13579    時間: 2017-11-18 16:48
伊森一亨特 發表于 2017-11-15 10:45
樓主,你有兩個I2C函數,都用了 PB6和PB7引腳,一個是復用開漏,一個是復用推挽,請問為什么這樣寫呢?謝謝

模擬iic的。應該是sclk和sda。肯定要用不同gpio配置方式。自己看看iic協議吧。
作者: Sheng_min    時間: 2017-11-22 16:17
學習學習
作者: 誤入0人間    時間: 2017-11-28 21:36
厲害厲害
作者: 伊森Y亨特    時間: 2017-12-21 10:02
請問讀FIFO是怎么讀?讀到中斷標志位就一直讀嗎?還是讀到中斷就只讀4個樣本?
作者: 開猴子的挖掘機    時間: 2018-1-15 16:37
請問數據處理方面的算法在哪部分
作者: helloapy    時間: 2018-2-22 10:56
學習了~

作者: helloapy    時間: 2018-2-22 14:07
求教樓主,為什么我采集到的數據是這樣的,數據值一直在變小啊

1519279446(1).png (40.56 KB, 下載次數: 203)

1519279446(1).png

作者: wsnlove666    時間: 2018-3-8 10:05
想學習一下,分不夠了
作者: 尼克狐先生    時間: 2018-3-15 18:18
樓主流弊,學習學習
作者: Endover    時間: 2018-3-19 21:12
helloapy 發表于 2018-2-22 14:07
求教樓主,為什么我采集到的數據是這樣的,數據值一直在變小啊

兄弟,咱倆遇到的問題一樣啊,不知道你解決了沒有
作者: 致橡樹    時間: 2018-3-25 09:23
你好,請問你所用的iic-max30100模塊可以發我一下淘寶鏈接嗎?找不到帶LCD顯示屏的30100模塊,麻煩了。
作者: p_p_sunday    時間: 2018-3-29 09:44
好東西,學習下。
作者: gzl115    時間: 2018-4-3 23:36
請問樓主這個算法有一些資料文檔嗎,可以分享一下嗎,謝謝
作者: gzl115    時間: 2018-4-5 09:49
請問樓主這個可以用來放在手腕上測量嗎,我調試了你的代碼發現在手指測量可以得出想要得到的波形,但手腕上卻不太一樣
作者: Okj    時間: 2018-4-13 11:03
學習了
作者: nandyku    時間: 2018-4-13 15:53
樓主,我參考你的移植到F4上,接上線沒反應怎么回事?燈都不亮
作者: nandyku    時間: 2018-4-14 09:54
我一直測出來心率為29
作者: 徐潤澤    時間: 2018-4-23 19:39
學習了
作者: 文城寶寶    時間: 2018-4-23 21:38
樓主厲害
作者: liubingyu    時間: 2018-4-24 20:45
文城寶寶 發表于 2018-4-23 21:38
樓主厲害

樓主太給力啦
作者: baxlumen    時間: 2018-4-27 11:36
附件掛了,樓主能在傳一份嗎
作者: chichngguangshu    時間: 2018-5-1 15:24
樓主很強
作者: chichngguangshu    時間: 2018-5-1 15:29
樓主很強
作者: 匆匆那年0825    時間: 2018-5-2 10:22
請問樓主用的MAX30100長什么樣子 有鏈接嗎
作者: fenglianbin    時間: 2018-5-2 19:26
學習了
作者: FangLai    時間: 2018-5-3 16:18
厲害厲害 學習學習
作者: FangLai    時間: 2018-5-3 16:56
樓主用的是什么采集軟件

作者: hwasun    時間: 2018-5-3 21:29
厲害厲害 學習學習
作者: xxswkl    時間: 2018-5-4 15:28
資料下載了不能用,是什么原因?
作者: xxswkl    時間: 2018-5-4 15:29
nandyku 發表于 2018-4-13 15:53
樓主,我參考你的移植到F4上,接上線沒反應怎么回事?燈都不亮

請問,你的問題解決了嗎?
作者: xxswkl    時間: 2018-5-4 16:49
有可以用的代碼嗎?可以發一下嗎?
作者: 15382291381    時間: 2018-5-20 16:56
分不夠下載啊
作者: 904786907    時間: 2018-5-25 11:13
樓主,為什么我下載不了這個壓縮包?按下載顯示服務器錯誤?
作者: aaa951300    時間: 2018-6-3 23:58
謝謝樓主!
作者: 蘭木滄溟    時間: 2018-6-4 11:17
感謝分享
作者: mxsohu    時間: 2018-6-5 14:30
謝謝樓主分享,樓主制作和上傳辛苦了
作者: KingSealEast    時間: 2018-6-6 11:11
請教一下樓主,這個MAX30100測心率血氧的模塊INT,IRD和RD分別接在那個引腳?我使用了你提供的程序,發現上面沒有說明啊,能指點一下嗎?
作者: hei1043218814    時間: 2018-6-10 00:11
KingSealEast 發表于 2018-6-6 11:11
請教一下樓主,這個MAX30100測心率血氧的模塊INT,IRD和RD分別接在那個引腳?我使用了你提供的程序,發現上 ...

那三個可以不用接的 IIC和vcc gnd四個線就夠了其實
作者: hei1043218814    時間: 2018-6-10 00:16
KingSealEast 發表于 2018-6-6 11:11
請教一下樓主,這個MAX30100測心率血氧的模塊INT,IRD和RD分別接在那個引腳?我使用了你提供的程序,發現上 ...

說錯了 還要一個int中斷管腳 一共五個
作者: kat5566    時間: 2018-6-10 13:08
很好,很給力
作者: lqzhappy    時間: 2018-6-14 07:11
太強了,樓主!!FFT相關算法不熟悉,使用你的算法完美實現心率測量,敢問樓主現在薪資水平多少?太厲害了
作者: mettie    時間: 2018-6-18 15:33
厲害了
作者: loveme758    時間: 2018-7-23 09:59
需要看看
作者: OuYK    時間: 2018-8-9 10:41
        很給力!
作者: Colin.Yao    時間: 2018-8-9 13:56
匆匆那年0825 發表于 2018-5-2 10:22
請問樓主用的MAX30100長什么樣子 有購買鏈接嗎

MAX30100 MAX30101 MAX30102 都是差不多的  還有個測煙感的MAX30105  都是一個原理
作者: WuCun    時間: 2018-8-13 15:30
學習一下,感謝樓主的分享了
作者: 哎小樣丶    時間: 2018-8-14 10:17
編譯不過,錯誤很多 老哥
作者: kuangge123    時間: 2018-9-15 14:34
感謝樓主,代碼很給力,工程沒有模塊化有點亂.....
作者: 拓拔野2    時間: 2018-9-25 20:15
可以,很好的程序
作者: qmby919    時間: 2018-10-2 20:38
厲害厲害 學習學習
作者: wangbo0727    時間: 2018-10-15 08:38
血氧怎么計算,我計算出來的怎么都是60-70%之間啊;
你用的是FFT還有很多次濾波,我用一階濾波,也可以分離出心跳信號

1.jpg (237.29 KB, 下載次數: 765)

1.jpg

作者: 257.    時間: 2018-11-3 16:05
為什么下載不了?
作者: 17660448216    時間: 2018-11-5 13:50
請問這個接線是怎么接的
作者: 兩天半    時間: 2018-11-14 16:07
牛人,向你學習
作者: exodusyy    時間: 2018-11-15 09:33
學習。。。。。。。。。。。
作者: 亦心    時間: 2018-12-7 19:43
找了好久,好帖,下載下來仔細研究,謝謝樓主
作者: shllan    時間: 2018-12-7 22:15
學習一下
作者: kagamik    時間: 2018-12-24 11:56

好東西,學習下。
作者: hughtain    時間: 2019-1-15 19:32
哎小樣丶 發表于 2018-8-14 10:17
編譯不過,錯誤很多 老哥

不是樓主問題,是你自己的MDK沒有配置好
作者: hughtain    時間: 2019-1-15 19:36
樓主有點萌,超聲波模塊沒有去掉,哈哈
作者: hughtain    時間: 2019-1-15 19:40
哎小樣丶 發表于 2018-8-14 10:17
編譯不過,錯誤很多 老哥

剛剛看了下,把超聲波模塊ultrasonic那個文件夾移除,然后再stm32f10x_it.c里面注釋掉關于tim5的中斷子程序之類的就好了
作者: hughtain    時間: 2019-1-15 19:49
nandyku 發表于 2018-4-13 15:53
樓主,我參考你的移植到F4上,接上線沒反應怎么回事?燈都不亮

人家是f1的代碼,你確定你的f4的環境搭建好了嗎?
作者: Abc_zh    時間: 2019-2-24 15:23
可惜沒說怎么接線,要不然就完美了
作者: janussin    時間: 2019-3-5 20:20
希望能快點學習下
作者: 小車跑跑跑跑    時間: 2019-3-13 17:09
謝謝分享
作者: chenhh    時間: 2019-3-21 17:32
謝謝分享
作者: 2294629102    時間: 2019-3-30 15:48
樓主我找不到OLED對應的管腳啊   我的oled是 d0 d1 res dc cs的
作者: ddapw    時間: 2019-4-15 11:35
厲害厲害 學習學習
作者: dyyisme    時間: 2019-4-16 17:49
你好 想問請一下 芯片采集到什么時候為止呢?是通過寄存器控制嗎?
作者: 子上木    時間: 2019-4-20 20:58
請問這個可以改成用TFT液晶顯示嗎,嘗試著改了一下,模塊紅外光都沒能亮起來
作者: gswnllx    時間: 2019-4-22 16:41
不錯,頂一個
作者: xiechuangsen    時間: 2019-4-27 11:35
哎小樣丶 發表于 2018-8-14 10:17
編譯不過,錯誤很多 老哥

我也是,您這邊解決了嗎?
作者: 阿毛毛毛r    時間: 2019-5-12 15:53
hei1043218814 發表于 2018-6-10 00:16
說錯了 還要一個int中斷管腳 一共五個

請問一下int引腳接stm32的哪里啊?謝謝了,江湖救急!
作者: wdliming    時間: 2019-5-16 12:29
謝謝分享~~~
作者: mp777390387    時間: 2019-5-16 14:46
正需要這個
作者: touber    時間: 2019-5-19 08:44
絕對的好資料,謝謝樓主分享!
作者: touber    時間: 2019-5-19 08:48
我還沒下載成功呢!
作者: 大腦的男人    時間: 2019-5-20 09:02

學習了,想看一下源代碼
作者: cheney呂    時間: 2019-5-22 17:31
正在用這模塊,謝謝樓主分享,特別好
作者: 呵呵呵呵113    時間: 2019-5-23 21:24
這個很棒的資料呀
作者: zhang445465853    時間: 2019-7-8 15:17
學習了~
作者: wait_wait_    時間: 2019-9-1 13:07
好東西
作者: liugenli    時間: 2019-9-15 10:23
謝謝分享!
作者: qi19940913    時間: 2019-11-19 08:49
相當棒啊!
作者: qiuaqiuqiu    時間: 2020-1-11 16:58
歷害了樓主 ,希望下次可以多多分享
作者: cooleaf    時間: 2020-2-29 17:49
正準備用這模塊,謝謝樓主分享,特別好!
作者: user2402163    時間: 2020-3-19 17:58
注釋是代碼的靈魂,樓主威武
作者: 朱大炮    時間: 2020-3-21 10:18
點贊學習
作者: lin2222    時間: 2020-3-21 13:59
求問大家 要怎么進行硬件連線呢
作者: lin2222    時間: 2020-3-21 14:42
樓主 要想不用OLED顯示只用串口輸出要怎么修改代碼呢
作者: vitty    時間: 2020-4-7 12:08
沒有硬件連接圖呢
作者: ybjklabbbubunu    時間: 2020-4-9 08:39
是12864的屏還是12832的屏?可以兼容嗎
作者: ybjklabbbubunu    時間: 2020-4-9 08:42
如果不能怎么改
作者: Sky丶藍天    時間: 2020-4-9 10:18

作者: ybjklabbbubunu    時間: 2020-4-11 12:29
請問這怎么接線啊
作者: zxopenljx    時間: 2020-4-11 14:15
謝謝樓主




歡迎光臨 (http://www.izizhuan.cn/bbs/) Powered by Discuz! X3.1
成人免费毛片app| 91在线视频导航| 日韩一区二区在线观看视频播放| 精品久久久久久久久久久| **欧美大码日韩| 国产亚洲精品7777| 久久综合色鬼综合色| 国产福利精品一区二区| 蜜桃视频在线观看一区二区| 午夜亚洲视频| 欧美亚洲一区| 青青草97国产精品免费观看| 久久一二三四| 久久精品国产精品亚洲红杏| 久久www免费人成看片高清| 国产一区二区三区视频免费| 精品福利一区二区三区| 精品日韩一区二区| 亚洲а∨天堂久久精品喷水| 精品99999| 亚洲成人久久一区| 精品91自产拍在线观看一区| 亚洲精品国偷自产在线99热| 亚洲精品日韩在线| 中文字幕精品久久| 欧美理论片在线观看| 欧美丰满少妇xxxxx做受| 三年中国国语在线播放免费| 色哟哟日韩精品| 精品久久香蕉国产线看观看亚洲 | 国产亚洲欧美在线精品| 久久国产精品系列| 国产三级理论片| 国产xxxx孕妇| 婷婷丁香一区二区三区| 韩日中文字幕| 成年人深夜福利| 亚欧黄色av| 男人av在线| 自拍偷拍21p| 国产精品自拍合集| 日本毛片在线免费观看| 色婷婷综合久久久久中文字幕| 性欧美videossex精品| 国产在线视频三区| 国产美女免费网站| 日韩av电影网址| 国产视频手机在线观看| 久热中文字幕在线| www.九九热.com| 中文视频在线| 香蕉久久aⅴ一区二区三区| 成人免费看黄| 成人性生交大片免费看中文视频 | 国产亚洲精品久久久久久打不开 | 午夜精品久久久久久久白皮肤| 韩日欧美一区二区| 国产精品丝袜久久久久久不卡| 国产一区二区三区黄| 国产又粗又爽又黄的视频| 人妻熟女一二三区夜夜爱| 粗大的内捧猛烈进出视频| 无码人妻丰满熟妇啪啪欧美| 国产亚洲成人av| 国内精品偷拍视频| 国产精品中文久久久久久| 国产乱国产乱老熟300部视频| 九九九视频在线观看| 日韩av大片在线观看| 国内老熟妇对白xxxxhd| 日本夜夜草视频网站| 在线看片你懂的| 污视频网站免费在线观看| 成人97精品毛片免费看| 日韩av专区| 美国三级日本三级久久99| 久久色在线观看| 日本韩国欧美一区二区三区| 亚洲人午夜精品免费| 国产va免费精品高清在线| 欧美日韩国产综合在线| 日本特黄a级片| 亚洲天堂黄色片| 亚洲国产综合一区| www.99色.com| 欧美韩日亚洲| 伊人春色精品| 九色综合狠狠综合久久| 亚洲一卡二卡三卡四卡无卡久久 | 亚洲一区二区三区综合| 青青操免费在线视频| 男女爱爱视频免费| 天天插天天狠天天透| 操人在线观看| 日韩欧美视频| 国产.精品.日韩.另类.中文.在线.播放| 一区二区视频在线看| 亚洲精品国产拍免费91在线| 国产精品美女www| 亚洲高潮无码久久| xxx在线播放| 国产又黄又粗又长| 天天添天天操| 日韩脚交footjobhdboots| 欧美hd在线| 91丨porny丨中文| 日韩精品一区二区三区在线| 国产精品久久久久久久久久99| 高清无码一区二区在线观看吞精| 国产三级av在线播放| 色网站免费观看| 日韩国产福利| 精品久久电影| 久久久亚洲高清| 精品亚洲一区二区三区在线播放| 999视频在线观看| www.色就是色.com| 国产永久免费视频| 色老板视频在线观看| 国产视频一区二| 紧缚捆绑精品一区二区| 欧美久久免费观看| 成人黄色中文字幕| 人人爽人人爽av| 国产熟女精品视频| 免费国产在线观看| gogogo高清在线观看一区二区| 久久新电视剧免费观看| 亚洲日本成人女熟在线观看| 精品日韩欧美| 在线免费观看麻豆| 精品欧美日韩一区二区| 男女免费观看在线爽爽爽视频| 99tv成人| 国产精品色婷婷久久58| 中文国产成人精品| 久久综合九色99| aaa黄色大片| 亚洲videos| 国产精品无码2021在线观看| 国产ts一区| 国产91露脸合集magnet| 91精品国产综合久久福利软件| 色噜噜国产精品视频一区二区| 一本一道久久a久久综合精品| av女人的天堂| 久久久久久日本一区99| 夜级特黄日本大片_在线| 综合综合综合综合综合网| 成人国产视频在线观看 | 欧美一级黄色影院| 日韩欧美不卡视频| jizz在线免费播放| 婷婷激情成人| 国产99一区视频免费| 国产一区二区日韩精品欧美精品| 欧美日韩在线精品| 波多野吉衣中文字幕| 最近2018年在线中文字幕高清| 日本在线免费播放| 欧美 亚欧 日韩视频在线| 色综合 综合色| 国产精品久久久av| 亚洲在线观看网站| 色一情一乱一区二区三区| h网站视频在线观看| 91亚洲国产成人久久精品| 亚洲影视在线观看| 在线欧美日韩国产| 国产精品美女av| 日韩av在线中文| 国产男女裸体做爰爽爽| 无人视频在线观看免费| 国产欧美日韩影院| 最近中文字幕一区二区三区| 国产97在线播放| 亚洲日本黄色片| 无码精品人妻一区二区| 成人高清免费观看mv| 午夜亚洲福利| 欧美影视一区在线| 成人区精品一区二区| 免费人成视频在线播放| 久久久精品2019中文字幕神马| 免费日韩在线观看| 一级特黄aaa大片在线观看| 深夜福利视频在线观看| 久久国产小视频| 精品久久久久久亚洲精品| 国产精品三级美女白浆呻吟| 性猛交╳xxx乱大交| 最新天堂网www| 欧美亚洲人成在线| 久久久亚洲精品一区二区三区| www.亚洲人.com| chinese少妇国语对白| 性生活免费网站| 97超碰资源站在线观看| 三级欧美韩日大片在线看| 日韩欧美国产综合在线一区二区三区| 欧美激情第六页| www.91| 国产精品久久久久久久久久久久久久久久 | 日韩av网址在线| 这里只有精品66| 亚洲精品无码久久久久| 国产在线69| 国产乱码字幕精品高清av| 欧美床上激情在线观看| 中文字幕在线视频精品| 国产老女人av| 精品中国亚洲| 激情亚洲一区二区三区四区| 99精品综合| 亚洲天堂av一区| 国产一区二区色| 91视频免费在线看| 香蕉av一区| 国产精品久久久久久模特| 91精品国产综合久久久蜜臀粉嫩| 国产免费一区二区三区| 中文有码在线播放| 免费男女羞羞的视频网站在线观看| 国产精品自拍三区| 欧美国产第一页| 在线观看亚洲免费视频| 欧美著名女优| 视频一区欧美日韩| 久久影视电视剧免费网站清宫辞电视| 在线观看av免费观看| 国产1卡2卡三卡四卡网站| 99久久九九| 精品欧美一区二区三区精品久久| av在线播放天堂| 一二三四视频在线社区中文字幕2 一二三四日本中文字幕 | 精品无人区一区二区三区| 国产原创视频在线| 国产一线二线在线观看| 国产成人av电影在线播放| 国产欧美日韩精品在线观看| 久久精品99国产精| 91吃瓜网在线观看| 国产精品66部| 亚洲va欧美va国产综合剧情| 日本学生初尝黑人巨免费视频| 国产一区久久精品| 久久综合九色欧美综合狠狠| 91精品久久久久久| 国产精品久久久久精| 亚洲国产91视频| 色综合一区二区| 欧美性受xxxx黑人猛交88| 91福利免费视频| 高清日韩中文字幕| 91麻豆精品国产无毒不卡在线观看| 青青艹视频在线| 日本视频网址| 亚洲精品久久| 欧美激情亚洲激情| 国精产品久拍自产在线网站| 在线观看a视频| 国产亚洲欧洲997久久综合 | 久久爱91午夜羞羞| 亚洲精品久久久久久国产精华液| 三区精品视频| 一本大道一区二区三区| 天美av一区二区三区久久| 亚洲第一网站免费视频| 在线观看国产福利| 蜜桃一级网站.| 国产精品一区二区无线| 成人免费看黄网站| 成人av一区二区三区在线观看| 精品伊人久久久| 日韩激情在线视频| 成人在线电影网站| 国产原创av在线| 国产欧美一区二区三区网站| 日本一区二区三区免费观看| 四虎永久网址| 91精品久久久久久久久久不卡| 日韩在线视频中文字幕| 懂色av粉嫩av蜜臀av一区二区三区| 羞羞的视频在线观看| 亚洲靠逼com| 和岳每晚弄的高潮嗷嗷叫视频| 性一交一乱一伦一色一情| 日韩亚洲在线| 国产999精品久久久| 亚洲大尺度视频| 久久美女视频| 欧美成人精品一区二区三区| 久久国产精品二区| 视频在线一区| 精品调教chinesegay| 91激情视频在线观看| av漫画网站在线观看| 欧美日韩一级片网站| 无码人妻少妇色欲av一区二区| 国产视频在线看| 亚洲精品国产高清久久伦理二区| 一区二区不卡在线视频 午夜欧美不卡' | 中文幕无线码中文字蜜桃| 不卡av免费观看| 一本久道中文字幕精品亚洲嫩 | 人人干人人插| 久久99国产精品久久99| 日韩一区国产在线观看| 嫩草影院入口一二三| 国产精一品亚洲二区在线视频| 久99久视频| 小视频在线播放| 国产酒店精品激情| 日韩欧美三级一区二区| 成年女人免费v片| 大陆成人av片| 日韩精品一区二区三区外面 | 国产欧美另类| 91香蕉亚洲精品| 欧美妇乱xxxxx视频| 美女视频黄 久久| 中文字幕日韩一区二区三区| 超碰成人福利网| 国产亚洲va综合人人澡精品 | 毛片毛片毛片| 国产69精品久久久久毛片| 一区二区不卡在线观看| 麻豆视频免费网站| 久久久精品国产免大香伊| 大西瓜av在线| 在线免费毛片| 午夜a成v人精品| 永久免费毛片在线观看| 成人看片毛片免费播放器| 国产视频精品一区二区三区| 黄色一级免费视频| 日本一区二区三区播放| 国内免费久久久久久久久久久| 精品人妻一区二区三区三区四区| 欧美日韩午夜| 国产高清一区视频| 日本调教视频在线观看| 夜夜亚洲天天久久| 蜜臀视频在线观看| 色呦呦在线看| 伊人av综合网| 伊人免费在线观看| 亚洲看片一区| 久久大片网站| 1pon在线| 亚洲综合在线第一页| 美女露出粉嫩尿囗让男人桶| 欧美专区视频| 97成人超碰免| 欧美做爰性欧美大fennong| 国产精品影视在线| 亚洲高清在线免费观看| gogo久久| 在线日韩欧美视频| 7777久久亚洲中文字幕| 日韩高清在线电影| 浴室偷拍美女洗澡456在线| 蜜桃视频在线观看网站| 精品成人乱色一区二区| 麻豆91精品91久久久| 99精品电影| 精品高清视频| 蝌蚪视频在线播放| 日韩午夜激情视频| 99热只有这里有精品| 亚洲福利免费| 久久国产精品网| 美女91在线| 日韩亚洲欧美中文高清在线| 欧美视频一二区| 国产调教视频一区| 精品1卡二卡三卡四卡老狼| 伊人www22综合色| 91久久综合亚洲鲁鲁五月天| 好色视频app| 婷婷综合另类小说色区| 日韩激情小视频| 日韩一级网站| 天堂av在线中文| 日韩三级电影视频| 在线电影中文日韩| 亚欧洲精品视频| 久久婷婷色综合| 黄色片子免费看| 欧美理论在线播放| 欧美日韩一区二区三区在线视频 | 国产精品视频网站在线观看| 成人福利在线| 久久久精品影院| 欧美成人亚洲高清在线观看| 国产精品福利一区二区三区| 东方av正在进入| 亚洲精品女人| 国产日韩欧美精品在线观看| 五月天av在线|