【FR8016外设模拟I2C应用】BLE心率监测-程序员宅基地

技术标签: 蓝牙  


  本次测评fr8016的模拟i2c外设和蓝牙功能,通过芯片的IO口模拟I2C通信时序与心率模块max30102通信,采集人体心率,将结果通过BLE上传给安卓手机显示。运用到SDK的内容有

  • BLE协议栈GATT、GAP
  • IO模拟I2C
  • 系统定时任务CLOCK
  • 操作系统抽象层OSAL

  下面将逐一介绍,从max30102驱动开始,最终实现心率数据向安卓手机上传,完成一个BLE应用。

一、FR8016资源与SDK架构

1.1 FR8016资源

在这里插入图片描述

  • FLASH Cache RAM:这是一个8KB的数据RAM,主要由缓存控制器使用。缓存控制器直接从外部QSPI FLASH执行,从而减少对FLASH的访问。
  • UART:异步串行接口,具有32字节深度的FIFO,波特率从4800到921600不等。
  • SPI:串行外设接口,具有128字节深度和8位宽度的FIFO。最大总线频率为24MHz。
  • I2C:这是用于传感器和/或主机MCU通信的主I2C接口。它包括一个8位宽、8字节深的RX FIFO和一个8位宽、10字节深的TX FIFO。最大总线频率为2MHz。
  • QSPI Controller:与Quad SPI Flash设备的接口,最大总线频率为24MHz
  • SARADC:差分逐次逼近寄存器模数转换器。它支持多达8个外部模拟输入通道,10位宽度和1MHz采样率。
  • RADIO Transciver:此模块实现2.4GHz的蓝牙低能量协议的射频部分。
  • clock generator:此块负责系统的计时。它包含一个24MHz晶体振荡器,用于系统的有源模式。还有一个62.5 kHz振荡器(RC62.5K),精度(<300 ppm)。RCX振荡器可用作休眠时钟,以提高功耗,同时减少系统的物料清单。
  • timer:2个独立的16位计数器计时器.
  • PWM:PWM模块电路实现脉宽调制波输出。6通道数字PWM输出模块,超高达(1/48M)分辨率。另外还有另一个3通道PMU PWM输出模块,具有1/(PMU系统clk)分辨率。
  • Keyboard scanner: 该电路实现了对键盘矩阵的扫描和去抖动,并在不需要CPU的情况下对可配置的动作产生中断。
  • AHB/APB bus:执行AHB和APB规范的AMBA Lite版本。
  • I2S和PDM端口:该部分通过脉冲密度调制(PDM)和IC间声音(I2S)接口实现音频流。它支持使用PDM接口和内部编解码器块的数字麦克风、模拟麦克风和单声道扬声器.I2S接口具有64 16位宽度FIFO深度、最大24MHz总线速度和16 kHz/8kHz、16位采样率。PDM接口具有64个16位宽度FIFO深度、1MHz/2MHz总线速度和16 kHz/8kHz、16位采样率。
  • audio codec:它由1路16位∑ΔADC和1路16位∑ΔDAC组成,采样率高达48kHz。内部麦克风偏置等于0.9*编解码器电源电压,输入PGA放大器-17.25dB-30dB增益范围,输出耳机PA,音频编解码器块内输出功率高达50mW。
  • 电源管理。一个复杂的电源管理电路,带有降压型DC-DC转换器和几个LDO,可通过PMU模块打开/关闭。即使FR801xH处于睡眠/深度睡眠模式,也会提供额外的引脚为外部设备供电.它还包括用于蓄电池充电的恒流/恒压(CCCV)充电器和充电状态燃油表电路。CCCV充电器电流从48mA到258mA不等。
    该模块还包括一个LDO输出,最大驱动能力为125mA,输出电压范围为1.8~3.5V。引脚垫驱动能力为12mA。所有焊盘的总驱动能力等于LDO输出驱动能力,即125mA。

