37_软件I2C通信实验

news2024/7/6 17:39:17

目录

I2C通信协议

多主机I2C总线系统结构

I2C协议

应答信号ACK

数据有效性

数据传输

I2C设备地址

I2C通讯整个过程

硬件连接

EEPROM(24C02)

 24C02字节写时序

24C02字节读时序

实验源码

I2C通信协议

I2C(IIC,Inter-Integrated Circuit),两线式串行总线,由PHILIPS公司开发用于连接微控制器及其外围设备。它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。IIC是半双工通信方式。

多主机I2C总线系统结构

I2C协议空闲时都是高电平

I2C协议

空闲状态

I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

开始信号停止信号

起始信号:当SCL为高期间, SDA由高到低的跳变;启动信号是种电平跳变时序信号,而不是一个电平信号。

停止信号:当SCL为高期间, SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。

 

 

应答信号ACK

发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应签信号为低电平时,规定为有效应答位(ACK简称应答位)表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。对于反馈有效应答位ACK的要求是,接收器在第9个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信

 

数据有效性

I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。

即,数据在SCL的上升沿到来之前就需准备好。并在在下降沿到来之前必须稳定。

 

数据传输

I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。

I2C设备地址

I2C设备地址一般为8位,最高位7bit位为1时代表读,为0时代表写操作,0~6bit位为从设备地址。

I2C通讯整个过程

写数据

1.主机检测到总线空闲状态下,发送开始信号。

2.主机发送从机地址(8bit)。

3.主机发送地址后,总线上设备将会与自己地址比较,相同则发送应答信号(ACK),确定发送器和接收器。

5.发送器(此时是主机)在发送一个数据(要写到哪里),等待应答。

6.发送器(此时是主机)收到应答信号后开始发送一个字节。

7.接收器(此时是从机)接收完成后发发送一个应答信号(ACK);

8.循环6、7步骤知道数据所有数据发送完成。

9.发送器(此时是主机)发送最后一个字节完成后,收到接收器(此时是从机)应答后,会发送停止信号(告诉接收器此次通讯结束),释放总线。

读数据

1.主机检测到总线空闲状态下,发送开始信号。

2.主机发送从机地址(8bit)写。

3.主机发送地址后,总线上设备将会与自己地址比较,相同则发送应答信号(ACK)

4.主机在发送一个数据(要的读的地址),收到从机应答(ACK)。

5.主机收到应答后重新发送开始信号,然后发送设备地址改为读数据,确定发送器和接收器。

6.发送器(此时是从机)开始发送一个字节。

7.接收器(此时是主机)接收完成后发发送一个应答信号(ACK);

8.直到接受器(此时是主机),不想要数据后,接受到最后一个字节后,不会发送应答信号,而是发送一个停止信号,随后释放总线。

硬件连接

 

EEPROM(24C02)

总容量是256(2048bit/8)个字节。接口: IIC

 

 24C02字节写时序

 

24C02字节读时序

 

实验源码

/**
  ******************************************************************************
  * @file           : user_rcc_config.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_rcc_config.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		RCC配置
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Rcc_config(void)
{	
	/*使能GPIOA时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	/*使能GPIOA时钟*/
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB,ENABLE);
	/*使能UART1时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	

}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_gpio.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_gpio.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		GPIO初始化函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Gpio_Init(void)
{	
	/*GPIO结构体*/
	GPIO_InitTypeDef GPIO_InitTypeDefstruct;
	
	/*UART1发送引脚配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_AF_PP;//推挽复用输出
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;
	/*写入结构体到GPIOA*/
	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
	
	/*UART1接收引脚配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;
	/*写入结构体到GPIOA*/	
	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
	
	/*软件I2C GPIOB6时钟线, GPIOB7数据线*/
	GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_Out_PP ;  //推挽输出
	GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_50MHz;
	/*写入结构体到GPIOB*/
	GPIO_Init(GPIOB, &GPIO_InitTypeDefstruct);
	/*默认设置为I2C空闲状态*/
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	


}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_uart.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_uart.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/

extern uint16_t USART_RX_STA;
extern uint8_t USART_RX_BUF[200];


/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/
#if 1
#pragma import(__use_no_semihosting)  
/*实现Printf代码*/
struct __FILE 
{ 
	int handle; 

}; 
FILE __stdout;       

