51单片机——I2C-EEPROM

I2C:总线标准或通信协议

EEPROM:AT24C02芯片

开发板板载了1个EEPROM模块,可实现IIC通信

1、EEPROM模块电路(AT24C02)

芯片的SCLSDA管脚是连接在单片机的P2.1和P2.0上 

2、I2C介绍

        I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的两线式串行总线,用于连接微控制器(MCU)及其外围设备。是微电子通信控制领域广泛采用的一种总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点

        I2C 总线只有两根双向信号线。一根是数据线SDA,另一根是时钟线SCL

2.1 I2C物理层

I2C通信设备常用的连接方式如下图所示:

特点(了解一下即可): 

(1)它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯主机及多个通讯从机

(2)一个I2C总线只使用两条总线线路,一条双向串行数据线(SDA),一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步

(3)每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问

(4)总线通过上拉电阻接到电源。当I2C设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平

(5)多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线

(6)具有三种传输模式:标准模式传输速率为100kbit/s,快速模式为400kbit/s,高速模式下可达 3.4Mbit/s,但目前大多I2C设备尚不支持高速模式

(7)连接到相同总线的IC数量受到总线的最大电容400pF限制(接5-6个没有问题)

2.2 I2C协议层(作用于MCU)

I2C的协议定义了通信的起始和停止信号、数据有效性、响应、仲裁、时钟同步和地址广播等环节

2.2.1 数据有效性规定

I2C总线进行数据传送时,时钟(SCL)信号为高电平期间,数据(SDA)线上的数据必须保持稳定;只有在时钟(SCL)线上的信号为低电平期间,数据(SDA)线上的高电平或低电平状态才允许变化。如下图所示:

 

每次数据传输都以字节为单位,每次传输的字节数不受限制

每一个字节必须保证是8位长度。数据传送时,先传送最高位

2.2.1.1 读数据的代码 

SCL为高电平时才能读数据 

 //6、读字节
u8 iic_read_byte(u8 ack){
    u8 i=0,receive=0;
    for(i=0;i<8;i++){
        IIC_SCL=0;  //开始时SCL为低电平
        delay_10us(1);  //有一个延时,是因为高低电平变化时,会有一个变化时间,需要延时一下
        IIC_SCL=1;  //往后走变为高电平
        receive<<=1;
        if(IIC_SDA==1){
            receive++;
        }
        delay_10us(1);
    }
    if(!ack){
        iic_ack();
    }else{
        iic_nack();
    }
    return receive;
}

2.2.1.2 写数据的代码 

void iic_write_byte(u8 dat){
    u8 i=0;
    IIC_SCL=0;  //为0时,数据可以改变
    //循环8次,将一个字节传出去
    //要求:先传高位,再传低位
    for(i=0;i<8;i++){
        if((dat&0x80)>0){
            IIC_SDA=1;
        }else{
            IIC_SDA=0;
        }
        dat<<=1;  //把次高位变为最高位
        delay_10us(1);
        IIC_SCL=1;
        delay_10us(1);
        IIC_SCL=0;
        delay_10us(1);
    }
}  

2.2.2 起始和停止信号

起始条件:SCL线为高电平期间,SDA线由电平向电平的变化表示起始信号

终止条件:SCL线为高电平期间,SDA线由电平向电平的变化表示终止信号

如下图所示:

2.2.2.1 起始信号

 void iic_start(){
    IIC_SDA=1;
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=0;  //SDA先变为低电平,先写SDA
//    delay_10us(1);  //可以加,也可以不加
    IIC_SCL=0;  //拉低后,就准备发送和接收数据
//    delay_10us(1);  //可以加,也可以不加
}

2.2.2.2 停止信号

 void iic_stop(){
    IIC_SDA=0;
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=1;
    IIC_SCL=1;  //写不写都可以
}

2.2.3 应答响应

