第三十三章 OTP——一次性编程区域读写

第三十三章 OTP——一次性编程区域读写

目录

第三十三章 OTP——一次性编程区域读写

1 OTP功能特性

1.1 非易失性

1.2 一次性写入限制

1.3 物理保护机制

1.4 访问权限控制

2 应用场景

2.1 唯一标识符(UID)存储

2.2 校准参数存储

2.3 安全密钥存储

2.4 客户定制化数据

3 注意事项

3.1 写入次数限制

3.2 电压与时序要求

3.3 安全风险

4 程序设计

4.1 OTP上电

4.2 设置时间基准

4.3 写入数据

4.4 OTP断电

4.5 主函数main()

5 下载验证

6 总结


W55MH32OTPOne-Time Programmable,一次性可编程存储器)是芯片内部一种特殊的非易失性存储区域,主要用于存储需要一次性写入且不可擦除的关键数据。以下从功能特性、典型应用、程序设计及注意事项等方面展开详解:

1 OTP功能特性

1.1 非易失性

OTP存储的数据在芯片掉电后仍可保留,无需额外电源维持,与FlashEEPROM类似。

1.2 一次性写入限制

W55MH32OTP区域仅允许每个存储单元(通常为位或字节)写入一次(部分型号支持按块/页写入,但整体仍为一次性)。写入后无法擦除或覆盖,因此写入前需确保数据准确性。

1.3 物理保护机制

OTP的写入通常通过熔断(Fuse)或特殊工艺实现(如反熔丝)。写入操作会永久改变存储单元的物理状态(如熔断金属连线),从而保证数据不可篡改。