1.2 SDK架构

  FR801xH SDK 的架构如下图所示。 SDK 包含了完整的 BLE 5.0 协议栈, 包括完整的 controller, host, profile, SIG Mesh部分。 其中蓝牙协议栈的 controller 和 host 部分以及操作系统抽象层 OSAL 都是以库的形式提供, 图中为灰色部分。 MCU 外设驱动和 profile, 以及应用层的例程代码, 都是以源码的形式提供, 图中为绿色部分。
在这里插入图片描述

二、心率芯片max30102通信协议及驱动编程

2.1 max30102介绍

2.1.1 功能图

在这里插入图片描述

2.1.2 详细说明

  MAX30102是一个完整的脉搏血氧饱和度和心率传感器系统解决方案模块,专为可穿戴设备的苛刻要求而设计。该设备在不牺牲光学或电学性能的情况下保持非常小的解决方案尺寸。集成到可穿戴系统中需要最少的外部硬件组件。
  MAX30102通过软件寄存器完全可调,数字输出数据可存储在IC内的32深FIFO中。FIFO允许MAX30102连接到共享总线上的微控制器或处理器,在共享总线上数据不是从MAX30102的寄存器连续读取的。

2.1.3 血氧饱和度子系统

  MAX30102的SpO2子系统包含环境光消除(ALC)、连续时间sigma-delta ADC和专有的离散时间滤波器。自动高度控制有一个内部跟踪/保持电路,以消除环境光并增加有效动态范围。SpO2 ADC的可编程满标度范围为2µA至16µA。ALC可抵消高达200µA的环境电流。
  内部ADC是一个具有18位分辨率的连续时间过采样sigma-delta转换器。ADC采样率为10.24MHz。ADC输出数据速率可从50sps(每秒采样数)编程到3200sps。

2.1.4 温度传感器

  MAX30102有一个片上温度传感器,用于校准SpO2子系统的温度依赖性。温度传感器的固有分辨率为0.0625°C。
  设备输出数据对红外LED的波长相对不敏感,其中红色LED的波长对于正确解释数据至关重要。与MAX30102输出信号一起使用的SpO2算法可以补偿与环境温度变化相关的SpO2误差。

2.1.5 LED驱动器

  MAX30102集成了红色和红外LED驱动器,用于调制用于SpO2和HR测量的LED脉冲。在适当的电源电压下,LED电流可编程设定在0到50mA之间。LED脉冲宽度可从69µs编程到411µs,以允许算法根据用例优化SpO2和HR精度以及功耗。

2.1.6 接近功能

  当用户的手指不在传感器上时,该装置包括接近功能以节省功率并减少可见光发射。当SpO2或HR功能启动时(通过写入模式寄存器),IR LED在接近模式下激活,驱动电流由PILOT PA寄存器设置。当通过超过IR ADC计数阈值(在PROX\u INT\u THRESH寄存器中设置)检测到物体时,部件自动转换到正常SpO2/HR模式。要重新进入接近模式,必须重写模式寄存器(即使值相同)。
  可通过将接近功能重置为0来禁用接近功能。在这种情况下,血氧饱和度或心率模式立即开始。

2.2 i2c通信协议

2.2.1 从FIFO读取

  通常,从I2C接口读取寄存器会自动递增寄存器地址指针,这样所有寄存器都可以在无I2C启动事件的突发读取中读取。在MAX30102中,这适用于除FIFO数据寄存器(寄存器0x07)以外的所有寄存器。
  读取FIFO\数据寄存器不会自动增加寄存器地址。突发读取该寄存器从同一地址反复读取数据。每个样本都包含多个字节的数据,因此应从该寄存器(在同一事务中)读取多个字节以获得一个完整的样本。
  另一个例外是0xFF。在0xFF寄存器之后读取更多字节不会使地址指针返回0x00,读取的数据也没有意义。

2.2.2 FIFO数据结构

  数据FIFO由一个32采样内存组组成,它可以存储IR和Red ADC数据。由于每个样本由两个数据通道组成,因此每个样本有6个字节的数据,因此FIFO中可以存储总共192个字节的数据。
  FIFO数据左对齐,如表1所示;换句话说,无论ADC分辨率设置如何,MSB位始终位于位17数据位置。FIFO数据结构的直观表示见表2。