每当发送器件传输完一个字节(长度:8)的数据后,后面必须紧跟一个校验位,这个校验位是接收端通过控制 SDA(数据线)来实现的,以提醒发送端数据我这边已经接收完成,数据传送可以继续进行。这个校验位其实就是数据或地址传输过程中的响应

响应包括“应答(ACK)”和“非应答(NACK)”两种信号

        作为数据接收端时,当设备(无论主从机)接收到I2C传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号即特定的低电平脉冲, 发送方会继续发送下一个数据

        若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号即特定的高电平脉冲,发送方接收到该信号后会产生一个停止信号,结束信号传输

应答响应时序图如下图所示:

发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答

接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据1表示非应答(主机在接收之前,需要释放SDA)

2.2.3.1 应答0

 void iic_ack(){
    IIC_SCL=0;
    IIC_SDA=0;  //应答
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}

2.2.3.2 非应答1

 void iic_nack(){
    IIC_SCL=0;
    IIC_SDA=1;  //非应答
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}

2.2.3.3 等待应答

返回值为0应答;返回值为1非应答

u8 iic_wait_ack(){
    u8 time_temp=0;  //注意:定义变量时放在上方,否则容易出现问题
    IIC_SCL=1;
    delay_10us(1);
    //意外情况,没有应答
    while(IIC_SDA){  //等待IIC_SDA出现低电平
        time_temp++;
        if(time_temp>100){  //超时了,强制退出
            iic_stop();
            return 1;
        }
    }
    IIC_SCL=0;
    return 0;
}

这些信号中,起始信号是必需的,结束信号和应答信号都可以不要 

2.2.4 总线的寻址方式

(1)I2C总线寻址按照从机地址位数可分为两种,一种是7位,另一种是10位。采用7位的寻址字节(寻址字节是起始信号后的第一个字节)的位定义如下图所示:

D7-D1位组成从机的地址。D0位是数据传送方向位,为“0”时表示主机向从机数据,为“1”时表示主机由从机数据 

(2)AT24C02器件地址为7位,高4位固定为1010,低3位由A0/A1/A2信号线的电平决定。因为传输地址或数据是以字节为单位传送的,当传送地址时,器件地址占7位,还有最后一位(最低位R/W)用来选择读写方向,它与地址无关。其格式如下图所示:

如果要对芯片进行写操作时,R/W 即为0,写器件地址即为0XA0;如果要对芯片进行读操作时,R/W 即为1,此时读器件地址为0XA1

(1)和(2)连起来看,两个图代表的意思一样

2.2.5 数据传输

在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/W),用“0”表示主机发送(写)数据(W),“1”表示主机接收()数据(R)

2.2.5.1 写数据

有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。A 表示应答,A 非表示非应答(高电平)。S表示起始信号,P表示终止信号

 

