[RISC-V MCU 创新应用比赛] 基于CH32V307,LORA以及VHF频率通信的老人居家远程健康监测控制系统

[复制链接]
 楼主| donatello1996 发表于 2023-2-28 22:11 | 显示全部楼层 |阅读模式
本帖最后由 donatello1996 于 2023-2-28 23:26 编辑

简介:使用CH32V307-EVT评估板接上必要传感器外设,监测老人居家的环境温度、大气压、有害气体浓度、心率、血样、血氧、三轴加速度、三轴陀螺仪等指标,其中三轴加速度和三轴陀螺仪是为了监控老人是否发生摔倒的情况,通过400M LORA数字信号发送于老人子女手上的另一块电路板(以下以子女电路板代称),LORA通信距离视乎发射器功率,使老人子女可以通过子女电路板在一公里以内实时监测老人居家的上述指标,同时,CH32V307-EVT评估板还通过板上TTL串口控制一个VHF语音对讲模块,子女电路板上也接入一个相同型号,相同频率的VHF语音对讲模块,VHF在城市内可进行一公里内的无衰减异步语音通信,进行三公里内的衰减异步语音通信,老人和老人子女均可通过VHF语音对讲模块上的PTT按钮进行语音通话,而无需使用网络流量,开机即用,老人子女也可以通过串口方式对VHF语音对讲模块写频。除了上述功能外,老人手上的CH32V307-EVT评估板还带有手势识别模块和RDA5807收音机模块,以手势控制收音机模块的输出音量和自动搜索可用电台,用于老人日常消遣。此系统相比起之前兴起的4G、WIFI、NBIOT物联网智能家居系统,优势在于完全脱离网络流量限制,LORA通信和VHF通信都是高稳定性、超远距离、开机即用无需登录云平台的通信手段,140MHz和400MHz这两个频段使用大功率发射天线,可以满足一公里内的无衰减通信和三公里内的衰减通信,此系统一般用于老人与老人子女同住处,老人子女上班与出租屋距离不远的场合,若是老人与老人子女远于三公里,那就只能使用网络流量的方式通过云平台进行通信了。
硬件说明:
此系统使用到了CH32V307-EVT板上的I2C、SPI、串口、外部中断、AD接口、DA接口等外设,监测老人居家的环境温度和大气压所使用的模块为I2C接口的BMP280模块,该模块可以检测环境温度和大气压。监测有害气体浓度所使用的模块为电压输出和电平输出的MQ135模块,当MQ135模块检测到一氧化碳,甲醛等有害气体浓度大于阈值时,会在D0接口输出下降沿和持续的低电平,CH32V307-EVT评估板可通过外部中断进行监测。监测老人心率和血氧的模块是串口的MAX30102心率血氧采集模块,此模块需要使用手指尖进行检测,厂家后续第二代产品可升级为直接接触式检测,但输出方式不变,仍为串口。监测老人三轴加速度和三轴陀螺仪所使用的模块为I2C接口MPU6050模块。收音机模块为I2C接口的RDA5807模块,需要外接天线和扬声器使用。老人可通过I2C接口的PAJ7620模块进行手势控制,该模块支持八个手势控制,分别为前、后、左、右、上、下、顺时针、逆时针,检测灵敏度尚可,但肯定比不了独立按键直接控制,该模块厂家也在后续升级中。VHF语音对讲模块上集成了麦克风、扬声器和PTT发射按钮,CH32V307-EVT板也是通过串口进行VHF语音对讲模块控制。发射LORA数字信号所使用的模块为SPI接口+外部中断接口安信可RA02模块,主控为SX1278,需要配备发射天线。VHF语音对讲模块和安信可RA02模块都必须成对使用,也就是另外的一个VHF语音对讲模块和安信可RA02模块需要接到另外的电路板上进行无线通信。VHF语音对讲模块和安信可RA02模块的频段是错开的,VHF语音对讲模块可用频段为140-170MHz,安信可RA02模块可用频段为400-470MHz,两个模块一起使用不会造成任何干扰,但安信可RA02模块不可以与UHF模块同时使用(400-470MHz)。由于MPU6050模块对I2C硬件要求过高,所以使用独立的I2C总线,不与BMP280模块、PAJ7620模块、RDA5807模块同时使用。
微信截图_20230228224211.jpg
d738b183f593f09e135ed0c0f62b114.jpg b41635594025f370d02c9db59c589c7.jpg b3706368d9c97f8555e05d2d41d152c.jpg 5ebb8750976856f438922b436006558.jpg
f1827660c310f7c4f75971ad72b5495.jpg db8dabe3f180e0583eb52aac68a7f33.jpg d2d321ff7fbd9e14c5d6910db6a4458.jpg adcb701d0db5d37023905e416c6d35d.jpg 79359051bac94ec8d273ab9757e1925.jpg 85f75b49ada30f0c86e25e2125e8741.jpg 8e077eda2c24acd5c19c7a77f49be2e.jpg 6ca530d93eabf4fc48db1ea507bc65d.jpg


