This commit is contained in:
Qiea
2024-12-19 14:06:05 +08:00
parent 1c0f3b676f
commit dcd484c1bd
58 changed files with 14859 additions and 863 deletions

416
HARDWARE/EC800/EC800M.c Normal file
View File

@@ -0,0 +1,416 @@
#include "EC800M.h"
#include "usart.h"
#include "delay.h"
#include "sdram.h"
#include "stm32f4xx.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include "cnn.h"
unsigned char Flag_topic;
extern UART_BUF buf_uart2; //NBIOT
extern UART_BUF buf_uart1; //TTL
char *strx,*extstrx;
CSTX_4G CSTX_4G_Status; //模块的状态信息
int errcount=0; //发送命令失败次数 防止死循环
int errCountData=0;
char ATSTR[BUFLEN]; //组建AT命令的函数
char IMEINUMBER[BUFLEN];//+CGSN: "869523052178994"
#define DESTINATION_SIZE 256
char *strx,*extstrx;
char destination[DESTINATION_SIZE];
/*云端下发的时间*/
int month_def = 1;
int date_def = 0;
int hour_def = 0;
int min_def = 0;
int sec_def= 0;
////////////////////////只要修改三要素/////////////////////////////////
#define PRODUCEKEY "k16dsL76w8K" //修改产品秘钥
#define DEVICENAME "device_1" //修改设备名称
#define DEVICESECRET "b36d0f9e35c7fede452a85c59473a411" //设备的API
void Clear_Buffer(uint16_t *USARTx_RX_STA, uint8_t *USARTx_RX_BUF) {
delay_ms(300);
memset(USARTx_RX_BUF, 0, USART_REC_LEN);
*USARTx_RX_STA = 0;
}
void extract_IMSI(uint8_t *input_str, char *output_str) {
char *start_ptr = strstr((char *)input_str, "460");
if (start_ptr != NULL) {
strncpy(output_str, start_ptr, 15);
output_str[15] = '\0'; // 添加字符串结束符
} else {
output_str[0] = '\0';
}
}
/*****************************************************
初始化模块 和单片机连接,获取卡号和信号质量
*****************************************************/
uint8_t CSTX_4G_Init(void)
{
//打印初始化信息
printf("start init EC800X\r\n");
//发第一个命令ATE1
Uart2_SendStr("ATE1\r\n");
delay_ms(200);
strx = strstr((char*)USART2_RX_BUF, "OK");
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
while(strx==NULL)
{
printf("单片机正在连接模块......\r\n");
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("\n\rATE1\r\nATE1");
delay_ms(300);
strx = strstr((char*)USART2_RX_BUF, "OK");
// if(errcount++ > 10) {
// printf("\r\n未连接到模块\r\n");
// return 0;
// }
}
printf("****单片机和模块连接成功*****\r\n");
Uart2_SendStr("ATI\r\n");//获取模块的版本
delay_ms(30);
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
delay_ms(30);
strx = strstr((char*)USART2_RX_BUF, "460");
while(strx==NULL)
{
printf("****获取卡号*****\r\n");
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
delay_ms(30);
strx = strstr((char*)USART2_RX_BUF, "460");
printf("%s",USART2_RX_BUF);
}
char output_str[16];
extract_IMSI(USART2_RX_BUF, output_str);
printf("我的卡号是 : %s \r\n",output_str);
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+CGATT?\r\n");//查询激活状态
delay_ms(30);
strx = strstr((char*)USART2_RX_BUF, "+CGATT: 1");
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
while(strx==NULL)
{
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+CGATT?\r\n");//获取激活状态
delay_ms(30);
strx = strstr((char*)USART2_RX_BUF, "+CGATT: 1");
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+CSQ\r\n");//查看获取CSQ值
delay_ms(30);
strx = strstr((char*)USART2_RX_BUF, "+CSQ:");
if(strx)printf("信号质量是:%s 注意信号最大值是31 \r\n",USART2_RX_BUF);
return 1;
}
/*****************************************************
收到服务器下发的数据就直接打印 +QMTRECV: 0,0,"$creq/a19d2d64-3ee3-5070-8078-ad43e10a52f0","LED11"
*****************************************************/
unsigned char CSTX_4G_RECData(void)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"+QMTRECV");//返回+QMTRECV:,表明接收到服务器发回的数据
if(strx)
{
delay_ms(300); // 必须延时
strncpy(destination, (char *)USART2_RX_BUF, DESTINATION_SIZE - 1);
destination[DESTINATION_SIZE - 1] = '\0';
TimeInfo TimeInfo = parseTimeInfo(destination);
month_def =TimeInfo.month;
date_def =TimeInfo.day;
hour_def =TimeInfo.hour;
min_def =TimeInfo.minute;
sec_def =TimeInfo.second;
printf(" Month: %d, Day: %d, Hour: %d, Minute: %d, Second: %d\r\n",
TimeInfo.month, TimeInfo.day, TimeInfo.hour, TimeInfo.minute, TimeInfo.second);
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
return 1;
}
return 0;
}
/*****************************************************
注册到ONENET topic = 0 -> 自定义topic 用于准备接收下发的时间 topic = 1 -> 物模型topic 用于上传数据
*****************************************************/
void CSTX_4G_RegALiYunIOT(unsigned char topic)//平台注册
{
int errcount = 0;
static unsigned char flag=0;
if(flag == 0){
printf("****初始化完成*****\r\n\r\n");
Uart2_SendStr("AT+QMTDISC=0\r\n");//Disconnect a client from MQTT server
delay_ms(30);
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+QMTCLOSE=0\r\n");//删除句柄
delay_ms(30);
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
delay_ms(30);
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+QMTCFG=\"version\",0,4\r\n");//切换下版本
delay_ms(30); //等待300ms反馈OK
strx = strstr((char*)USART2_RX_BUF, "OK");
while(strx==NULL)
{
strx = strstr((char*)USART2_RX_BUF, "OK");
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
memset(ATSTR,0,BUFLEN);
sprintf(ATSTR,"AT+QMTCFG=\"ALIAUTH\",0,\"%s\",\"%s\",\"%s\"\r\n",PRODUCEKEY,DEVICENAME,DEVICESECRET); //+QMTCONN: 0,0,0
printf("ATSTR = %s \r\n",ATSTR);
Uart2_SendStr(ATSTR);
delay_ms(30);
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTOPEN: 0,0 +QMTOPEN: 0,0
while(strx==NULL)
{
errcount++;
delay_ms(30);
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返回OK
if(errcount>10000) //防止死循环
{
NVIC_SystemReset(); //没有创建TCP SOCKET就重启系统等到服务器就绪
}
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883\r\n");//切换下版本
delay_ms(30); //等待300ms反馈OK
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返OK
while(strx==NULL)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返OK
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Uart2_SendStr("AT+QMTCONN=0,\"-test-\"\r\n");//切换下版本
delay_ms(30); //等待300ms反馈OK
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返OK
while(strx==NULL)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返OK
printf("连接中……\r\n");
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
}
flag = 1;
if(topic == 0){
if(Flag_topic == 1){
memset(ATSTR,0,BUFLEN);
sprintf(ATSTR,"AT+QMTUNS=0,100,\"/%s/%s/user/Set_time\"\r\n",PRODUCEKEY,DEVICENAME); //+QMTCONN: 0,0,0
printf("ATSTR = %s \r\n",ATSTR);
Uart2_SendStr(ATSTR);//发送链接到阿里云
delay_ms(30);
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
while(strx==NULL)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
}
memset(ATSTR,0,BUFLEN);
sprintf(ATSTR,"AT+QMTSUB=0,1,\"/%s/%s/user/Set_time\",0\r\n",PRODUCEKEY,DEVICENAME); //+QMTCONN: 0,0,0
printf("ATSTR = %s \r\n",ATSTR);
Uart2_SendStr(ATSTR);//发送链接到阿里云
delay_ms(30);
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
while(strx==NULL)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Flag_topic = 0;
}
else if(topic == 1){
memset(ATSTR,0,BUFLEN);
sprintf(ATSTR,"AT+QMTUNS=0,100,\"/%s/%s/user/Set_time\"\r\n",PRODUCEKEY,DEVICENAME); //+QMTCONN: 0,0,0
printf("ATSTR = %s \r\n",ATSTR);
Uart2_SendStr(ATSTR);//发送链接到阿里云
delay_ms(30);
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
while(strx==NULL)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
memset(ATSTR,0,BUFLEN);
sprintf(ATSTR,"AT+QMTSUB=0,1,\"/%s/%s/thing/event/property/set\",0\r\n",PRODUCEKEY,DEVICENAME); //+QMTCONN: 0,0,0
printf("ATSTR = %s \r\n",ATSTR);
Uart2_SendStr(ATSTR);//发送链接到阿里云
delay_ms(30);
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
while(strx==NULL)
{
strx=strstr((const char*)USART2_RX_BUF,(const char*)"OK");//返+QMTCONN: 0,0,0
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
Flag_topic = 1;
}
}
uint16_t MakeALiYunPayload_s(char *Str,char *Data, const char* identifier)
{
// Onenet有效载荷固定格式的模板
const char PayloadTemplate[60] = "{\"id\":\"123\",\"version\":\"1.0\",\"params\":{\"%s\":{\"value\":\"%s\"}}}";
char JsonBuf[BUFLEN]; // 临时数据缓存
unsigned int StrLen; // 有效载荷数据长度
// 使用snprintf将Data和identifier插入到PayloadTemplate中
snprintf(JsonBuf,sizeof(JsonBuf),PayloadTemplate,identifier,Data);
// 计算有效载荷的数据长度
StrLen = strlen((const char*)JsonBuf); // strlen返回的是字节数无需再除以sizeof(char)
// 拷贝有效载荷数据到Str
memcpy(Str, JsonBuf, StrLen);
// 返回长度
return StrLen;
}
void convert_to_string(uint8_t *Send_Json, char *output_str, size_t length)
{
// 将 uint8_t 数组转换为字符串
memcpy(output_str, Send_Json, length);
output_str[length] = '\0'; // 添加字符串结束符
}
void CSTX_4G_ALiYunIOTSenddata_string(char *Data,const char* identifier)//上发数据,上发的数据跟对应的插件有关系,用户需要注意插件然后对应数据即可
{
static char Send_buff[BUFLEN];//AT命令临时缓存
u16 JsonLen; // Json包数据长度
memset((char *)Send_buff, 0, BUFLEN); // 开辟数据缓存 //开辟数据缓存 sprintf((char*)Json,"{\"Temp\":%d,\"Humi\":%d}",Temperature,Humidity);//拷贝数据 装订联网三要素 Temperature,Humidity
memset(ATSTR,0,BUFLEN);
JsonLen = MakeALiYunPayload_s(Send_buff,Data, identifier); //得到json
memset(ATSTR,0,BUFLEN);
sprintf(ATSTR,"AT+QMTPUBEX=0,0,0,0,\"/sys/%s/%s/thing/event/property/post\",%d\r\n",PRODUCEKEY,DEVICENAME,JsonLen);
printf("ATSTR = %s \r\n",ATSTR);
Uart2_SendStr(ATSTR);//mqtt订阅
strx=strstr((const char*)USART2_RX_BUF,(const char*)">");//准备发送数据
errcount=0;
while(strx==NULL)
{
errcount++;
strx=strstr((const char*)USART2_RX_BUF,(const char*)">");//准备发送数据 模块的反馈
delay_ms(10);
if(errcount>100) //超时退出
{
errcount = 0;
break;
}
}
printf("Data数据为:%s\r\n",Send_buff);
delay_ms(50);
Uart2_SendStr(Send_buff);
// 发送JSON数据
delay_ms(50);
// 等待发送完成响应
errcount = 0;
strx = strstr((const char*)USART2_RX_BUF, (const char*)"+QMTPUBEX: 0,0,0"); // 返SEND OK +QMTPUB: 0,0,0
while (strx == NULL)
{
errcount++;
strx = strstr((const char*)USART2_RX_BUF, (const char*)"+QMTPUBEX: 0,0,0"); // 返SEND OK
delay_ms(100);
if (errcount > 10) // 超时退出
{
printf("发送数据超时!\n");
errcount = 0;
break;
}
}
Clear_Buffer(&USART2_RX_STA, USART2_RX_BUF);
}
// 解析函数实现
TimeInfo parseTimeInfo(const char *jsonString) {
TimeInfo TimeInfo = {0}; // 初始化结构体为0
// 查找JSON字符串中"params"部分的起始位置
const char *paramsStart = strstr(jsonString, "\"params\"");
if (paramsStart != NULL) {
// 创建一个临时缓冲区来复制JSON的"params"部分(注意,这里为了简化处理,直接使用了静态缓冲区)
char TempBuffer[256];
strncpy(TempBuffer, paramsStart, sizeof(TempBuffer) - 1);
TempBuffer[sizeof(TempBuffer) - 1] = '\0';
// 使用简单的字符串解析来提取时间信息(注意,这种方法很脆弱,仅适用于格式固定的字符串)
char *token;
token = strtok(TempBuffer, ",\"{}:");
while (token != NULL) {
if (strcmp(token, "date") == 0) {
token = strtok(NULL, ",\"{}:");
TimeInfo.day = atoi(token); // JSON中"date"实际上是日这里暂存到day字段
} else if (strcmp(token, "month") == 0) {
token = strtok(NULL, ",\"{}:");
TimeInfo.month = atoi(token);
} else if (strcmp(token, "year") == 0) {
// JSON中没有直接的"year"字段,但我们可以从其他信息中推断,或者假设一个默认的年份(这里不处理)
// 或者如果"date"和"month"存在,且你有某种方式知道是哪一年(比如当前年份),你可以在这里设置它
} else if (strcmp(token, "hour") == 0) {
token = strtok(NULL, ",\"{}:");
TimeInfo.hour = atoi(token);
} else if (strcmp(token, "minute") == 0) {
token = strtok(NULL, ",\"{}:");
TimeInfo.minute = atoi(token);
} else if (strcmp(token, "second") == 0) {
token = strtok(NULL, ",\"{}:");
TimeInfo.second = atoi(token);
}
token = strtok(NULL, ",\"{}:");
}
// 注意:上面的代码没有处理"year"字段因为你的示例JSON中没有提供。
// 你需要根据实际情况来处理这个字段,比如使用当前年份,或者从其他来源获取年份信息。
// 这里为了示例我们假设年份是固定的比如2024年你可以在实际代码中修改这个值。
TimeInfo.year = 2024; // 假设的年份,根据实际情况修改
}
return TimeInfo;
}
///重定向c库函数scanf到串口重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{ RX1_len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
/* 等待串口输入数据 */
while (__HAL_UART_GET_FLAG(&UART1_Handler, UART_FLAG_RXNE) == RESET);
//while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return (int)HAL_UART_Receive(&UART1_Handler,(uint8_t*)USART_RX_BUF,RX1_len,1000);
//return (int)USART_ReceiveData(USART1);
}

44
HARDWARE/EC800/EC800M.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef __EC800M_H
#define __EC800M_H
#include "stm32f4xx.h"
#include "string.h"
#include "sys.h"
#include "string.h"
#include "stdio.h"
#include "usart.h"
extern unsigned char Flag_topic;
typedef struct
{
uint8_t CSQ;
uint8_t Socketnum; //编号
uint8_t reclen; //获取到数据的长度
uint8_t res;
uint8_t recdatalen[10];
uint8_t recdata[100];
uint8_t netstatus;//网络指示灯
} CSTX_4G;
typedef struct {
int year;
int month;
int day;
int hour;
int minute;
int second;
}TimeInfo;
void Clear_Buffer(uint16_t *USARTx_RX_STA, uint8_t *USARTx_RX_BUF);
uint8_t CSTX_4G_Init(void);
void CSTX_4G_CreateTCPSokcet(void);
void CSTX_4G_Senddata(int len,uint8_t *data);
void CSTX_4G_RegALiYunIOT(unsigned char topic);//平台注册
uint16_t MakeALiYunPayload_s(char *Str,char *Data, const char* identifier);//上发数据,上发的数据跟对应的插件有关系,用户需要注意插件然后对应数据即可
char* Get_4GIMEI_NUM(void); //获取IMEI号
unsigned char CSTX_4G_RECData(void);
void extract_IMSI(uint8_t *input_str, char *output_str);
void CSTX_4G_ALiYunIOTSenddata_string(char *Data,const char* identifier);
TimeInfo parseTimeInfo(const char *jsonString);
#endif