模拟IIC通讯协议(stm32)(硬件iic后面在补)

一、IIC基础知识总结。

        1、IIC通讯需要两条线就可以,SCL、SDA。

        2、IIC的数据传输的速率,不同的ic是不同的,根据电平维持的延时函数的时间来确定IIC数据传输的速率.

        3、IIC的延时函数可以使用延时函数,延时函数一般使用系统滴答时钟产生延时,也是在Sysclk频率总线的基础上产生的延时。这个延时和“__NOP();”指令产生的延时是一样的,“__NOP();”也是依靠Sysclk频率产生延时。使用场景:“__NOP();”指令是一个汇编指令的运行产生延时,是占用cpu的,短时间且精确的延时是可以使用的;较长时间的精准的延时还是需要使用系统滴答时钟的定时器实现延时的。

        4、标准的IIC传输节拍信号是由7种的:起始信号、停止信号、产生ACK应答信号、产生NACK应答信号、等待ACK应答信号、接收1byte字节信号、发送1byte字节信号。

        5、在标准IIC信号中分为两种形式:边沿信号,上升沿或者下降沿(起始信号、停止信号)。电平信号,高电平或者低电平(产生ACK应答信号、产生NACK应答信号、等待ACK应答信号、接收1byte字节信号、发送1byte字节信号)。

        6、上面的两类信号,也就是7种信号中,SDA的信号必须在SCL为高电平的时候有效。

        7、在上面的7种基础信号的基础上,根据不同的芯片封装不同的数据发送和接收的函数,下面将简单介绍一般的数据发送和接收协议形式,大部分ic芯片都是相同的。

        ic数据的发送:

        (1)发送起始位。

        (2)发送写控制字节,写控制字节的最后一位表示“写”,其他的位表示IC的id。

        (3)等待IC的ACK回应。

        (4)发送地址字节。

        (5)等待IC的ACK回应。

        (6)发送写入的数据字节。

        (7)等待IC的ACK回应。

        (8)如果单字节写入,只能写入一次,Pag页的写入,5,6可以进行多次。

        (9)最后给IC发送停止位。

        ic数据的接收:

        (1)发送起始位。

        (2)发送写控制字节,写控制字节的最后一位表示“写”,其他的位表示IC的id。

        (3)等待IC的ACK回应。

        (4)写入地址高字节(如果是16位地址数据)。

        (5)等待IC的ACK回应。

        (6)写入地址低字节

        (7)等待IC的ACK回应。

        (8)发送起始位。

        (9)发送读控制字节,读控制字节的最后一位表示“读”,其他的位表示IC的id。

        (10)等待IC的ACK回应。

        (11)接收数据。

        (12)数据没有接收完毕,继续接收,发送ACK回应信号。

        (13)接收数据。

        (14)数据接收完毕,发送NACK回应信号。

        (15)发送停止位。

        8、停止信号,最后保持SCL为高电平;其他信号,函数结束的最后一定要保持SCL为低电平。

二、IIC使用引脚的配置电平的配置。

1、SDA的GPIO输入

static void i2c_sda_in(void)
{GPIO_InitTypeDef  gpio_cfg;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_cfg.Pin = bus_i2c->sda_pin;gpio_cfg.Mode = GPIO_MODE_INPUT;
//    gpio_cfg.Pull = GPIO_PULLUP;HAL_GPIO_Init((GPIO_TypeDef*)bus_i2c->sda_port, &gpio_cfg);
}

2、SDA的GPIO输出

static void i2c_sda_out(void)
{GPIO_InitTypeDef  gpio_cfg;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_cfg.Pin = bus_i2c->sda_pin;gpio_cfg.Mode = GPIO_MODE_OUTPUT_OD;gpio_cfg.Pull = GPIO_PULLUP;gpio_cfg.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init((GPIO_TypeDef*)bus_i2c->sda_port, &gpio_cfg);
}

3、SCL的GPIO输出

static void i2c_scl_out(void)
{GPIO_InitTypeDef  gpio_cfg;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_cfg.Pin = bus_i2c->scl_pin;gpio_cfg.Mode = GPIO_MODE_OUTPUT_OD;gpio_cfg.Pull = GPIO_PULLUP;gpio_cfg.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init((GPIO_TypeDef*)bus_i2c->scl_port, &gpio_cfg);
}