软件说明:
开发平台为VSCode,编译使用官方编译链riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-w64-mingw32,命令行编译:
微信截图_20230228231725.jpg
  1. <div>riscv64-unknown-elf-gcc -g -O3 --specs=nosys.specs --specs=nano.specs -msave-restore -march=rv32imafc -mabi=ilp32 -msmall-data-limit=8 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common -Wunused -Wuninitialized -nostartfiles -Xlinker -T ./Link/Link1.ld ./Startup/startup_ch32v30x_D8C1.S -I./Bsp -I./Core -I./Driver -I./Startup -I./User -I./Eth -L./Lib ./Startup/syscalls.c ./Startup/system_ch32v30x.c ./Driver/ch32v30x_adc.c ./Driver/ch32v30x_rcc.c ./Driver/ch32v30x_dac.c ./Driver/ch32v30x_misc.c ./Driver/ch32v30x_gpio.c ./Driver/ch32v30x_exti.c ./Driver/ch32v30x_spi.c ./Driver/ch32v30x_dma.c ./Driver/ch32v30x_tim.c ./Driver/ch32v30x_usart.c ./Driver/ch32v30x_i2c.c ./Bsp/debug.c ./Bsp/spi1_spi2.c ./Bsp/i2c.c ./Bsp/uart.c ./Bsp/adc_pa0.c ./Bsp/lora.c ./Bsp/bmp280.c ./Bsp/paj7620.c ./Bsp/mpu6050.c ./User/main.c ./User/ch32v30x_it.c -lm -o main</div><div>
  2. </div><div>riscv64-unknown-elf-objcopy -O binary main main.bin</div>
微信截图_20230228230110.jpg

