项目是尚硅谷发的开源项目,想学习的去b站搜索即可

宠物定位器项目

1. 项目硬件介绍

我会在嘉立创画出部分原理图,方便自己学习,到时候上传到github.

1.1MCU部分

采样stm32f103c8t6,这个没什么好介绍的,

2. 项目软件部分

2.1串口调试部分

  1. 首先需要串口重定向,这是是hal库,就这样写就行了
1
2
3
4
5
6
/*重写fput函数,重定向到串口*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,1000);
return ch;
}
  1. 这里有一个小技巧,就是可以打印文件名,和打印在哪儿一行,方便调试

需要说的是

1
2
3
4
__FILE__   //代码文件名
__TIME__ //代表时间
__LINE__ //代表行号
##__VA_ARGS__ //代表不定长数据
1
2
3
4
5
6
7
8
9
#define FILE__NAME \
(strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#define __FILE__NAME__ \
(strchr(FILE__NAME,'/') ? strchr(FILE__NAME,'/') + 1 : FILE__NAME)


#define debug_println(format, ...) \
printf("[%s:%d]" format "\r\n",__FILE__NAME__,__LINE__,##__VA_ARGS__)

  1. 串口接收不定长数据,这里,是个小技巧,大概就是定义两个缓存区,先接收数据,存到缓存区,再把数据拷贝到另一个缓存

这里我列出了部分代码。接收不定长数据关键在于,HAL_UARTEx_ReceiveToIdle这个函数,它可以保持接收数据的长度。

1
2
3
4
uint8_t  gps_buff[GPS_BUFF_LEN];
uint16_t gps_buff_len;
uint8_t gps_double_buff[GPS_DOUBLE_BUFF_LEN];
uint16_t gps_double_buff_len;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void Int_AT6558R_Read_GPS(void)
{
/*清空缓存*/
memset(gps_double_buff,0,sizeof(gps_double_buff));
gps_double_buff_len = 0;

while (1)
{
HAL_UARTEx_ReceiveToIdle(&huart2,gps_buff,GPS_BUFF_LEN,&gps_buff_len,1000);
if((strstr((char*)gps_double_buff,"GGA") != NULL) &&
(strstr((char*)gps_double_buff,"TXT") != NULL) )
{
break;
}
if(gps_buff_len > 0)
{
memcpy(&gps_double_buff[gps_double_buff_len],gps_buff,gps_buff_len);
gps_double_buff_len += gps_buff_len;
memset(gps_buff,0,sizeof(gps_buff));
gps_buff_len = 0;
}
}
debug_println("\n%s", gps_double_buff);
}

2.2 gps模块

  1. 首先gps模块,采用串口进行通信,它需要遵守NMEA协议

1. NMEA协议

可以看到,每一次数据帧的格式都是$地址,数据,*校验和

像这样$PCAS00*01

本次数据就用到了以下的命令

1
2
3
#define AT6558R_FREQ "PCAS02,1000"  //设置定位更新率
#define AT6558R_MODE "PCAS04,3" //配置工作系统 北斗和 GPS 双模
#define AT6558R_INFO "PCAS06,2" //查询产品信息
  1. 校验和算法就是,地址,数据的异或,可以这么来算,首先我们发送的命令是字符串,最后一个是\0结尾,只要检测到\0,就停止计算
1
2
3
4
5
uint8_t tmp = 0;
for(uint8_t i = 0; cmd[i] != '\0'; i++)
{
tmp ^= cmd[i];
}
  1. 拼接字符串

sprintf 它可以将字符串拼接起来,需要头文件stdio.h

2.工作流程

首先使能GPS_EN ,高电平有效,配置串口, 波特率9600,其他默认

2.3 计步器

  1. 首先它采用i2c协议通信,这里使用硬件I2C,更简单

硬件i2c相关的api函数如下

1
2
HAL_I2C_Mem_Read()
HAL_I2C_Mem_Write()

2. 4 NB_LOT 模块

2.5 W5500模块

2.6 CJSON解析

2.7 RTC和时间戳