STC12读取内部ID方法介绍
- 🔖这里以STC12LE5A60S2为例,从STC12手册的第一章,1.10小结可以找到相关的ID相关的信息。这个信息主要是用于程序加密或产品销售管理等方面。
- 🌿STC12LE5A60S2系统板:
https://oshwhub.com/perseverance51/stc12le5a60s2-ji-tong-ban
📓芯片的ID信息源
- 📑芯片ID信息源:内部RAM的F1H ~ F7H单元的内容也为全球唯一ID号。以及在程序区的最后7个字节的全球唯一ID号。后者需要在使用STC-ISP下载程序的时候,勾选相应的选项:
在代码区的最后添加ID号
。
- 📜读取ID效果:
✨在采用代码区的最后添加ID号的方法,在通过STC-ISP写入程序到单片机时,根据芯片型号flash容量的大小,擦除和写入的时间会有所增长。
📝示例代码
- 🌿串口采用独立波特率发生器。
- 🌿采用外部22.1184MHz晶振
- 🌿波特率:9600
- 📋通过串口发送对应的字符,来获取相对于的信息。
/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU Programme Demo ----------------------------*/
/* --- Fax: 86-755-82944243 ----------------------------------------*/
/* --- Tel: 86-755-82948412 ----------------------------------------*/
/* --- Web: www.STCMCU.com -----------------------------------------*/
/* If you want to use the program or the program referenced in the */
/* article, please specify in which data and procedures from STC */
/*------------------------------------------------------------------*/
/* 本程序经过测试完全正常, 不提供电话技术支持, 如不能理解, 请自行补充相关基础. */
/************* 本程序功能说明 **************
测试方法:
根据您的主时钟和波特率修改下面的相关定义,编译后下载到MCU。
通过串口助手向MCU发送数据,MCU收到后原样返回。
发单个字符'a',将返回RAM区的唯一 ID号。
发单个字符'o',将返回ROM区的唯一 ID号。(需要在STC-ISP下载时勾选“在代码区的最后添加ID号”选项)
发单个字符'r',将返回内部震荡频率。
*/
/*************** 用户定义参数 *****************************/
#define MAIN_Fosc 22118400L //define main clock
#define Baudrate0 9600 //define the baudrate,
//12T mode: 600~115200 for 22.1184MHZ, 300~57600 for 11.0592MHZ
//1T mode: 7200~1382400 for 22.1184MHZ, 3600~691200 for 11.0592MHZ
/**********************************************************/
#include <reg51.h>
//ID号的存放在程序区的地址为程序空间的最后7字节
//#define ID_ADDR_ROM 0x03f9 //1K程序空间的MCU
//#define ID_ADDR_ROM 0x07f9 //2K程序空间的MCU
//#define ID_ADDR_ROM 0x0bf9 //3K程序空间的MCU
//#define ID_ADDR_ROM 0x0ff9 //4K程序空间的MCU
//#define ID_ADDR_ROM 0x13f9 //5K程序空间的MCU
//#define ID_ADDR_ROM 0x1ff9 //8K程序空间的MCU
//#define ID_ADDR_ROM 0x27f9 //10K程序空间的MCU
//#define ID_ADDR_ROM 0x2ff9 //12K程序空间的MCU
//#define ID_ADDR_ROM 0x3ff9 //16K程序空间的MCU
//#define ID_ADDR_ROM 0x4ff9 //20K程序空间的MCU
//#define ID_ADDR_ROM 0x5ff9 //24K程序空间的MCU
//#define ID_ADDR_ROM 0x6ff9 //28K程序空间的MCU
//#define ID_ADDR_ROM 0x7ff9 //32K程序空间的MCU
//#define ID_ADDR_ROM 0x9ff9 //40K程序空间的MCU
//#define ID_ADDR_ROM 0xbff9 //48K程序空间的MCU
//#define ID_ADDR_ROM 0xcff9 //52K程序空间的MCU
//#define ID_ADDR_ROM 0xdff9 //56K程序空间的MCU
#define ID_ADDR_ROM 0xeff9 //60K程序空间的MCU -->STC12LE5A60S2
sfr AUXR = 0x8E;
sfr BRT = 0x9c; //独立波特率发生器
bit B_TI;
unsigned char id[7]; //用于读取RAM区的ID
unsigned char ROM_id[7]; //用于读取ROM区的ID
unsigned long Rosc, RoscZ;
unsigned char Command;
void uart0_init(void);
/****************** 编译器自动生成,用户请勿修改 ************************************/
#define T1_TimerReload (256 - MAIN_Fosc / 192 / Baudrate0) //Calculate the timer1 reload value at 12T mode
//#define T1_TimerReload (256 - MAIN_Fosc / 16 / Baudrate0) //Calculate the timer1 reload value ar 1T mode
/**********************************************************/
void TxByte(unsigned char dat);
unsigned char HEX2DEC(unsigned char dat);
void PrintStrings(unsigned char code* sts);
void main(void)
{
unsigned char i;
unsigned int j;
unsigned char idata* p;
unsigned char code* cptr;
p = 0xf1;
for(i = 0; i < 7; i++) //从RAM区读取ID号
{
id[i] = *p;
p++;
}
cptr = ID_ADDR_ROM; //从程序区读取ID号
for(i = 0; i < 7; i++) //读7个字节
{
ROM_id[i] = *cptr;
cptr++;
}
cptr = 0;
Rosc = 0;
for(p = 0xf8; p <= 0xfb; p++) Rosc = (Rosc << 8) + *p;
RoscZ = 0;
for(p = 0xfc; p > 0; p++) RoscZ = (RoscZ << 8) + *p;
uart0_init();
PrintStrings("读ID和内部震荡频率\r\n");
PrintStrings("发单个字符'a',将返回唯一RAM ID号。\r\n");
PrintStrings("发单个字符'o',将返回唯一ROM ID号。\r\n");
PrintStrings("发单个字符'r',将返回内部震荡频率。\r\n");
while(1)
{
for(j = 0; j < 1500; j++) ; //14T per loop, delay 1ms
if(Command != 0) //收到命令
{
if(Command == 'a') //读取ID命令
{
PrintStrings("本IC的RAM ID号为:");
for(i = 0; i < 7; i++)
{
TxByte(HEX2DEC(id[i] >> 4));
TxByte(HEX2DEC(id[i] & 0x0f));
TxByte(' ');
}
TxByte(0x0d);
TxByte(0x0a);
}
if(Command == 'o') //读取ID命令
{
PrintStrings("本IC的ROM ID号为:");
for(i = 0; i < 7; i++)
{
TxByte(HEX2DEC(ROM_id[i] >> 4));
TxByte(HEX2DEC(ROM_id[i] & 0x0f));
TxByte(' ');
}
TxByte(0x0d);
TxByte(0x0a);
}
if(Command == 'r') //读取内部频率命令
{
PrintStrings("内部震荡频率为:");
TxByte(Rosc / 10000000L + '0');
TxByte(Rosc % 10000000L / 1000000L + '0');
TxByte('.');
TxByte(Rosc % 1000000L / 100000L + '0');
TxByte(Rosc % 100000L / 10000 + '0');
TxByte(Rosc % 10000 / 1000 + '0');
TxByte(Rosc % 1000 / 100 + '0');
TxByte(Rosc % 100 / 10 + '0');
TxByte(Rosc % 10 + '0');
TxByte('M');
TxByte('H');
TxByte('Z');
TxByte(0x0d);
TxByte(0x0a);
}
Command = 0;
}
}
}
unsigned char HEX2DEC(unsigned char dat)
{
dat &= 0x0f;
if(dat <= 9) return (dat + '0');
else return (dat + 55);
}
void TxByte(unsigned char dat)
{
B_TI = 0;
SBUF = dat;
while(!B_TI) ;
B_TI = 0;
}
/**********************************************/
void PrintStrings(unsigned char code* sts)
{
for(; *sts != 0; sts++) TxByte(*sts);
}
void uart0_init(void)
{
SCON = 0x50; //UART0 set as 10bit , UART0 RX enable
BRT = 0xFA; //设置定时重载值:22.1184MHz,9600
AUXR |= 0x01; //串口1使用独立波特率发射器为波特率发生器
AUXR |= 0x10; //启动独立波特率发射器
ES = 1;
EA = 1;
}
/**********************************************/
void UART0_RCV(void) interrupt 4
{
if(RI)
{
RI = 0;
Command = SBUF;
}
if(TI)
{
TI = 0;
B_TI = 1;
}
}