此系统不带RTOS,完全由裸机实现,CH32V307设置主频为140MHz,初始化所有必要外设后进入主循环,主循环不间断读取AD电压值和手势传感器值,手势传感器值用于控制RDA5807模块调频和调音量,以及VHF语音模块。200个循环读取一次BMP280的电压值、温度值、MPU6050的三轴加速度值和三轴陀螺仪值,250个循环写入一次血氧和心跳的AT请求指令,300个循环读取一次AT返回数值,1000个循环进行一次LORA数字信号发送,10000个循环将有害气体告警字节清零:
  1.    Delay_Init();
  2.     UART1_Init(115200);
  3.         printf("SystemClk:%d\n",SystemCoreClock);
  4.         printf("Leader Qiao is niubility.\n");
  5.         printf("Brother Long is lihaility.\n");
  6.         printf("Master XU is dalaoility.\n");

  7.         UART2_Init(9600 , 1);
  8.         UART2_Send_String("UART2\n");

  9.         ADC_Function_Init();
  10.         DAC1_Init();

  11.     //W5500_Init();

  12.         SPI1_Init();
  13.         SPI2_Init();
  14.         RA02_GPIO_Init();
  15.     RA02_EXTI8_Int_Init();
  16.         SX1276_Init(400 , 7);

  17.         I2C_Init_PB6_PB7();
  18.         BMP280_Init();
  19.         PAJ7620_Init();

  20.         I2C_Init_PD8_PD9();
  21.         MPU6050_Init();

  22.         printf("RDA5807P_Intialization = %d\n" , RDA5807P_Intialization());

  23.         while(1)
  24.         {

  25.                 // if(mpu_dmp_get_data(&pitch , &roll , &yaw) == 0)
  26.                 // {
  27.                 //         MPU_Get_Accelerometer(&aacx,&aacy,&aacz);
  28.                 //         MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);

  29.                 //         printf("pitch = %d.%-3d roll = %d.%-3d yaw = %d.%-3d\n" ,
  30.                 //         (int)pitch , abs(((int)(pitch * 1000)) % 1000) ,
  31.                 //         (int)roll , abs(((int)(roll * 1000)) % 1000) ,
  32.                 //         (int)yaw , abs(((int)(yaw * 1000)) % 1000)
  33.                 //         );
  34.                 // }

  35.                 ret = I2C_Read_Addr_PB6_PB7(PAJ7620_ID , 0x43);
  36.                 if(ret != 0)
  37.                 {
  38.                         switch(ret)
  39.                         {
  40.                                 case 16:
  41.                                 {
  42.                                         printf("Approach.\n");

  43.                                         break;
  44.                                 }
  45.                                 case 32:
  46.                                 {
  47.                                         printf("Away.\n");
  48.                                         break;
  49.                                 }
  50.                                 case 4:
  51.                                 {
  52.                                         printf("Forward.\n");
  53.                                         break;
  54.                                 }
  55.                                 case 8:
  56.                                 {
  57.                                         printf("Backword.\n");
  58.                                         break;
  59.                                 }
  60.                                 case 2:
  61.                                 {
  62.                                         printf("Left.\n");
  63.                                         break;
  64.                                 }
  65.                                 case 1:
  66.                                 {
  67.                                         printf("Right.\n");
  68.                                         break;
  69.                                 }
  70.                                 case 64:
  71.                                 {
  72.                                         printf("Clockwise.\n");
  73.                                         break;
  74.                                 }
  75.                                 case 128:
  76.                                 {
  77.                                         printf("Anti-clockwise.\n");
  78.                                         break;
  79.                                 }
  80.                         }
  81.                 }

  82.                 if(timer_count % 200 == 0)
  83.                 {
  84.                         adc_val = Get_ADC_Val(1);
  85.                         printf("adc_val = %d\n" , adc_val);
  86.                         lora_tx_buffer[2] = adc_val >> 8;
  87.                         lora_tx_buffer[3] = adc_val & 0xff;
  88.                         lora_tx_buffer[4] = 0;

  89.                         BMP280_Read_Pressure_Tempature(&pres , &temp);
  90.                         asl = BMP280PressureToAltitude(&pres);
  91.                         printf("pres = %d.%-3d , temp = %d.%-3d , asl = %d.%-3d\n" ,
  92.                         (int)pres , abs(((int)(pres * 1000)) % 1000) ,
  93.                         (int)temp , abs(((int)(temp * 1000)) % 1000) ,
  94.                         (int)asl , abs(((int)(asl * 1000)) % 1000)
  95.                         );

  96.                         lora_tx_buffer[6] = ((int)pres) >> 8;
  97.                         lora_tx_buffer[7] = ((int)pres) & 0xff;

  98.                         lora_tx_buffer[8] = (((int)(pres * 65536)) & 65536) >> 8;
  99.                         lora_tx_buffer[9] = ((int)(pres * 65536)) & 0xff;

  100.                         lora_tx_buffer[10] = ((int)temp) >> 8;
  101.                         lora_tx_buffer[11] = ((int)temp) & 0xff;
  102.                        
  103.                         aacx = I2C_Read_Addr_PD8_PD9(0x68 , ACCEL_XOUT_H) << 8 | I2C_Read_Addr_PD8_PD9(0x68 , ACCEL_XOUT_H + 1);
  104.                         aacy = I2C_Read_Addr_PD8_PD9(0x68 , ACCEL_YOUT_H) << 8 | I2C_Read_Addr_PD8_PD9(0x68 , ACCEL_YOUT_H + 1);
  105.                         aacz = I2C_Read_Addr_PD8_PD9(0x68 , ACCEL_ZOUT_H) << 8 | I2C_Read_Addr_PD8_PD9(0x68 , ACCEL_ZOUT_H + 1);
  106.                     printf("%d %d %d\n" , aacx , aacy , aacz);

  107.                         lora_tx_buffer[12] = aacx >> 8;
  108.                         lora_tx_buffer[13] = aacx & 0xff;

  109.                         lora_tx_buffer[14] = aacy >> 8;
  110.                         lora_tx_buffer[15] = aacy & 0xff;

  111.                         lora_tx_buffer[16] = aacz >> 8;
  112.                         lora_tx_buffer[17] = aacz & 0xff;
  113.                 }

  114.                 if(timer_count % 250 == 0)
  115.                 {
  116.                         printf("timer_count = %d\n" , timer_count);
  117.                         flag_spo2_heart = 1 - flag_spo2_heart;
  118.                         if(flag_spo2_heart == true)
  119.                                 UART2_Send_String("AT+HEART\r\n");
  120.                         else
  121.                                 UART2_Send_String("AT+SPO2\r\n");
  122.                 }
  123.                 if(timer_count % 300 == 0)
  124.                 {
  125.                         printf("spo2 = %d heart = %d\n" , spo2 , heart);
  126.                         lora_tx_buffer[18] = spo2 >> 8;
  127.                         lora_tx_buffer[19] = spo2 & 0xff;
  128.                         lora_tx_buffer[20] = heart >> 8;
  129.                         lora_tx_buffer[21] = heart & 0xff;
  130.                 }

  131.                 // if(rec_start && !rec_stop)
  132.                 // {
  133.                 //         rec_adc_val[rec_count++] = Get_ADC_Val(0);
  134.                 //         printf("%d\n" , rec_adc_val[rec_count - 1]);
  135.                 //         DAC_SetChannel1Data(DAC_Align_12b_R, rec_adc_val[rec_count - 1]);
  136.                 // }
  137.                 // else if(!rec_start && rec_stop)
  138.                 // {
  139.                 //         rec_stop = false;
  140.                 //         printf("rec_count = %d\n" , rec_count);
  141.                 //         for(i = 0 ; i < rec_count ; i ++)
  142.                 //         {
  143.                 //                 DAC_SetChannel1Data(DAC_Align_12b_R, rec_adc_val[i]);
  144.                 //         }
  145.                 //         rec_count = 0;
  146.                 // }

  147.                 if(timer_count % 1000 == 0)
  148.                 {
  149.                         printf("timer_count = %d\n" , timer_count);
  150.                         Lora_TxData(lora_tx_buffer , 50);
  151.                 }

  152.                 if(timer_count % 10000 == 0)
  153.                 {
  154.                         lora_tx_buffer[4] = 0;
  155.                 }               

  156.                 timer_count ++;

  157.                 if(timer_count >= 1000000000)
  158.                         timer_count = 0;
  159.         }