void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 




/*!
	\brief		UART1初始化
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void Uart1_Init(u32 bound)
{
	/*UART结构体*/
	USART_InitTypeDef USART_InitTypeDefstruct;
	
	/*UART结构体配置*/
	USART_InitTypeDefstruct.USART_BaudRate = bound; //波特率
	USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流
	USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能
	USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验
	USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位
	USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位
	/*写入USART1*/
	USART_Init(USART1,&USART_InitTypeDefstruct);
	
	/*使能串口1*/
	USART_Cmd(USART1,ENABLE);

}


/*!
	\brief		UART1中断服务函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void USART1_IRQHandler(void)
{

}
	

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_i2c.h
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Define to prevent recursive incluson---------------------------------------*/
#ifndef _USER_I2C_H__
#define _USER_I2C_H__

/* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include "user_delay.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C 
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C 
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C 
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C 
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C 
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C    
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    

#define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808 
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08 
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008 
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408 
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808 
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08 
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 
//IO方向设置
#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;} //输入模式
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;} //输出模式
//IO操作函数	 
#define IIC_SCL    BIT_ADDR(GPIOB_ODR_Addr,6) //SCL 输出高
#define IIC_SDA    BIT_ADDR(GPIOB_ODR_Addr,7) //SDA 输出高
#define READ_SDA   BIT_ADDR(GPIOB_IDR_Addr,7) //输入SDA 读取 
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

void IIC_Start(void);
void IIC_Stop(void);
uint8_t IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);
void IIC_Send_Byte(u8 txd);
u8 IIC_Read_Byte(uint8_t ack);

#endif

/************************************************************** END OF FILE ****/
/**
  ******************************************************************************
  * @file           : user_i2c.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_i2c.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		I2C开始信号
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void IIC_Start(void)
{	
	/*数据线配置为输出,为准备开始信号做准备*/
	SDA_OUT();
	/*数据线空闲*/
	IIC_SDA = 1;	  	  
	IIC_SCL = 1;
	/*等待*/
	delay_us(4);
	/*数据线高,数据线又高变低产生一个开始信号*/
	IIC_SDA=0;
	/*等待*/
	delay_us(4);	
	/*锁住I2C总线,防止其他设备用总线,准备发送或接受数据*/
	IIC_SCL=0;
}

/*!
	\brief		I2C停止信号
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void IIC_Stop(void)
{	
	/*数据线配置为输出,为准备开始信号做准备*/
	SDA_OUT();
	/*数据线强制拉低总线*/
	IIC_SCL = 0;
	IIC_SDA = 0;	  	  
	/*等待*/
	delay_us(4);
	/*释放总线*/
	IIC_SCL = 1;
	IIC_SDA = 1;	  	  
	/*等待*/
	delay_us(4);	

}

/*!
	\brief		等待应答信号
	\param[in]	none
	\param[out]	none
	\retval 	1,接收应答失败,0,接收应答成功
*/
uint8_t IIC_Wait_Ack(void)
{
	uint8_t ucErrTime=0;
	/*SDA设置为输入 */
	SDA_IN();   
	/*释放总线*/
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	
	/*等待应答*/
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 1;
		}
	}
	/*时钟拉低防止总线被其他用*/
	IIC_SCL=0;//时钟输出0 	   
	return 0;  
} 

/*!
	\brief		应答信号
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void IIC_Ack(void)
{
	/*应答时序准备等待*/
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	/*应答信号时钟线高,数据线低*/
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}

/*!
\brief		    不应答信号
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void IIC_NAck(void)
{
	/*不应答时序准备等待*/
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	/*不应答信号时钟线高,数据线高*/
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}

