久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 單片機心率程序為什么沒有數據啊?就大神解答一下 [打印本頁]

作者: 零點一    時間: 2025-4-11 16:07
標題: 單片機心率程序為什么沒有數據啊?就大神解答一下
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <stdio.h>

  4. #define uint unsigned int
  5. #define uchar unsigned char

  6. // 定義心率引腳
  7. sbit SCL = P3^3;
  8. sbit SDA = P3^4;
  9. sbit INT = P3^2;
  10. // 定義MAX30102的I2C地址
  11. #define MAX30102_ADDR 0xAE

  12. // 定義 MAX30102 寄存器地址
  13. #define REG_INTR_STATUS_1 0x00
  14. #define REG_INTR_STATUS_2 0x01
  15. #define REG_INTR_ENABLE_1 0x02
  16. #define REG_INTR_ENABLE_2 0x03
  17. #define REG_FIFO_WR_PTR 0x04
  18. #define REG_OVF_COUNTER 0x05
  19. #define REG_FIFO_RD_PTR 0x06
  20. #define REG_FIFO_DATA 0x07
  21. #define REG_FIFO_CONFIG 0x08
  22. #define REG_MODE_CONFIG 0x09
  23. #define REG_SPO2_CONFIG 0x0A
  24. #define REG_LED1_PA 0x0C
  25. #define REG_LED2_PA 0x0D
  26. #define REG_PILOT_PA 0x10
  27. #define REG_MULTI_LED_CTRL1 0x11
  28. #define REG_MULTI_LED_CTRL2 0x12
  29. #define REG_TEMP_INTR 0x1F
  30. #define REG_TEMP_FRAC 0x20
  31. #define REG_TEMP_CONFIG 0x21
  32. #define REG_PROX_INT_THRESH 0x30
  33. #define REG_REV_ID 0xFE
  34. #define REG_PART_ID 0xFF

  35. // 全局變量用于心率計算
  36. unsigned int pulse_count = 0;
  37. unsigned int prev_pulse_count = 0;
  38. unsigned int heart_rate = 0;
  39. uint count; // 計數
  40. bit flag_1s = 0;
  41. unsigned int one_second_count = 0;

  42. // 微秒級延時函數
  43. void delay(uint t) // @12T 1us
  44. {
  45.     while (t--);
  46. }

  47. // I2C起始信號
  48. void I2C_Start() {
  49.     SDA = 1;
  50.     SCL = 1;
  51.     delay(1);
  52.     SDA = 0;
  53.     delay(1);
  54.     SCL = 0;
  55. }

  56. // I2C停止信號
  57. void I2C_Stop() {
  58.     SDA = 0;
  59.     SCL = 1;
  60.     delay(1);
  61.     SDA = 1;
  62.     delay(1);
  63. }

  64. // I2C發送一個字節
  65. void I2C_SendByte(unsigned char dat) {
  66.     unsigned char i;
  67.     for (i = 0; i < 8; i++) {
  68.         SDA = (dat & 0x80) >> 7;
  69.         dat <<= 1;
  70.         SCL = 1;
  71.         delay(1);
  72.         SCL = 0;
  73.         delay(1);
  74.     }
  75. }

  76. // I2C接收一個字節
  77. unsigned char I2C_ReceiveByte() {
  78.     unsigned char i, dat = 0;
  79.     SDA = 1;
  80.     for (i = 0; i < 8; i++) {
  81.         SCL = 1;
  82.         dat <<= 1;
  83.         if (SDA) dat |= 0x01;
  84.         SCL = 0;
  85.         delay(1);
  86.     }
  87.     return dat;
  88. }

  89. // I2C發送應答信號
  90. void I2C_SendAck(bit ack) {
  91.     SDA = ack;
  92.     SCL = 1;
  93.     delay(1);
  94.     SCL = 0;
  95.     delay(1);
  96. }

  97. // I2C接收應答信號
  98. bit I2C_ReceiveAck() {
  99.     bit ack;
  100.     SDA = 1;
  101.     SCL = 1;
  102.     ack = SDA;
  103.     SCL = 0;
  104.     delay(1);
  105.     return ack;
  106. }

  107. // 向MAX30102寫一個字節數據
  108. bit MAX30102_WriteByte(unsigned char reg, unsigned char dat) {
  109.     I2C_Start();
  110.     I2C_SendByte(MAX30102_ADDR & 0xFE);  // 寫地址
  111.     if (I2C_ReceiveAck()) {
  112.         I2C_Stop();
  113.         return 0;
  114.     }
  115.     I2C_SendByte(reg);
  116.     if (I2C_ReceiveAck()) {
  117.         I2C_Stop();
  118.         return 0;
  119.     }
  120.     I2C_SendByte(dat);
  121.     if (I2C_ReceiveAck()) {
  122.         I2C_Stop();
  123.         return 0;
  124.     }
  125.     I2C_Stop();
  126.     return 1;
  127. }

  128. // 從MAX30102讀一個字節數據
  129. bit MAX30102_ReadByte(unsigned char reg, unsigned char *dat) {
  130.     I2C_Start();
  131.     I2C_SendByte(MAX30102_ADDR & 0xFE);  // 寫地址
  132.     if (I2C_ReceiveAck()) {
  133.         I2C_Stop();
  134.         return 0;
  135.     }
  136.     I2C_SendByte(reg);
  137.     if (I2C_ReceiveAck()) {
  138.         I2C_Stop();
  139.         return 0;
  140.     }
  141.     I2C_Start();
  142.     I2C_SendByte(MAX30102_ADDR | 0x01);  // 讀地址
  143.     if (I2C_ReceiveAck()) {
  144.         I2C_Stop();
  145.         return 0;
  146.     }
  147.     *dat = I2C_ReceiveByte();
  148.     I2C_SendAck(1);  // 非應答
  149.     I2C_Stop();
  150.     return 1;
  151. }

  152. // 初始化MAX30102
  153. bit MAX30102_Init() {
  154.     unsigned char reg_val;
  155.     if (!MAX30102_WriteByte(REG_MODE_CONFIG, 0x40)) return 0; // 復位 MAX30102
  156.     do {
  157.         if (!MAX30102_ReadByte(REG_MODE_CONFIG, ®_val)) return 0;
  158.     } while (reg_val & 0x40);
  159.     if (!MAX30102_WriteByte(REG_FIFO_CONFIG, 0x00)) return 0; // 設置 FIFO 配置
  160.     if (!MAX30102_WriteByte(REG_MODE_CONFIG, 0x02)) return 0; // 設置模式配置為心率模式
  161.     if (!MAX30102_WriteByte(REG_SPO2_CONFIG, 0x27)) return 0; // 設置 SpO2 配置
  162.     if (!MAX30102_WriteByte(REG_LED1_PA, 0x2F)) return 0; // 設置 LED 強度
  163.     if (!MAX30102_WriteByte(REG_LED2_PA, 0x2F)) return 0;
  164.     return 1;
  165. }

  166. // 讀取 FIFO 數據
  167. bit MAX30102_ReadFIFO(unsigned long *data) {
  168.     unsigned char byte1, byte2, byte3;
  169.     if (!MAX30102_ReadByte(REG_FIFO_DATA, &byte1)) return 0;
  170.     if (!MAX30102_ReadByte(REG_FIFO_DATA, &byte2)) return 0;
  171.     if (!MAX30102_ReadByte(REG_FIFO_DATA, &byte3)) return 0;
  172.     *data = ((unsigned long)byte1 << 16) | ((unsigned long)byte2 << 8) | (unsigned long)byte3;
  173.     return 1;
  174. }

  175. // 簡單的心率計算
  176. int calculateHeartRate(unsigned long *data, int size) {
  177.     int peaks = 0;
  178.     int i;
  179.     for (i = 1; i < size - 1; i++) {
  180.         if (data[i] > data[i - 1] && data[i] > data[i + 1]) {
  181.             peaks++;
  182.         }
  183.     }
  184.     // 簡單估算心率,假設采樣率為 100Hz
  185.     int heartRate = peaks * 60 / (size / 100);
  186.     return heartRate;
  187. }

  188. // 定時器0初始化函數
  189. void InitTimer0(void)
  190. {
  191.     TMOD = 0x01;
  192.     TH0 = 0xFC;
  193.     TL0 = 0x18;
  194.     EA = 1;
  195.     ET0 = 1;
  196.     TR0 = 1;
  197. }

  198. // 外部中斷 0 服務函數,用于檢測心率脈沖
  199. void External0_ISR() interrupt 0
  200. {
  201.     static uint last_time = 0;
  202.     uint current_time = count;
  203.     if (current_time - last_time > 20) // 消抖處理,20ms
  204.     {
  205.         pulse_count++;
  206.         last_time = current_time;
  207.     }
  208. }

  209. // 定時器0中斷服務函數
  210. void Timer0Interrupt() interrupt 1
  211. {
  212.     static uint i;
  213.     TH0 = 0xFC;
  214.     TL0 = 0x18;
  215.     count++;
  216.     i++;
  217.     one_second_count++;
  218.     if (one_second_count >= 1000) // 1秒
  219.     {
  220.         one_second_count = 0;
  221.         flag_1s = 1;
  222.     }
  223. }

  224. // 主程序
  225. unsigned long fifoData[1000]; // 定義為全局變量以減小 main 函數自動段大小
  226. void main()
  227. {
  228.     int i;

  229.     // 初始化定時器0
  230.     InitTimer0();
  231.     // 初始化外部中斷 0
  232.     IT0 = 1;  // 下降沿觸發
  233.     EX0 = 1;  // 使能外部中斷 0
  234.     EA = 1;   // 使能全局中斷
  235.     IE0 = 0;  // INT0中斷請求標志清0

  236.     // 初始化MAX30102
  237.     if (!MAX30102_Init()) {
  238.         while (1);
  239.     }

  240.     // 讀取FIFO數據
  241.     for (i = 0; i < 1000; i++) {
  242.         if (!MAX30102_ReadFIFO(&fifoData[i])) {
  243.             while (1);
  244.         }
  245.     }

  246.     // 計算初始心率
  247.     heart_rate = calculateHeartRate(fifoData, 1000);

  248.     while (1)
  249.     {
  250.         if (flag_1s) // 1秒
  251.         {
  252.             flag_1s = 0;
  253.             heart_rate = pulse_count * 60; // 計算心率
  254.             pulse_count = 0; // 清零脈沖計數
  255.         }
復制代碼

   編譯能過,心率沒有數據






歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 91偷拍精品一区二区三区 | 麻豆久久久9性大片 | 国内精品视频在线观看 | 最新中文字幕 | 欧美xxxⅹ性欧美大片 | 九九久久久 | 麻豆天堂 | 亚洲视频免费在线观看 | 亚洲国产精品一区二区久久 | 日韩免费视频 | 国产福利在线 | 99精品一区二区三区 | 欧美一级黄视频 | 精品国产视频 | 男女下面一进一出网站 | 罗宾被扒开腿做同人网站 | 精品自拍视频在线观看 | 日本精品视频一区二区三区四区 | 欧美日韩视频 | av黄色在线 | 国产精品v| 日本视频免费观看 | 国产区精品 | 亚洲欧美一区二区三区视频 | 可以免费看的毛片 | av看片网站 | 亚洲三级免费看 | 日韩一区二区不卡 | 久久精品视频亚洲 | 羞羞视频免费在线 | 精品av天堂毛片久久久借种 | 999免费视频 | 精品成人免费一区二区在线播放 | 中文字幕 亚洲一区 | 91一区二区三区在线观看 | av在线免费观看网址 | 99久久国产免费 | 色毛片| 亚洲综合天堂 | 国产精品视屏 | 国产福利91精品一区二区三区 |