keil5,stc89c52rc,esp8266-01s,串口
用keil5写串口,以便发送AT指令,飞燕平台接收解析到温度值,实现用云智能远程查看温度值,当然,这只是串口的代码,
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include "DS18B20.h"
#define uchar unsigned char //0-255
void UartInit(void)
{
SCON = 0x50; //串口工作模式1
TMOD &= 0x0F; //清空定时器1模式位
TMOD |= 0x20; //设置定时器1为模式2(8位自动重装载)
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
TR1 = 1; //启动定时器1
}
//串口延时
void delay_uart(short ms)
{
short i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 1141; j++);
}
}
// 串口发送单个字符
void uartSendChar(unsigned char c)
{
SBUF = c;
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志
}
// 串口发送字符串
void uartSendString(const char* str)
{
while (*str)
{
uartSendChar(*str++);
}
}
void Send_AT_Cmd()
{
uartSendString("AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"\r\n");
delay_uart(300);
uartSendString("AT+MQTTUSERCFG=0,1,\"NULL\",\"vyjNlubh0QeZW06dprJi&a1EekF90GyL\",\"c199f60d4f0b08a7ca7e2ccbcb193b1e93ff8e10d677eebbb991fea908dd92c9\",0,0,\"\"\r\n");
delay_uart(300);
uartSendString("AT+MQTTCLIENTID=0,\"a1EekF90GyL.vyjNlubh0QeZW06dprJi|securemode=2\\,signmethod=hmacsha256\\,timestamp=1681564451348|\"\r\n");
delay_uart(300);
uartSendString("AT+MQTTCONN=0,\"a1EekF90GyL.iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883,1\r\n");
delay_uart(300);
uartSendString("AT+MQTTSUB=0,\"/sys/a1EekF90GyL/vyjNlubh0QeZW06dprJi/thing/service/property/set\",1\r\n");
delay_uart(300);
}
void printTemp(float temp)
{
char String_temp_at[128] = "AT+MQTTPUB=0,\"/sys/a1EekF90GyL/vyjNlubh0QeZW06dprJi/thing/event/property/post\",\"{params:{temperature:%.1f}}\",1,0\r\n";//字符串格式
char buffer[256]; // 缓冲区,用于存储转换后的字符串
sprintf(buffer, String_temp_at, temp); // 将温度值转换为字符串格式
uartSendString(buffer); // 发送字符串到串口
}
void main()
{
UartInit(); // 初始化串口
Send_AT_Cmd();
while (1)
{
float temp = ReadTemp()/10.0;
printTemp(temp);// 将温度值打印到串口
delay_uart(600); // 延时一段时间
}
}
1,换STC15F2K60S2系列单片机
2,如果有固定的数组变量,例如有些AT指令是固定的,将它的数组定义前面加上const,这样数组会存到FLASH,不会存到data与idata中
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:根据错误信息,您的代码中自动分配的内存段太大,导致编译失败。这可能是因为您的代码中使用了大量的局部变量和数组,导致栈空间不足。
为了解决这个问题,您可以考虑将一些局部变量和数组改为全局变量,并将其存储在外部RAM中(例如XRAM)。这样可以释放栈空间,从而避免自动分配的内存段过大的问题。
在Keil中,您可以使用"__xdata"关键字将变量定义为外部RAM中的变量。例如,以下代码定义了一个整数变量"count",并将其存储在外部RAM中:
__xdata int count;
请注意,在使用外部RAM时,需要将RAM的地址范围配置到您的芯片的存储器映射中。具体的配置方法和地址范围取决于您的芯片型号和硬件设计。
【修改后的完整代码如下】:
为了解决自动分配的内存段太大的问题,您可以将一些局部变量和数组改为全局变量,并将其存储在外部RAM中。以下是可能的修改方案:
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include "DS18B20.h"
#define uchar unsigned char //0-255
__xdata float temp; // 将温度值定义为全局变量,并存储在外部RAM中
void UartInit(void)
{
SCON = 0x50; //串口工作模式1
TMOD &= 0x0F; //清空定时器1模式位
TMOD |= 0x20; //设置定时器1为模式2(8位自动重装载)
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
TR1 = 1; //启动定时器1
}
//串口延时
void delay_uart(short ms)
{
short i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 1141; j++);
}
}
// 串口发送单个字符
void uartSendChar(unsigned char c)
{
SBUF = c;
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志
}
// 串口发送字符串
void uartSendString(const char* str)
{
while (*str)
{
uartSendChar(*str++);
}
}
void Send_AT_Cmd()
{
uartSendString("AT+CIPSNTPCFG=1,8,\"ntp1.aliyun.com\"\r\n");
delay_uart(300);
uartSendString("AT+MQTTUSERCFG=0,1,\"NULL\",\"vyjNlubh0QeZW06dprJi&a1EekF90GyL\",\"c199f60d4f0b08a7ca7e2ccbcb193b1e93ff8e10d677eebbb991fea908dd92c9\",0,0,\"\"\r\n");
delay_uart(300);
uartSendString("AT+MQTTCLIENTID=0,\"a1EekF90GyL.vyjNlubh0QeZW06dprJi|securemode=2\\,signmethod=hmacsha256\\,timestamp=1681564451348|\"\r\n");
delay_uart(300);
uartSendString("AT+MQTTCONN=0,\"a1EekF90GyL.iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883,1\r\n");
delay_uart(300);
uartSendString("AT+MQTTSUB=0,\"/sys/a1EekF90GyL/vyjNlubh0QeZW06dprJi/thing/service/property/set\",1\r\n");
delay_uart(300);
}
void printTemp()
{
char String_temp_at[128] = "AT+MQTTPUB=0,\"/sys/a1EekF90GyL/vyjNlubh0QeZW06dprJi/thing/event/property/post\",\"{params:{temperature:%.1f}}\",1,0\r\n";//字符串格式
char buffer[256]; // 缓冲区,用于存储转换后的字符串
sprintf(buffer, String_temp_at, temp); // 将温度值转换为字符串格式
uartSendString(buffer); // 发送字符串到串口
}
void main()
{
UartInit(); // 初始化串口
Send_AT_Cmd();
while (1)
{
temp = ReadTemp()/10.0;
printTemp();// 将温度值打印到串口
delay_uart(600); // 延时一段时间
}
}
在这个修改后的代码中,我们将温度值定义为全局变量"temp",并将其存储在外部RAM中。这样可以释放栈空间,避免自动分配的内存段过大的问题。我们还将"printTemp"函数的参数删除,因为它现在可以直接访问全局变量"temp"。
请注意,在使用外部RAM时,您需要将RAM的地址范围配置到您的芯片的存储器映射中。具体的配置方法和地址范围取决于您的芯片型号和硬件设计。
希望这个修改后的代码能够帮助您解决问题。如果您有其他问题或需要更多帮助,请随时提出。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:
第一个错误信息显示为“fatal error: #error directive: This memory model is not supported by this chip”, 这是因为选择的memory model与芯片不匹配导致的。需要根据芯片的内存结构来选择合适的memory model,否则会编译出错。
对于第二个问题,如果芯片不支持xdata类型,那么可以考虑使用其它的内存类型,如idata、pdata等。或者可以通过手动定义指针来操作需要使用xdata的变量,例如:
unsigned char xdata *p_xdata_var;
p_xdata_var = (unsigned char xdata *)0x8000; // 将指针指向xdata内存地址0x8000
*p_xdata_var = 0x12; // 将0x12写入xdata内存地址0x8000
这样可以在不使用xdata类型的情况下操作xdata内存,但需要注意指针的定义和使用。