4、SDA输出高低电平

static void i2c_sda_write(unsigned char value)
{HAL_GPIO_WritePin((GPIO_TypeDef*)bus_i2c->sda_port, bus_i2c->sda_pin, value?GPIO_PIN_SET:GPIO_PIN_RESET);
}

5、SCL输出高低电平

static void i2c_scl_write(unsigned char value)
{HAL_GPIO_WritePin((GPIO_TypeDef*)bus_i2c->scl_port, bus_i2c->scl_pin, value?GPIO_PIN_SET:GPIO_PIN_RESET);
}

6、SDA电平读取

static unsigned int i2c_sda_read(void)
{return HAL_GPIO_ReadPin((GPIO_TypeDef*)bus_i2c->sda_port, bus_i2c->sda_pin);
}

三、IIC基础信号

1、起始信号(边沿信号)

        刚开始的时候SDA和SCL引脚信号应该都是高电平,起始信号之后要保持SCL为低电平。

在SCL高电平的时候,SDA产生下降沿。

(1)SAD拉高+延时函数

(2)SCL拉高+延时函数

(3)SDA拉低+延时函数

(4)SCL拉低+延时函数

static void i2c_start(void)
{i2c_sda_out();i2c_sda_write(1);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_sda_write(0);i2c_delay();i2c_scl_write(0);i2c_delay();
}

2、停止信号(边沿信号)

           结束的时候SCL的电平一定是低电平,但是SDA的电平是不确定的,所以应该先把SDA电平拉低。

        在SCL为高电平的时候,SDA产生上升沿。

(1)SDA拉低+延时函数

(2)SCL拉高+延时函数

(3)SDA拉高+延时函数

static void i2c_stop(void)
{i2c_sda_out();i2c_sda_write(0);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_sda_write(1);i2c_delay();
}

3、延时函数

        延时函数就使用汇编指令“__NOP()”。具体知识参考其他文章。

static void i2c_delay(void)
{__NOP();
}

4、发送ACK应答信号(电平信号)

        SCL电平一定是低电平,SDA电平未知。SCL为高电平的时候,SDA为低电平,为ACK应答信号。但是这个信号必须在数据接受完之后发送才有效。

(1)SDA拉低+延时函数

(2)SCL拉高+延时函数

(3)SCL拉低+延时函数

static void i2c_write_ack(void)
{i2c_sda_out();i2c_sda_write(0);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_scl_write(0);i2c_delay();
}

5、发送NACK应答信号(电平信号)

        SCL电平一定为低电平,SDA的状态确定。在SCL为高电平的时候,SDA为高电平。这个信号也是只有在读取完数据之后发送才可以。

(1)SDA拉高+延时函数

(2)SCL拉高+延时函数

(3)SCL拉低+延时函数

static void i2c_write_nack(void)
{i2c_sda_out();i2c_sda_write(1);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_scl_write(0);i2c_delay();
}

6、等待ACK应答信号(电平信号)

        SCL一定为高电平,SDA电平不确定。在SCL为高电平的时候,读取SDA电平,当读取到SDA为低电平的时候,就说明接收到了ACK信号。

(1)SCL拉高+延时函数

(2)读取SDA电平+延时函数

(3)SCL拉低+延时函数

static unsigned char i2c_read_ack(void)
{unsigned char level = 0;i2c_sda_in();i2c_scl_write(1);i2c_delay();if(i2c_sda_read())level = 1;i2c_scl_write(0);i2c_delay();return level;
}

7、发送数据(电平信号)

        只有在SCL为高电平的时候SDA电平才有效,在SCL为高电平的时候,必须保持SDA电平稳定,所以SCL电平变化之前,SDA应该先变化。

(1)SDA电平变化+延时函数(根绝写入数据位设置电平)

(2)SCL拉高+延时函数

(3)SCL拉低+延时函数

