用power monitor的at24c02和w25q64电流 - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki

at24c02程序

/**
  *****************************************************************************
  * 					使用PS端IIC外设读写EEEPROM
  *****************************************************************************
  *
  * @File    : main.c
  * @By      : Sun
  * @Version : V1.1
  * @Date    : 2022 / 06 / 13
  *
  *****************************************************************************
**/
#include "ACZ702_Lib/COMMON.h"

#define PS_KEY 15
#define PS_LED 11
int main_ps_io(void)
{
    uint8_t State;   //存放按键(MIO47)的电平状态,0为低电平,1为高电平

    PS_GPIO_Init(); //初始化PS端MIO和EMIO
    PS_GPIO_SetMode(PS_LED, OUTPUT, 0);
    //设置PL_LED(EMIO0)为输出并且初始为低电平
    PS_GPIO_SetMode(PS_KEY, INPUT, 0); //设置PS_KEY(MIO47)方向为输入

//    while(1)
//    {
//        State = PS_GPIO_GetPort(PS_KEY);   //读取PS_KEY的电平值并存储到State变量里
//        PS_GPIO_SetPort(PS_LED,!State);    //将State变量的值取非赋予PS_LED来输出
//    }
//    return 0;
}



#define SEND_PACK_SIZE 8 //EEPROM最多只能连续写一页数据(32byte)

int main(void)
{
	uint8_t Write_Data[SEND_PACK_SIZE];
	uint8_t Read_Data[SEND_PACK_SIZE];
	uint16_t i;
	uint16_t Error_Cnt=0;

	//PS_IIC_Init(&IIC0,XPAR_XIICPS_0_DEVICE_ID,100000);	//初始化设备IIC0,时钟频率为100kHz
	AXI_IIC_Init(&AXI_IIC0,XPAR_IIC_0_DEVICE_ID);	//初始化设备Iic,时钟频率为100kHz

	//将数据0~31放入数组Write_Data里
	for(i=0;i<SEND_PACK_SIZE;i++)
	{
		Write_Data[i]=i;
	}


	main_ps_io();

	while(1){
		if(PS_GPIO_GetPort(PS_KEY)==0){
			//将0~31写入EEPROM的第一页0~31地址里
			//PS_IIC_SeqWrite_Reg(&IIC0,0x50,REG16, 0x00,Write_Data,SEND_PACK_SIZE);
			for(int i=0; i<100; i++){
				AXI_IIC_SeqWrite_Reg(&AXI_IIC0,0x51,REG8, 0x00,Write_Data,SEND_PACK_SIZE);
				usleep(10*000);
			}

			sleep(1);
			//读取EEPROM的第一页0~31地址里的数据,存放在Read_Data数组里
			//PS_IIC_SeqRead_Reg(&IIC0, 0x50,REG16, 0x00,Read_Data,SEND_PACK_SIZE);
			for(int i=0; i<100; i++){
				AXI_IIC_SeqRead_Reg(&AXI_IIC0, 0x51,REG8, 0x00,Read_Data,SEND_PACK_SIZE);
			}
//
//			//对比Write_Data与Read_Data是否一致
//			for(i=0;i<SEND_PACK_SIZE;i++)
//			{
//				if(Write_Data[i] != Read_Data[i])
//				{
//					Error_Cnt++;//记录错误数据个数
//				}
//			}
//
//			printf("Error = %d !\n",Error_Cnt);//打印错误数据的个数,全对则为0,代表读写成功
//			if(Error_Cnt == 0)
//				printf("Write EEPROM successful !!!\n");
//			else
//				printf("Write EEPROM failed !!!\n");

		}
	}
}

w25q64程序


#include "ACZ702_Lib/COMMON.h"

#define PS_KEY 15
#define PS_LED 11
int main_ps_io(void)
{
    uint8_t State;   //存放按键(MIO47)的电平状态,0为低电平,1为高电平

    PS_GPIO_Init(); //初始化PS端MIO和EMIO
    PS_GPIO_SetMode(PS_LED, OUTPUT, 0);
    //设置PL_LED(EMIO0)为输出并且初始为低电平
    PS_GPIO_SetMode(PS_KEY, INPUT, 0); //设置PS_KEY(MIO47)方向为输入

//    while(1)
//    {
//        State = PS_GPIO_GetPort(PS_KEY);   //读取PS_KEY的电平值并存储到State变量里
//        PS_GPIO_SetPort(PS_LED,!State);    //将State变量的值取非赋予PS_LED来输出
//    }
//    return 0;
}