BMP280模块初始化:
  1. uint8_t BMP280_Init(void)
  2. {
  3.     uint8_t bmp280_id;
  4.     uint8_t tmp[1];

  5.     I2C_Read_Datas_PB6_PB7(BMP280_SLAVE_ADDRESS, BMP280_CHIPID_REG, 1, &bmp280_id);

  6.         printf("bmp280_id = 0x%x\n" , bmp280_id);

  7.     I2C_Read_Datas_PB6_PB7(BMP280_SLAVE_ADDRESS, BMP280_DIG_T1_LSB_REG , 24 , (u8 *)&bmp280Cal);
  8.        
  9.         //printf("%d %d %d %d %d %d %d %d %d %d %d %d\n" ,
  10.         // bmp280Cal.dig_T1 , bmp280Cal.dig_T2 , bmp280Cal.dig_T3 ,
  11.         // bmp280Cal.dig_P1 , bmp280Cal.dig_P2 , bmp280Cal.dig_P3 ,
  12.         // bmp280Cal.dig_P4 , bmp280Cal.dig_P5 , bmp280Cal.dig_P6 ,
  13.         // bmp280Cal.dig_P7 , bmp280Cal.dig_P8 , bmp280Cal.dig_P9);

  14.     tmp[0] = BMP280_MODE;
  15.     I2C_Write_Reg_Datas_PB6_PB7(BMP280_SLAVE_ADDRESS , BMP280_CTRLMEAS_REG , 1 , tmp);

  16.     tmp[0] = 5 << 2;
  17.     I2C_Write_Reg_Datas_PB6_PB7(BMP280_SLAVE_ADDRESS , BMP280_CONFIG_REG , 1 , tmp);

  18.     return bmp280_id;
  19. }


