1、瑞萨RA4M2 开发板介绍
瑞萨电子 RA4M2 32 位微控制器 (MCU) 产品群使用支持 TrustZone 的高性能 Arm® Cortex®-M33 内核。 与片内的 Secure Crypto Engine (SCE) 配合使用,可实现安全芯片的功能。 RA4M2 采用高效的 40nm 工艺,由灵活配置软件包 (FSP) 这个开放且灵活的生态系统概念提供支持,FSP 基于 FREERTOS 构建,并能够进行扩展,以使用其他实时操作系统 (RTOS) 和中间件。 RA4M2 适用于物联网应用的需求, 如多样化的通信功能、面向未来应用的安全功能、大容量嵌入式 RAM 和较低的运行功耗(从闪存运行 CoreMark® 算法时功耗低至 81µA/MHz)。
2、 DA16200 介绍
DA16200 片上系统 (SoC) 是全球首款为一直在线的 Wi-Fi 物联网设备提供一年以上电池续航时间的 Wi-Fi SoC。 DA16200 是一款低功耗 Wi-Fi 网络 SoC,即使是持续连接 Wi-Fi 网络的设备,其电池寿命也能大大延长。 大多数应用中可实现一年以上的电池寿命。 SoC 的续航时间业界领先,所以无需在输出功率或续航方面有所权衡。 该芯片还具有非常强大的物联网安全性,包括 WPA3 和 TLS,用于 Wi-Fi 和更高堆栈层的身份验证和加密。 DA16200 是完全卸载的器件,因此整个 Wi-Fi 和 TCP/IP 网络堆栈,甚至最终产品应用代码都可以在芯片上运行,无需外部 CPU 或 MCU。 另外,小型廉价 MCU 也可以发送 DA16200 命令,而 SoC 仍将执行完整的卸载网络堆栈功能。
3、开发板连接方式
通过瑞萨旁边的标准接插件可以很方便的进行连接和测试
下面我们使用串口发送AT指令的方式进行测试
4、 开发工具我们使用瑞萨自己的e2stdio就是eclipe的魔改版本
我们打开后选择我们的开发板套件为RA4M2
在pin这里我们选择对应的串口引脚在栈这里将我们的串口加进去
5、书写驱动
这里驱动是借鉴的网友的我将他的粘贴到下发
da16200_AT.c
/* @hehung 2023-2-8 转载请注明出处,版权由@hehung所有 email: 1398660197@qq.com wechat: hehung95 */ #include "hal_data.h" #include "da16200_AT.h" #include "app_common.h" #include "app_led.h" #include "app_wifi.h" // this structure is used to cache the received AT informations typedef struct { char at_buf[DA16200_STR_LEN_256]; uint16_t at_len; uint16_t at_timeout; } s_AtCmdBfType; /** AT Command sets */ /*LDRA_INSPECTED 27 D This structure must be accessible in user code. It cannot be static. */ da16200_at_cmd_set_t g_da16200_cmd_set[] = { /** Intial AT command */ [DA16200_AT_CMD_INDEX_ATZ] = { .p_cmd = (uint8_t *) "ATZ\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_10, .retry_delay = DA16200_DELAY_500MS, .wait_timeout = DA16200_DELAY_1000MS }, /** Echo on/ off */ [DA16200_AT_CMD_INDEX_ATE] = { .p_cmd = (uint8_t *) "ATE\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* ATF */ [ DA16200_AT_CMD_INDEX_AT_ATF] = { .p_cmd = (uint8_t *) "ATF\r\n", .p_success_resp = (uint8_t *) "DONE", .max_resp_length = DA16200_STR_LEN_128, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_500MS, .wait_timeout = DA16200_DELAY_3000MS }, /* Set boot mode */ [DA16200_AT_CMD_INDEX_AT_TMRFNOINIT] = { .p_cmd = (uint8_t *) "AT+TMRFNOINIT=0\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Set Station mode */ [DA16200_AT_CMD_INDEX_AT_WFMODE] = { .p_cmd = (uint8_t *) "AT+WFMODE=0\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Restart */ [ DA16200_AT_CMD_INDEX_AT_RESTART] = { .p_cmd = (uint8_t *) "AT+RESTART\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_128, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_1000MS, .wait_timeout = DA16200_DELAY_1000MS }, /* 连接wifi热点 */ [DA16200_AT_CMD_INDEX_AT_WFJAP] = { .p_cmd = (uint8_t *) "AT+WFJAP=hehungphone,4,1,1234543210\r\n", .p_success_resp = (uint8_t *) "+WFJAP:1", .max_resp_length = DA16200_STR_LEN_128, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_1000MS, .wait_timeout = DA16200_DELAY_5000MS }, /* TCP连接 - Contact to the ONENET TCP server:183.230.40.40:1811 */ [DA16200_AT_CMD_INDEX_AT_TRTC] = { .p_cmd = (uint8_t *) "AT+TRTC=183.230.40.40,1811,0\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_2000MS }, // 断开TCP连接 [DA16200_AT_CMD_INDEX_AT_TRTRM] = { .p_cmd = (uint8_t *) "AT+TRTRM=1\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Set Country Code */ [DA16200_AT_CMD_INDEX_AT_WFCC] = { .p_cmd = (uint8_t *) "AT+WFCC=CH\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Set Country Code */ [ DA16200_AT_CMD_INDEX_AT_WFSAP] = { .p_cmd = (uint8_t *) "AT+WFSAP=Renesas_Wifi,3,1,12345678,1,CH\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_128, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Set IP */ [ DA16200_AT_CMD_INDEX_AT_NWIP] = { .p_cmd = (uint8_t *) "AT+NWIP=1,192.168.10.2,255.255.255.0,192.168.10.1\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_1000MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Start DHCP */ [ DA16200_AT_CMD_INDEX_AT_NWDHS] = { .p_cmd = (uint8_t *) "AT+NWDHS=1\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* DHCP IP area set*/ [ DA16200_AT_CMD_INDEX_AT_NWDHR] = { .p_cmd = (uint8_t *) "AT+NWDHR=192.168.10.3,192.168.10.10\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* TCP server port set*/ [ DA16200_AT_CMD_INDEX_AT_TRTS] = { .p_cmd = (uint8_t *) "AT+TRTS=80\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* TCP server port message save */ [ DA16200_AT_CMD_INDEX_AT_TRSAVE] = { .p_cmd = (uint8_t *) "AT+TRSAVE\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* Wifi AP connect status */ [ DA16200_AT_CMD_INDEX_AT_WFSTA] = { .p_cmd = (uint8_t *) "AT+WFSTA\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_1, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, /* sntp start with address 'pool.ntp.org'*/ [ DA16200_AT_CMD_INDEX_AT_NWSNTP_START] = { .p_cmd = (uint8_t *) "AT+NWSNTP=1,pool.ntp.org,60\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, [ DA16200_AT_CMD_INDEX_AT_NWSNTP_STOP] = { .p_cmd = (uint8_t *) "AT+NWSNTP=0\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, [ DA16200_AT_CMD_INDEX_AT_NWSNTP_STATUS] = { .p_cmd = (uint8_t *) "AT+NWSNTP=?\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_200MS, .wait_timeout = DA16200_DELAY_1000MS }, [ DA16200_AT_CMD_INDEX_AT_TZONE_GET] = { .p_cmd = (uint8_t *) "AT+TZONE=?\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_100MS, .wait_timeout = DA16200_DELAY_500MS }, [ DA16200_AT_CMD_INDEX_AT_TZONE_SET] = { .p_cmd = (uint8_t *) "AT+TZONE=28800\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_100MS, .wait_timeout = DA16200_DELAY_500MS }, [ DA16200_AT_CMD_INDEX_AT_TIME_GET] = { .p_cmd = (uint8_t *) "AT+TIME=?\r\n", .p_success_resp = (uint8_t *) "+TIME", .max_resp_length = DA16200_STR_LEN_64, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_100MS, .wait_timeout = DA16200_DELAY_500MS }, [DA16200_AT_CMD_INDEX_AT_NWDHC] = { .p_cmd = (uint8_t *) "AT+NWDHC\r\n", .p_success_resp = (uint8_t *) "OK", .max_resp_length = DA16200_STR_LEN_32, .retry = DA16200_RETRY_VALUE_5, .retry_delay = DA16200_DELAY_100MS, .wait_timeout = DA16200_DELAY_500MS } }; static uint32_t g_wifi_receive_time_count = 0; static uint32_t count = 0; static demo_data_t g_demo_data; static s_AtCmdBfType g_at_buf; static s_Da16200FbType RespList[] = { {Da16200_TRDTC_response, "+TRDTC:1"} }; // DA16200 wifi module AT command fsp_err_t Da1620_ATCommandExe(da16200_at_cmd_index_t at_cmd, uint8_t *resp_buff) { uint16_t bytes_read = 0U; uint16_t bytes_write; fsp_err_t result = FSP_ERR_ASSERTION; uint8_t retry_count = 0U; da16200_at_cmd_set_t * p_cmd_set = g_da16200_cmd_set; // setting mutex for lock wifi uart if (pdTRUE == xSemaphoreTake(wifi_mutex, portMAX_DELAY)) { do { /** AT MODODR command **/ bytes_write = (uint16_t) strlen((char *) p_cmd_set[at_cmd].p_cmd); wifi_serial_write((uint8_t*)p_cmd_set[at_cmd].p_cmd, bytes_write); bytes_read = p_cmd_set[at_cmd].max_resp_length; /** Clear respond memory **/ memset (resp_buff, 0, bytes_read); result = wifi_serial_read(resp_buff, &bytes_read, (const char*)p_cmd_set[at_cmd].p_success_resp, p_cmd_set[at_cmd].wait_timeout); if (FSP_SUCCESS == result) { break; } DELAY_MS(p_cmd_set[at_cmd].retry_delay); ++retry_count; } while(retry_count < p_cmd_set[at_cmd].retry); // release the mutex, unlock (void)xSemaphoreGive(wifi_mutex); } return result; } /************************************************************************************ * Name: is_str_present * Function: compare string * Parameters: p_resp_str, p_search_str * Return: comparing result ************************************************************************************/ uint8_t is_str_present(const char * p_resp_str, const char * p_search_str) { if (strstr (p_resp_str, p_search_str)) { return SF_WIFI_TRUE; } return SF_WIFI_FALSE; } /************************************************************************************ * Name: wifi_serial_read * Function: read receive data * Parameters: p_dest, p_bytes, p_resp_ptr, timeout_ms * Return: read result ************************************************************************************/ fsp_err_t wifi_serial_read(uint8_t * p_dest, const uint16_t * p_bytes, const char * p_resp_ptr, uint32_t timeout_ms) { fsp_err_t status = FSP_SUCCESS; uint16_t bytes = *p_bytes; uint16_t i; uint8_t expected_resp_present; g_wifi_receive_time_count = 0U; do { // some data received from DA16200 if (g_at_buf.at_len >= strlen(p_resp_ptr)) { if (g_at_buf.at_len >= bytes) { /* Overflow */ status = FSP_ERR_RXBUF_OVERFLOW; break; } // compare the response data expected_resp_present = is_str_present(g_at_buf.at_buf, p_resp_ptr); if(SF_WIFI_TRUE == expected_resp_present) { printf ("==>da16200 recv:%s\n", g_at_buf.at_buf); status = FSP_SUCCESS; break; } // memset(g_at_buf.at_buf, '\0', sizeof(g_at_buf.at_buf)); } expected_resp_present = is_str_present(g_at_buf.at_buf, "ERROR"); if(SF_WIFI_TRUE == expected_resp_present) { // error printf ("==>da16200 error:%s\n", g_at_buf.at_buf); status = FSP_ERR_ASSERTION; break; } // timeout if(g_wifi_receive_time_count >= timeout_ms) { if (g_at_buf.at_len >= 0) memset(g_at_buf.at_buf, '\0', sizeof(g_at_buf.at_buf)); g_wifi_receive_time_count = 0U; status = FSP_ERR_TIMEOUT; break; } /* Added delay for freeRTOS and used for solved thread dead */ DELAY_MS(1); } while(1); // load the data to dest buffer if (FSP_SUCCESS == status) { for (i = 0; i < g_at_buf.at_len; i++) { *p_dest = g_at_buf.at_buf[i]; p_dest ++; } } return status; } /************************************************************************************ * Name: wifi_serial_write * Function: write data * Parameters: p_src, bytes * Return: write result ************************************************************************************/ fsp_err_t wifi_serial_write(uint8_t * p_src, uint16_t bytes) { fsp_err_t status = FSP_SUCCESS; if (g_at_buf.at_len > 0U) { g_at_buf.at_len = 0U; memset(g_at_buf.at_buf, '\0', sizeof(g_at_buf.at_buf)); } status = g_uart0.p_api->write(g_uart0.p_ctrl, p_src, bytes); return(status); } /************************************************************************************ * Name: uart0_notification * Function: write data callback * Parameters: p_args * Return: write result ************************************************************************************/ void uart0_notification(uart_callback_args_t *p_args) { if (p_args->event == UART_EVENT_RX_CHAR) { if (g_at_buf.at_len < (DA16200_STR_LEN_256 - 1U)) { // save the data into the buffer 'g_at_buf.at_buf' g_at_buf.at_buf[g_at_buf.at_len] = (uint8_t)p_args->data; g_at_buf.at_len ++; } } } /************************************************************************************ * Name: timer0_1ms_callback * Function: 1ms callback * Parameters: p_args * Return: 1ms timing ************************************************************************************/ void timer0_1ms_callback(timer_callback_args_t *p_args) { FSP_PARAMETER_NOT_USED(p_args); g_wifi_receive_time_count++; g_demo_data.led_blink_count++; if(g_demo_data.led_blink_count >= 1000) { count++; g_demo_data.led_blink_count = 0; if(count%2) { Led_Ctrl(LED_3, 1); } else { Led_Ctrl(LED_3, 0); } } // Used for handle the UART data from DA16200 WIfi_CheckPreiodLoop(); } // This function is used for handle the response data void Da16200_FeedbackHandle(void) { uint8_t i; for (i = 0; i < (sizeof(RespList) / sizeof(s_Da16200FbType)); i++) { if (SF_WIFI_TRUE == is_str_present(g_at_buf.at_buf, RespList->p_cmd)) { RespList->RespFbFunc(g_at_buf.at_buf, g_at_buf.at_len); } } if (g_at_buf.at_len > 0) { ENTER_CRITICAL(); // clear buffer memset(g_at_buf.at_buf, '\0', sizeof(g_at_buf.at_buf)); g_at_buf.at_len = 0; EXIT_CRITICAL(); } }
da16200_AT.h
#ifndef DA16200_AT_H_
#define DA16200_AT_H_
#include "hal_data.h"
/** Macros to define string length */
#define DA16200_STR_LEN_8 (8U) ///< Length 8
#define DA16200_STR_LEN_16 (16U) ///< Length 16
#define DA16200_STR_LEN_32 (32U) ///< Length 32
#define DA16200_STR_LEN_64 (64U) ///< Length 64
#define DA16200_STR_LEN_128 (128U) ///< Length 128
#define DA16200_STR_LEN_256 (256U) ///< Length 128
#define DA16200_STR_LEN_512 (512U) ///< Length 512
/** DA16200 delay in milliseconds between AT command retry */
#define DA16200_DELAY_0 (0U) ///< No delay
#define DA16200_DELAY_20MS (20U) ///< Delay of 20 milliseconds
#define DA16200_DELAY_50MS (50U) ///< Delay of 50 milliseconds
#define DA16200_DELAY_100MS (100U) ///< Delay of 100 milliseconds
#define DA16200_DELAY_200MS (200U) ///< Delay of 200 milliseconds
#define DA16200_DELAY_300MS (300U) ///< Delay of 300 milliseconds
#define DA16200_DELAY_500MS (500U) ///< Delay of 500 milliseconds
#define DA16200_DELAY_1000MS (1000U) ///< Delay of 1000 milliseconds
#define DA16200_DELAY_2000MS (2000U) ///< Delay of 2000 milliseconds
#define DA16200_DELAY_3000MS (3000U) ///< Delay of 3000 milliseconds
#define DA16200_DELAY_4000MS (4000U) ///< Delay of 4000 milliseconds
#define DA16200_DELAY_5000MS (5000U) ///< Delay of 5000 milliseconds
/** DA16200 retry count for AT command set */
#define DA16200_RETRY_VALUE_0 (0U) ///< No Retry
#define DA16200_RETRY_VALUE_1 (1U) ///< Retry Once
#define DA16200_RETRY_VALUE_5 (5U) ///< Retry 5 times
#define DA16200_RETRY_VALUE_10 (10U) ///< Retry 10 times
/** Logical Value TRUE for Cellular */
#define SF_WIFI_TRUE (1U)
/** Logical Value FALSE for Cellular */
#define SF_WIFI_FALSE (0U)
/** Structure defining AT commands parameters */
typedef struct da16200_at_cmd_set
{
uint8_t * p_cmd; ///< AT Command
uint8_t * p_success_resp; ///< Success response string
uint16_t max_resp_length; ///< Maximum length of expected response
uint8_t retry; ///< Retry count
uint16_t retry_delay; ///< Delay between AT command retry
uint16_t wait_timeout; ///< Waiting time for feedback
} da16200_at_cmd_set_t;
typedef enum da16200_at_cmd_index
{
DA16200_AT_CMD_INDEX_ATZ = 0, ///< Index for Command ATZ
DA16200_AT_CMD_INDEX_ATE,
DA16200_AT_CMD_INDEX_AT_ATF,
DA16200_AT_CMD_INDEX_AT_TMRFNOINIT,
DA16200_AT_CMD_INDEX_AT_WFMODE,
DA16200_AT_CMD_INDEX_AT_RESTART,
DA16200_AT_CMD_INDEX_AT_WFJAP,
DA16200_AT_CMD_INDEX_AT_TRTC,
DA16200_AT_CMD_INDEX_AT_TRTRM,
DA16200_AT_CMD_INDEX_AT_WFCC,
DA16200_AT_CMD_INDEX_AT_WFSAP,
DA16200_AT_CMD_INDEX_AT_NWIP,
DA16200_AT_CMD_INDEX_AT_NWDHS,
DA16200_AT_CMD_INDEX_AT_NWDHR,
DA16200_AT_CMD_INDEX_AT_TRTS,
DA16200_AT_CMD_INDEX_AT_TRSAVE,
DA16200_AT_CMD_INDEX_AT_WFSTA,
DA16200_AT_CMD_INDEX_AT_NWSNTP_START,
DA16200_AT_CMD_INDEX_AT_NWSNTP_STOP,
DA16200_AT_CMD_INDEX_AT_NWSNTP_STATUS,
DA16200_AT_CMD_INDEX_AT_TZONE_GET,
DA16200_AT_CMD_INDEX_AT_TZONE_SET,
DA16200_AT_CMD_INDEX_AT_TIME_GET,
DA16200_AT_CMD_INDEX_AT_NWDHC,
DA16200_AT_CMD_INDEX_AT_NONE
} da16200_at_cmd_index_t;
typedef struct
{
char * p_cmd; // AT Command
void (*Da16200_AtCmdCbFunc)(char *resp_buf); // callback function
} s_Da16200AtCmdCbType;
typedef struct demo_data
{
uint8_t led_blink_flag;
uint16_t led_blink_count;
} demo_data_t;
typedef struct
{
void (*RespFbFunc)(char *resp_data, uint16_t resp_data_len);
char * p_cmd;
} s_Da16200FbType;
extern fsp_err_t wifi_serial_read(uint8_t * p_dest,
const uint16_t * p_bytes,
const char * p_resp_ptr,
uint32_t timeout_ms);
extern fsp_err_t wifi_serial_write(uint8_t * p_src, uint16_t bytes);
extern uint8_t is_str_present(const char * p_resp_str, const char * p_search_str);
extern fsp_err_t Da1620_ATCommandExe(da16200_at_cmd_index_t at_cmd, uint8_t *resp_buff);
extern void Da16200_FeedbackHandle(void);
#endif /* DA16200_AT_H_ */
6、书写自己的测试
这里我写了一个连接tcp并且一直发送helloword的程序
#include "hal_data.h"
#include "da16200_AT.h"
#include "app_common.h"
#include "app_led.h"
#include "app_wifi.h"
// 服务器配置
#define TCP_SERVER_IP "192.168.31.147"
#define TCP_SERVER_PORT 11111
// 数据发送间隔(毫秒)
#define SEND_INTERVAL_MS 1000
// 初始化WiFi模块
fsp_err_t init_wifi_module(void) {
fsp_err_t err;
uint8_t resp_buff[DA16200_STR_LEN_256];
// 复位模块
err = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_ATZ, resp_buff);
if (err != FSP_SUCCESS) {
printf("ATZ command failed\n");
return err;
}
// 关闭回显
err = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_ATE, resp_buff);
if (err != FSP_SUCCESS) {
printf("ATE command failed\n");
return err;
}
// 设置工作模式为Station
err = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_WFMODE, resp_buff);
if (err != FSP_SUCCESS) {
printf("WFMODE command failed\n");
return err;
}
// 连接WiFi热点
err = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_WFJAP, resp_buff);
if (err != FSP_SUCCESS) {
printf("WFJAP command failed\n");
return err;
}
printf("WiFi connected successfully\n");
return FSP_SUCCESS;
}
// 连接TCP服务器
fsp_err_t connect_tcp_server(void) {
fsp_err_t err;
uint8_t resp_buff[DA16200_STR_LEN_256];
// 构建连接TCP服务器的命令
char cmd_buffer[64];
sprintf(cmd_buffer, "AT+TRTC=%s,%d,0\r\n", TCP_SERVER_IP, TCP_SERVER_PORT);
// 更新命令集
da16200_at_cmd_set_t *p_cmd_set = g_da16200_cmd_set;
p_cmd_set[DA16200_AT_CMD_INDEX_AT_TRTC].p_cmd = (uint8_t *)cmd_buffer;
// 连接TCP服务器
err = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TRTC, resp_buff);
if (err != FSP_SUCCESS) {
printf("TRTC command failed\n");
return err;
}
printf("TCP server connected successfully\n");
return FSP_SUCCESS;
}
// 发送数据到TCP服务器
fsp_err_t send_data_to_tcp(const char *data) {
fsp_err_t err;
uint8_t resp_buff[DA16200_STR_LEN_256];
uint16_t data_len = strlen(data);
// 构建发送数据的命令
char cmd_buffer[64];
sprintf(cmd_buffer, "AT+TRTSEND=0,%d\r\n", data_len);
// 发送数据长度命令
err = Da1620_ATCommandExe(DA16200_AT_CMD_INDEX_AT_TRTS, resp_buff);
if (err != FSP_SUCCESS) {
printf("TRTSEND length command failed\n");
return err;
}
// 发送实际数据
err = wifi_serial_write((uint8_t *)data, data_len);
if (err != FSP_SUCCESS) {
printf("Data send failed\n");
return err;
}
printf("Data sent: %s\n", data);
return FSP_SUCCESS;
}
// 主应用程序
void app_main(void) {
fsp_err_t err;
// 初始化WiFi模块
err = init_wifi_module();
if (err != FSP_SUCCESS) {
printf("WiFi initialization failed\n");
return;
}
// 连接TCP服务器
err = connect_tcp_server();
if (err != FSP_SUCCESS) {
printf("TCP connection failed\n");
return;
}
// 持续发送"helloworld"
while (1) {
err = send_data_to_tcp("helloworld");
if (err != FSP_SUCCESS) {
printf("Send failed, trying to reconnect...\n");
// 尝试重新连接TCP服务器
err = connect_tcp_server();
if (err != FSP_SUCCESS) {
printf("Reconnection failed, will retry later\n");
}
}
// 延时
DELAY_MS(SEND_INTERVAL_MS);
}
}
结果
可以看到打印出来了字符的16进制
总结
在嵌入式系统开发中,微控制器与通信模块的协同工作能力是项目成功的关键。近期对RA4M2微控制器与DA16200 WiFi模块的联合测试,让我对这对组合有了深刻的认识。 RA4M2作为瑞萨电子的高性能MCU,展现出了卓越的处理能力和低功耗特性。其丰富的外设接口,特别是UART通信功能,为与DA16200的连接提供了便利。在测试中,通过简单配置UART参数,就能实现与WiFi模块的稳定通信,数据传输准确可靠。 DA16200 WiFi模块的AT命令集设计简洁明了,易于理解和使用。通过发送AT指令,可以方便地配置WiFi连接参数、建立TCP连接并进行数据传输。模块对AT命令的响应迅速,状态反馈清晰,大大降低了开发难度。 在联合测试过程中,两者的兼容性表现出色。RA4M2能够稳定地控制DA16200模块完成WiFi连接、TCP通信等操作,即使在长时间运行测试中,也未出现明显的通信异常或数据丢失现象。这为开发基于WiFi的物联网应用奠定了坚实的基础。 不过,测试中也发现了一些需要注意的地方。例如,DA16200在处理大量连续数据时,偶尔会出现缓冲区溢出的情况,需要合理控制数据发送速率。另外,在复杂电磁环境下,WiFi连接的稳定性会受到一定影响,需要进一步优化抗干扰措施。 总体而言,RA4M2与DA16200的组合是一套性能优良、可靠性高的解决方案,非常适合用于开发各类物联网终端设备。通过这次测试,我不仅熟悉了这两款器件的特性和使用方法,也积累了宝贵的嵌入式系统开发经验。