基于RK3399&ESP8285自动售货柜项目—MP08开发板端代码详解

基于RK3399&ESP8285自动售货柜项目—②MP08开发板端代码详解

本系列文章将详细讲解该基于RK3399及ESP8285自动售货柜的完整实现方法,从硬件连接到网络通信再到软件实现,本产品所用开发板为RK3399以及MP08_2019/11/03 , 如有疑问与见解,可随时留言或评论

本系列以往文章列表:

基于RK3399&ESP8285自动售货柜项目—ESP8266(8285)程序编写与烧录 (zsxq.com)


上一篇我们讲解了如何搭建AiThinkIDE开发环境以及编写和烧录程序,那么这一篇我们来详细讲解本项目在MP08开发板上的代码实现原理,如果你手上也有这块板子,可以完全按照本系列文章来进行项目的实现

一、ESP开发代码结构

由于本项目不用过多深入学习ESP_SDK,故只用知道如何利用结构框架去编写想要的功能即可

我们先来看看官方例程代码:

/*跟其他C代码一样,这里放头文件,注意:AiThinkIDE没有标准C库函数,故没有如stdio.h 或者 string。h等,不要包含他们*/
#include "driver/uart.h"  //串口0需要的头文件
#include "osapi.h"  //串口1需要的头文件
#include "user_interface.h" //WIFI连接需要的头文件
#include "gpio.h"  //端口控制需要的头文件
#include "user_config.h"

/*这一长段条件编译不用管他是干嘛的,写程序放进来就行*/
#if ((SPI_FLASH_SIZE_MAP == 0) || (SPI_FLASH_SIZE_MAP == 1))
#error "The flash map is not supported"
#elif (SPI_FLASH_SIZE_MAP == 2)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0xfb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0xfc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0xfd000
#elif (SPI_FLASH_SIZE_MAP == 3)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x1fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x1fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x1fd000
#elif (SPI_FLASH_SIZE_MAP == 4)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x3fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x3fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x3fd000
#elif (SPI_FLASH_SIZE_MAP == 5)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x101000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x1fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x1fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x1fd000
#elif (SPI_FLASH_SIZE_MAP == 6)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x101000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x3fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x3fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x3fd000
#else
#error "The flash map is not supported"
#endif


void ICACHE_FLASH_ATTR user_init(void)
{
	//相当于main函数,一般放各类软硬件的初始化代码,为程序入口
}

//这个结构体定义也必须要,不用管他是干嘛的,SDK3.0规定必须要这一段
static const partition_item_t at_partition_table[] = {
    { SYSTEM_PARTITION_BOOTLOADER, 						0x0, 												0x1000},
    { SYSTEM_PARTITION_OTA_1,   						0x1000, 											SYSTEM_PARTITION_OTA_SIZE},
    { SYSTEM_PARTITION_OTA_2,   						SYSTEM_PARTITION_OTA_2_ADDR, 						SYSTEM_PARTITION_OTA_SIZE},
    { SYSTEM_PARTITION_RF_CAL,  						SYSTEM_PARTITION_RF_CAL_ADDR, 						0x1000},
    { SYSTEM_PARTITION_PHY_DATA, 						SYSTEM_PARTITION_PHY_DATA_ADDR, 					0x1000},
    { SYSTEM_PARTITION_SYSTEM_PARAMETER, 				SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR, 			0x3000},
};

//这一个函数也要放进来,直接复制就行
void ICACHE_FLASH_ATTR user_pre_init(void)
{
    if(!system_partition_table_regist(at_partition_table, sizeof(at_partition_table)/sizeof(at_partition_table[0]),SPI_FLASH_SIZE_MAP)) {
		os_printf("system_partition_table_regist fail\r\n");
		while(1);
	}
}

可以看到,整个代码结构就由这几部分构成,我们主要编写user_init函数里的内容,并且也可以自己定义想要的函数,函数名前的ICACHE_FLASH_ATTR表示的是函数地址存储位置在flash里,最好都加上

编写代码我们还需要去下载几个官方文档,里面有各种API函数用法介绍,本质跟STM32库函数差不多

ESP8266文档中心 | 安信可科技 (ai-thinker.com)
在这里插入图片描述

二、本项目MP09开发板端代码实现

2.1MP08开发板原理图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IuzgMAmI-1669960267096)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202112651324.png)]