void at24c02_write_one_byte(u8 addr,u8 dat){  //addr:at24c02的地址
    iic_start();                                                //S
    iic_write_byte(0xa0);  //1010 0000          //从机地址和0
    iic_wait_ack();                                         //A
    iic_write_byte(addr);  //指定地址             //寄存器(at24c02)地址
    iic_wait_ack();                                         //A
    iic_write_byte(dat);                                 //数据
    iic_wait_ack();                                         //A/A非
    iic_stop();                                                //P
    delay_ms(10);

2.2.5.2 读数据 

有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。A 表示应答,A 非表示非应答(高电平)。S表示起始信号,P表示终止信号

 u8 at24c02_read_one_byte(u8 addr){  //addr:at24c02的数据地址
    u8 temp=0;
    iic_start();                                                //S
    iic_write_byte(0xa0);  //1010 0000          //从机地址和0
    iic_wait_ack();                                         //A
    iic_write_byte(addr);  //指定地址             //寄存器(at24c02)地址
    iic_wait_ack();                                         //A/A非
    
    iic_start();                                                //S
    iic_write_byte(0xa1);  //1010 0001          //从机地址和1
    iic_wait_ack();                                         //A
    temp=iic_read_byte(1);  //读时从当前地址开始读(因为上方已经指定过at24c02的地址了,所以不需要再次指定at24c02的地址 )
    iic_stop();                                                //P
    return temp;
}

3、软件设计

3.1 创建多文件工程

3.1.1 创建文件夹

在电脑上创建一个实验文件夹,为了与教程配套,这里命名为“I2C-EEPROM实验”,然后在该文件夹内新建App、Public、User三个文件夹,如下图所示:

 

Listings和Objects是软件自动生成的 

App文件夹:用于存放外设驱动文件,如LED、数码管、定时器等(24c02、iic、key、smg四个文件夹)

Public文件夹:用于存放51单片机公共的文件,如延时、51头文件、变量类型重定义等。

User文件夹:用于存放用户主函数文件,如main.c

3.1.2 新建工程

首先打开KEILC51软件,新建一个工程,将工程命名为template并保存在“I2C-EEPROM实验”文件夹下,然后选择芯片类型为“AT89C52”,不使用系统创建启动文件

3.1.3 向工程添加文件

(1)将含有.c文件的文件夹添加到工程中,这里我在工程中创建3组,User、App、Publi,通常在工程组的命名与创建的文件夹名保持一致,方便查找到源文件位置

 

(2)点击下图中的图标,创建新文件,Ctrl+S将文件重命名,并保存到对应的文件夹中

例如:创建新文件,Ctrl+S将文件重命名为public.c,并保存到public文件夹中

 

(3)这样每一个文件夹中都有一个.c和一个.h文件(文件名和文件夹名一样),之后需要将建好的文件添加到(1)创建的工程中

 

App:24c02.c、iic.c、key.c、smg.c

Public:public.c

User:main.c

 

3.1.4 配置魔术棒选项卡

(1)点击下图中的图标

 

(2) 点击Output选项卡,将CreateHEXFile选项勾上

 

(3)点击C51选项卡,将前面添加到工程组中的文件路径包括进来,否则程序中调用其他文件夹的头文件则会报错找不到头文件路径

 

 

 

3.2 实验代码

要实现的功能是:系统运行时,数码管右3位显示0,按K1键将数据写入到EEPROM内保存,按K2键读取EEPROM内保存的数据,按K3键显示数据加1,按K4键显示数据清零,最大能写入的数据是255

一般我们以文件形式存放对应功能的驱动程序时,会创建2个文件,一个是.c源文件,另一个是.h头文件。源文件(.c)通常存放的是外设的驱动程序,比如按键检测函数;而头文件(.h)通常用 来存放管脚定义、变量声明、函数声明

3.2.1 public文件

3.2.1.1 public.h

//头文件中放置函数的声明、全局变量的定义
#ifndef _public_H
#define _public_H
#include "reg52.h"
//全局变量
typedef unsigned int u16;
typedef unsigned char u8;
//两个延迟函数声明
void delay_10us(u16 us);
void delay_ms(u16 ms);
#endif

在头文件的开头,使用“#ifndef”关键字,判断标号“_public_H”是否被定义,若没有被定义,则从“#ifndef”至“#endif”关键字之间的内容都有效

这个头文件(public.h文件)若被其它文件“#include”,它就会被包含到其该文件中,且头文件中紧接着使用“#define”关键字定义上面判断的标号“_public_H”。当这个头文件被同一个文件第二次“#include”包含的时候,由于有了第一次包含中的“#define _public_H” 定义,这时再判断“#ifndef _public_H”,判断的结果就是假了,从“#ifndef” 至“#endif”之间的内容都无效,从而防止了同一个头文件被包含多次,编译时就不会出现“redefine(重复定义)”的错误了

3.2.1.2 public.c

#include "public.h"
void delay_10us(u16 us){
    while(us--);
}
void delay_ms(u16 ms){
    u16 i=0,j=0;
    for(i=0;i<ms;i++){
        for(j=0;j<110;j++);
    }
}

3.2.2 独立按键

3.2.2.1 key.h文件

#ifndef _key_H
#define _key_H
#include "public.h"
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;
u16 key_scan(u16 mode);
#endif

3.2.2.2 key.c文件

 #include "key.h"
u16 key_scan(u16 mode){
    static u16 key=1;
    if(mode==1){
        key=1;
    }
    if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0)){
        delay_10us(1000);
        key=0;
        if(KEY1==0){
            return 1;
        }else if(KEY2==0){
            return 2;
        }else if(KEY3==0){
            return 3;
        }else if(KEY4==0){
            return 4;
        }
    }else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1){
        key=1;
        return 0;
    }
}