PAJ7620初始化:
  1. void PAJ7620_Init()
  2. {
  3.     int i;
  4.     I2C_Write_Reg_Data_PB6_PB7(PAJ7620_ID , PAJ7620_REGITER_BANK_SEL , PAJ7620_BANK0);
  5.     I2C_Write_Reg_Data_PB6_PB7(PAJ7620_ID , PAJ7620_REGITER_BANK_SEL , PAJ7620_BANK0);
  6.     printf("PAJ7620 Init 0 = 0x%x\n" , I2C_Read_Addr_PB6_PB7(PAJ7620_ID , 0));
  7.     printf("PAJ7620 Init 1 = 0x%x\n" , I2C_Read_Addr_PB6_PB7(PAJ7620_ID , 1));

  8.     for(i = 0 ; i < INIT_REG_ARRAY_SIZE ; i ++)
  9.         I2C_Write_Reg_Data_PB6_PB7(PAJ7620_ID , initRegisterArray[i][0] , initRegisterArray[i][1]);

  10.     I2C_Write_Reg_Data_PB6_PB7(PAJ7620_ID , PAJ7620_REGITER_BANK_SEL , PAJ7620_BANK0);
  11. }


MPU6050初始化:
  1. void MPU6050_Init()
  2. {
  3.         int ret;
  4.         ret = I2C_Read_Addr_PD8_PD9(0x68 , 0x75);
  5.         printf("MPU6050_Init = 0x%x\n" , ret);

  6.         I2C_Write_Reg_Data_PD8_PD9(0x68 , SMPLRT_DIV , 7);
  7.         //Write to sample rate register
  8.         printf("SMPLRT_DIV = 0x%x\n" , I2C_Read_Addr_PD8_PD9(0x68 , SMPLRT_DIV));

  9.         I2C_Write_Reg_Data_PD8_PD9(0x68 , PWR_MGMT_1 , 1);
  10.         // Write to power management register
  11.         printf("PWR_MGMT_1 = 0x%x\n" , I2C_Read_Addr_PD8_PD9(0x68 , PWR_MGMT_1));

  12.         I2C_Write_Reg_Data_PD8_PD9(0x68 , CONFIG , 0);
  13.         // Write to Configuration register
  14.         printf("CONFIG = 0x%x\n" , I2C_Read_Addr_PD8_PD9(0x68 , CONFIG));

  15.         I2C_Write_Reg_Data_PD8_PD9 (0x68 , GYRO_CONFIG , 24);
  16.         // Write to Gyro Configuration register
  17.         printf("GYRO_CONFIG = 0x%x\n" , I2C_Read_Addr_PD8_PD9(0x68 , GYRO_CONFIG));

  18.         I2C_Write_Reg_Data_PD8_PD9 (0x68 , INT_ENABLE , 1);
  19.         //Write to interrupt enable register
  20.         printf("INT_ENABLE = 0x%x\n" , I2C_Read_Addr_PD8_PD9(0x68 , INT_ENABLE));
  21. }