W55MH32为反熔丝工艺型OTP,即具有只能写1(将未编程的0变为1)、不能写0(已编程的1无法恢复为0的特性。

反熔丝OTP原理如下:

  • 初始状态(未编程):存储单元为逻辑0(如反熔丝未击穿,等效高阻或电容,代表0)。
  • 编程时:施加高电压击穿反熔丝,单元变为逻辑1(等效低阻,代表1),且一旦编程(写1),无法逆向恢复为0(物理结构不可逆)。

与熔丝型OTP对比

  • 熔丝型:初始为1(熔丝未熔断),编程时熔断熔丝,单元变为0(只能写0,不能写1)。
  • 反熔丝型:初始为0,编程后为1(只能写1,不能写0),符合1不可逆的描述。

1.4 访问权限控制

W55MH32OTP区域支持写保护(通过寄存器锁存),需通过特定指令(写入解锁密钥)才能开启写入权限,防止误操作。

2 应用场景

OTP的“一次性写入+非易失”特性使其适用于以下场景:

2.1 唯一标识符(UID)存储

芯片出厂时,厂商可能通过OTP写入全局唯一的设备ID(如96位或更长),用于产品追溯、防伪或加密认证(如作为AES密钥的种子)。

2.2 校准参数存储

传感器或模拟模块(如ADCDAC)的校准数据(如偏移量、增益系数)需在出厂前通过测试设备写入OTP,避免因Flash擦写次数限制导致数据丢失。

2.3 安全密钥存储

用于存储加密密钥(如AES-128/256密钥、HMAC密钥)或安全配置(如禁止JTAG调试的锁定位)。由于OTP不可擦除,即使芯片被物理攻击,密钥也难以被篡改或窃取。

2.4 客户定制化数据

设备制造商可在生产阶段写入客户定制信息(如硬件版本、区域配置),避免后续软件修改带来的成本。

3 注意事项

3.1 写入次数限制

OTP的每个存储单元仅允许写入一次(支持按位写入,但同一位多次写入会被视为“01”的单向操作)。若尝试重复写入同一地址,可能导致数据错误或硬件锁死。

3.2 电压与时序要求

OTP的写入需要稳定的电源(通常需满足芯片手册规定的最小电压,如2.7V~3.6V),且写入时序需严格遵循数据手册(如写入脉冲宽度、地址建立时间)。

3.3 安全风险

部分OTP区域可能与芯片的安全机制(如读保护、调试接口锁定)关联。错误写入可能导致芯片无法调试或功能失效,需谨慎操作。

4 程序设计

以下为OTP例程的程序设计流程:

4.1 OTP上电

在使用OTP模块前我们需要为其提供稳定的工作电源,通过配置系统时钟、解锁保护机制,并设置低压差稳压器(LDO)的启动时间,确保OTP在操作(如写入熔断)时电源满足要求。主要通过OTP_PowerOn()函数来实现,内容如下:

void OTP_PowerOn(uint32_t Time)
{
	RCC->RCC_SYSCFG_CONFIG = 0x01;
	SYSCFG->SYSCFG_LOCK = 0xAB12DFCD;
	if(Time > OTP_POWERON_TIME)
	{
		OTP->OTP_LDO =Time;
	}
	else
	{
		OTP->OTP_LDO = OTP_POWERON_TIME;
	}
}

OTP_PowerOn()函数是OTP模块的电源初始化函数,主要用于配置OTP的供电时序以确保其稳定工作:首先通过RCC->RCC_SYSCFG_CONFIG=0x01启用SYSCFG模块时钟,为后续配置提供基础;接着向SYSCFG->SYSCFG_LOCK写入解锁密钥0xAB12DFCD解除保护,允许修改OTP电源参数;最后根据输入的Time配置OTPLDO(低压差稳压器)启动时间——若Time大于预设的最小启动时间OTP_POWERON_TIME,则使用Time,否则强制使用最小值,以此平衡供电稳定性与效率,避免因电源波动或启动时间不足导致OTP操作(如写入熔断)失败。

4.2 设置时间基准

OTP_SetTime()函数为OTP的写入(熔断或反熔丝)提供精确的控制电压施加的时间:

void OTP_SetTime(uint16_t Time)
{
	OTP->OTP_10ns |= Time;
}

OTP_SetTime()函数通过将输入的Time参数按位或到OTP_10ns寄存器,以10纳秒为单位叠加配置OTP操作的时间参数(如写入脉冲宽度),确保电压/电流施加时间满足OTP物理状态改变的要求,从而保证数据写入的可靠性。该设计兼顾了时间配置的灵活性与安全性,允许开发者根据实际需求动态调整关键时序。

4.3 写入数据

OTP_WriteByte()函数用于向OTP指定地址写入一个字节的数据,内容如下:

void OTP_WriteByte(uint8_t Addr,uint8_t Data)
{
	assert_param(IS_OTP_ADDRESS(Addr));
	
	OTP->OTP_WR = (Addr << 8) | Data;
	OTP->OTP_CTRL = BIT(0);
	while(OTP->OTP_CTRL & BIT(2));
}

OTP_WriteByte()函数通过“地址验证→数据装载→触发写入→等待完成”的闭环流程,实现了向OTP指定地址写入一个字节数据的功能。其核心是通过操作OTP模块的寄存器,与硬件协同完成存储单元的物理状态修改,确保数据的一次性可靠写入。

4.4 OTP断电

OTP_PowerOff()函数用于关闭OTP模块的工作电源或使其进入低功耗模式,通常在OTP操作完成后调用,以降低系统功耗或防止意外写入。其核心逻辑是通过解锁保护寄存器并禁用相关时钟,切断OTP模块的供电或配置其进入休眠状态。函数内容如下:

void OTP_PowerOff(void)
{
	SYSCFG->SYSCFG_LOCK = 0xAB12DFCD;
	RCC->RCC_SYSCFG_CONFIG = 0x00;
}

函数首先向SYSCFG_LOCK写入解锁密钥以解除保护,然后通过RCC_SYSCFG_CONFIG禁用SYSCFG时钟,最终切断OTP的供电或使其进入休眠状态。

4.5 主函数main()

主函数main()如下:

int main(void)
{
    RCC_ClocksTypeDef clocks;
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    delay_init();
    UART_Configuration(115200);
    RCC_GetClocksFreq(&clocks);
 
    printf("\n");
    printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",
           (float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
           (float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);
 
    printf("OTP Write Read Test.\n");
 
    OTP_PowerOn(clocks.PCLK2_Frequency / 10);      //100ms
    OTP_SetTime(clocks.PCLK2_Frequency / 1000000); //1us
 
    OTP_WriteByte(OTP_ADDRESS_0, 0x5A);
 
    printf("OPT Data0 : 0x%x\n", OTP->OTP_DATA0);
    printf("OPT Data1 : 0x%x\n", OTP->OTP_DATA1);
    printf("OPT Data2 : 0x%x\n", OTP->OTP_DATA2);
    printf("OPT Data3 : 0x%x\n", OTP->OTP_DATA3);
    printf("OPT Data4 : 0x%x\n", OTP->OTP_DATA4);
    printf("OPT Data5 : 0x%x\n", OTP->OTP_DATA5);
    printf("OPT Data6 : 0x%x\n", OTP->OTP_DATA6);
    printf("OPT Data7 : 0x%x\n", OTP->OTP_DATA7);
 
    OTP_PowerOff();
    while (1);
}

程序首先初始化系统时钟(启用PWRBKP外设时钟)、延时函数及串口(波特率115200),并通过RCC_GetClocksFreq获取系统各时钟频率(如SYSCLKPCLK2等),打印验证时钟配置;接着启动OTP电源(OTP_PowerOn,基于PCLK2频率配置100ms启动时间)、设置OTP写入时序(OTP_SetTime,基于PCLK2频率配置1μs时间参数),向OTP0号地址写入数据0x5A;随后读取并打印OTP8个数据寄存器(DATA0~DATA7),验证写入是否成功;最后关闭OTP电源(OTP_PowerOff)以降低功耗,进入无限循环保持运行。

整体通过初始化、时钟验证、OTP配置、写入-读取验证及电源管理,完成对OTP功能的测试。

5 下载验证

程序下载运行后,串口输出显示系统时钟(如SYSCLK 72MHz)配置正常,OTP测试中地址0DATA0)写入0x5A成功,其余地址为默认0x0,验证了OTP写入和读取功能功能:

6 总结

W55MH32OTP是一种专为“一次性关键数据存储”设计的非易失性存储器,其核心价值在于数据的不可篡改性。在实际应用中,需结合芯片型号的数据手册,严格遵循写入流程,确保数据的准确性和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值