static void i2c_write_byte(unsigned short data)
{int i;unsigned char temp = (unsigned char)(data & 0xFF);i2c_sda_out();for(i=0;i<8;i++){if(temp & 0x80)i2c_sda_write(1);elsei2c_sda_write(0);temp <<= 1;i2c_delay();i2c_scl_write(1);i2c_delay();i2c_scl_write(0);i2c_delay();}
}

8、接收数据(电平信号)

        数据接收和数据发送是一样的,SDA在SCL为高电平的时候有效,所以SCL为高电平的时候读取SDA引脚的电平状态。

(1)SCL拉高+延时函数

(2)读取SDA电平+延时函数

(3)SCL拉低+延时函数

static unsigned char i2c_read_byte(void)
{int i;unsigned char temp = 0;i2c_sda_in();for(i=0;i<8;i++){i2c_scl_write(1);i2c_delay();temp <<= 1;if(i2c_sda_read())temp |= 0x01;i2c_scl_write(0);i2c_delay();}return temp;
}

四、针对IC的写入数据指令和读书数据指令流程

      下面是针对IC的一般情况的数据写入和读出的操作流程。

1、IIC对IC的数据写入(单字节写入)

        下图所示的就是IIC对IC芯片的数据写入的基本逻辑。除了两个边沿信号(起始、停止信号)是不需要等待IC给ACK回应的。写入数据或者地址都是需等待IC的ACK回应,确认IC收到了数据。

(1)写入启动。

(2)写入“ic写控制字节”。

(3)等待ACK响应。

(4)写入寄存器地址。

(5)等待ACK响应。(如果没等到就写入stop位并返回)。

(6)写入要写入的数据(可以使用循环写入多个byte)。

(7)每次写入数据都需要等待ACK响应。

(8)写入stop位。

uint8_t PCT2075DP_Write(uint8_t reg, void* data,uint8_t size)
{int i;uint8_t* pData = (uint8_t*)data;i2c_scl_out();i2c_start();i2c_write_byte(0x90);if(i2c_read_ack){i2c_stop();return -1;}i2c_write_byte(reg);if(i2c_read_ack){i2c_stop();return -3;}for(i=0; i<size; i++){i2c_write_byte(pData[i]);if(i2c_read_ack){i2c_stop();return i;}}i2c_stop();return i;
}

2、IIC对IC的数据读出(单字节读出)

       IIC对IC的数据读取除了两个边沿信号(起始、停止信号)是不需要给IC一个ACK回应信号的。进行数据的读取的时候,每读取一个字节都是需要给IC发送一个ACK回应,代表已经接收到数据,还需要继续接收数据;如果接收到的是最后一个数据,并且不在接收数据,那么就回应NACK信号。

(1)写起始信号位。

(2)写入“ic写控制字节”。

(3)等待IC的ACK回应。

(4)写入地址高字节(如果地址16位就写高字节)。

(5)等待IC的ACK回应。

(6)写入地址低字节。

(7)等待IC的ACK回应。

(8)写入起始信号(本次是重启IIC总线)。

(9)写入“ic读控制字节”。

(10)等待IC的ACK回应。

(11)读取数据字节。

(12)写入ACK回应信号(表示继续读取)。

(13)读取数据字节。

(14)写入NACK回应信号(表示数据读取结束)。

(15)写入停止位。