RDA5807初始化:
  1. bool RDA5807P_Intialization(void)
  2. {
  3.         uint8_t error_ind = 0;
  4.         uint8_t RDA5807P_REGR[10]={0x0};
  5.     uint8_t i = 0;

  6.     RDA5807P_REGW[0] = 0x00;
  7.     RDA5807P_REGW[1] = 0x02;

  8.         error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807P_REGW[0], 2);
  9.         Delay_ms(50);

  10.         error_ind = OperationRDAFM_2w(READ, (uint8_t *)&RDA5807P_REGR[0], 10);
  11.         Delay_ms(50);

  12.     gChipID = RDA5807P_REGR[8];
  13.     gChipID = ((gChipID<<8) | RDA5807P_REGR[9]);

  14.         printf("gChipID = %d\n" , gChipID);

  15.     if (gChipID == 0x5808)  //RDA5807N
  16.     {
  17.         for (i=0;i<8;i++)
  18.             RDA5807P_REGW[i] = RDA5807N_initialization_reg[i];
  19.      
  20.         error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807N_initialization_reg[0], 2);
  21.         Delay_ms(600);
  22.             error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807N_initialization_reg[0], sizeof(RDA5807N_initialization_reg));
  23.     }
  24.     else if (gChipID == 0x5804)     //RDA5807PE,RDA5807SP
  25.     {
  26.         for (i=0;i<8;i++)
  27.             RDA5807P_REGW[i] = RDA5807PE_initialization_reg[i];
  28.      
  29.         error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807PE_initialization_reg[0], 2);
  30.         Delay_ms(600);
  31.             error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807PE_initialization_reg[0], sizeof(RDA5807PE_initialization_reg));
  32.     }
  33.     else if (gChipID == 0x5801)     //RDA5807H,RDA5807HP
  34.     {
  35.         for (i=0;i<8;i++)
  36.             RDA5807P_REGW[i] = RDA5807PH_initialization_reg[i];
  37.      
  38.         error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807PH_initialization_reg[0], 2);
  39.         Delay_ms(600);
  40.             error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807PH_initialization_reg[0], sizeof(RDA5807PH_initialization_reg));
  41.         Delay_ms(100);

  42.                 do
  43.                 {
  44.                         i++;
  45.                         if(i>10)
  46.                                 return 0;
  47.                        
  48.                 RDA5807P_SetFreq(8750);

  49.                 Delay_ms(10);          

  50.                 //read REG0A&0B       
  51.                 OperationRDAFM_2w(READ,&(RDA5807P_REGR[0]), 4);
  52.                 if((RDA5807P_REGR[3]&0x80)==0)
  53.                         {
  54.                                 RDA5807P_REGW[1] &= 0xFE;       
  55.                                 error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807P_REGW[0], 2);
  56.                                 Delay_ms(50);       
  57.                                 RDA5807P_REGW[1] |= 0x01;
  58.                                 error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807P_REGW[0], 2);
  59.                                 Delay_ms(50);

  60.                 }
  61.                 }while((RDA5807P_REGR[3]&0x80)==0);
  62.     }
  63.     else
  64.     {
  65.         gChipID = RDA5807P_REGR[4];
  66.         gChipID = ((gChipID<<8) | RDA5807P_REGR[5]);
  67.     }
  68.    
  69.     if ((gChipID == 0x5802) || (gChipID == 0x5803))
  70.     {
  71.         gChipID = 0x5802;

  72.         for (i=0;i<8;i++)
  73.             RDA5807P_REGW[i] = RDA5807P_initialization_reg[i];


  74.         error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807P_initialization_reg[0], 2);
  75.         Delay_ms(600);
  76.         error_ind = OperationRDAFM_2w(WRITE, (uint8_t *)&RDA5807P_initialization_reg[0], sizeof(RDA5807P_initialization_reg));

  77.     }

  78.         Delay_ms(50);
  79.        
  80.         if (error_ind )
  81.            return 0;
  82.         else
  83.            return 1;
  84. }