表1。FIFO数据左对齐
在这里插入图片描述

2.2.3FIFO数据每个通道包含3个字节

  FIFO数据左对齐,这意味着无论ADC分辨率设置如何,MSB始终位于同一位置。未使用FIFO数据[18]–[23]。表2显示了每个三元组字节的结构(包含每个通道的18位ADC数据输出)。
  SpO2模式下的每个数据样本包含两个数据三元组(每个三元组3个字节),要读取一个样本,每个字节需要一个I2C读取命令。因此,要在SpO2模式下读取一个样本,需要读取6个I2C字节。读取每个样本的第一个字节后,FIFO读取指针将自动递增。

2.2.4 写/读指针

  写/读指针用于控制FIFO中的数据流。每次向FIFO添加新样本时,写入指针都会递增。每次从FIFO读取样本时,读取指针都会递增。要从FIFO中重新读取样本,将其值减一,然后再次读取数据寄存器。
  在进入SpO2模式或HR模式时,应清除FIFO写/读指针(返回0x00),以便在FIFO中没有表示的旧数据。如果VDD通电或VDD低于其UVLO电压,指针将自动清除。
表2。FIFO数据(每个通道3字节)
在这里插入图片描述
在这里插入图片描述

2.3 驱动编程

2.3.1 从FIFO读取数据的伪代码示例

第一个事务:获取FIFO_WR_PTR:
START;
Send device address + write mode
Send address of FIFO_WR_PTR;
REPEATED_START;
Send device address + read mode
Read FIFO_WR_PTR;
STOP;
中央处理器评估要从FIFO读取的样本数:
NUM_AVAILABLE_SAMPLES = FIFO_WR_PTR – FIFO_RD_PTR
(Note: pointer wrap around should be taken into account)
NUM_SAMPLES_TO_READ = < less than or equal to NUM_AVAILABLE_SAMPLES >
第二个事务:从FIFO读取样本数:
START;
Send device address + write mode
Send address of FIFO_DATA;
REPEATED_START;
Send device address + read mode
for (i = 0; i < NUM_SAMPLES_TO_READ; i++) {
Read FIFO_DATA;
Save LED1[23:16];
Read FIFO_DATA;
Save LED1[15:8];
Read FIFO_DATA;
Save LED1[7:0];
Read FIFO_DATA;
Save LED2[23:16];
Read FIFO_DATA;
Save LED2[15:8];
Read FIFO_DATA;
Save LED2[7:0];
Read FIFO_DATA;
}
STOP;
START;
Send device address + write mode
Send address of FIFO_RD_PTR;
Write FIFO_RD_PTR;
STOP;
第三个事务:写入FIFO_RD_PTR寄存器。如果第二个事务成功,则FIFO_RD_PTR指向FIFO中的下一个样本,而第三个事务不是必需的。否则,处理器会适当地更新FIFO_RD_PTR,以便重新读取样本。

2.3.2 编程实现

  这里以读取数据的FIFO为例子,介绍fr8016读取max30102的fifo。