typedef struct{
	u8 txbuf[256];
	u8 rxbuf[256];
	u8 length;
}t_buf;

t_buf WriteBuffer[]={
    //s1: read id
	{{0x90},{0x00},6},
	{{0x9f},{0x00},8},
	{{0x4b},{0x00},13},

	//s2: sector erase
	{{0x06},{0x00},1},
	{{0x20,0x00,0x00,0x10},{0x00},4},
	{{0xff},{0x00},0}, //length=0 => delay_ms

	//s3: page program
	{{0x06},{0x00},1},
	{{0x02,0x00,0x00,0x10,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88},{0x00},250},
	{{0xff},{0x00},0}, //length=0 => delay_ms

	//s4: spi/dspi/qspi read
	{{0x0b,0x00,0x00,0x10},{0x00},250},
	{{0x3b,0x00,0x00,0x10},{0x00},250},
	{{0x6b,0x00,0x00,0x10},{0x00},250},

//	//s5: sector erase
//	{{0x06},{0x00},1},
//	{{0x20,0x00,0x00,0x10},{0x00},4},
//	{{0xff},{0x00},0}, //length=0 => delay_ms
//
//	//s6: qspi program
//	{{0x06},{0x00},1},
//	{{0x32,0x00,0x00,0x10,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x11,0x22},{0x00},12},
//	{{0xff},{0x00},0}, //length=0 => delay_ms
//
//	//s7: qspi read
//	{{0x6b,0x00,0x00,0x10},{0x00},14},
//	{{0xbb,0x00,0x00,0x10},{0x00},14},
//	{{0xeb,0x00,0x00,0x10},{0x00},14},

	//s8: enter qpi mode (QE=1), 貌似不支持
//	{{0x38},{0x00},1},   //not support
//	{{0x01,0x00,0x02},{0x00},3},
//	{{0xA3,0x00,0x00,0x00},{0x00},4},
//
//	//s9: sector erase
//	{{0x06},{0x00},1},
//	{{0x20,0x00,0x00,0x10},{0x00},4},
//	{{0xff},{0x00},0}, //length=0 => delay_ms
//
//	//s10: qpi read
//	{{0x0b,0x00,0x00,0x10},{0x00},14},
//
//	//s11: qpi program
//	{{0x06},{0x00},1},
//	{{0x02,0x00,0x00,0x10,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11},{0x00},12},
//	{{0xff},{0x00},0}, //length=0 => delay_ms
//
//	//s12: qpi read
//	{{0xbb,0x00,0x00,0x10},{0x00},14},
//	{{0xeb,0x00,0x00,0x10},{0x00},14},
};



void print_buffer(u8 *pdata, int length)
{
	for(int i=0; i<length; i++){
		xil_printf("pdata[%d]=%x\r\n", i, pdata[i]);
	}
	xil_printf("********************\r\n");
}


void test_flash()
{
	for(int i=0; i<sizeof(WriteBuffer)/sizeof(*WriteBuffer); i++){
		if(WriteBuffer[i].length==0){
			usleep(WriteBuffer[i].txbuf[0]*1000);
			continue;
		}

		AXI_SPI_Transfer(&AXI_SPI0, 0, WriteBuffer[i].rxbuf, WriteBuffer[i].txbuf, WriteBuffer[i].length);
		xil_printf("Exec CMD=%x\r\n\r\n", WriteBuffer[i].txbuf[0]);
		print_buffer(WriteBuffer[i].rxbuf, WriteBuffer[i].length);
	}
}

int main(void)
{

	//初始化通用中断控制器
	ScuGic_Init();
	main_ps_io();

	//初始化AXI_SPI0,设为主机模式
	AXI_SPI_Init(&AXI_SPI0, XPAR_SPI_0_DEVICE_ID, XSP_MASTER_OPTION);

	//初始化私有定时器中断,定时间隔100ms
	ScuTimer_Int_Init(100000);

//	for(int i=0; i<sizeof(WriteBuffer)/sizeof(*WriteBuffer); i++){
//		if(WriteBuffer[i].length==0){
//			usleep(WriteBuffer[i].txbuf[0]*1000);
//			continue;
//		}
//
//		AXI_SPI_Transfer(&AXI_SPI0, 0, WriteBuffer[i].rxbuf, WriteBuffer[i].txbuf, WriteBuffer[i].length);
//		xil_printf("Exec CMD=%x\r\n\r\n", WriteBuffer[i].txbuf[0]);
//		print_buffer(WriteBuffer[i].rxbuf, WriteBuffer[i].length);
//	}


	while(1) {
		//刷新间隔由私有定时器中断控制,中断服务函数在ISR.c中
//		if(Refresh_Flag) {
//			Refresh_Flag = 0;
//
//			//xil_printf("timer run!\r\n");
//		}

		if(PS_GPIO_GetPort(PS_KEY)==0){
			test_flash();
		}
	}

	return 0;
}