该原理图为我用万用表徒手测并绘制,仅供引脚走线参考使用,电阻电容等均未调整数值

通过原理图我们可以看到

  • 每个减速电机得三个引脚分别接在了L、C、H线上
  • 其中L引脚由原理图中间的74HC595D控制器的Q0-Q7控制
  • C引脚由ESP_IO12控制
  • H引脚由ESP_IO2控制

知道了电机由哪几个引脚控制,我们就可以往上进行推理,可知要想选择开启哪个电机就得控制74HC595D的Q0-Q7哪个引脚,所以我们需要找到74HC595D芯片手册来查看如何控制

2.274HC595D驱动方式

74HC595D数据手册

通过数据手册,我们可以知道,要想给Q0-Q7输出想要的信号值,就得在SER串行数据输入端输入相应的值并锁存到锁存寄存器里

所以,驱动方式总结如下:

  1. 设置SER串行数据输入引脚电平
  2. 拉高SCK,使SER数据被移位进入八位移位寄存器
  3. 重复以上两个步骤共8次,发送8位数据(1Byte)
  4. 拉高RCK,使得八位移位寄存器中的数据被送到八位锁存器里
  5. 锁存器里的数据将会自动发送到Q0-Q7各个引脚

提示:当我们想驱动Q3和Q5引脚输出高电平,我们的8位数据就应该为00101000,也就是0x28

根据以上信息,我们可以写出以下代码:

在看代码前,我们需要了解几个官方API函数:

  • os_printf:跟标准C库函数printf一样,但这里必须用os_printf
  • os_delay_us:官方给的专用微秒延时API
  • system_soft_wdt_feed:看门狗喂狗函数,不喂好像也没事,最好加上,安信可官方说默认开启了看门狗
  • GPIO_OUTPUT_SET(GPIO_ID_PIN(x),1):GPIO口输出电平控制宏,x为引脚编号,后面的1为高电平,0则为低电平
  • PIN_FUNC_SELECT:引脚功能选择宏函数
  • API函数及其具体用法可参照ESP8266_SDK_API参考指南
void delay_ms(uint32_t ms)
{
	while(ms--)
	{
		os_delay_us(1000);//os_delay_us为官方API
		system_soft_wdt_feed();//喂狗
	}
}

//发送数据函数
void hc595d_send_byte(uint8_t data)
{
	uint8_t i;

	for(i = 0;i < 8;i++)
	{
		if(data & (0x80>>i))
		{
			GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1);//IO4高电平
		}
		else
		{
			GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0);//IO4低电平
		}
		GPIO_OUTPUT_SET(GPIO_ID_PIN(13),0);//先拉低
		os_delay_us(5);//适当延时
		GPIO_OUTPUT_SET(GPIO_ID_PIN(13),1);//上升沿将一位数据移入移位寄存器
		os_delay_us(5);//适当延时
	}
}
//锁存函数
void hc595d_latch_data(void)
{
	GPIO_OUTPUT_SET(GPIO_ID_PIN(15),0);//先拉低
	os_delay_us(5);//适当延时
	GPIO_OUTPUT_SET(GPIO_ID_PIN(15),1);//上升沿将数据送入锁存寄存器
	os_delay_us(5);//适当延时
}

void driver_motor(uint8_t j)
{
	/*
	 * HC595D	ESP_IO12	ESP_IO2
	 * MOTOR_L	MOTOR_C		MOTOR_H		转向
	 * 1		1			0			逆时针
	 * 1		0			0			x
	 * 1		0			1			x
	 * 1		1			1			逆时针
	 * */
	hc595d_send_byte(j);//发送1byte数据
	hc595d_latch_data();//锁存
	GPIO_OUTPUT_SET(GPIO_ID_PIN(12),1);
	GPIO_OUTPUT_SET(GPIO_ID_PIN(2),0);
	GPIO_OUTPUT_SET(GPIO_ID_PIN(5),j%2);//led监视
	os_printf("j:%2d on\r\n",j);
    //售货机转1秒就停止
	delay_ms(1000);
	GPIO_OUTPUT_SET(GPIO_ID_PIN(12),0);
}