int8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
/**
* \brief        Read a set of samples from the MAX30102 FIFO register
* \par          Details
*               This function reads a set of samples from the MAX30102 FIFO register
*
* \param[out]   *pun_red_led   - pointer that stores the red LED reading data
* \param[out]   *pun_ir_led    - pointer that stores the IR LED reading data
*
* \retval       true on success
*/
{
    
    uint32_t un_temp;
    unsigned char uch_temp;
    char ach_i2c_data[6];
    uint8_t Ack1,Ack2,Ack3;//,Ack4;
    *pun_red_led=0;
    *pun_ir_led=0;
    //read and clear status register
    maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
    maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
    ach_i2c_data[0]=REG_FIFO_DATA;
    sensirion_i2c_start();
    Ack1 = sensirion_i2c_write_byte(I2C_WRITE_ADDR);	//发送设备写地址
    Ack2 = sensirion_i2c_write_byte(ach_i2c_data[0]);	//发送寄存器地址
    sensirion_i2c_start();
    Ack3 = sensirion_i2c_write_byte(I2C_READ_ADDR);	//发送设备读地址
    //un_temp=(unsigned char) ach_i2c_data[0];
    un_temp = sensirion_i2c_read_byte(1);//读取
    un_temp<<=16;
    *pun_red_led+=un_temp;
    //un_temp=(unsigned char) ach_i2c_data[1];
    un_temp = sensirion_i2c_read_byte(1);//读取
    un_temp<<=8;
    *pun_red_led+=un_temp;
    //un_temp=(unsigned char) ach_i2c_data[2];
    un_temp = sensirion_i2c_read_byte(1);//读取
    *pun_red_led+=un_temp;
// un_temp=(unsigned char) ach_i2c_data[3];
    un_temp = sensirion_i2c_read_byte(1);//读取
    un_temp<<=16;
    *pun_ir_led+=un_temp;
    //un_temp=(unsigned char) ach_i2c_data[4];
    un_temp = sensirion_i2c_read_byte(1);//读取
    un_temp<<=8;
    *pun_ir_led+=un_temp;
    //un_temp=(unsigned char) ach_i2c_data[5];
    un_temp = sensirion_i2c_read_byte(0);//读取
    sensirion_i2c_stop();//产生停止
    *pun_ir_led+=un_temp;
    *pun_red_led&=0x03FFFF;  //Mask MSB [23:18]
    *pun_ir_led&=0x03FFFF;  //Mask MSB [23:18]
    if(Ack1 || Ack2 || Ack3)//如果
        return -1; //发送失败
    else
        return 0; //发送成功
}

  上面需要使用到FR8016的SDK的模拟I2C函数,比如i2c起始,i2c读写一个字节。

#define DELAY_USECC (SENSIRION_I2C_CLOCK_PERIOD_USEC / 2)

static uint8_t sensirion_wait_while_clock_stretching(void) {
    
    uint8_t timeout = 100;

    while (--timeout) {
    
		//co_printf("timeout= %d\r\n",timeout);
        if (sensirion_SCL_read())
            return STATUS_OK;
        sensirion_sleep_usec(DELAY_USECC);
    }

    return STATUS_FAIL;
}

static int8_t sensirion_i2c_write_byte(uint8_t data) {
    
    int8_t nack, i;
    for (i = 7; i >= 0; i--) {
    
        sensirion_SCL_out();
        if ((data >> i) & 0x01)
            sensirion_SDA_in();
        else
            sensirion_SDA_out();
        sensirion_sleep_usec(DELAY_USECC);
        sensirion_SCL_in();
        sensirion_sleep_usec(DELAY_USECC);
        if (sensirion_wait_while_clock_stretching())
            return STATUS_FAIL;
    }
    sensirion_SCL_out();
    sensirion_SDA_in();
    sensirion_sleep_usec(DELAY_USECC);
    sensirion_SCL_in();
    if (sensirion_wait_while_clock_stretching())
        return STATUS_FAIL;
//	printf("sensirion_i2c_write_byte\r\n************");
    nack = (sensirion_SDA_read() != 0);//判断ACK    
    sensirion_SCL_out();
//printf("nack =%d\r\n",nack);
    return nack;
}

static uint8_t sensirion_i2c_read_byte(uint8_t ack) {
    
    int8_t i;
    uint8_t data = 0;
    sensirion_SDA_in();
    for (i = 7; i >= 0; i--) {
    
        sensirion_sleep_usec(DELAY_USECC);
        sensirion_SCL_in();
        if (sensirion_wait_while_clock_stretching())
            return STATUS_FAIL;
        data |= (sensirion_SDA_read() != 0) << i;
        sensirion_SCL_out();
    }
    if (ack)
        sensirion_SDA_out();
    else
        sensirion_SDA_in();
    sensirion_sleep_usec(DELAY_USECC);
    sensirion_SCL_in();
    sensirion_sleep_usec(DELAY_USECC);
    if (sensirion_wait_while_clock_stretching())
        return STATUS_FAIL;
    sensirion_SCL_out();
    sensirion_SDA_in();

    return data;
}