at24c02电流波形

493a5ed859c6a20d84c7f0619dc00d33 9b581c84ce78f39af6abdd4c60fc21a5 1beec3b5fde14cc513f5d1d165010032 25db525ff51f59edfbe9006e529cb416

图1. 总体波形:wr+rd
图2:wr波形
图3:rd波形
图4:总体波形放大

可以看到,写完后,电流突然变的很小。经过400ms后,电流开始变大。这个时刻似乎芯片发生了一个状态的转变?? 原因不清楚

w25q64电流波形

5ca3ce72a134cccf6431f1d84fc06b9e b678be1a47444085cbd54a5c336024fb 725843197150a7e49452399e530aa02e 2eb254b7ccb3f07bcf340879b2dce405 4fcc4df44dfcd4d8d7bb609793911587 48b105ca98e9349ff497a25d2dacedb5

图1:总体波形:sector_erase + page_program + 1wire_read + 2wire_read + 4wire_read
图2:sector_erase,Ipp=17mA, Istb=11mA
图3:page_program, Istb=19mA
图4:1wire_read, Ipp=8mA, Istb=1.3mA
图5:2wire_read, 电流异常的大
图6:4wire_read, 电流异常的大

总结

  • spi flash电流比eeprom电流大很多倍
  • 这颗flash芯片,读的时候电流有较大的peak,原因可能是2点:1)没有挂稳压电容;2)采样率是10us(100kHz),时间不够精细。10us可能都读完了。因此可以把那些电流非常大的peak去掉。

补充,后来又重新测了以下qspi-flash

u8 txBuffer[4096];
u8 rxBuffer[4096];
void test_flash2()
{
//	//s1:QE=1
//	txBuffer[0]=0x06;
//	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 1);
//
//	txBuffer[0]=0x31;
//	txBuffer[1]=1<<1;
//	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 1);


	//s2: sector erase
	txBuffer[0]=0x06;
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 1);

	txBuffer[0]=0x20;
	txBuffer[1]=0x00;
	txBuffer[2]=0x00;
	txBuffer[3]=0x10;
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 4);
	//pulling_sr();
	usleep(100*1000);

	//s3: page program
	txBuffer[0]=0x06;
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 1);

	txBuffer[0]=0x02;
	txBuffer[1]=0x00;
	txBuffer[2]=0x00;
	txBuffer[3]=0x10;

	for(int i=4; i<4096; i++){
		txBuffer[i]=i;
	}
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 4096);
	//pulling_sr();
	usleep(100*1000);

	//s4: spi/dspi/qspi read
	txBuffer[0]=0x0b;
	txBuffer[1]=0x00;
	txBuffer[2]=0x00;
	txBuffer[3]=0x10;
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 4096);
	usleep(100*1000);
	for(int i=0; i<32; i++) xil_printf("%d\r\n", rxBuffer[i]);
	xil_printf("*******************\r\n");

	txBuffer[0]=0x3b;
	txBuffer[1]=0x00;
	txBuffer[2]=0x00;
	txBuffer[3]=0x10;
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 4096);
	usleep(100*1000);
	for(int i=0; i<32; i++) xil_printf("%d\r\n", rxBuffer[i]);
	xil_printf("*******************\r\n");

	txBuffer[0]=0x6b;
	txBuffer[1]=0x00;
	txBuffer[2]=0x00;
	txBuffer[3]=0x10;
	AXI_SPI_Transfer(&AXI_SPI0, 0, rxBuffer, txBuffer, 4096);
	usleep(100*1000);
	for(int i=0; i<32; i++) xil_printf("%d\r\n", rxBuffer[i]);
	xil_printf("*******************\r\n");
}

image image image image image image

感觉:还是2线和4线模式有点异常,刚开始启动的时候有个比较大的电流。