void user_init(void)
{
	system_soft_wdt_feed();//喂狗
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4);//IO4-SER
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U,FUNC_GPIO15);//IO15-RCK
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U,FUNC_GPIO13);//IO13-SCK
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12);//IO12-MOTOR_C
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2);//IO2-MOTOR_H
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5);//IO5-LED
}

以上就是如何去驱动74HC595D来控制MP08开发板上8个电机的方法

现在,我们来考虑售货机通信方面的问题,从这里开始呢,就可以根据不同的方式来去控制MP08售货机板子

  • 第一种方法:利用RK3399和MP08进行TCP连接,这样我们可以在RK3399板子上对MP08进行可视化操作

  • 第二种方法:无需其他外设,只需一部手机,我们可以在手机端连接MP08上的ESP8285,进行操控

  • 第三种方法:MP08上的ESP8285连接WiFi,然后连接上云服务器,手机端通过云服务器来进行远程发送数据去控制MP08

……方法非常多,远不止这几种,我们这里采用第一种方法

2.3MP08—TCP_Client代码实现

这里我们将MP08上的ESP8285作为TCP客户端连接RK3399的TCP服务端、

tcp_client.c

#include "user_config.h"
#include "driver/uart.h"  //串口0需要的头文件
#include "osapi.h"  //串口1需要的头文件
#include "user_interface.h" //WIFI连接需要的头文件
#include "espconn.h"//TCP连接需要的头文件
#include "mem.h" //系统操作需要的头文件
#include "gpio.h"


os_timer_t checkTimer_wifistate;
struct espconn user_tcp_conn;

uint8_t my_atoi(char *pdata,unsigned short len)
{
	uint8_t ret = 0;
	os_printf("len = %d\r\n",len);
	while(len--)
	{
		ret *= 10;
		ret += *pdata++ - '0';
	}
	os_printf("ret = %d\r\n",ret);
	return ret;
}

//将输入的点击编号转化为二进制
//如驱动1号电机Q0,则为00000001->0x01
//如驱动8号电机Q7,则为10000000->0x80
uint8_t to_binaray(uint8_t num)
{
	uint8_t ret = 0;

	switch(num)
	{
	case 1:ret = 1;break;
	case 2:ret = 2;break;
	case 3:ret = 4;break;
	case 4:ret = 8;break;
	case 5:ret = 16;break;
	case 6:ret = 32;break;
	case 7:ret = 64;break;
	case 8:ret = 128;break;
	default:break;
	}

	return ret;
}

//tcp发送数据回调函数
void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg)  //发送
{
	os_printf("发送数据成功!");
}
//tcp断开后的回调函数
void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg)  //断开
{
	os_printf("断开连接成功!");
}
//tcp收到数据后的回调函数
void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg,  //接收
		char *pdata, unsigned short len) {

	os_printf("收到数据:%s\r\n", pdata);
	driver_motor(to_binaray(my_atoi(pdata,len)));//电机驱动
	espconn_sent((struct espconn *) arg, "0", strlen("0"));
}
//注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err) 
{
	os_printf("连接错误,错误代码为%d\r\n", err);
	espconn_connect((struct espconn *) arg);
}
//注册 TCP 连接成功建立后的回调函数
void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg)  
{
	struct espconn *pespconn = arg;
	espconn_regist_recvcb(pespconn, user_tcp_recv_cb);  //接收
	espconn_regist_sentcb(pespconn, user_tcp_sent_cb);  //发送
	espconn_regist_disconcb(pespconn, user_tcp_discon_cb);  //断开
	espconn_sent(pespconn, "8226", strlen("8226"));
	os_printf("连接服务器成功!\r\n");
}

void ICACHE_FLASH_ATTR my_station_init(struct ip_addr *remote_ip,
		struct ip_addr *local_ip, int remote_port) {
	user_tcp_conn.proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp));  //分配空间
	user_tcp_conn.type = ESPCONN_TCP;  //设置类型为TCP协议
	os_memcpy(user_tcp_conn.proto.tcp->local_ip, local_ip, 4);
	os_memcpy(user_tcp_conn.proto.tcp->remote_ip, remote_ip, 4);
	user_tcp_conn.proto.tcp->local_port = espconn_port();  //本地端口
	user_tcp_conn.proto.tcp->remote_port = remote_port;  //目标端口
	//注册连接成功回调函数和重新连接回调函数
	espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb);//注册 TCP 连接成功建立后的回调函数
	espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb);//注册 TCP 连接发生异常断开时的回调函数,可以在回调函数中进行重连
	//启用连接
	espconn_connect(&user_tcp_conn);
}