static uint8_t sensirion_i2c_start(void) {
    
    sensirion_SCL_in();
    if (sensirion_wait_while_clock_stretching())
        return STATUS_FAIL;

    sensirion_SDA_out();
    sensirion_sleep_usec(DELAY_USECC);
    sensirion_SCL_out();
    sensirion_sleep_usec(DELAY_USECC);
    return STATUS_OK;
}

static void sensirion_i2c_stop(void) {
    
    sensirion_SDA_out();
    sensirion_sleep_usec(DELAY_USECC);
    sensirion_SCL_in();
    sensirion_sleep_usec(DELAY_USECC);
    sensirion_SDA_in();
    sensirion_sleep_usec(DELAY_USECC);
}

三、【SDK组件一】蓝牙协议栈GATT和GAP编程

  SDK 里面包含了完整的协议栈, 虽然 controller 和 host 部分是以库的形式提供, 但给出了接口丰富的 API 提供给上层应用开发调用。 Profile 则是以源码的形式提供。
GAP操作如下:

/*********************************************************************
 * @fn      simple_peripheral_init
 *
 * @brief   Initialize simple peripheral profile, BLE related parameters.
 *
 * @param   None. 
 *       
 *
 * @return  None.
 */
void simple_peripheral_init(void)
{
    
    // set local device name
	uint8_t local_name[] = "Simple Peripheral";
	gap_set_dev_name(local_name, sizeof(local_name));

	// Initialize security related settings.
	gap_security_param_t param =
	{
    
	    .mitm = false,
	    .ble_secure_conn = false,
	    .io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT,
	    .pair_init_mode = GAP_PAIRING_MODE_WAIT_FOR_REQ,
	    .bond_auth = true,
	    .password = 0,
	};

	gap_security_param_init(&param);

	gap_set_cb_func(app_gap_evt_cb);

	gap_bond_manager_init(BLE_BONDING_INFO_SAVE_ADDR, BLE_REMOTE_SERVICE_SAVE_ADDR, 8, true);
	gap_bond_manager_delete_all();

	mac_addr_t addr;
	gap_address_get(&addr);
	co_printf("Local BDADDR: 0x%2X%2X%2X%2X%2X%2X\r\n", addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5]);

	// Adding services to database
    sp_gatt_add_service();
	speaker_gatt_add_service();				    //创建Speaker profile,
    
	//按键初始化 PD6 PC5
	pmu_set_pin_pull(GPIO_PORT_D, (1<<GPIO_BIT_6), true);
	pmu_set_pin_pull(GPIO_PORT_C, (1<<GPIO_BIT_5), true);
	pmu_port_wakeup_func_set(GPIO_PD6|GPIO_PC5);
	button_init(GPIO_PD6|GPIO_PC5);

	demo_LCD_APP();							            //显示屏
//	demo_CAPB18_APP();						            //气压计
	demo_SHT3x_APP();						            //温湿度
//	gyro_dev_init();						            //加速度传感器
//	
//	//OS Timer
	os_timer_init(&timer_refresh,timer_refresh_fun,NULL);//创建一个周期性1s定时的系统定时器
	os_timer_start(&timer_refresh,1000,1);

}

GATT操作主要是在回调函数sp_gatt_read_cb和sp_gatt_write_cb里进行:

/*********************************************************************
 * @fn      sp_gatt_msg_handler
 *
 * @brief   Simple Profile callback funtion for GATT messages. GATT read/write
 *			operations are handeled here.
 *
 * @param   p_msg       - GATT messages from GATT layer.
 *
 * @return  uint16_t    - Length of handled message.
 */
static uint16_t sp_gatt_msg_handler(gatt_msg_t *p_msg)
{
    
    switch(p_msg->msg_evt)
    {
    
        case GATTC_MSG_READ_REQ:
            sp_gatt_read_cb((uint8_t *)(p_msg->param.msg.p_msg_data), &(p_msg->param.msg.msg_len), p_msg->att_idx);
            break;
        
        case GATTC_MSG_WRITE_REQ:
            sp_gatt_write_cb((uint8_t*)(p_msg->param.msg.p_msg_data), (p_msg->param.msg.msg_len), p_msg->att_idx,p_msg->conn_idx);
            break;
            
        default:
            break;
    }
    return p_msg->param.msg.msg_len;
}