读取血氧和心跳值使用串口空闲中断:
  1. __attribute__((interrupt(), weak)) void USART2_IRQHandler(void)
  2. {
  3.         int i = 0;
  4.         if(USART_GetITStatus(USART2 , USART_IT_IDLE) != RESET)  
  5.         {
  6.                 USART_ReceiveData(USART2);
  7.                 DMA_Cmd(DMA1_Channel6 , DISABLE);  
  8.                 com2_rx_count = COM_RX_BUFFER_SIZE - DMA_GetCurrDataCounter(DMA1_Channel6);
  9.                 DMA1_Channel6->CNTR = COM_RX_BUFFER_SIZE;
  10.                 DMA_Cmd(DMA1_Channel6 , ENABLE);
  11.                 for(i = 0 ; i < com2_rx_count ; i ++)
  12.                 {
  13.                         if(com2_rx_buffer[i] == '+' && com2_rx_buffer[i + 1] == 'S' && com2_rx_buffer[i + 2] == 'P'
  14.                         && com2_rx_buffer[i + 3] == 'O' && com2_rx_buffer[i + 4] == '2'  && com2_rx_buffer[i + 5] == '='
  15.                         && com2_rx_buffer[i + 6] != 'N'
  16.                         )
  17.                         {
  18.                                 spo2 =  (com2_rx_buffer[i + 6] - '0') * 10 + com2_rx_buffer[i + 7] - '0';
  19.                         }
  20.                         if(com2_rx_buffer[i] == '+' && com2_rx_buffer[i + 1] == 'H' && com2_rx_buffer[i + 2] == 'E'
  21.                         && com2_rx_buffer[i + 3] == 'A' && com2_rx_buffer[i + 4] == 'R'  && com2_rx_buffer[i + 5] == 'T'
  22.                         && com2_rx_buffer[i + 6] == '=' && com2_rx_buffer[i + 7] != 'N'
  23.                         )
  24.                         {
  25.                                 heart = com2_rx_buffer[i + 7] - '0';

  26.                                 if('0' <= com2_rx_buffer[i + 8] && com2_rx_buffer[i + 8] <= '9')
  27.                                 {
  28.                                         heart = (com2_rx_buffer[i + 7] - '0') * 10 + com2_rx_buffer[i + 8] - '0';
  29.                                 }

  30.                                 if('0' <= com2_rx_buffer[i + 9] && com2_rx_buffer[i + 9] <= '9')
  31.                                 {
  32.                                         heart = (com2_rx_buffer[i + 7] - '0') * 100 + (com2_rx_buffer[i + 8] - '0') * 10 + com2_rx_buffer[i + 9] - '0';
  33.                                 }
  34.                                
  35.                         }
  36.                 }

  37.         }
  38. }