/*!
\brief		    发送一个字节
	\param[in]	数据
	\param[in]	none
	\retval 	none
*/
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	 
	/*拉低时钟准备数据传输*/
    IIC_SCL=0;
    for(t=0;t<8;t++)
    {              
        
		if((txd&0x80)>>7)
			IIC_SDA=1;
		else
			IIC_SDA=0;
		txd<<=1; 	  
		delay_us(2);  
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	  

/*!
\brief		    读一个字节
	\param[in]	ack=1时,发送ACK,ack=0,发送nACK
	\param[in]	none
	\retval 	none
*/
u8 IIC_Read_Byte(uint8_t ack)
{
	uint8_t i,receive=0;
	/*SDA设置为输入*/
	SDA_IN();
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_eeprom_24c02.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_eeprom_24c02.h"
#include "user_uart.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		读取一个字节函数
	\param[in]	要读的地址
	\param[in]	none
	\retval 	none
*/
uint8_t AT24C02_ReadOneByte(uint8_t ReadAddr)
{				  
	uint8_t temp=0;	
	/*开始信号*/	
    IIC_Start();  
	/*发送器件地址0XA0,写数据*/
	IIC_Send_Byte(0XA0);    	 
	/*等待应答*/
	IIC_Wait_Ack(); 
	/*发送要读的地址*/
    IIC_Send_Byte(ReadAddr);  
	/*等待应答*/
	IIC_Wait_Ack();	 
	
	IIC_Start();  	 	   
	IIC_Send_Byte(0XA1);           //进入接收模式			   
	IIC_Wait_Ack();	 
    temp=IIC_Read_Byte(0);		   
    IIC_Stop();//产生一个停止条件	    
	return temp;
}


/*!
	\brief		写一个字节函数
	\param[in]	要写的地址
	\param[in]  要写的数据
	\retval 	none
*/
void AT24C02_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite)
{		
	/*开始信号*/	
    IIC_Start();  
	/*发送器件地址0XA0,写数据 */
	IIC_Send_Byte(0XA0);   
	/*等待应答*/	
	IIC_Wait_Ack();	  
	/*发送要写地址*/
    IIC_Send_Byte(WriteAddr); 
	/*等待应答*/	
	IIC_Wait_Ack(); 
	/*发送要写数据*/
	IIC_Send_Byte(DataToWrite);   
	/*等待应答*/	
	IIC_Wait_Ack();  
	/*产生一个停止条件 */
    IIC_Stop();
	delay_ms(10);	 
}


/*!
	\brief		检查EEPROM是否正常函数
	\param[in]	none
	\param[in]  none
\retval 	1:检测失败 0:检测成功
*/
uint8_t AT24C02_Check(void)
{
	uint8_t temp;
	/*255地址写入0x55*/
	AT24C02_WriteOneByte(0,0X20);
	/*读出255地址是否,是写入数据*/
	temp=AT24C02_ReadOneByte(0);	 
	if(temp==0X20)
	{
		/*正常*/
		return 0; 
	}
	/*不正常*/
	return 1;											  
}


/*!
	\brief		连续读取指定地址指定个数据函数
	\param[in]	开始读出的地址0~255
	\param[in]  存放数据数组首地址
	\param[in]  要读出数据的个数
\retval 	    none
*/
void AT24C02_Read(uint8_t ReadAddr,u8 *pBuffer,uint8_t NumToRead)
{
	while(NumToRead)
	{
		*pBuffer++=AT24C02_ReadOneByte(ReadAddr++);	
		NumToRead--;
	}
}  

/*!
	\brief		连续写指定地址指定个数据函数
	\param[in]	开始写的地址0~255
	\param[in]  要写数据数组首地址
	\param[in]  要写出数据的个数
\retval 	    none
*/
void AT24C02_Write(uint8_t WriteAddr,uint8_t *pBuffer,uint8_t NumToWrite)
{
	while(NumToWrite--)
	{
		AT24C02_WriteOneByte(WriteAddr,*pBuffer);
		WriteAddr++;
		pBuffer++;
	}
}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_mian.h
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "user_eeprom_24c02.h"


/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
#define SIZE sizeof(Test_Buffer)
/* Variables 变量--------------------------------------------------------------*/ 
uint8_t Test_Buffer[]={"I2C,Test"};
uint8_t Read_Buffer[SIZE];
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

 int main(void)
 {	
    uint8_t i;
	/*配置系统中断分组为2位抢占2位响应*/
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	 /*延时函数初始化*/
	 delay_init();
	/*RCC配置*/
	 Rcc_config();
	/*GPIO初始化*/ 
	 Gpio_Init();
	/*USART1初始化*/
	 Uart1_Init(9600); 
	 /*检测EEPROM*/
	 while(AT24C02_Check()){
		printf("没有检测到芯片\r\n");
	 }
	 /*死循环*/
	 while(1){
	 /*写数据*/
	 AT24C02_Write(0,(uint8_t*)Test_Buffer,SIZE);

	 delay_ms(1000);
	 /*读数据*/
     AT24C02_Read(0,Read_Buffer,SIZE);

	/*打印*/	 
	 for(i = 0; i<SIZE; i++)
		 {
			printf("%c",Read_Buffer[i]);				 
		 }

		printf("\r\n");
	}

}
 
 /************************************************************** END OF FILE ****/

 

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

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

相关文章

ATtiny13与Proteus仿真-ADC仿真

ADC仿真 1、ADC介绍 ATtiny13的ADC有如下特点: 10位分辨率0.5 LSB 积分非线性 2 LSB 绝对精度13 - 260 μs 转换时间在最高分辨率下高达 15 kSPS四个多路复用单端输入通道ADC 结果读数的可选左调整0 - VCC ADC 输入电压范围可选择的 1.1V ADC 参考电压自由运行或单一转换模式…

[附源码]计算机毕业设计家庭医生签约服务管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

dmb ish osh

转自&#xff1a;原理和实战解析Linux中如何正确地使用内存屏障 圈里流传着一句话“珍爱生命&#xff0c;远离屏障”&#xff0c;这足以说明内存屏障是一个相当晦涩和难以准确把握的东西。使用过弱的屏障&#xff0c;会导致软件不稳定。使用过强的屏障&#xff0c;会引起性能问…

c语言篇(动态内存管理)

前言&#xff1a; 对于数据的存储我们可以静态存储&#xff0c;也可以动态存储&#xff0c;两种方式都有自己特有的好处&#xff0c;这篇文章教我们如和进行动态的数据存储&#xff01;&#xff01;&#xff01;&#xff01; &#x1f49e; &#x1f49e; 欢迎来到小马学习代码…

自动驾驶之单目3D目标检测TensorRT调研

目前在github上只能找到2个项目 TensorRT-CenterNet-3D tkDNN 两者都是使用CenterNet&#xff0c;但第1个基于TensorRT5,无法与当前最新的TensorRT6和TensorRT7兼容。经测试&#xff0c;第1个无法在XavierJetpack 4.3/4.4上部署&#xff0c;因此选择部署第二个tkDNN。 1. 基本…

Python学习基础笔记三十八——time模块

1、time模块&#xff1a;和时间有关系的&#xff0c;我们就用到了时间模块&#xff1a; import timeprint(time.time()) #获得当前时间戳 2、表示时间的三种方式&#xff1a; 在Python中&#xff0c;通常用三种方式来表示时间&#xff1a;时间戳、元组(struct_time)、格式…

LeetCode刷题复盘笔记—一文搞懂动态规划之337. 打家劫舍 III问题(动态规划系列第十九篇)

今日主要总结一下动态规划完全背包的一道题目&#xff0c;337. 打家劫舍 III 题目&#xff1a;337. 打家劫舍 III Leetcode题目地址 题目描述&#xff1a; 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口&#xff0c;我们称之为 root 。 除了 root 之外&#xff0…

UDS入门至精通系列:Service 19(二)

文章目录 前言一、协议的定义(19 04/06)二、数据库编辑(CANdelaStudio)三、CAPL应用(Service 19 04 / 06)总结前言 本文主要讲述了ECU诊断中用到的DTC Status以及Service 19 02作用和用法。 本文主要讲述了ECU诊断中用到的DTC Status以及Service 19 02作用和用法。 本文…

Transformer15

今天还是Transformer~~ 都连载这么多了 , 据说是全球首个面向遥感任务设计的亿级视觉大模型 大规模视觉基础模型在基于自然图像的视觉任务中取得了重大进展。得益于良好的可扩展性和表征能力&#xff0c;基于视觉Transformer (Vision Transformer, ViT) 的大规模视觉基础模型吸…

Instruction Tuning(FLAN、instructGPT、chatGPT)

首页最近被chatGPT刷屏&#xff0c;但翔二博主左看右看发现很多想法似乎都是一脉相通的&#xff0c;于是连夜从存档中找了一些文章尝试理一理它的理论路线。 具身智能综述和应用&#xff08;Embodied AI&#xff09;多模态中的指令控制 同时想到今年在智源人工智能前沿报告&a…

线程,线程池的使用

文章目录线程&#xff0c;线程池的使用1. 多线程基础1.1 线程和进程1.2 多线程的创建1.2.1 继承Thread类1.2.2 实现Runnable接口1.2.3 匿名内部类方式1.2.4 守护线程1.3 线程安全1.3.1 卖票案例1.3.2 线程同步2. 线程池的实现方式2.1 Java提供的四种线程池2.2 线程池的创建原理…

微信小程序开发【从0到1~入门篇】

目录 1. 微信小程序介绍 1.1 什么是小程序&#xff1f; 1.2 小程序可以干什么&#xff1f; 2. 申请账号 2.1 申请帐号 2.2 测试号申请&#xff08;我们小程序账号申请完成之后&#xff0c;建议务必要申请一个测试号用来开发&#xff09; 3. 安装开发工具 3.1 选择稳定…

我的创作纪念日(2021-12-10 2022-12-10)

&#x1f306; 内容速览阴差阳错成为一名博主&#xff1f;这一年来的收获日常生活未来憧憬阴差阳错成为一名博主&#xff1f; 如上图所见&#xff0c;她就是我在CSDN上发布的第一篇博客——无标题&#xff0c;有时候机缘来的那么突然&#xff0c;我甚至都没有给她想一个凑合的名…

spring——Spring 注入内部Bean——构造函数方式注入内部 Bean

项目依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.or…

【MySQL进阶篇】存储引擎

&#x1f349;个人主页&#xff1a;个人主页 &#x1f353;系列专栏&#xff1a;MySQL数据库 目录 1.MySQL体系结构 1). 连接层 2). 服务层 3). 引擎层 4). 存储层 2.存储引擎介绍 3.存储引擎特点 1. InnoDB 2.MyISAM 3.Memory 4.区别及特点 4.存储引擎选择 1.MySQ…

MAC QT OpenGL 图像曝光度调节

目录 一.MAC QT OpenGL 图像曝光度调节演示 1.原始图片2.效果演示 二.MAC QT OpenGL 图像曝光度调节源码下载三.其他平台图像曝光度调节版本 1.IOS 曝光度演示效果2.Windows OpenGL ES 曝光度演示效果3.Windows OpenGL 曝光度演示效果 四.猜你喜欢 零基础 OpenGL ES 学习路线推…

39-kafka-监控Eagle

39-kafka-监控Eagle&#xff1a; Eagle的安装 1.修改 kafka 启动命令 修改 kafka-server-start.sh 命令中 if [ "x$KAFKA_HEAP_OPTS" "x" ]; then export KAFKA_HEAP_OPTS"-Xmx1G -Xms1G" fi 为 if [ "x$KAFKA_HEAP_OPTS" &qu…

功能测试(八)—— APP之专项测试、性能测试、性能测试工具SoloPi

目录 APP测试要点 目标 一、APP专项测试 1.1 兼容性 1.2 安装 1.3 卸载 1.4 升级 1.5 干扰测试(交叉事件测试) 1.6 Push推送 1.7 用户体验 二、 性能测试工具 2.1 APP性能测试工具介绍 —— SoloPi简介 2.2 APP性能测试工具 —— SoloPi使用 三、APP性能测试 3.…

English Learning - L2 窥得大段表达门径 2022.12.8 周四

English Learning - L2 窥得大段表达门径 2022.12.8 周四引言2 形容词2.1 -ing 形容词 VS -ed 形容词核心思想举例3 名词3.1 修饰成分修饰成分的排列的黄金原则&#xff1a;左二右六举例3.2 名词的数3.2.1 "名词 介词/副词/不定式 等" 构成的复合名词变复数&#xf…

Spring Boot 使用 Micrometer 集成 Prometheus 监控 Java 应用性能

一、背景 SpringBoot的应用监控方案比较多,SpringBoot + Prometheus + Grafana是目前比较常用的方案之一。它们三者之间的关系大概如下图: 二、Micrometer的介绍 Micrometer为Java 平台上的性能数据收集提供了一个通用的 API,它提供了多种度量指标类型(Timers、Guauges、…