四、【SDK组件二】操作系统抽象层OSAL

本次使用os_user_loop_event_set创建了循环任务读取max30102的心率数据。OSAL有以下部分组成:

  • os_task_create:创建一个任务。 最多支持 20 个任务。 任务不分优先级。 消息按抛送的顺序进行处理
  • os_task_delete:删除一个已经创建的任务。
  • os_msg_post:向某个已经创建的目标任务抛一个消息事件
  • os_user_loop_event_set:用户设置一个跑在 while(1)循环中的函数, 便于用户做一些循环检测或者操作处理。 该循环处理事件优先级最低, 另外用户在需要睡眠时应先清除这个事件。
  • os_user_loop_event_clear:清除循环处理事件。

五、【SDK组件三】系统定时任务CLOCK

软件定时器用来创建一个定时任务,比如10秒钟处理一次任务A,20秒处理一次任务B。

  • os_timer_init:初始化一个软件定时器。 最多支持 50 个定时器。 使用软件定时器之前, 必须调用该函数进行初始化。
  • os_timer_start:启动一个软件定时器
  • os_timer_stop:停止一个软件定时器

六、测试

连接图

(FR8016) PC6 ->SCL(MAX30102)
(FR8016) PC7 ->SDA(MAX30102)
(FR8016) PA5 ->INT(MAX30102)
在这里插入图片描述

测试一:功能验证

手机在应用商店下载一个 蓝牙调试器。可见我的心率在80~90之间,完成了心率数据通过BLE上传到我的安卓手机。
在这里插入图片描述

测试二:BLE安全

通过USB dongle抓包,可见fr8016与我的安卓手机建立了加密通信。
在这里插入图片描述

测试三:逻辑分析仪分析

由下图可见,fr8016与max30102能正常的进行i2c通信。
在这里插入图片描述

项目地址

修改后上传

视频链接

拍摄后上传

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43810563/article/details/115440618

智能推荐

Android Studio使用百度语音合成是TTS时报错: ****.so文件找不到的有关问题_旧版的百度语言合成报错-程序员宅基地

文章浏览阅读2.1k次。使用百度语音合成过程时,一直error : notfint libgnustl_shared.so在项目工程gradle文件中添加如下代码段:sourceSets { main { jniLibs.srcDirs = ['libs'] } }..._旧版的百度语言合成报错

BZOJ1202: [HNOI2005]狡猾的商人_狡猾的商人[hnoi2005]-程序员宅基地

文章浏览阅读425次。Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了n个月以来的收入情况,其中第i个月的收入额为Ai(i=1,2,3…n-1,n), 。当 Ai大于0时表示这个月盈利Ai 元,当 Ai小于0时表示这个月亏损Ai元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那_狡猾的商人[hnoi2005]

HTML5 Web SQL 数据库_方式准则的定义-程序员宅基地

文章浏览阅读1k次。1、HTML5 Web SQL 数据库 Web SQL 数据库 API 并不是 HTML5 规范的一部分,但是它是一个独立的规范,引入了一组使用 SQL 操作客户端数据库的 APIs。如果你是一个 Web 后端程序员,应该很容易理解 SQL 的操作。Web SQL 数据库可以在最新版的 Safari, Chrome 和 Opera 浏览器中工作。2、核心方法 以下是规范中定义的三个_方式准则的定义

spring Boot 中使用线程池异步执行多个定时任务_springboot启动后自动开启多个线程程序-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏6次。spring Boot 中使用线程池异步执行多个定时任务在启动类中添加注解@EnableScheduling配置自定义线程池在启动类中添加注解@EnableScheduling第一步添加注解,这样才会使定时任务启动配置自定义线程池@Configurationpublic class ScheduleConfiguration implements SchedulingConfigurer..._springboot启动后自动开启多个线程程序

