物联网古天乐 发表于 2016-10-18 15:57:52

【常见问题】ESP8266外设

ADC 的性能参数有几个通道?采样率和有效位数是多少?
通道:1采样率:停止 Wi-Fi 的情况下,能达到每秒 100000 次。Wi-Fi 正常工作的情况下,能达到每秒 1000 次。有效位数:内部 ADC 有效位数为 12 位。uint16 system_adc_read(void)//API 返回值的有效位数是 10 位。

从哪里可以得到 ADC 的寄存器 “bitmap” 信息?
ADC 是和内部 RF 电路高度集成的,所以 bitmap 和寄存器信息没有公开,如有特殊需求请与技术支持联系。

ADC 的精度如何?
ESP8266 连接路由器后,单 STA 模式会进入 modem_sleep,导致芯片内部电流发生变化,参ESP8266 连接路由器后,单 STA 模式会进入 modem_sleep,导致芯片内部电流发生变化,参考值变化,因此 ADC 采集异常。用户如果需要测量的非常准确,可以用 system_adc_fast_read 的函数,但是测量之前需要关闭 RF,Wi-Fi 连接会断开。如果需要测试比较准确,数值相差 1,或 2,可以配置 Wi-Fi 为 non_sleep 模式 wifi_set_sleep_type(NONE_SLEEP_T);建议该用户这样配置。如果对精确性要求不高,可以允许模块进入 sleep 模式,功耗较低。

内部 ADC 的用途是什么?
内部 ADC 可以用于温度检测和粗略地测量外部设备电流。由于 ADC 容易受噪声影响,所以推荐只在低精度的需求时使用。比如熔断机制。

(u8 tx_addr, u8 tx_cmd, u8 tx_rep) 这三个参数是什么意思?
tx_addr 是发送地址;u8 tx_cmd 是发送 cmd;u8 tx_rep 是重复发送的次数。

如何使能 UART 流控?

[*]UART 通信时,如需配置 UART 通信的数据格式,请参考 SDK/driver_lib/driver/ 路径下的 uart.c 文件。
[*]UART 通信,如需配置硬件流控。请执行下面两个步骤:
(1) 请在 uart.h 中将下面的宏置 1。#define UART_HW_RTS 1 //set 1: enable uart hw flow control RTS, PIN MTDO, FOR UART0#define UART_HW_CTS 1 //set1: enable uart hw flow contrl CTS , PIN MTCK, FOR UART0
(2) 配置硬件流控的门限值截图中红色标注部分为硬件流控的门限值,在 RXFIFO 中字节数大于 110 后,RTS 将会被拉高。
http://espressif.com/sites/default/files/files/111.png

如何配置信息打印到 UART1 上?
UART1 只有 Tx 功能,可以在 UART0 用于通讯时,做打印 log 用途。
请参考如下代码:
void ICACHE_FLASH_ATTR uart_init_new(void) { // Wait for FIFOs to be emptied    UART_WaitTxFifoEmpty(UART0);     UART_WaitTxFifoEmpty(UART1); // Configure UART settings    UART_ConfigTypeDef uart_config;     uart_config.baud_rate    = BIT_RATE_74880;     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_intr.UART_RX_FifoFullIntrThresh = 100;     uart_intr.UART_RX_TimeOutIntrThresh = 2;     uart_intr.UART_TX_FifoEmptyIntrThresh = 20;     UART_IntrConfig(UART0, &uart_intr); // Set UART1 for printing    UART_SetPrintPort(UART1); // Register interrupt handler    UART_intr_handler_register(uart0_rx_intr_handler);     ETS_UART_INTR_ENABLE(); }

SDIO 是否支持 SD 卡?
ESP8266 是 SDIO Slave ,不支持 SD 卡。

SDIO 最高速度能支持到多少?
SDIO 时钟能到 50 MHz ,理论最高速度是 200 Mbps 。

使用 PWM 时,发现最开始时有窄波,是什么原因?
这个是精度较高的 PWM 的调节方式,PWM 的精度可以达到 22222 深度。精度的调节主要靠后面的窄波。注意这种方式的 PWM Duty 无法配置为 100%。

为什么上电时会有 LED 灯闪一下的情况?
要看灯的驱动是如何设计的。如是低电平灯亮,并且在上电的时候将 IO 强制拉为低电平,那么在上电的瞬间可能会出现灯闪一下。是因为除了 FLASH 相关的 IO 和 GPIO4 ,GPIO5 ,其他 IO 上电后上拉默认使能。
解决方法:
[*]上电的瞬间,user_init 中将上拉关闭。
[*]如第一条无效的,需要我们提供相应的 boot.bin。在该 BIN 被搬到 RAM 的过程里,IO 的上拉就会被关闭。这比 user_init 生效要早。


发现 PWM 的变化缓慢,是什么原因?
客户采用了 SDK example/IOT_demo 中的渐变 API。如 light_set_aim, light_set_aim_r 这些 API 使用的是渐变方式。不会立即生效,需要渐变的过程。
如用户需要 PWM Duty 设置后立即生效,需要调用接口 pwm_set_duty,需要注意调用 pwm_set_duty 后调用 pwm_start 此次设置才能生效。

GPIO 可以直接连 5V 吗?
不可以。GPIO 只能承受 3.6V。需要通过降压电路,否则会造成 GPIO 损坏。

哪里能找到 GPIO 的 register 和 bitmap 信息?
请参考文档《ESP8266 技术参考》。

如何编程 GPIO?
对于 Non-OS SDK,比如需要把 MTDO 配置成输入,同时下降沿触发中断:void ICACHE_FLASH_ATTR gpio_init(void)
{
//GPIO Alternate Function
      PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U,FUNC_GPIO15);
      GPIO_DIS_OUTPUT(GPIO_ID_PIN(15));
      //Configure it in input mode.
      ETS_GPIO_INTR_DISABLE();
    //Close the GPIO interrupt
//Register the interrupt function
      ETS_GPIO_INTR_ATTACH(GPIO_INTERRUPT,NULL);
      gpio_pin_intr_state_set(GPIO_ID_PIN(15),GPIO_PIN_INTR_NEGEDGE);
      //Falling edge trigger
      ETS_GPIO_INTR_ENABLE() ;
    //Enable the GPIO interrupt
}
对于 RTOS SDK,实现相同的功能。{
   GPIO_ConfigTypeDef gpio_in_cfg;
    //Define GPIO Init Structure
   gpio_in_cfg.GPIO_IntrType = GPIO_PIN_INTR_NEGEDGE;
    //Falling edge trigger
   gpio_in_cfg.GPIO_Mode = GPIO_Mode_Input;
    //Input mode
   gpio_in_cfg.GPIO_Pin = GPIO_Pin_15;
    // Enable GPIO
   gpio_config(&gpio_in_cfg);
    //Initialization function
   GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS,
BIT(GPIO_UART_IN_NUM));
   gpio_intr_handler_register(interrupt_GPIO_UART);
    // Register the interrupt function
   _xt_isr_unmask(1 << ETS_GPIO_INUM);
    //Enable the GPIO interrupt
}
注意:Non-OS SDK 和 RTOS SDK 的实现方法稍有不同。

