[i=s] 本帖最后由 宇岚 于 2025-5-14 19:21 编辑 [/i]<br />
<br />
#申请原创# #技术资源# 
一、简介
随着科技持续进步,人们对于健康的要求越来越高,智能可穿戴手表应运而生;本项目旨在使用常见不同模块实现简易的智能手表框架,主控选型上采用极海半导体推出的工业级基础拓展型MCU:APM32E030R8T6,这款MCU集成搭载 Arm® Cortex®-M0 + 内核,工作主频 72MHz,采用 12 寸 55nm 先进工艺,具有内置 64KB Flash、8KB SRAM、2 个 I2C、2 个 USART、2个 位高精度 ADC 等丰富资源,符合本次项目要求;
二、系统框图
本项目使用APM32E030R8T6作为主控,使用到的模块有:DS18B20、MAX30102、ATGM336H以及ADXL345等,可实现温度、血压、血氧的测量、GPS定位、计时功能以及步数感应功能;

三、模块实现
下面将从模块原理、硬件设计和程序设计三部分详细介绍各个模块的实现思路:
温度传感器
温度获取功能使用的是DS18B20,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点.
模块工作原理
DS18B20作为单线半双工通信,共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1;

复位脉冲:主机输出低电平保持至少480us,然后释放总线,电平拉高保持15~60us;

应答信号:DS18B20拉低电平保持60~240us;

写时序:写"0" 输出低电平60us,释放总线延迟2us; 写"1" 输出低电平2us,释放总线延迟60us;

读时序:输出电平延时2us,转输入模式延时12us,读取总线电平(15us以内),延时50us;

硬件设计

引脚描述:
| 引脚名称 | 描述 | 
| VCC | 供给电压5V | 
| GND | 地线 | 
| I/O | 通信引脚,接PA12 | 
程序设计
第一步,模块初始化,初始化PA12引脚,配置其为上拉推挽模式;
u8 DS18B20_Init(void)
{
    GPIO_Config_T  GPIO_InitStructure;
    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);  //使能PORTA口时钟 
    GPIO_InitStructure.pin = GPIO_Pin_12;               //PORTA12 推挽输出
    GPIO_InitStructure.mode = GPIO_Mode_Out_PP;         //配置为输出 
    GPIO_InitStructure.speed = GPIO_Speed_50MHz;
    GPIO_Config(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_PIN_12);    //输出12
    DS18B20_Rst();
}
第二步,复位模块,先拉低PA12引脚5ms,再拉高PA12引脚保持5ms;
第三步,发送指令0xCC,跳过ROM是,再发送指令0x44,开启转换,最后发送0xBE,读取数据;
short DS18B20_Get_Temp(void)
{
    u8 temp;
    u8 TL,TH;
    short tem;
    DS18B20_Start ();                   // ds1820 start convert
    delay_ms(5);                    //延迟5ms
    DS18B20_Rst();                      //ds18b20 复位
    delay_ms(5);                    //延迟5ms
    DS18B20_Check();     
    DS18B20_Write_Byte(0xcc);           // 发送0xCC
    DS18B20_Write_Byte(0x44);           // 发送0x44
    DS18B20_Write_Byte(0xbe);           // 发送0xBE     
    TL=DS18B20_Read_Byte();             // LSB   
    TH=DS18B20_Read_Byte();             // MSB  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;//温度为负  
    }else temp=1;//温度为正       
    tem=TH; //获得高八位
    tem<<=8;  
    tem+=TL;//获得底八位
    tem=(float)tem*0.625;//转换   
    if(temp)return tem; //返回温度值
    else return -tem;  
}
第四步,读取两个字节 TH 和 TL ;
第五步,根据DS18B20的温度运算法则进行数据处理;
至此,DS18B20模块读取温度功能实现;
GPS定位模块
ATGM336H是一种高性能的GPS模块,可以在较低功耗下提供高精度、高可靠性的位置信息服务。它采用了SiRFstarIII技术,并支持多种导航卫星系统,包括GPS、GLONASS、Galileo、QZSS和SBAS。ATGM336H可以快速获取卫星信号,提供高达10Hz的位置刷新速率,并能在较弱的GPS信号环境下保持高精度。
模块工作原理
我们将模块的TX和RX通过串口通信串口助手,ATGM336H利用串口发送定位信息给主控芯片,串口波特率为9600,可以看到,模块会通过串口不断打印**数据;**

其中信息头的第一个是消息ID,通过查阅芯片手册,简单的含义如下:
| 缩写标识符 | 含义 | 
| BD | BDS,北斗二代卫星系统 | 
| GP | GPS | 
| GL | GLONASS | 
| GA | Galileo | 
| GN | GNSS,全球卫星导航系统 | 
需要关注其中的“GNRMC”这条信息,将这条信息解析:
$GNRMC,015135.000,A,4159.65553,N,12136.79345,E,0.52,0.00,191123,,,A*7F
- 消息ID —— \$GNRMC
- 定位点的UTC时间 —— 015135.000
- 定位状态 —— A:定位;V:导航(我们进行定位时,如果该位为A表示数据有效,该位为V表示数据无效)
- 纬度 —— 4159.65553
- 纬度方向 —— N
- 经度 —— 12136.79345
- 经度方向 —— E
硬件设计
实物图如下