Maven编译打包项目 mvn clean install报错ERROR_mvn clean install有errors-程序员宅基地

文章浏览阅读1.1k次。在项目的target文件夹下把之前"mvn clean package"生成的压缩包(我的是jar包)删掉重新执行"mvn clean package"再执行"mvn clean install"即可_mvn clean install有errors

navacate连接不上mysql_navicat连接mysql失败怎么办-程序员宅基地

文章浏览阅读974次。Navicat连接mysql数据库时,不断报1405错误,下面是针对这个的解决办法:MySQL服务器正在运行,停止它。如果是作为Windows服务运行的服务器,进入计算机管理--->服务和应用程序------>服务。如果服务器不是作为服务而运行的,可能需要使用任务管理器来强制停止它。创建1个文本文件(此处命名为mysql-init.txt),并将下述命令置于单一行中:SET PASSW..._nvarchar链接不上数据库

随便推点

微信小程序api视频课程-定时器-setTimeout的使用_微信小程序 settimeout 向上层传值-程序员宅基地

文章浏览阅读1.1k次。JS代码 /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { setTimeout( function(){ wx.showToast({ title: '黄菊华老师', }) },2000 ) },说明该代码只执行一次..._微信小程序 settimeout 向上层传值

uploadify2.1.4如何能使按钮显示中文-程序员宅基地

文章浏览阅读48次。uploadify2.1.4如何能使按钮显示中文博客分类:uploadify网上关于这段话的搜索恐怕是太多了。方法多也试过了不知怎么,反正不行。最终自己想办法给解决了。当然首先还是要有fla源码。直接去管网就可以下载。[url]http://www.uploadify.com/wp-content/uploads/uploadify-v2.1.4...

戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)_vmware-vcsa-all-6.7.0-8169922.iso-程序员宅基地

文章浏览阅读9.6k次,点赞5次,收藏36次。戴尔服务器安装VMware ESXI6.7.0教程(U盘安装)一、前期准备1、下载镜像下载esxi6.7镜像:VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso这里推荐到戴尔官网下载,Baidu搜索“戴尔驱动下载”,选择进入官网,根据提示输入服务器型号搜索适用于该型号服务器的所有驱动下一步选择具体类型的驱动选择一项下载即可待下载完成后打开软碟通(UItraISO),在“文件”选项中打开刚才下载好的镜像文件然后选择启动_vmware-vcsa-all-6.7.0-8169922.iso

百度语音技术永久免费的语音自动转字幕介绍 -程序员宅基地

文章浏览阅读2k次。百度语音技术永久免费的语音自动转字幕介绍基于百度语音技术,识别率97%无时长限制,无文件大小限制永久免费,简单,易用,速度快支持中文,英文,粤语永久免费的语音转字幕网站: http://thinktothings.com视频介绍 https://www.bilibili.com/video/av42750807 ...

Dyninst学习笔记-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏9次。Instrumentation是一种直接修改程序二进制文件的方法。其可以用于程序的调试,优化,安全等等。对这个词一般的翻译是“插桩”,但这更多使用于软件测试领域。【找一些相关的例子】Dyninst可以动态或静态的修改程序的二进制代码。动态修改是在目标进程运行时插入代码(dynamic binary instrumentation)。静态修改则是直接向二进制文件插入代码(static b_dyninst

在服务器上部署asp网站,部署asp网站到云服务器-程序员宅基地

文章浏览阅读2.9k次。部署asp网站到云服务器 内容精选换一换通常情况下,需要结合客户的实际业务环境和具体需求进行业务改造评估,建议您进行服务咨询。这里仅描述一些通用的策略供您参考,主要分如下几方面进行考虑:业务迁移不管您的业务是否已经上线华为云,业务迁移的策略是一致的。建议您将时延敏感型,有快速批量就近部署需求的业务迁移至IEC;保留数据量大,且需要长期稳定运行的业务在中心云上。迁移方法请参见如何计算隔离独享计算资源..._nas asp网站