HSPI 每个数据包的大小最大是多少?
数据包每次发送最大 64 字节数据,四字节对齐,在 memory map 上是连续的。数据可以先传输到 LSB 或者 MSB 中,低位组在前或高位组在前,所以缓存是很灵活的。合理的使用 buffer,可以稳定实现 90% 的时钟速度。

对于多设备同时连接到 ESP8266 的情况,HSPI 是如何同时驱动设备的?
与 I2C 接口不同,HSPI 时钟不需要配合最慢的连接设备。HSPI 时钟可以及时的配置为使能的设备。HSPI_CS0 管脚可以自动选择。对于 LCD 类型的设备,需要频繁使用 CS 管脚。如果是连接高速设备,需要使用源端接电阻。

如何使用 64 字节的数据缓存?
使用函数CLEAR_PERI_REG_MASK(SPI_USER(spiNum), SPI_USR_MISO_HIGHPART );使能 MISO 的高位传输。

如何配置 (H)SPI 接口?
请参考 Non-OS SDK 下,example/peripheral_test。

哪些 API 会保存到 Flash ?
wifi_station_set_auto_connectwifi_station_ap_number_setwifi_set_phy_modewifi_softap_set_configwifi_station_set_configwifi_set_opmodesystem_restart_enhancesystem_restoresystem_upgrade_reboot

系统参数是如何保存的?
SPI Flash 的最后三个扇区被定义为系统参数区,其中前两个扇区用于交替保存系统参数,最后一个扇区用来保存使用前面两个扇区的 flag。这样设计的目的是保证在擦写系统参数区时,即使在擦写任意一个扇区时意外掉电,导致该扇区中数据异常的情况下,也不会导致系统的参数异常。

Flash 任何位置都可以随意读写吗?
读写操作都需要四字节对齐。我们推荐对 block 操作,避免频繁的小数据读写。

可以在所有的 ESP8266 上执行同样的 Flash 读写操作吗?
对应不同的 Flash 大小,有着不同的 Flash map,所以对应不同的固件,Flash map 可能不一样,比如对应 8 Mbit 的 Flash,读写 0x100000 地址就是非法的。