3.2.3 动态数码管

3.2.3.1 smg.h

#ifndef _smg_H
#define _smg_H
#include "public.h"
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
#define SMG_A_DP_PORT P0
extern u8 gsmg_code[];
void smg_display(u8 save_buff[],u8 pos);
#endif

3.2.3.2 smg.c

#include "smg.h"
u8 gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//save_buff是一个u8类型的数组,方便外部传入要显示的数据
//pos是数码管从左开始第几个位置开始显示,取值范围是1-8
void smg_display(u8 save_buff[],u8 pos){
    u16 i=0;
    u16 pos_temp=pos-1;
    for(i=pos_temp;i<8;i++){
        //位选
        switch(i){
            case 0:
                LSC=1,LSB=1,LSA=1;  //7
                break;
            case 1:
                LSC=1,LSB=1,LSA=0;  //6
                break;
            case 2:
                LSC=1,LSB=0,LSA=1;  //5
                break;
            case 3:
                LSC=1,LSB=0,LSA=0;  //4
                break;
            case 4:
                LSC=0,LSB=1,LSA=1;  //3
                break;
            case 5:
                LSC=0,LSB=1,LSA=0;  //2
                break;
            case 6:
                LSC=0,LSB=0,LSA=1;  //1
                break;
            case 7:
                LSC=0,LSB=0,LSA=0;  //0
                break;
        }
        SMG_A_DP_PORT=gsmg_code[save_buff[i-pos_temp]];  //save_buff[?](?:0、1、2)
        delay_10us(100);
        SMG_A_DP_PORT=0x00;  //消隐
    }
}

3.2.4 I2C读写字节函数

3.2.4.1 iic.h

#ifndef _iic_H
#define _iic_H
#include "public.h"
//定义管脚
sbit IIC_SCL=P2^1;
sbit IIC_SDA=P2^0;

//iic协议层的函数
//1、起始信号
void iic_start();
//2、停止信号
void iic_stop();
//3、应答
void iic_ack();
//4、非应答
void iic_nack();
//5、等待应答
u8 iic_wait_ack();
//6、读字节
u8 iic_read_byte(u8 ack);
//7、写字节
void iic_write_byte(u8 dat);
#endif

3.2.4.2 iic.c 

#include "iic.h"
//iic协议层的函数

//1、起始信号
void iic_start(){
    IIC_SDA=1;
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=0;
//    delay_10us(1);  //可以加,也可以不加
    IIC_SCL=0;  //拉低后,就准备发送和接收数据
//    delay_10us(1);  //可以加,也可以不加
}

//2、停止信号
void iic_stop(){
    IIC_SDA=0;
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=1;
    IIC_SCL=1;  //写不写都可以
}

//3、应答
void iic_ack(){
    IIC_SCL=0;
    IIC_SDA=0;  //应答
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}

//4、非应答
void iic_nack(){
    IIC_SCL=0;
    IIC_SDA=1;  //非应答
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}

//5、等待应答,返回值为0应答;返回值为1非应答
u8 iic_wait_ack(){
    u8 time_temp=0;  //注意:定义变量时放在上方,否则容易出现问题
    IIC_SCL=1;
    delay_10us(1);
    //意外情况,没有应答
    while(IIC_SDA){  //等待IIC_SDA出现低电平
        time_temp++;
        if(time_temp>100){  //超时了,强制退出
            iic_stop();
            return 1;
        }
    }
    IIC_SCL=0;
    return 0;
}

