STC12c5A60s2单片机 想通过片外EEPROM保存掉电信息!
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STC12c5A60s2单片机 想通过片外EEPROM保存掉电信息!相关的知识,希望对你有一定的参考价值。
用的以前51单片机的IIC读写eeprom程序,改了延时,但还是用问题!第一次接触STC12c5A60s2,不晓得要注意些什么。有谁有可运行的程序吗?我想参考下!STC12c5A60s2-能成功的读eeprom和写eeprom就行!
我正在用的代码,如果需要可以添加到你的程序里,直接调用其中的相关函数即可实现读写功能,至于为什么这么写不作赘述,自己查查资料,再对照代码应该就可以理解。加油吧!:头文件:
EEPstore.h
#ifndef _EEPSTORE_H_
#define _EEPSTORE_H_
#define USE_IAR 1 //程序中是否使用中断(1:是,0:否)
#define READPointer //连续读函数的指针指向数据类型(方便复制:idata,xdata,code,空:通用指针)
#define WRITEPointer //连续写函数的指针指向数据类型(方便复制:idata,xdata,code,空:通用指针)
/*=============【载减函数】================*/
#define USE_EROM_read_continuous 0
#define USE_EROM_write_continuous 0
#define USE_EROM_read_word 1
#define USE_EROM_write_word 1
/*=========================================*/
//进行选择编译的条件
extern UINT8 EROM_read_byte(UINT16 addr);//读制定地址一字
extern void EROM_write_byte(UINT16 addr,UINT8 dat);//向指定地址写一字
extern void EROM_erase_sector(UINT8 n);//擦除指定扇区
extern void EROM_read_continuous(UINT16 addr,UINT8 READPointer *pr,UINT8 len);//连续读出EROM内容到指定缓存
extern void EROM_write_continuous(UINT16 addr,UINT8 WRITEPointer *pr,UINT8 len);//将缓存内容连续写入EROM
extern UINT16 EROM_read_word(UINT16 addr);//读指定地址一字数据
extern void EROM_write_word(UINT16 addr,UINT16 dat);//向指定地址写一字数据
//
//************************************************************
// 【 以下宏不要修改 】
//************************************************************
//EEOPROM首址(不同STC型号有所不同)
#define EROM_START 0x0000 //STC12C5A60S2
#define IAPTRIG() IAP_TRIG = 0x5A, IAP_TRIG = 0xA5
#define EN_IAP 0x82 //系统时钟 >= 12MHz
#endif
C文件
EEPstore.c
/*******************************************************************
STC12C5A60S2扇区分布:
第一扇区(512个字节) 第二扇区(512个字节)
起始地址 结束地址 起始地址 结束地址
0000H 01FFH 0200H 03FFH
*******************************************************************/
#include"main.h"
#include"EEPstore.h"
//UINT8 num1;
//UINT16 num2;
/********************************************************************
*函数名称:command_and_close
*输入:无
*输出:无
*函数功能:IAP触发命令 + 禁止IAP操作(清IAP相关寄存器)
********************************************************************/
static void command_and_close( void )
//#if (USE_ISR)
// EA = 0;
//#endif
//
IAPTRIG();
_nop_();
_nop_();
_nop_();
//#if (USE_ISR)
// EA = 1;
//#endif
IAP_CONTR = 0;
IAP_CMD = 0;
IAP_TRIG = 0;
IAP_ADDRH = 0xFF;
IAP_ADDRL = 0xFF;
/********************************************************************
*函数名称:EROM_read_byte
*输入:(地址)
*返回:(地址内容)
*函数功能:读指定地址一字节数据
********************************************************************/
UINT8 EROM_read_byte(UINT16 addr)
IAP_CONTR = EN_IAP;
IAP_CMD = 1; //允许读取EEPROM
IAP_ADDRL = addr;
IAP_ADDRH = (UINT8)(addr>>8) + (UINT8)(EROM_START>>8);
command_and_close();
return IAP_DATA;
/********************************************************************
*函数名称:EROM_write_byte
*输入:(地址,数据)
*输出:无
*函数功能:向指定地址写一字节数据
********************************************************************/
void EROM_write_byte(UINT16 addr, UINT8 dat)
IAP_CONTR = EN_IAP;
IAP_CMD = 2; //允许编写EEPROM
IAP_ADDRL = addr;
IAP_ADDRH = (UINT8)(addr>>8) + (UINT8)(EROM_START>>8);
IAP_DATA = dat;
command_and_close();
/********************************************************************
*函数名称:
*输入:(扇区号)
*输出:无
*函数功能:擦除指定扇区
********************************************************************/
void EROM_erase_sector(UINT8 n)
IAP_CONTR = EN_IAP;
IAP_CMD = 3; //允许擦除EEPROM
IAP_ADDRL = 0x00;
IAP_ADDRH = (UINT8)(EROM_START>>8) + n*0x02;
command_and_close();
/********************************************************************
*函数名称:EROM_read_continuous
*输入:(起始地址,指针指向,字节长)
*输出:无
*函数功能:连续读数据
********************************************************************/
#if (USE_EROM_read_continuous)
void EROM_read_continuous(UINT16 addr, UINT8 READPointer *pr, UINT8 len)
while (len--)
*pr = EROM_read_byte(addr);
pr++;
addr++;
#endif
/********************************************************************
*函数名称:EROM_write_continuous
*输入:(起始地址,指针指向,字节长)
*输出:无
*函数功能:连续写数据
********************************************************************/
#if (USE_EROM_write_continuous)
void EROM_write_continuous(UINT16 addr, UINT8 WRITEPointer *pr, UINT8 len)
while (len--)
EROM_write_byte(addr, *pr);
pr++;
addr++;
#endif
/********************************************************************
*函数名称:EROM_read_word
*输入:起始地址
*输出:读取的数据
*函数功能:读指定地址一字数据
********************************************************************/
#if (USE_EROM_read_word)
UINT16 EROM_read_word(UINT16 addr)
UINT16 dat;
((UINT8 *)&dat)[0] = EROM_read_byte(addr++);
((UINT8 *)&dat)[1] = EROM_read_byte(addr);
return dat;
#endif
/********************************************************************
*函数名称:EROM_write_word
*输入:写入的地址,写入的数据
*输出:无
*函数功能:向指定地址写一字数据
********************************************************************/
#if (USE_EROM_write_word)
void EROM_write_word(UINT16 addr, UINT16 dat)
EROM_write_byte(addr++, ((UINT8 *)&dat)[0]);
EROM_write_byte(addr, ((UINT8 *)&dat)[1]);
#endif追问
谢谢啊!如楼上说的在手册里找到了片内EEPROM的实现方法!所以分给他了!但还是非常感谢!我会加油的!你的程序我收下了!
参考技术A 我都是用STC12c5A60s2内部自带的eeprom。也很方便,设置下控制寄存器然后套模板,并且不用像IIC的那样还得考虑时序、晶振。官方手册上有模板程序追问我写了下,把一个数组存入到eeprom,然后读到另一个数组。对比两个数组还是不一样。数组元素有三个!最后一个一样的!不晓得哪里出了问题!
追答不把手册翻个几遍,不可能详细了解一款芯片。有问题,先看手册
本回答被提问者采纳单片机期末复习
一、硬件结构
1.1部分引脚说明
RST:复位引脚,两个机器周期的高电平后复位
ALE:锁存低八位地址
EA:高电平时,访问内部程序存储器(ROM)
P0:双向IO口、分时复用-低八位地址,数据总线
P1:双向IO口
P2:双向IO口,访问外部存储器时,提供高八位地址总线
P3:双向IO口,有第二功能
1.2存储器
物理上分为:4 个空间
- 即片内ROM、 、 片外ROM(程序存储器)
- 片内RAM、 、 片外RAM(数据存储器)
逻辑上分为: : 3 个空间 ,
- 程序内存(ROM) ( 片内 、 外 ) 统一编址 MOVC
- 数据存储器 ( 片内) ) MOV
- 数据存储器(片外) MOVX
1.2.1程序存储器(ROM
- 作用:存储用户程序和表格常数
- 特殊单元:
0000H:复位后从这里开始执行程序
中断单元:
- 外中断0 (INT0 ) 0003H
- 定时器0 (T0 ) 000BH
- 外中断1 (INT1 ) 0013H
- 定时器1 (T1 ) 001BH
- 串行口(UART ) 0023H
1.2.2内部数据存储器(RAM
通用工作寄存器组
00~1FH共32个,四组通用寄存器,即(四组R0~R7)
可以使用RS1(PSW.4)RS0(PSW.3)来切换寄存器区
RS1 RS0 寄存器区 内存地址 00 0区 00-07H 01 1区 08-0FH 10 2区 10-17H 11 3区 18-1FH 位地址空间
20-2FH 共128位
外部数据存储器空间
MCS-51 可以外扩64KB RAM 或I/O 口。外部RAM和 和I/O口统一编址
特殊功能寄存器(SFR)
80-FFH 共21个离散分布,11个可以位寻址
介绍
A(ACC),存放操作数、运算结果
B,乘除法使用,也可以用作通用RAM单元
PSW
CY AC F0 RS1 RS0 OV - P D7 D6 D5 D4 D3 D2 D1 D0 - CY,进位标志,可被硬件,软件清零或置位。
- AC,辅助进位标志,低四位有进位或借位时置位。
- F0,用户定义的状态标志,软件清零或置位
- RS1、RS0,寄存器区控制位
- OV,溢出标志,加减指令溢出时置位
- p,奇偶标志,ACC中1的个数为奇数时置位
特殊功能寄存器介绍
- 堆栈指针SP:指示堆栈在内部RAM中的位置,系统复位后SP为07H,堆栈实际从08H开始
- 数据指针-DPTR:存放16位数据地址,访问外部(RAM或P)可分为DPH,DPL单独操作
- 端口P0-P3:IO端口锁存器
- 其他SFR:SBUF、SCON、TH0、TL0、TH1、TL1、IP、IE、TMOD、TCON、PCON
注 : PC 不属于 SFR
1.2.3并行口结构与操作
? 访问外部存储器时,地址由P0 和P2 口送出, 数据 通过P0 口传送,此时P0 口是 分时复用 的双向总线。
不使用外部存储器时,可作为准双向口使用。P2口:
- 不外接数据存储器时,P2 口作为通用I/O 口。
- 外接256B 数据存储器时,使用MOVX @Ri 类指令,由P0 送出低8 位地址,P2 口不受影响。
- 使用MOVX @DPTR 类指令时,需输出16 位地址,存储器访问周期内P2 口保持高8 位地址信息,而锁
存器的内容保持不变,故访问周期结束后锁存器的内容又回到引脚上。可在一定限度内作I/O 使用,如
作为输入口。P3口:
- 作通用I / O 时, “ 选择输出功能 ” 应保持高电平
- 工作于第二功能时,该位锁存器应置1
- 作输入口时,输出锁存器和选择输出功能端都 应置1 。
- 第二功能专用输入,取自输入通道第一 缓冲器G1 )输出端,通用输入信号取自 “ 读引脚 ”
I/O 口 第二功能 说 明 P 3.0 RXD 串行口数据接收端 P 3.1 TXD 串行口数据发送端 P 3.2 INT0 外部中断请求0 P 3.3 INT1 外部中断请求1 P 3.4 T0 定时器/ 计数器0 P 3.5 T1 定时器/ 计数器1 P 3.6 WR 外部RAM 写信号 P 3.7 RD 外部RAM
1.2.4时钟电路与复位电路
? 1个机器周期:12个晶荡(时钟)周期(或6个状态周期)
指令的执行时间称作指令周期
1.2.5复位
复位可使单片机或系统部件处于确定的初始状态。
- PC:0000H
- RAM:随机值(运行中复位不改变RAM内容)
- SFR:
- P0~P3=FFH
- SP=07H
- 其余各位为0
? 复位电路的作用非常重要,能否成功复位关系到单片机系统能否正常运行的问题。如果振荡电路正常而单片机系统不能正常运行,其主要原因是单片机没有完成正常复位,程序计数器的值没有回0 0 ,特殊功能寄存器没有回到初始状态。这时可以适当地 调整上电复位电路的阻容值 ,增加其充电时间常数来 解决问题
二、指令系统
2.1指令格式及常用符号
机器指令 :计算机能直接识别和执行的指令
单字节指令:一般那种没有数字的是单字节指令
如:
? INC A
MOV A,R0
双字节指令:一般带有一个数字的为双字节指令,带有rel的也增加一个字节
如:
? MOV A,#50H
? JC rel
三字节指令:一般带有两个数字的为三字节指令
如:
? MOV 20H,#30H
Rn (n=0~7 )- 当前工作寄存器组中的寄存器R0~R7 之一
Ri (i=0,1 )- 当前工作寄存器组中的寄存器R0 或R1
@ ---------- 间址寄存器前缀
- #data ------8 位立即数/
- #data16-----16 位立即数
- direct------ 片内低128 个RAM 单元地址及SFR 地址
- addr11------11 位目的地址
- addr16------16 位目的地址
- rel---------8 位地址偏移量 , 范围:-128 ~+127
- bit--------- 片内RAM 位地址、 、SFR 的位地址
- ( ×)------ 表示 × 地址单元或寄存器中的内容
/ ----------位操作数的取反操作前缀
2.2寻址方式
? 7种寻址方式
2.2.1寄存器寻址
? MOV A,R0
2.2.2直接寻址
? MOV A,50H
2.2.3寄存器间接寻址
? MOV A,@R0
2.2.4立即寻址
? MOV A,#50H
2.2.5变指寻址
? MOVC A,@A+DPTR
2.2.6相对寻址
? 用于跳转指令,实现程序分支,注意加上指令字节数
如:
? rel=75H,psw.7=1,JC rel存在1000H开始的单元,
执行JC rel后,程序将跳转到1077H单元,(因为要加上JC rel的两个字节)
2.2.7位寻址
? 位寻址方式实质属于 位的直接寻址。
2.3指令
? 注意,使用MOVX A,@Ri读取片外RAM时,高八位地址由P2提供
PUSH,POP
? PUSH 先SP+1 在送值
? POP 先出值,在SP-1
XCH 字节交换
若(R0 )=80H, (A )=20H 。
执行指令 XCH A ,R0 后,
(A )=80H ,(R0 )=20H。XCHD 间址操作数的低半字节与A 的低半字节互换
若(R0 )=30H ,(30H )=67H , (A )=20H 。执行指令
XCHD A ,@R0 指令后,(A )=27H ,(30H )=60H。MUL AB ;A为低八位,B为高八位
DIV AB ;A为整数,B 为余数
ANL
ORL
XRL ;异或
CLR
CPL ;取反
AJMP ;2K PC+2
LJMP ;64K
SJMP;256(-128~+127) PC+2
JMP ;PC+1
JB、JBC、JNB ;PC + 3
JC、JNC ; PC + 2
2.4调用与返回
调用
ACALL addr11:
? PC += 2
? SP += 1
? SP = PC(低八位)
? SP+=1
? SP = PC(高八位)
? PC(低11位)=addr11
LCALL addr16:
? PC += 3
? SP += 1
? SP = PC(低八位)
? SP+=1
? SP = PC(高八位)
? PC = addr16
SP中存的是程序返回地址,PC存的是当前执行指令的值
返回
RET
? PC (高八位)= SP
? SP -= 1
? PC(低八位) = SP
? SP -= 1
RETI
? PC (高八位)= SP
? SP -= 1
? PC(低八位) = SP
? SP -= 1
RET 与 RETI 对堆栈的操作是完全相同的,但是RETI专用于中断的返回,它具有清除内部相应的中断状态触发器的功能。
三、程序设计
? 单片机应用系统由 硬件系统 和 应用程序
? 注意:查表时,如果表是DW存的,那么查询之前,需要左移一下A,若是DB存的,则不需要
JMP @A+DPTR
AJMP XXXX ; 最多128种分支, (256/2
LJMP XXXX; 最多85种分支 (256/3
其余略过,具体看书
四、中断系统
? 外部中断0和1(INT0、INT1)? 采集到低电平或者脉冲下降沿时,产生中断请求。 INT0来自P3.2引脚 INT1来自P3.3引脚
定时/计数器0和1(T0、T1)? 定时功能时,计数脉冲来自片内? 计数功能时,计数脉冲来自片外。T0来自P3.4引脚 T1来自P3.5引脚? 计数值由8个1变成8个0时,产生中断请求。
串行中断? 发送或接收完一个字节数据时,产生中断请求发送来自P3.0引脚接收来自P3.1引脚
中断相关特殊寄存器
中断允许寄存器IE
中断优先级寄存器IP
定时/ 计数器及外部中断控制寄存器TCON
串口控制寄存器SCONTCON
SCON
IE
IP
五、定时器、计数器
TMOD
TCON
5.1工作方式
T0:0、1、2、3
T1:0、1、2
方式0:
13位,初值计算:
- 计数模式(C/T=1):
8192-N
定时模式:
8192-N,
? N=t/Tcy,(即,要求的时间/单片机的机器周期)
? eg: 定时1ms,单片机晶振频率12M,则机器周期为1μs,那么N=1ms/1μs=1000
? 初值就是 7192,然后转换为十六进制送入TH0(高八位),TL0(低五位)即可
但是由于,13位,送的时候,不太方便,所以一般不用方式0
方式1:
16位,初值计算
65536-N
送初值的时候,需要将初值高八位送入TH0,低八位送入TL0
eg:N=500,则可以这样送
MOV TH0,#(65536-500) / 256 MOV TL0,#(65536-500) MOD 256
?
方式2:
8位,自动重装载
256-N
送初值的时候,只要将初值送给TH0,和TL0即可
方式3:
8位,(仅T0有此方式,T1 方式3将停止计数)
TL0进行8位定时/计数
TH0进行8位定时(T1方式2时,可出借TR1 、TF1)
? 模式3 对T T0 和T1是不同的。
对于T1,设置为模式3将使它保持原有的计数值 其作用
如同使 如同使 TR1 = 0,即停止计数。
对于T0,将使 TL0 和 TH0 成为两个独立的 8位计数器 。 TH0
只能作定时器 , 对机器周期计数 ,借用T1 的 TR1 和 TF1 , 并占用
T1的中断源 ,此时T1 仍可工作在模式0 、1 或 2, 用于不需要中
断控制的场合 , 如用于作波特率发生器 (工作于模式2)。
5.2注意的问题
5.2.1对输入信号的要求
定时器方式:
输入来自内部时钟脉冲(fosc/12),定时精度取决于振荡器频率
计数器方式
外部输入脉冲的最高频率为震荡器频率的1/24。即 晶振频率/24
5.2.2赋初值
除了模式二的自动重装载外,其余的模式,在中断程序内需要重新赋初值
5.2.3运行中读定时器/计数器
由于 不可能在同一时刻读取THx 和TLx 的内容,读取的计数值有可能出错。例如:先读TLx ,后读THx ,由于定时器在不断运行,读THx 前若恰好产生 生TLx 溢出向THx 进位的情况,则读得的TLx 是错误的。同样,若先读
THx ,后读TLx也会出错。
解决方式:
? 先读THx, , 后读TLx, , 再读THx, 若两次读得的THx 相同 , 则可确定读得的内容是正确的 。 若前后读得的THx 有变化 , 则重复上述过程 , 这次重复读得的内容应是正确的。
RDTIME : MOV A ,TH0 MOV R0 ,TL0 CJNE A ,TH0 ,RDTIME MOV R1 ,A RET
5.3初始化
- 对TMOD赋值,确定T0、T1工作方式
- 求初值,并写入TH0、TL0或者TH1、TL1
- 中断方式时,对IE进行赋值,开开中断
- 查询方式时,检测TF0或TF1,为1代表计时时间到,将其清0,使TR0或TR1置位,启动定时、计数工作。
eg:
? 用T0 扩展一个外部中断源。将T0 设置为计数器方式,按方式2工 工
作,TH0 、TL0 的初值均为0FFH ,T0 允许中断,CPU 开放中断。其初
始化程序如下:MOV TMOD,#06H ; 置T0 为计数器方式2 MOV TL0,#0FFH ; 置计数初值 MOV TH0,#0FFH SETB TR0 ; 启动T0 工作 SETB EA ;CPU 开中断 SETB ET0 ; 允许T0 中断
5.4例
定时时间较大时(大于65ms)
实现方法:一是采用1 个定时器定时一定的间隔(如20ms ),然后用软件进行计数;二是采用2 个定时器级联,其中一个定时器用来产生周期信号(如20ms 为周期),然后将该信号送入另一个计数器的外部脉冲输入端进行脉冲计数。
编写程序,实现用定时/ 计数器T0 定时,使P1.7 引脚输出周期为2s 的方波。设系统的晶振频率为12MHz 。
$color{red}{采用 定时50ms ,然后再 计数20}$
ORG 0000H LJMP MAIN ORG 000BH LJMP DVT0 ORG 0030H MAIN: MOV TMOD,#01H; 置T0 方式1 MOV TH0,#3CH ; 装入计数初值 MOV TL0,#0B0H ; 首次计数值 MOV R7,#20 ; 计数50 次 SETB ET0 ;T0 开中断 SETB EA ;CPU 开中断 SETB TR0 ; 启动T0 SJMP $ ; DVT0: DJNZ R7,NT0 MOV R7,#20 CPL P1.7 NT0: MOV TH0,#3CH MOV TL0,#0B0H RETI END
六、串行口
SCON
PCON
6.1工作方式
SM0、SM1选择四种工作方式
方式0,同步移位寄存器方式
用于扩展并行I/O
- 一帧8 位,无起始位和停止位。
- RXD :数据输入/ 输出端。
TXD :同步脉冲输出端,每个脉冲对应一个数据位。 - 波特率B = fosc/12
如: fosc=12MHz , B=1MHz ,每位数据占1μs 。 - 发送过程: 写入SBUF ,启动发送,一帧发送结束,TI=1 。
接收过程:REN=1 且RI=0 ,启动接收,一帧接收完毕, RI=1 。
eg:
数据从RXD(P3.0)引脚串行输出,低位在先,高位
在后;TXD(P3.1)引脚输出移位脉冲,其频率为foc/12;
发送完毕后,中断标志位TI为1。MOV SCON,#00H ;串行口方式0 MOV SBUF,A ;将数据送出 JNB TI,$ ;等待数据发送完毕
方式1:八位数据异步通讯方式
一帧10 位:8 位数据位,1 个起始位(0) ,1 个停止位(1)
RXD :接收数据端。 TXD :发送数据端。
波特率:用T1 作为波特率发生器,B=(2 SMOD /32) ×T1 溢出率。
发送:写入SBUF ,同时启动发送,一帧发送结束,TI=1 。
接收:REN=1 ,允许接收。接收完一帧,若RI=0 且停止位为1( 或SM2=0) ,将接收数据装入SBUF ,停止位装入RB8 ,并使
RI=1 ;否则丢弃接收数据,不置位RI 。当REN=1 ,CPU 开始采样RXD 引脚负跳变信号,若出
现负跳变,才进入数据接收状态,先检测起始位,若第一
位为0 ,继续接收其余位;否则,停止接收,重新采样负跳
变。数据采样速率为波特率16 倍频,在数据位中间,用第7 、
8 、9 个脉冲采样3 次数据位,并3 中取2 保留采样值。
方式2、方式3:9位数据异步通讯方式
- 一帧为11 位:9 位数据位,1 个起始位(0) ,1 个停止位(1)。 。
第 第9 位数据位在TB8/RB8 中,常用作校验位和多机通讯标识
位。 - RXD :接收数据端,TXD :发送数据端
- 波特率: 方式2 :B=(2 SMOD /64) ×fosc 。
方式3 :B=(2 SMOD /32) ×T1 溢出率 - ) 发送: 先装入TB8 ,写入SBUF 并启动发送,发送结
束,TI=1 。
接收:REN=1 ,允许接收。接收完一帧,若RI=0 且第
9 位为1 ( 或SM2=0) ,将接收数据装入接收SBUF ,第9 位装
入RB8 ,使RI=1 ;否则丢弃接收数据,不置位RI
- 一帧为11 位:9 位数据位,1 个起始位(0) ,1 个停止位(1)。 。
6.2波特率确定与初始化步骤
波特率确定
固定波特率:
方式0波特率= fosc/12
方式2波特率 = ($2^{SMOD}$/64)*fosc
可变波特率:
方式1波特率 = ($2^{smod}$/32)*T1溢出率
方式3波特率 = ($2^{smod}$/32)*T1溢出率
? (定时器1)T1溢出率
- fosc/(12*($2^n$-定时器初值))
- n为定时器的模式位数,模式0-->13, 模式1----->16, 模式2----->8
经推导定时器初值可近似为
$2^n-(2^{smod}1.085x)/(波特率/2400)$
其中,smod与pcon最高位相同,x为晶振频率/M,计算结果,四舍五入即可。
初始化步骤
- 确定T1工作方式(找到n)(MOV TMOD,#20H)
- 设置PCON
- 计算初值(上面的公式)
- 启动T1(SETB TR1)
- (开开单片机中断(SETB EA))
- (开开串行口中断(SETB ES))
发送程序
查询方式
SEND: MOV A,@R0 ; 取数据 MOV SBUF,A ;发数据 JNB TI,$ ; 等待发送结束 CLR TI ;清除标志位 INC R0 ;准备下一次发送 SJMP SEND
中断方式
ORG 0 LJMP MAIN ORG 0023H LJMP DVSEND ORG 0100H MAIN: ...... MOV A,@R0 ; 取数据 MOV SBUF,A ;发数据 DVSEND: CLR TI INC R0 MOV A,@R0 MOV SBUF,A RETI
接收程序
REN=1、RI=0等待接收,当RI=1,从SBUF读取数据
查询方式
WAIT: JBC RI,NEXT SJMP WAIT NEXT: MOV A,SBUF MOV @R0,A INC R0 SJMP WAIT
中断方式
ORG 0023H LJMP DVGET MAIN: ...... SJMP $ DVGET: CLR RI MOV A,SBUF MOV @R0,A INC R0 RETI
?
以上是关于STC12c5A60s2单片机 想通过片外EEPROM保存掉电信息!的主要内容,如果未能解决你的问题,请参考以下文章
stc12c5a60s2的单片机与at89c51单片机有啥区别论文上面要用