//连接局域网wifi,连接tcp服务器
void Check_WifiState(void) {
	uint8 getState;
	getState = wifi_station_get_connect_status();
	//查询 ESP8266 WiFi station 接口连接 AP 的状态
	if (getState == STATION_GOT_IP) {
		os_printf("WIFI连接成功!\r\n");
		os_timer_disarm(&checkTimer_wifistate);
		struct ip_info info;
		const char remote_ip[4] = { 192, 168, 31, 116 };//目标IP地址
		wifi_get_ip_info(STATION_IF, &info);	//查询 WiFi模块的 IP 地址
		my_station_init((struct ip_addr *) remote_ip, &info.ip, 6000);//连接到目标服务器的6000端口
 }
}

void tcp_client_init()	//初始化
{

	wifi_set_opmode(0x01);	//设置为STATION模式

	struct station_config stationConf;
	os_strcpy(stationConf.ssid, "Xiaomi_9908");	  //改成你自己的   路由器的用户名 
	os_strcpy(stationConf.password, "20010624w"); //改成你自己的   路由器的密码
	wifi_station_set_config(&stationConf);	//设置WiFi station接口配置,并保存到 flash
	wifi_station_connect();	//连接路由器

	os_timer_disarm(&checkTimer_wifistate);	//取消定时器定时
	os_timer_setfn(&checkTimer_wifistate, (os_timer_func_t *) Check_WifiState,
	NULL);	//设置定时器回调函数
	os_timer_arm(&checkTimer_wifistate, 500, 1);	//启动定时器,单位:毫秒
}


在此代码中,如有不了解的API函数,可随时查阅ESP8266_SDK_API参考指南,里面对每个API都有用法讲解,但不够清晰,可参照该代码进行理解

注意:

  • WiFi名和密码需要更改成和RK3399同局域网的WiFi
  • 目标IP地址需要更改为RK3399的ip地址,可输入ipconfig查询

2.4MP08完整代码

将以下代码替换到上一篇文章所创建工程的user_main.c

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Di7Bl1G4-1669960267098)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202130356806.png)]

#include "driver/uart.h"  //串口0需要的头文件
#include "osapi.h"  //串口1需要的头文件
#include "user_interface.h" //WIFI连接需要的头文件
#include "gpio.h"  //端口控制需要的头文件
#include "user_config.h"

#if ((SPI_FLASH_SIZE_MAP == 0) || (SPI_FLASH_SIZE_MAP == 1))
#error "The flash map is not supported"
#elif (SPI_FLASH_SIZE_MAP == 2)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0xfb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0xfc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0xfd000
#elif (SPI_FLASH_SIZE_MAP == 3)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x1fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x1fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x1fd000
#elif (SPI_FLASH_SIZE_MAP == 4)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x81000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x3fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x3fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x3fd000
#elif (SPI_FLASH_SIZE_MAP == 5)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x101000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x1fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x1fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x1fd000
#elif (SPI_FLASH_SIZE_MAP == 6)
#define SYSTEM_PARTITION_OTA_SIZE							0x6A000
#define SYSTEM_PARTITION_OTA_2_ADDR							0x101000
#define SYSTEM_PARTITION_RF_CAL_ADDR						0x3fb000
#define SYSTEM_PARTITION_PHY_DATA_ADDR						0x3fc000
#define SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR				0x3fd000
#else
#error "The flash map is not supported"
#endif

void delay_ms(uint32_t ms)
{
	while(ms--)
	{
		os_delay_us(1000);
		system_soft_wdt_feed();//喂狗
	}
}

//发送数据函数
void hc595d_send_byte(uint8_t data)
{
	uint8_t i;

	for(i = 0;i < 8;i++)
	{
		if(data & (0x80>>i))
		{
			GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1);//IO4高电平
		}
		else
		{
			GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0);//IO4低电平
		}
		GPIO_OUTPUT_SET(GPIO_ID_PIN(13),0);//先拉低
		os_delay_us(5);//适当延时
		GPIO_OUTPUT_SET(GPIO_ID_PIN(13),1);//上升沿将一位数据移入移位寄存器
		os_delay_us(5);//适当延时
	}
}
//锁存函数
void hc595d_latch_data(void)
{
	GPIO_OUTPUT_SET(GPIO_ID_PIN(15),0);//先拉低
	os_delay_us(5);//适当延时
	GPIO_OUTPUT_SET(GPIO_ID_PIN(15),1);//上升沿将数据送入锁存寄存器
	os_delay_us(5);//适当延时
}