SX1276初始化:
  1. SX1276初始化:
  2. void SPI1_Init()
  3. {
  4.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  5.     SPI_InitTypeDef  SPI_InitStructure = {0};

  6.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);

  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE );
  8.         GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE );

  9.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  10.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  11.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  12.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  13.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  14.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  15.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  16.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  17.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  18.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  19.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  20.     SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  21.     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  22.     SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  23.     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  24.     SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  25.     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  26.     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
  27.     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  28.     SPI_InitStructure.SPI_CRCPolynomial = 7;
  29.     SPI_Init(SPI1, &SPI_InitStructure);
  30.     SPI_Cmd(SPI1, ENABLE);

  31. }

  32. uint8_t SPI1_ReadWriteByte(uint8_t data)
  33. {               
  34.         uint8_t retry = 0;                                        
  35.         while ((SPI1->STATR & SPI_I2S_FLAG_TXE) == RESET)
  36.         {
  37.                 retry ++;
  38.                 if(retry > 200)return 0;
  39.         }                          
  40.         SPI1->DATAR = data;
  41.         retry=0;

  42.         while ((SPI1->STATR & SPI_I2S_FLAG_RXNE) == RESET)
  43.         {
  44.                 retry ++;
  45.                 if(retry > 200)return 0;
  46.     }
  47.         return SPI1->DATAR;
  48. }

  49. void SX1276_Init(uint32_t fre , uint8_t bw)
  50. {   
  51.     xLORA.InitOK = 0;
  52.     LoRaSettings.RFFrequency = fre * 1000 * 1000;
  53.     LoRaSettings.SpreadingFactor = 11;
  54.     LoRaSettings.SignalBw = bw;
  55.    
  56.     SX1276_Reset();   

  57.         SX1276Read(0x06, ®Temp ,1);
  58.         while(regTemp != 0x6C)
  59.         {
  60.             printf("SX1276_Init error.\n");
  61.             Delay_ms(300);
  62.         }
  63.    
  64.     SX1276_SetOpMode(RFLR_OPMODE_SLEEP);

  65.     SX1276Read(0x01, ®Temp , 1);
  66.     printf("0x01 regTemp = 0x%x\n" , regTemp);
  67.     regTemp |= 0x80 ;        
  68.     SX1276Write( 0x01, ®Temp , 1);
  69.     SX1276Read (0x01, ®Temp , 1);
  70.         printf("0x01 regTemp = 0x%x\n" , regTemp);
  71.    
  72.     regTemp  = RFLR_LNA_GAIN_G1;
  73.     SX1276Write ( REG_LR_LNA , ®Temp , 1);
  74.    
  75.     SX1276LoRaSetRFFrequency(LoRaSettings.RFFrequency);
  76.     SX1276LoRaSetSpreadingFactor(LoRaSettings.SpreadingFactor);
  77.     SX1276LoRaSetErrorCoding(LoRaSettings.ErrorCoding);
  78.     SX1276LoRaSetPacketCrcOn(LoRaSettings.CrcOn);
  79.     SX1276LoRaSetSignalBandwidth(LoRaSettings.SignalBw);

  80.     SX1276LoRaSetImplicitHeaderOn(LoRaSettings.ImplicitHeaderOn );
  81.     SX1276LoRaSetSymbTimeout(0x3FF);
  82.         
  83.     SX1276Write( 0x22, &LoRaSettings.PayloadLength , 1 );
  84.    
  85.     SX1276LoRaSetLowDatarateOptimize( true );
  86.    
  87.     SX1276LoRaSetPAOutput( RFLR_PACONFIG_PASELECT_PABOOST );
  88.    
  89.     regTemp = 0x87;
  90.     SX1276Write(REG_LR_PADAC , ®Temp , 1);
  91.     regTemp = 0x8F;   
  92.     SX1276Write(REG_LR_PACONFIG , ®Temp , 1);
  93.    
  94.     //SX1276Read (0x26, ®Temp , 1);
  95.     //regTemp = (regTemp & 0xF7) | ( 1<<3);
  96.     //SX1276Write (0x26, ®Temp, 1);      
  97.    
  98.     regTemp = 0xFF;
  99.     SX1276Write(REG_LR_IRQFLAGS ,®Temp, 1);

  100.     xLORA.InitOK = 1;   
  101.    
  102.     Lora_RxMode(0);
  103.     printf("SX1276_Init OK.\n");
  104. }  

SX1276使用外部中断进行发送缓冲区清零:
  1. __attribute__((interrupt(), weak)) void LORA_DIO0_HANDLER(void)
  2. {

  3.     EXTI_ClearITPendingBit(LORA_DIO0_PIN);
  4.     printf("LORA_DIO0_HANDLER xLORA.TxMode = %d xLORA.RxMode = %d\n" , xLORA.TxMode , xLORA.RxMode);
  5.     if(xLORA.TxMode == 1)   
  6.     {
  7.         printf("LORA_DIO0_HANDLER xLORA.TxMode = 1\n");
  8.         regTemp = 0xFF;
  9.         SX1276Write( 0x12, ®Temp , 1);                 
  10.         xLORA.TxMode = 0;
  11.                  
  12.         Lora_RxMode(0);
  13.         xLORA .RxMode = 1;
  14.               
  15.         return;
  16.     }
  17.    
  18.     if(xLORA.RxMode == 1)
  19.         {            
  20.         regTemp = 0xFF;
  21.         SX1276Write( 0x12, ®Temp ,1 );           
  22.    
  23.         if( LoRaSettings.ImplicitHeaderOn == true )
  24.                 RxSize = LoRaSettings.PayloadLength ;      
  25.         else
  26.                 SX1276Read( REG_LR_NBRXBYTES, &RxSize, 1 );
  27.         
  28.         SX1276Read( REG_LR_FIFORXCURRENTADDR, ®Temp ,1);
  29.         SX1276Write( REG_LR_FIFOADDRPTR, ®Temp ,1 );
  30.         SX1276Read(0, RxBuffer, RxSize );   
  31.                
  32.         printf("RxSize %d RxBuffer: %s\r" , RxSize , RxBuffer);   
  33.         }
  34. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

56

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

8

主题

56

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部