ESP8266的艰辛学习之路
初始化学习
经过2个星期的8266的不断学习,终于掌握了其中的必须功能
这里说一下我的学习系统:
硬件:nodemcu Dev Kit v1.0版本
软件:
1)最新的ESP8266 RTOS SDK
2)ESPFlashDownloadTool_v3.6.1.0.exe
3)stc-isp-15xx-v6.23串口助手
4)AiThinkerIDE_V0.5 IDE
5)cygwin c语言编译环境
开始学习
直接参考链接:
http://wiki.ai-thinker.com/ai_ide_use
建立最初的工程,这里有一些参数设置你需要认真知道原理,不然以后会出错的,后面会说到这个坑
这个RTOS的SDK是基于FreeRTOS这个开源操作系统的,这就意味着你可以建立很多线程和任务
串口打印
工程建立好了,那就需要打印串口输出功能,我们在user init那里加上:
user_main.c:
uart_init_new();//初始化uart
默认串口的波特率我们需要改变一下,进入uset_init_new();瞄一下
void
uart_init_new(void)
{
UART_WaitTxFifoEmpty(UART0);
UART_WaitTxFifoEmpty(UART1);
UART_ConfigTypeDef uart_config;
uart_config.baud_rate = BIT_RATE_115200;
uart_config.data_bits = UART_WordLength_8b;
uart_config.parity = USART_Parity_None;
uart_config.stop_bits = USART_StopBits_1;
uart_config.flow_ctrl = USART_HardwareFlowControl_None;
uart_config.UART_RxFlowThresh = 120;
uart_config.UART_InverseMask = UART_None_Inverse;
UART_ParamConfig(UART0, &uart_config);
UART_IntrConfTypeDef uart_intr;
uart_intr.UART_IntrEnMask = UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_FULL_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA;
uart_intr.UART_RX_FifoFullIntrThresh = 127;
uart_intr.UART_RX_TimeOutIntrThresh = 2;
uart_intr.UART_TX_FifoEmptyIntrThresh = 20;
UART_IntrConfig(UART0, &uart_intr);
UART_SetPrintPort(UART0);
UART_intr_handler_register(uart0_rx_intr_handler, NULL);
ETS_UART_INTR_ENABLE();
}
就在这里修改一下波特率就好了!打印的话就用大家熟悉的printf(“test\r\n”);来测试一下就好;接下来我们继续。
smartconfig功能
想起2-3年前试过学习8266的编程,那时候好多东西都要自己写,甚至搭开发环境都很复杂,但是,多亏于8266的低成本,还有国内众多开发者的支持,现在的8266的sdk真的是我见过的开发得最好的sdk之一。。。好了,废话不多说,smartconfig功能基本上都已经写好了,格式如下:
1.开始smartconfig任务
xTaskCreate(smartconfig_task, "smartconfig_task", 256, NULL, 2, NULL);
void ICACHE_FLASH_ATTR
smartconfig_task(void *pvParameters)
{
//注册smartconfig的回调
smartconfig_start(smartconfig_done);
vTaskDelete(NULL);
}
2.回调
/*
* smartconfig任务回调
* */
uint8 onetime=0;
void ICACHE_FLASH_ATTR
smartconfig_done(sc_status status, void *pdata)
{
switch(status) {
case SC_STATUS_WAIT:
printf("SC_STATUS_WAIT\n");
break;
case SC_STATUS_FIND_CHANNEL:
printf("SC_STATUS_FIND_CHANNEL\n");
break;
case SC_STATUS_GETTING_SSID_PSWD:
printf("SC_STATUS_GETTING_SSID_PSWD\n");
sc_type *type = pdata;
if (*type == SC_TYPE_ESPTOUCH) {
printf("SC_TYPE:SC_TYPE_ESPTOUCH\n");
} else {
printf("SC_TYPE:SC_TYPE_AIRKISS\n");
}
break;
case SC_STATUS_LINK:
printf("SC_STATUS_LINK\n");
struct station_config *sta_conf = pdata;
if(onetime==0)
{
onetime=1;
wifi_station_set_config(sta_conf);
wifi_station_disconnect();
wifi_station_connect();
}
break;
case SC_STATUS_LINK_OVER:
printf("SC_STATUS_LINK_OVER\n");
if (pdata != NULL) {
//SC_TYPE_ESPTOUCH
uint8 phone_ip[4] = {0};
memcpy(phone_ip, (uint8*)pdata, 4);
printf("Phone ip: %d.%d.%d.%d\n",phone_ip[0],phone_ip[1],phone_ip[2],phone_ip[3]);
onetime=0;
} else {
//SC_TYPE_AIRKISS - support airkiss v2.0
//airkiss_start_discover();
}
smartconfig_stop();
reset_smartconfig_status = false;
break;
}
}
3.手机端的配置代码就参考官网的app代码就好了,很容易用的;</>
GPIO口配置
这里带过一下GPIO的配置
输出:
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO4);
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1);
先选中,然后设置输出就可以了.
输入:
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U,FUNC_GPIO5);
GPIO_DIS_OUTPUT(GPIO_ID_PIN(5));
uint8 level=GPIO_INPUT_GET(GPIO_ID_PIN(5));
配置输入多了一步,就是把口的输出功能禁用掉就可以了。
FreeRTOS基本的任务格式
先创建任务,其实就是一个方法:
void ICACHE_FLASH_ATTR
resetconfig_task(void *pvParameters) {
gpioinit();
while (1) {
uint8 level = GPIO_INPUT_GET(GPIO_ID_PIN(5));
if (level == 0) {
vTaskDelay(3000 / portTICK_RATE_MS);
level = GPIO_INPUT_GET(GPIO_ID_PIN(5));
if (level == 0) {
if(!reset_smartconfig_status)
{
printf("reset to do smartconfig task\r\n");
wifi_station_disconnect();//先断开连接函数
os_timer_disarm(&reconnect_timer);
reset_smartconfig_status = true;//开始复位重新smartconfig状态位
xTaskCreate(smartconfig_task, "smartconfig_task", 256, NULL,
2, NULL); //smartconfig任务
}
}
}
vTaskDelay(1000 / portTICK_RATE_MS);
}
vTaskDelete(NULL);
}
延时使用:
vTaskDelay(1000 / portTICK_RATE_MS);
在方法的末尾需要加上:
vTaskDelete(NULL);
UDP功能
我是做智能硬件的,里面多数用到udp,tcp一般只有网关才用到;
主要需要设置远程ip和远程端口号,注册发送,接收回调,初始化就可以了,其实很简单;
SNTP功能
这是一个实时时钟,联网后可以查询到实时的时间,使用方法如下:
sntp_setservername(0, "0.cn.pool.ntp.org");
sntp_setservername(1, "1.cn.pool.ntp.org");
sntp_setservername(2, "2.cn.pool.ntp.org");
sntp_init();