//6、读字节
u8 iic_read_byte(u8 ack){
    u8 i=0,receive=0;
    for(i=0;i<8;i++){
        IIC_SCL=0;
        delay_10us(1);
        IIC_SCL=1;
        receive<<=1;
        if(IIC_SDA==1){
            receive++;
        }
        delay_10us(1);
    }
    //注意:看看测试时和案例是否一样(没有区别)
    if(!ack){
        iic_ack();
    }else{
        iic_nack();
    }
    return receive;
}
//7、写字节
void iic_write_byte(u8 dat){
    u8 i=0;
    IIC_SCL=0;  //为0时,数据可以改变
    //循环8次,将一个字节传出去
    //要求:先传高位,再传低位
    for(i=0;i<8;i++){
        if((dat&0x80)>0){
            IIC_SDA=1;
        }else{
            IIC_SDA=0;
        }
        dat<<=1;  //把次高位变为最高位
        delay_10us(1);
        IIC_SCL=1;
        delay_10us(1);
        IIC_SCL=0;
        delay_10us(1);
    }

3.2.5 AT24C02读写字节函数

3.2.5.1 at24c02.h

#ifndef _at24c02_H
#define _at24c02_H
#include "public.h"
#include "iic.h"
//写入数据函数
void at24c02_write_one_byte(u8 addr,u8 dat);
//读数据函数
u8 at24c02_read_one_byte(u8 addr);
#endif

3.2.5.2 at24c02.c

#include "at24c02.h"
//写
void at24c02_write_one_byte(u8 addr,u8 dat){  //addr:at24c02的地址
    iic_start();
    iic_write_byte(0xa0);  //1010 0000
    iic_wait_ack();
    iic_write_byte(addr);  //指定地址
    iic_wait_ack();
    iic_write_byte(dat);
    iic_wait_ack();
    iic_stop();
    delay_ms(10);
}

//读
u8 at24c02_read_one_byte(u8 addr){  //addr:at24c02的数据地址
    u8 temp=0;
    iic_start();
    iic_write_byte(0xa0);
    iic_wait_ack();
    iic_write_byte(addr);  //指定地址
    iic_wait_ack();
    
    iic_start();
    iic_write_byte(0xa1);
    iic_wait_ack();
    temp=iic_read_byte(1);  //读时从当前地址开始读
    iic_stop();
    return temp;
}

3.2.6 main.c

 #include "public.h"
#include "smg.h"
#include "key.h"
#include "iic.h"
#include "at24c02.h"
#define EEPROM_ADDRESS 0  //不超过255即可
/*
系统运行时,数码管右3位显示0
按K1键将数据写入到EEPROM内保存
按K2键读取EEPROM内保存的数据
按K3键显示数据加1,最大能写入的数据是255(0-255)
按K4键显示数据清零
*/
void main(){
    u8 key_temp=0;
    u8 save_value=0;  //可以不设为0
    u8 save_buff[3];
    while(1){
        key_temp=key_scan(0);
        if(key_temp==1){  //保存数据(写)
            at24c02_write_one_byte(EEPROM_ADDRESS,save_value);
        }else if(key_temp==2){  //读取数据
            save_value=at24c02_read_one_byte(EEPROM_ADDRESS);
        }else if(key_temp==3){  //数据+1
            save_value++;
            if(save_value==255){
                save_value=255;
            }
        }else if(key_temp==4){  //数据清零
            save_value=0;
        }
        //save_value是一个十进制的值
        //让数码管显示数据,需要得到save_value个位、十位和百位的值
        save_buff[0]=save_value/100;  //百位
        save_buff[1]=save_value/10%10;  //十位
        save_buff[2]=save_value%10;  //个位
        smg_display(save_buff,6);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

了解npm:JavaScript包管理工具

在JavaScript的生态系统中&#xff0c;npm&#xff08;Node Package Manager&#xff09;无疑是一个举足轻重的存在。它不仅是Node.js的包管理器&#xff0c;更是前端开发不可或缺的一部分&#xff0c;为开发者提供了丰富的包资源、便捷的包管理以及强大的社区支持。本文将深入…

Vscode辅助编码AI神器continue插件

案例效果 1、安装或者更新vscode 有些版本的vscode不支持continue,最好更新到最新版,也可以直接官网下载 https://code.visualstudio.com/Download 2、安装continue插件 搜索continue,还未安装的,右下脚有个Install,点击安装即可 <

ffmpeg aac s16 encode_audio.c

用ffmpeg库时&#xff0c;用代码对pcm内容采用aac编码进行压缩&#xff0c;出现如下错误。 [aac 000002bc5edc6e40] Format aac detected only with low score of 1, misdetection possible! [aac 000002bc5edc8140] Error decoding AAC frame header. [aac 000002bc5edc81…

what?ngify 比 axios 更好用,更强大?

文章目录 前言一、什么是ngify&#xff1f;二、npm安装三、发起请求3.1 获取 JSON 数据3.2 获取其他类型的数据3.3 改变服务器状态3.4 设置 URL 参数3.5 设置请求标头3.6 与服务器响应事件交互3.7 接收原始进度事件3.8 处理请求失败3.9 Http Observables 四、更换 HTTP 请求实现…

论文笔记(六十一)Implicit Behavioral Cloning

Implicit Behavioral Cloning 文章概括摘要1 引言2 背景&#xff1a;隐式模型的训练与推理3 隐式模型与显式模型的有趣属性4 policy学习成果5 理论见解&#xff1a;隐式模型的通用逼近性6 相关工作7 结论 文章概括 引用&#xff1a; inproceedings{florence2022implicit,titl…

CES 2025|美格智能高算力AI模组助力“通天晓”人形机器人震撼发布

当地时间1月7日&#xff0c;2025年国际消费电子展&#xff08;CES 2025&#xff09;在美国拉斯维加斯正式开幕。美格智能合作伙伴阿加犀联合高通在展会上面向全球重磅发布人形机器人原型机——通天晓&#xff08;Ultra Magnus&#xff09;。该人形机器人内置美格智能基于高通QC…

【安卓开发】自定义应用图标

要在 Android Studio 中设置应用的图标并自定义大小&#xff0c;可以使用 Android Studio 提供的图标生成工具。以下是具体步骤&#xff1a; 1、打开图标生成工具&#xff1a; 在 Android Studio 中&#xff0c;右键点击 res 文件夹&#xff0c;选择 New -> Image Asset。 …

django基于Python的电影推荐系统

Django 基于 Python 的电影推荐系统 一、系统概述 Django 基于 Python 的电影推荐系统是一款利用 Django 框架开发的智能化应用程序&#xff0c;旨在为电影爱好者提供个性化的电影推荐服务。该系统通过收集和分析用户的观影历史、评分数据、电影的属性信息&#xff08;如类型…

C++笔记之数据单位与C语言变量类型和范围

C++笔记之数据单位与C语言变量类型和范围 code review! 文章目录 C++笔记之数据单位与C语言变量类型和范围一、数据单位1. 数据单位表:按单位的递增顺序排列2. 关于换算关系的说明3. 一般用法及注意事项4. 扩展内容5. 理解和使用建议二、C 语言变量类型和范围基本数据类型标准…

从零开始开发纯血鸿蒙应用之多签名证书管理

从零开始开发纯血鸿蒙应用 一、前言二、鸿蒙应用配置签名证书的方式1、自动获取签名证书2、手动配置签名证书 三、多签名证书配置和使用四、多证书使用 一、前言 由于手机操作系统&#xff0c;比电脑操作系统脆弱很多&#xff0c;同时&#xff0c;由于手机的便携性&#xff0c…

OCR文字识别—基于PP-OCR模型实现ONNX C++推理部署

概述 PaddleOCR 是一款基于 PaddlePaddle 深度学习平台的开源 OCR 工具。PP-OCR是PaddleOCR自研的实用的超轻量OCR系统。它是一个两阶段的OCR系统&#xff0c;其中文本检测算法选用DB&#xff0c;文本识别算法选用CRNN&#xff0c;并在检测和识别模块之间添加文本方向分类器&a…

webpack03

什么是source-map 将代码编译压缩之后&#xff0c;&#xff0c;可以通过source-map映射会原来的代码&#xff0c;&#xff0c;&#xff0c;在调试的时候可以准确找到原代码报错位置&#xff0c;&#xff0c;&#xff0c;进行修改 source-map有很多值&#xff1a; eval &#…

H266/VVC 帧内预测中 ISP 技术

帧内子划分 ISP ISP 技术是在 JVET-2002-v3 提案中详细介绍其原理&#xff0c;在 VTM8 中完整展示算法。ISP是线基内预测&#xff08;LIP&#xff09;模式的更新版本&#xff0c;它改善了原始方法在编码增益和复杂度之间的权衡&#xff0c;ISP 算法的核心原理就是利用较近的像…

day05_Spark SQL

文章目录 day05_Spark SQL课程笔记一、今日课程内容二、Spark SQL 基本介绍&#xff08;了解&#xff09;1、什么是Spark SQL**为什么 Spark SQL 是“SQL与大数据之间的桥梁”&#xff1f;****实际意义**为什么要学习Spark SQL呢?**为什么 Spark SQL 像“瑞士军刀”&#xff1…

Win11+WLS Ubuntu 鸿蒙开发环境搭建(二)

参考文章 penHarmony南向开发笔记&#xff08;一&#xff09;开发环境搭建 OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——标准系统移植指南&#xff08;一&#xff09; OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——小型系统芯片移植指南&#xff08;二&…

【杂谈】-50+个生成式人工智能面试问题(四)

7、生成式AI面试问题与微调相关 Q23. LLMs中的微调是什么&#xff1f; 答案&#xff1a;虽然预训练语言模型非常强大&#xff0c;但它们并不是任何特定任务的专家。它们可能对语言有惊人的理解能力&#xff0c;但仍需要一些LLMs微调过程&#xff0c;开发者通过这个过程提升它…

【深度学习】数据预处理

为了能用深度学习来解决现实世界的问题&#xff0c;我们经常从预处理原始数据开始&#xff0c; 而不是从那些准备好的张量格式数据开始。 在Python中常用的数据分析工具中&#xff0c;我们通常使用pandas软件包。 像庞大的Python生态系统中的许多其他扩展包一样&#xff0c;pan…

赛灵思(Xilinx)公司Artix-7系列FPGA

苦难从不值得歌颂&#xff0c;在苦难中萃取的坚韧才值得珍视&#xff1b; 痛苦同样不必美化&#xff0c;从痛苦中开掘出希望才是壮举。 没有人是绝对意义的主角&#xff0c; 但每个人又都是自己生活剧本里的英雄。滑雪&#xff0c;是姿态优雅的“贴地飞行”&#xff0c;也有着成…

城市生命线安全综合监管平台

【落地产品&#xff0c;有需要可留言联系&#xff0c;支持项目合作或源码合作】 一、建设背景 以关于城市安全的重要论述为建设纲要&#xff0c;聚焦城市安全重点领域&#xff0c;围绕燃气爆炸、城市内涝、地下管线交互风险、第三方施工破坏、供水爆管、桥梁坍塌、道路塌陷七…

请求方式(基于注解实现)

1.编写web.xml文件配置启动信息 <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app><display-name>Archetype Created Web Application</di…