可否提供 Flash 擦写例证?
uint32 sector 是开始的 sector,uint32 cnt 是擦除的 sector 数目。
#define FLASH_WRITE_LEN_BYTE (1024*4)#define FLASH_WRITE_CONTENT (0X10)void flash_sector_rw_test(uint32 sector,uint32 cnt){      char* w_data=(char*)os_malloc(FLASH_WRITE_LEN_BYTE);      uint32 flash_operate=0;      uint32 i=0;      uint8 status=0;      os_printf("Test Sector is 0x%x\n",sector);      if(NULL==w_data){         os_printf("Memory little\n");         return;}os_memset(w_data,FLASH_WRITE_CONTENT,FLASH_WRITE_LEN_BYTE);for(i=0;i<cnt;i++){      if(spi_flash_erase_sector(sector+i)==0)       {         os_printf("erase sector0x%x ok\n",sector+i);      }      else{         os_printf("Err:erase sector0x%x err\n",sector+i);      }}for(i=0;i<cnt;i++){      if(spi_flash_write((sector+i)*(FLASH_WRITE_LEN_BYTE),(uint32*)w_data,FLASH_WRITE_LEN_BYTE)==0)      {         os_printf("write sector 0x%x ok\n",sector+i);      }      else{         os_printf("Err:write sector 0x%x err\n",sector+i);      }}for(i=0;i<cnt;i++){         os_memset(w_data,0x00,FLASH_WRITE_LEN_BYTE);      if(spi_flash_read((sector+i)*(FLASH_WRITE_LEN_BYTE), (uint32*)w_data,FLASH_WRITE_LEN_BYTE)==0)      {         uint32 j=0;         for(j=0;j<FLASH_WRITE_LEN_BYTE;j++){         if(*(w_data+j)!=FLASH_WRITE_CONTENT){            os_printf("Err Flash read w_data[%d]=0x%x\n",j,w_data);            //status=1;         }         if(*(w_data+j)==FLASH_WRITE_CONTENT&&j==FLASH_WRITE_LEN_BYTE-1)         {            os_printf("Sector0x%x Test Ok\n",sector+i);               }}      }      else {         os_printf("Err:read sector0x%x err\n",sector+i);
   }}os_free(w_data);w_data=NULL;}

如何判断 Flash 是否支持 QIO 或 DIO 模式?
判断 Flash 是否支持四线:
[*]QE 在状态寄存器的 BIT(9)。
[*]写状态寄存器的格式为 01H+StatusReg1+StatusReg2。
[*]有读 Flash 的如下命令:

[*]

[*]若是选择 QIO,必须支持 EBh 命令。
[*]若是选择 QOUT,必须支持 6 Bh 命令。

判断 Flash 是否支持两线:有读 Flash 的如下命令:
[*]

[*]若是选择 DIO,必须支持 BBh 命令。
[*]若是选择 DOUT,必须支持 3 Bh 命令。

特殊的 Flash:ISSI Flash 可以支持 QIO 模式。

为什么透传过程会丢包?
因为没有设置硬件流控。如果需要避免丢包,请设置硬件流控。透传功能使用的是 TCP 协议,每包数据是 1460 (取决于协议栈),只要网络良好,buffer 空间没有被消耗完,就可以不停地传输数据。对于透传,串口接收数据间隔超过约 20 ms,就会认为数据接收结束,将已经接受的数据传输到网络。如果网络不好,就可能会丢弃一些数据,因此,为避免这种情况,可以将串口设置为流控模式。

ESP8266 有几个 UART?
ESP8266 有两个 UART,其中 UARTO 有 TX、RX,可做数据传输;UART1 由于 RX 脚被 SPI-Flash 占用,只能使用 TX,可以做串口调试信息打印。

GPIO 电平状态是怎样的?
除了 XPD_DCDC,GPIO 可以配置上拉。关于 GPIO 的上电 IO 口默认状态为:除了 SDIO 6根线 +GPIO4+GPIO5+GPIO16 上电 IO 默认无上拉,其他的 GPIO 口均有上拉。由于是内部配置上拉,所以如需下拉,需外部加下拉方式或者加一个三级管的反相电路。
注意:GPIO 不能到 5V。GPIO4/5 外接 1M 电阻不能上拉到高电平;需 100K 电阻。
http://espressif.com/sites/default/files/faq/faq6.jpg

如何屏蔽上电打印?
U0TXD 默认上电有系列打印,对此敏感应用可通过 UART 的内部引脚交换功能,在初始化的时候,调用 system_uart_swap 函数,将 U0TXD、U0RXD 分别与 U0RTS (MTDO/GPIO15),U0CTS (MTCK/GPIO13) 交换来屏蔽该上电的系统打印。交换后,硬件上的下载管脚还是使用 U0TXD+U0RXD,通信时需要将 MTDO 对应接到 MCU 的 RXD,MTCK 对应接到 MCU 的 TXD。

为什么 ESP8266 上电时会出现乱码?如何修改波特率?
如果使用的是 26 MHz 晶振,ESP8266 UARTO 上电后的波特率是 74880,所以上电时会有乱码。
客户可以在 user_main() 里面修改 UART 配置,比如:void ICACHE_FLASH_ATTR
uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
{
      // rom use 74880 baut_rate, here reinitialize
      UartDev.baut_rate = uart0_br;
      uart_config(UART0);
      UartDev.baut_rate = uart1_br;
      uart_config(UART1);
}
































































页: [1]
查看完整版本: 【常见问题】ESP8266外设