uint8_t PCT2075DP_Read(uint8_t reg, void* data,uint8_t size, uint8_t poit)
{int i;uint8_t* pData = (uint8_t*)data;i2c_scl_out();i2c_start();i2c_write_byte(0x90);if(i2c_read_ack()){i2c_stop();return -1;}i2c_write_byte(0x00);if(i2c_read_ack()){i2c_stop();return -3;}i2c_start();i2c_write_byte(0x91);if(i2c_read_ack()){i2c_stop();return -4;}for(i=0; i<size; i++){pData[i] = i2c_read_byte();    //需要继续读的时候就回复i2c_write_ack()。if(i == size - 1){i2c_write_nack();}else{i2c_write_ack();}}i2c_stop();return i;
}

下面是总体代码:

#ifndef __MYIIC_H__
#define __MYIIC_H__#include "stm32l0xx_hal.h"
#include "stdint.h"
#include <stdio.h>
#include "delay.h"
#include "485.h"typedef struct sIIC_IO {unsigned int scl_port;unsigned int scl_pin;unsigned int sda_port;unsigned int sda_pin;
}g_tIIC_IO;extern void myTest(float *pvalue);
extern int pct7075_read(float *pvalue);
#endif
#include "Myiic.h"
#include <string.h>
/* 模拟IIC,7个函数。*(1)iic函数发送数据注意发送多少位的兼容。*(2)iic函数发送两个字节的还是一个字节的地址。*(3)SDA的数据电平只有在SCL为高电平的时候有效。*(4)iic功能函数:起始信号、停止信号、产生ACK应答、产生NACK应答,等待ACK应答,接收数据,发送数据*(5)利用面对对象思想,结构体封装模拟iic使用端口和与引脚*(6)引脚的输出输出初始化,引脚电平变化的函数,结构体的封装管理。*/g_tIIC_IO i2c1 = {.scl_port = (unsigned int)GPIOB,.scl_pin  = (unsigned int)GPIO_PIN_6,.sda_port = (unsigned int)GPIOB,.sda_pin  = (unsigned int)GPIO_PIN_7
};g_tIIC_IO *bus_i2c = &i2c1;static void i2c_delay(void)
{__NOP();
}static void i2c_sda_out(void)
{GPIO_InitTypeDef  gpio_cfg;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_cfg.Pin = bus_i2c->sda_pin;gpio_cfg.Mode = GPIO_MODE_OUTPUT_OD;gpio_cfg.Pull = GPIO_PULLUP;gpio_cfg.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init((GPIO_TypeDef*)bus_i2c->sda_port, &gpio_cfg);
}static void i2c_sda_write(unsigned char value)
{HAL_GPIO_WritePin((GPIO_TypeDef*)bus_i2c->sda_port, bus_i2c->sda_pin, value?GPIO_PIN_SET:GPIO_PIN_RESET);
}static void i2c_sda_in(void)
{GPIO_InitTypeDef  gpio_cfg;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_cfg.Pin = bus_i2c->sda_pin;gpio_cfg.Mode = GPIO_MODE_INPUT;
//    gpio_cfg.Pull = GPIO_PULLUP;HAL_GPIO_Init((GPIO_TypeDef*)bus_i2c->sda_port, &gpio_cfg);
}static unsigned int i2c_sda_read(void)
{return HAL_GPIO_ReadPin((GPIO_TypeDef*)bus_i2c->sda_port, bus_i2c->sda_pin);
}static void i2c_scl_out(void)
{GPIO_InitTypeDef  gpio_cfg;__HAL_RCC_GPIOB_CLK_ENABLE();gpio_cfg.Pin = bus_i2c->scl_pin;gpio_cfg.Mode = GPIO_MODE_OUTPUT_OD;gpio_cfg.Pull = GPIO_PULLUP;gpio_cfg.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init((GPIO_TypeDef*)bus_i2c->scl_port, &gpio_cfg);
}static void i2c_scl_write(unsigned char value)
{HAL_GPIO_WritePin((GPIO_TypeDef*)bus_i2c->scl_port, bus_i2c->scl_pin, value?GPIO_PIN_SET:GPIO_PIN_RESET);
}static void i2c_start(void)
{i2c_sda_out();i2c_sda_write(1);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_sda_write(0);i2c_delay();i2c_scl_write(0);i2c_delay();
}static void i2c_stop(void)
{i2c_sda_out();i2c_sda_write(0);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_sda_write(1);i2c_delay();
}static void i2c_write_nack(void)
{i2c_sda_out();i2c_sda_write(1);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_scl_write(0);i2c_delay();
}static void i2c_write_ack(void)
{i2c_sda_out();i2c_sda_write(0);i2c_delay();i2c_scl_write(1);i2c_delay();i2c_scl_write(0);i2c_delay();
}static unsigned char i2c_read_ack(void)
{unsigned char level = 0;i2c_sda_in();i2c_scl_write(1);i2c_delay();if(i2c_sda_read())level = 1;i2c_scl_write(0);i2c_delay();return level;
}static void i2c_write_byte(unsigned short data)
{int i;unsigned char temp = (unsigned char)(data & 0xFF);i2c_sda_out();for(i=0;i<8;i++){if(temp & 0x80)i2c_sda_write(1);elsei2c_sda_write(0);temp <<= 1;i2c_delay();i2c_scl_write(1);i2c_delay();i2c_scl_write(0);i2c_delay();}
}static unsigned char i2c_read_byte(void)
{int i;unsigned char temp = 0;i2c_sda_in();for(i=0;i<8;i++){i2c_scl_write(1);i2c_delay();temp <<= 1;if(i2c_sda_read())temp |= 0x01;i2c_scl_write(0);i2c_delay();}return temp;
}/* 上面就是iic的标准操作函数 */
/*****************************************************************/
/**address:地址*reg:寄存器指针指令**/uint8_t PCT2075DP_Write(uint8_t reg, void* data,uint8_t size)
{int i;uint8_t* pData = (uint8_t*)data;i2c_scl_out();i2c_start();i2c_write_byte(0x90);if(i2c_read_ack){i2c_stop();return -1;}i2c_write_byte(reg);if(i2c_read_ack){i2c_stop();return -3;}for(i=0; i<size; i++){i2c_write_byte(pData[i]);if(i2c_read_ack){i2c_stop();return i;}}i2c_stop();return i;
}uint8_t PCT2075DP_Read(uint8_t reg, void* data,uint8_t size, uint8_t poit)
{int i;uint8_t* pData = (uint8_t*)data;i2c_scl_out();i2c_start();i2c_write_byte(0x90);if(i2c_read_ack()){i2c_stop();return -1;}i2c_write_byte(0x00);if(i2c_read_ack()){i2c_stop();return -3;}i2c_start();i2c_write_byte(0x91);if(i2c_read_ack()){i2c_stop();return -4;}for(i=0; i<size; i++){pData[i] = i2c_read_byte();    //需要继续读的时候就回复i2c_write_ack()。if(i == size - 1){i2c_write_nack();}else{i2c_write_ack();}}i2c_stop();return i;
}void myTest(float *pvalue)
{uint16_t temp,data=0;int retry = 3;float value;/* run in normal mode */PCT2075DP_Write(0x01, &data, 1);while(retry --){if (PCT2075DP_Read(0x00, &temp, 2, 0) == 2)break;}temp = ((temp&0xFF00)>>8)|((temp&0x00FF)<<8);   // 传感器读取数据高8位与低8位位置调转,返回值直接short型value = temp;temp=0;value = value / 256;*pvalue= value;
}int i2c_write(g_tIIC_IO* bus, unsigned char address, unsigned short reg, void* pbuf, int size, unsigned char reg_16bit)
{int i = 0;unsigned char* buf_ptr;if(pbuf == NULL) return i;buf_ptr = (unsigned char*)pbuf;bus_i2c = bus;i2c_scl_out();i2c_start();i2c_write_byte(address | 0);if(i2c_read_ack()) {i2c_stop();return -1;}if(reg_16bit) {i2c_write_byte(reg >> 8);if(i2c_read_ack()) {i2c_stop();return -2;}}i2c_write_byte(reg);if(i2c_read_ack()) {i2c_stop();return -3;}for(i=0;i<size;i++) {i2c_write_byte(buf_ptr[i]);if(i2c_read_ack()) {i2c_stop();return i;}}i2c_stop();return i;
}int i2c_read(g_tIIC_IO* bus, unsigned char address, unsigned short reg, void* pbuf, int size, unsigned char reg_16bit)
{int i = 0;unsigned char* buf_ptr;if(pbuf == NULL) return i;buf_ptr = (unsigned char*)pbuf;bus_i2c = bus;i2c_scl_out();i2c_start();i2c_write_byte(address | 0);if(i2c_read_ack()) {i2c_stop();return -1;}if(reg_16bit) {i2c_write_byte(reg >> 8);if(i2c_read_ack()) {i2c_stop();return -2;}}i2c_write_byte(reg);if(i2c_read_ack()) {i2c_stop();return -3;}i2c_start();i2c_write_byte(address | 1);if(i2c_read_ack()) {i2c_stop();return -4;}for(i=0;i<size;i++) {buf_ptr[i] = i2c_read_byte();if(i == size - 1)i2c_write_nack();elsei2c_write_ack();}i2c_stop();return i;
}int pct7075_read(float *pvalue)
{int retry = 3; // 3次读取失败则传感器数据读取失效,回填0xFFshort temp;float value;
#ifdef PWR_CTRLunsigned char cfg;/* run in normal mode */cfg = 0x00;i2c_write(&PTC2075_I2C_BUS, PTC2075_SLV_ADDR, 0x01, &cfg, 1, 0);
#endif/* 多次读取,方式有时候读取失败 */while(retry --){if (i2c_read(&i2c1, 0x90, 0x00, &temp, 2, 0) == 2)break;}
#ifdef PWR_CTRL/* run in shutdown mode */cfg = 0x01;i2c_write(&i2c1, 0x90, 0x01, &cfg, 1, 0);
#endifif(!retry)   //读取数据失败的情况。{memset(pvalue, 0xFF, 4);return -1;}temp = ((temp&0xFF00)>>8)|((temp&0x00FF)<<8);   // 传感器读取数据高8位与低8位位置调转,返回值直接short型value = temp;value = value / 256;if(pvalue != 0) *pvalue = value;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/111085.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安防监控系统EasyCVR视频汇聚平台设备树收藏按钮的细节优化

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#…

【Linux】:Linux环境与版本

以下哪个命令输出Linux内核的版本信息 A.uname -r B.vmstat C.sar D.stat uname -r 查看linux内核版本信息 vmstat 报告关于内核线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息 sar 主要帮助我们掌握系统资源的使用情况&#xff0c;特别是内存和CPU的使用情况 stat 用于显示…

家政系统预约小程序具备哪些功能?

预约家政小程序有这么大的市场需求加上这么多的好处&#xff0c;相信未来发展前景不错。也必将吸引很多商家投资者着手开发属于自己的上门家政APP小程序软件&#xff0c;在实际的开发过程中需要具备哪些功能呢&#xff1f; 一、用户端功能&#xff1a; 1. 用户注册登录&#x…

了解 AI :了解 AI 方面的一些术语 (中英文对照)

本心、输入输出、结果 文章目录 了解 AI &#xff1a;了解 AI 方面的一些术语 &#xff08;中英文对照&#xff09;前言AI 方面的一些术语 &#xff08;中英文对照&#xff09;AI 方面的一些术语 &#xff08;中英文对照&#xff09; - 文字版弘扬爱国精神 了解 AI &#xff1a…

C:warning: null argument where non-null required (argument 2) [-Wnonnull]

main.c:950:32: warning: null argument where non-null required (argument 2) [-Wnonnull] 这个意思说&#xff0c;函数定义里面由一个attribute&#xff0c;标记第二个参数不能为空。 warning.c:25:2: warning: null argument where non-null required (argument 2) [-Wnon…

什么是热阻?

电流流过导体时&#xff0c;在导体两端会产生电压差&#xff0c;这个电压差除以流过导体的电流就是这个导体的电阻&#xff0c;单位是欧姆。这就是欧姆定律&#xff0c;大家都知道的东西。 当热源的热量在物体中传递时&#xff0c;在物体上也会产生温度差&#xff0c;这个温度差…

UE4 UltrDynamicSky与场景物体进行交互

找到材质 找到其最父类的材质 把这个拖过去连上即可

Canal

目录 一、认识Canal二、安装和配置Canal1、安装mysql2.开启MySQL主从3.安装Canal 三、监听Canal1.引入依赖&#xff1a;2.编写配置&#xff1a;3.修改Item实体类4.编写监听器 学习Redis 高级篇多级缓存【缓存同步】时&#xff0c;相关canal的知识 一、认识Canal Canal [kə’…

MySQL的自增id会用完吗?用完怎么办?

MySQL作为最常用的关系型数据库&#xff0c;无论是在应用还是在面试中都是必须掌握的技能。 目录 一、MySQL自增主键会用完吗 二、MySQL自增主键用完会怎样 1.程序员自己设置的自增主键 2.程序员没有设置自增主键&#xff0c;mysql自动创建row_id 三、mysql中还有哪些自增…

2023年Q3季度国内手机大盘销额下滑2%,TOP品牌销售数据分析

根据Canalys机构发布的最新报告&#xff0c;2023年第三季度&#xff0c;全球智能手机市场出货量仅下跌1%&#xff0c;可以认为目前全球手机市场的下滑势头有所减缓。而国内线上市场的表现也类似。 根据鲸参谋数据显示&#xff0c;今年Q3京东平台手机累计销量约1100万件&#xf…

买卖股票的最佳时机 II[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个整数数组prices&#xff0c;其中prices[i]表示某支股票第i天的价格。在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候最多只能持有一股股票。你也可以先购买&#xff0c;然后在同一天出售。返回你能获得…

第十六届中国智慧城市大会 | 国产化三维重建技术服务智慧城市建设

2023年10月13日&#xff0c;由武汉大势智慧科技有限公司、飞燕航空遥感技术有限公司主办的第十六届智慧城市大会-实景三维技术创新与应用论坛在广州成功举办。 来自实景三维、自然资源、数字孪生、AI大数据、航空遥感等多个领域的专家&#xff0c;深度分享各自的智慧城市建设经…

vue3后台管理系统之layout组件的搭建

1.1静态布局 <template><div class"layout_container"><!-- 左侧导航 --><div class"layout_slider"></div><!-- 顶部导航 --><div class"layout_tabbar"></div><!-- 内容展示区 --><…

Swager如何使用

Swager是一个API文档自动生成工具&#xff0c;可以用于生成API接口文档&#xff0c;供开发者和用户查看和使用。它可以通过描述API接口的规范&#xff0c;自动生成API文档&#xff0c;使得API接口的发布和使用变得更加简单和规范。 下面是使用Swagger的步骤&#xff1a; 首先…

C# LINQ常用操作方法——提升你的编程效率

导语&#xff1a;C# LINQ&#xff08;Language Integrated Query&#xff09;是一种强大且灵活的查询语言&#xff0c;可以将数据查询、过滤、排序和转换等操作无缝集成到C#代码中。本文将介绍一些常用的LINQ操作方法&#xff0c;帮助熟练掌握LINQ的使用&#xff0c;并进一步提…

Python 中,单例模式的5种实现方式(使用模块、使用装饰器、使用类方法、基于new方法实现、基于metaclass方式实现)

单例模式的5种实现方式 1 使用模块 2 使用装饰器 3 使用类方法 4.基于new方法实现 5 基于metaclass方式实现 单例模式的5种实现方式 什么是单例模式&#xff1f; 单例模式是指&#xff1a;保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点# 线程1 执行&#x…

王道计算机考研 操作系统学习笔记篇章二: 进程管理

目录 进程与线程 进程的概念 概念 进程的组成 PCB 程序段、数据段 进程的特征 总结 进程的状态与转换 进程的状态 创建态、就绪态 运行态 阻塞态 终止态 进程的转换 进程的组织 链接方式 索引方式 总结 进程控制 什么是进程控制 如何实现进程控制 进程控制相关的原…

SpringBoot整合WebSocket实战演练——Java入职十三天

前言 本文将介绍如何在Spring Boot应用程序中使用WebSocket实现服务端向客户端推送消息。Spring Boot和WebSocket的整合实现服务端向客户端推送消息,使得客户端能够实时接收并处理服务器发来的信息。WebSocket协议是一种双向通信的网络协议,使得客户端和服务器能够建立持久连…

pycharm远程连接miniconda完整过程,以及遇到的问题解决

问题1&#xff1a;no-zero exit code(126) env: ‘/home/user2/miniconda3/envs/ihan/bin/python3’: Too many levels of symbolic links Python interpreter process exited with a non-zero exit code 126 因为选择的新建导致太多软连接&#xff0c;先在服务器上建好虚拟环…

链式队列----数据结构

队列的基本概念 队列是一种操作受限的线性表&#xff08;先进先出&#xff09;&#xff0c;只允许在队尾插入&#xff0c;队头删除。 例如去银行办理业务&#xff0c;肯定是先来的先出去&#xff0c;后来的人排在后方&#xff0c;只有第一个人业务办理完了&#xff0c;才会有…