- 打卡等级:以坛为家II
- 打卡总天数:485
- 最近打卡:2025-05-03 08:49:35
已绑定手机
金牌会员
- 积分
- 2817
|
发表于 2023-3-26 11:04:08
|
显示全部楼层
这里有一个读取芯片ID的示例,不过本示例程序只在下载成功时、或MCU复位后进行读出1次,但是可以进行修改为当芯片上电或插入芯片后读取一次,只要芯片是同一个,读出的ID就是唯一不变的。代码如下:
/*芯片型号:STC8H3K64S4*/
/*时钟说明:MCU内部高速30MHz时钟,波特率说明:9600b/s */
//本示例程序已于2023-03-05下午测试通过,读出结果如下:
/*
------------------------------------------
---------------MCU-ID-READ----------------
------------------------------------------
[RAM-ID]F744C42503468E
[ROM-ID]F744C42503468E
*/
//本示例程序通过从RAM区域及ROM区域分别读出的MCU的ID序列号进行对比验证,并与
//程序下载成功时下载软件显示的ID序列号进行对比验证,测试正确无误。
//本示例程序只在下载成功时、或MCU复位后进行读出1次。
#include <STC8H.H>
#define SYSCLK 30000000UL //系统时钟频率值【用户指定值】,定义主频 30MHz,请按实际频率修改(用于delay函数自适应主频)
#define BAUD_SET (65536 - SYSCLK/9600/4) //波特率设定与计算【只在编译时计算1次】
#define RAM_AD 0xF1 //ID序列号在RAM空间的存放地址(首地址),具体MCU的该地址需要查阅具体手册获取
#define ROM_AD 0xFDF9 //ID序列号在ROM空间的存放地址(首地址),具体MCU的该地址需要查阅具体手册获取
typedef unsigned char u8;
typedef unsigned int u16;
u16 AID[7] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //用于存放RAM里面读出的ID序列号(7B,即7个字节)
u16 OID[7] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //用于存放ROM里面读出的ID序列号(7B,即7个字节)
//********************************函数声明区域********************************
void UART1_Init(void); //串口1初始化函数
void U1SEND_C(u8 SEND_C); //串口1发送单个字符数据函数
void U1SEND_S(u8* SEND_S); //串口1发送字符串数据函数
//********************************主函数区域********************************
void main()
{
u8 i; //定义循环控制变量i
u8 idata *RAM_P; //定义指针RAM_P,指向idata区域(若定义指向RAM区的指针则用idata关键字修饰)
u8 code *ROM_P; //定义指针ROM_P,指向code区域(若定义指向ROM区的指针则用code关键字修饰)
UART1_Init(); //串口1初始化
U1SEND_S("------------------------------------------\r\n");
U1SEND_S("---------------MCU-ID-READ----------------\r\n");
U1SEND_S("------------------------------------------\r\n");
RAM_P = RAM_AD; //让指针RAM_P指向0xF1(位于RAM区的首地址)
U1SEND_S("[RAM-ID]:");//从RAM读出的ID序列号为:
for(i=0;i < 7;i++) //读7B(高字节在前)
{
AID[i] = * RAM_P++;//取回RAM中的ID序列号依次存入RAM_ID[]
U1SEND_C((AID[i]/16 > 9)?AID[i]/16 - 10 +'A':AID[i]/16 + '0');//把读出的16进制的数据转换为ASCII字符格式
U1SEND_C((AID[i]%16 > 9)?AID[i]%16 - 10 +'A':AID[i]%16 + '0');//把读出的16进制的数据转换为ASCII字符格式
}
ROM_P = ROM_AD; //让指针ROM_P指向0xFDF9(位于ROM区的首地址)
U1SEND_S("\r\n");
U1SEND_S("[ROM-ID]:");//从ROM读出的ID序列号为:
for(i=0;i < 7;i++) //读7B(高字节在前)
{
OID[i] = * ROM_P++;//取回ROM中的ID序列号依次存入ROM_ID[]
U1SEND_C((OID[i]/16 > 9)?OID[i]/16 - 10 +'A':OID[i]/16 + '0');//把读出的16进制的数据转换为ASCII字符格式
U1SEND_C((OID[i]%16 > 9)?OID[i]%16 - 10 +'A':OID[i]%16 + '0');//把读出的16进制的数据转换为ASCII字符格式
}
U1SEND_S("\r\n");
U1SEND_S("------------------------------------------\r\n");
while(1)
{
;
}
}
//********************************自定义函数区域********************************
/*******************************************************
串口1初始化函数
无形参,
无返回值
9600bps@30MHz
*/
void UART1_Init(void) //串口1初始化函数
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = BAUD_SET; //利用波特率设置定时初始值
T2H = BAUD_SET >> 8;//利用波特率设置定时初始值
AUXR |= 0x10; //定时器2开始计时
RI = 0; //清除接收标志位
TI = 0; //清除发送标志位
}
/********************************************************
串口1发送单个字符数据函数
有形参,SEND_C即待发送的单字节数据;
无返回值
*/
void U1SEND_C(u8 SEND_C) //串口1发送单个字符数据函数
{
TI = 0; //清除发送完成标志位
SBUF = SEND_C; //开始发送单字节数据
while(!TI); //等待数据发送完成
}
/********************************************************
串口1发送字符串数据函数
有形参,SEND_S即待发送的单字节数据;
无返回值
*/
void U1SEND_S(u8* SEND_S) //串口1发送字符串数据函数
{
while(*SEND_S != '\0')//检测字符串结束标志
{
U1SEND_C(*SEND_S++); //串口1发送单个字符数据
}
}
/********************************************************/
|
|