void driver_motor(uint8_t j)
{
	/*
	 * 译码器	ESP_IO12	ESP_IO2
	 * MOTOR_L	MOTOR_C		MOTOR_H		转向
	 * 1		1			0			逆时针
	 * 1		0			0			x
	 * 1		0			1			x
	 * 1		1			1			逆时针
	 * */
	hc595d_send_byte(j);//发送1byte数据
	hc595d_latch_data();//锁存
	GPIO_OUTPUT_SET(GPIO_ID_PIN(12),1);
	GPIO_OUTPUT_SET(GPIO_ID_PIN(2),0);
	GPIO_OUTPUT_SET(GPIO_ID_PIN(5),j%2);//led监视
	os_printf("j:%2d on\r\n",j);
	delay_ms(1000);
	GPIO_OUTPUT_SET(GPIO_ID_PIN(12),0);
}

void user_init(void)
{
	system_soft_wdt_feed();//喂狗
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4);//IO4-SER
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U,FUNC_GPIO15);//IO15-RCK
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U,FUNC_GPIO13);//IO13-SCK
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO12);//IO12-MOTOR_C
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2);//IO2-MOTOR_H
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5);//IO5-LED
	//8266作为TCP客户端,目标端口为6000,IP地址见串口打印,此要先获取Tcp服务端的ip地址
	tcp_client_init();
}

static const partition_item_t at_partition_table[] = {
    { SYSTEM_PARTITION_BOOTLOADER, 						0x0, 												0x1000},
    { SYSTEM_PARTITION_OTA_1,   						0x1000, 											SYSTEM_PARTITION_OTA_SIZE},
    { SYSTEM_PARTITION_OTA_2,   						SYSTEM_PARTITION_OTA_2_ADDR, 						SYSTEM_PARTITION_OTA_SIZE},
    { SYSTEM_PARTITION_RF_CAL,  						SYSTEM_PARTITION_RF_CAL_ADDR, 						0x1000},
    { SYSTEM_PARTITION_PHY_DATA, 						SYSTEM_PARTITION_PHY_DATA_ADDR, 					0x1000},
    { SYSTEM_PARTITION_SYSTEM_PARAMETER, 				SYSTEM_PARTITION_SYSTEM_PARAMETER_ADDR, 			0x3000},
};

void ICACHE_FLASH_ATTR user_pre_init(void)
{
    if(!system_partition_table_regist(at_partition_table, sizeof(at_partition_table)/sizeof(at_partition_table[0]),SPI_FLASH_SIZE_MAP)) {
		os_printf("system_partition_table_regist fail\r\n");
		while(1);
	}
}

将以下代码加入到smart_config->user中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZ2kj4Vk-1669960267100)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202130535246.png)]

更改头文件user_config.h

#ifndef __USER_CONFIG_H__
#define __USER_CONFIG_H__


void delay_ms(unsigned int ms);
void hc595d_send_byte(unsigned char data);
void hc595d_latch_data(void);
void driver_motor(unsigned char j);

void tcp_client_init();

#endif


2.5编译烧录及运行结果

编译方法:保存(一定要先保存)-> Clean -> Build

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwLS025W-1669960267102)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202130850451.png)]

编译结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0no8sJk-1669960267104)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202131003116.png)]

烧录方式见上一篇文章讲解基于RK3399&ESP8285自动售货柜项目—ESP8266(8285)程序编写与烧录 (zsxq.com)

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDwAoEqq-1669960267106)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202131811486.png)]

开启RK3399-TCP服务器后

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oLo2a4TT-1669960267109)(D:\AiThinkerIDE_V1.5.2\文章\image-20221202132230158.png)]

参照本篇只需实现能够连接上WiFi即可,如要连接TCP服务器,下篇将会详细讲解RK3399服务器端代码,以及交互界面的制作,最终将完整实现本产品的制作

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值