引脚定义以及接线如下表所示
| 引脚名称 | 描述 | 
| VCC | 电源(3.3V-5V) | 
| GND | 地线 | 
| TXD | 发送引脚,接PA9 | 
| RXD | 接收引脚,接PA10 | 
| PPS | 时钟脉冲引脚,PA11 | 
软件设计
第一步,初始化模块,初始化USART1模块的两个引脚PA9和PA10,配置串口波特率为9600;
第二步,等待ATGM336H信号连接成功,当连接成功时,PPS引脚会拉低再拉高;
void ATGM336_Baisc_Init(void)  //模块信号引脚初始化  
{
      GPIO_Config_T GPIO_InitStructure;     //定义一个设置GPIO功能的变量
      RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);   //使能GPIOA时钟
      uart1_Init(9600);  //串口初始化
      GPIO_InitStructure.pin = GPIO_Pin_11;              //准备设置PA11
      GPIO_InitStructure.speed = GPIO_Speed_50MHz;      //IO速率50M
      GPIO_InitStructure.mode = GPIO_Mode_IPD;              //下拉输入
      GPIO_Config(GPIOA, &GPIO_InitStructure);                 //设置PA11
}
void ATGM336_Init(void)
{
    int i; 
    uart1_Init(9600);  //USART1初始化
        bool Point_flag;
        while(!GPIO_ReadInputBit(GPIOA,GPIO_Pin_11))  //等待PPS引脚拉低
    {
            if(Point_flag == 0){  //显示函数
            for(i=0;i<11;i++)
        {
                for(i=0;i<11;i++)OLED_ShowChar(0+(i*4),7,' ',1,0);delay_ms(10);
                Point_flag = 1;
        }
        }
        else
        {     //显示函数
            for(i=0;i<11;i++){OLED_ShowChar(0+(i*4),7,' ',1,0);}
            Point_flag = 0;
            delay_ms(10);
        }
        if(setc == 0)
            break;////如果拉低,跳出循环
    }
            if(GPIO_ReadInputBit(GPIOA,GPIO_Pin_11))//改变标志位
                GPS_state   = 1;
            for(i=0;i<9;i++){OLED_ShowChar(0+(i*4),7,' ',1,0);}
}
第三步,USART模块接收信息并解析
void GetsGpsBuffer()
{
    char *subString;
    char *subStringNext;
    char i = 0;
    char usefullBuffer[2];
    if (Save_Data.isGetData)
    {
        Save_Data.isGetData = false;
        //截取数据帧前六部分                              |对地航速 对地航向  日期
        //$GNRMC,112536.000,A,2322.75023,N,11326.28605,E,|  0.00,   0.00,  100722,,,A*78
        for (i = 0; i <= 6; i++)
        {
            if (i == 0)
            {
                if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
                    errorLog(1); // 解析错误
            }
            else
            {
                subString++;
                if ((subStringNext = strstr(subString, ",")) != NULL)
                {
                    switch (i)
                    {
                                        // 获取UTC时间
                    case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break; 
                                        // 获取UTC时间
                    case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break; 
                                        // 获取纬度信息
                    case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break; 
                                        // 获取N/S
                    case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;
                                        // 获取经度信息
                    case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break; 
                                        // 获取E/W
                    case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break; 
                    default:break;
                    }
                    subString = subStringNext;
                    Save_Data.isParseData = true;
                    if (usefullBuffer[0] == 'A')
                        Save_Data.isUsefull = true;
                    else if (usefullBuffer[0] == 'V')
                        Save_Data.isUsefull = false;
                }
                else
                {
                    errorLog(2); // 解析错误
                }
            }
        }
    }
}
第四步,数据转换,获取的信息里,单位是**“度-分”,需要将其转换为常用单位“度”;
void Data_Transfor (void)
{
    float latitude_temp1,latitude_temp2_min,latitude = 0, ;    // 存储纬度信息
    float longitude_temp1,longitude_temp2_min,longitude = 0;   // 存储经度信息
    latitude = strtod(receDataFrame.latitude,NULL);             // 字符串转换成浮点数
    longitude = strtod(receDataFrame.longitude,NULL);           // 字符串转换成浮点数
    // 纬度信息处理
    latitude_temp1 = (uint16_t)latitude/100;                         //提取度-分中度的不分
    latitude_temp2_min = (latitude%100 )/60                 //提取度-分中,分的部分并将其转为度
    latitude = (float)latitude_temp1 + latitude_temp2_min;
    // 经度信息处理
    // 五位经度信息
    longitude_temp1 = (uint16_t)longitude/100;                           //提取度-分中度的不分
    longitude_temp2_min = (longitude%100 )/60               //提取度-分中,分的部分并将其转为度
    latitude = (float)longitude_temp1 + longitude_temp2_min;
}
至此,GPS模块功能实现完成
四、文献出处
1.本片所涉及软件代码基于APM32E030官方SDK库,可在官网直接下载使用;
https://www.geehy.com/design/document
2.本问所设计参考文章有:
https://blog.csdn.net/qq_44016222/article/details/141892460?ops_request_misc=%257B%2522request%255Fid%2522%253A%252200602cae32b01e8caf708299723effe6%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=00602cae32b01e8caf708299723effe6&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-141892460-null-null.142^v102^pc_search_result_base6&utm_term=max30102%E5%BF%83%E7%8E%87%E8%A1%80%E6%B0%A7%E4%BC%A0%E6%84%9F%E5%99%A8&spm=1018.2226.3001.4187    -----MAX30102心率血氧传感器(IIC协议 STM32)-CSDN博客
https://blog.csdn.net/qq_44016222/article/details/141891589?ops_request_misc=%257B%2522request%255Fid%2522%253A%25225a1bfb03841971f12cfefecb83cbb8c1%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=5a1bfb03841971f12cfefecb83cbb8c1&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-141891589-null-null.142^v102^pc_search_result_base6&utm_term=ADXL345&spm=1018.2226.3001.4187
-----【STM32外设系列】GPS定位模块(ATGM336H)-CSDN博
3.由于篇幅原因,该项目分为上下两章详细描述;