|
楼主 |
发表于 2005-3-22 01:22:55
|
显示全部楼层
既然有这么多网友捧场,此段程序还有几个程序要一起链接编译,否则直接使用,会出现错误提示,在此也一并奉上:
注意:与 ADC 有关的程序段应删去,因为这些程序中还需要调用其它子程序。
;*******************************************************************************
;*
;* 子程序名: CTRLCOM_Manage.asm
;* 程序名称: 控制操作指令处理子程序
;* 版本: 1.0
;* 适用 MCU 型号: AVR所有型号
;* 使用资源: r5,r6,r16,r17,r18,r19,r20,r28,r29,r30,r31
;*
;* 程序功能:
;* 本程序是用于对控制操作指令进行处理操作的子程序,也是系统人-机对话输
;* 入处理的组成部分,对于各种不同输入对象下达的控制操作指令均可在此统一进行
;* 处理。共包括下面列表中这二个子程序。这二个子程序的具体使用方法请参考各自
;* 的说明。
;* ┏───────────┳───────────────────────┓
;* ┃ 子程序名称 ┃ 子程序功能描述 ┃
;* ┣───────────╋───────────────────────┫
;* ┃CTRLCOM_Initialization┃ 处理控制操作指令初始化 ┃
;* ┣───────────╋───────────────────────┫
;* ┃ CTRLCOM_Manage ┃ 识别和处理控制操作指令 ┃
;* ┗───────────┻───────────────────────┛
;*
;* 注释:
;* ①.对于不同的输入控制操作指令的对象可通过给通过设置相应的标志字节来区分,
;* 如:对“CCOMALW_USART ”(允许处理 USART 端口的控制操作指令标志)置相同的这
;* 个数值“CTRLCOM_ALWSI”($ca)来确定和识别下达执行相应操作的控制指令的身份。
;* 对于不同的输入对象可自由定义其标志字节。
;* ②.控制操作指令内容必须放在 SRAM 中的相应位置,由 Y 指针指向其存储地址。
;* 所有控制操作指令的格式为:Control(控制操作指令起始标识字符串)+ 设备编号(4
;* 个字节)+ 控制操作指令具体字。己定义的控制操作指令见子程序“CTRLCOMM_IPFMCOM”
;* (识别和执行控制操作指令处理子程序)的具体说明。
;* ③.对于新增加的控制操作指令处理程序,在编程时请注意,如果在程序中用到 Y
;* 指针的话,必须对其入栈保护,保证在返回时没有修改 Y 指针数值。否则会导致其他
;* 控制操作指令的识别错误。
;*
;* 编作者:
;* 编作者 E-Mail: PTZSW@163.COM
;* 编制日期: 2005年2月18日
;*
;*******************************************************************************
;*
;* 指令条数: 1298 + return
;* 指令执行周期: 0 + return
;* 低位寄存器使用: None
;* 高位寄存器使用: 5 (r16,r17,r18,r19,r20)
;* 指针寄存器使用: Y,Z
;*
;*******************************************************************************
;******** 本程序需调用的子程序定义:
.include "USART_INT.asm" ;USART异步中断接收和发送通信程序
.include "InsideADC_INT.asm" ;使用内部模拟/数字转换器进行电压测量程序
.include "Access_EEPROM.asm" ;存取 EEPROM (电可擦除只读存储器)程序
;******** 依据硬件设置需修改的 SRAM 存储地址定义:
.equ CCOMALW_USART = $0068 ;允许处理 USART 端口的控制操作指令标志
.equ CCOMA_PDNSCC = $0069 ;允许处理公共编号的特殊控制操作指令标志
;******** 存储在 EEPROM 中的特定数据起始地址定义:
.equ CC_EEPROM_DNAr = $0010 ;设备编号在 EEPROM 中的起始地址
.ESEG
.org $0010
DeviceNumber:
.DB "6688" ;设备编号
.CSEG
;******** 本程序常数定义:
.equ CTRLCOM_ALWSI = $ca ;允许处理控制操作指令标志值(11001010)
.equ CCTSSDV_RightI = $af ;控制操作指令正确标志值(10101111)
.equ CTRLCOM_MPFMSI = $ab ;控制操作指令己经执行标志值(10101011)
.equ CCOMMIPFM_RETI = $cc ;控制操作指令返回状态标志值(11001100)
.equ CCOMMIPFM_ENDI = $c3 ;控制操作指令结束状态标志值(11000011)
.equ CTRLCDN_CharNI = $04 ;设备编号使用的字节数
;******** 本程序寄存器变量定义:
.def CTRLCOM_TEMP = r16 ;暂存寄存器
.def CTRLCOM_TEMP2 = r17 ;暂存寄存器2
.def CTRLCOM_CNT = r18 ;循环计数器
.def CTRLCOM_MIPFM = r21 ;控制操作指令识别和执行状态寄存器
.def CTRLCOM_MPFMS = r22 ;判断控制操作指令执行与否寄存器
.def CCTSSDV_Right = r23 ;判断控制操作指令正确与否寄存器
;******** 程序指令代码清单:
;*******************************************************************************
;*
;* 处理控制操作指令初始化子程序 - “CTRLCOM_Initialization”
;*
;* 说明:
;* 本子程序用于初始化处理控制操作指令。
;* 本子程序只需在主程序中运行一次即可,但要在下面的所有程序运行前先执行。
;*
;*******************************************************************************
CTRLCOM_Initialization:
clr ZL ;清除允许处理 USART 端口的控制操作指令标志
sts CCOMALW_USART,ZL
ret ;子程序返回
;*******************************************************************************
;*
;* 识别和处理控制操作指令子程序 - “CTRLCOM_Manage”
;*
;* 说明:
;* 本子程序用于使用识别和处理控制操作指令。
;* 本子程序要在主程序中不间断地循环运行。
;*
;* SRAM 中标志字节用法:
;* 入口标志:本子程序将检查这些标志,依据这些标志置值来执行不同处理方式。
;* 允许处理 USART 的指令(CCOMALW_USART)= $ca(CTRLCOM_ALWSI)
;* 出口标志:本子程序运行后,将对下面这两个标志置值。
;* 允许处理 USART 的指令(CCOMALW_USART)= $00
;*******************************************************************************
CTRLCOM_Manage:
lds ZL,CCOMALW_USART ;检查是否允许处理 USART 端口的控制操作指令?
cpi ZL,CTRLCOM_ALWSI ;是,到相应处理
brne CTRLCOM_Manage1 ;否,则继续
rcall CTRLCOMM_USART ;进入由 USART 端口送来控制操作指令处理
rjmp CTRLCOM_Manage_RET ;返回
CTRLCOM_Manage1:
;此处可继续插入由其他地方传来控制操作指令处理程序
CTRLCOM_Manage_RET:
ret ;子程序返回
;*** 此段程序用于[由 USART 端口送来控制操作指令]处理
CTRLCOMM_USART:
lds ZL,USARTAI_TXEnd ;发送作业是否全部结束?
cpi ZL,USARTAI_TEndI ;否,返回,等待发送作业结束
breq CTRLCOMM_USART1 ;是,则继续
rjmp CTRLCOMM_USART_RET
CTRLCOMM_USART1:
lds ZL,USARTAI_RXUPD ;检查接收作业是否己更新?
cpi ZL,USARTAI_RUPDI ;否,直接返回
breq CTRLCOMM_USART2 ;是,则继续
rjmp CTRLCOMM_USART_RET
CTRLCOMM_USART2:
lds ZL,USARTAI_RXEnd ;检查接收作业是否全部结束?
cpi ZL,USARTAI_REndI ;否,转至接收错误处理
breq CTRLCOMM_USART_CCHead ;是,则继续
rjmp CTRLCOMM_USART_Error
CTRLCOMM_USART_CCHead:
ldi YL,Low(USARTAI_RXDAA+1) ;置由 USART 端口送来指令地址指针
ldi YH,High(USARTAI_RXDAA+1) ;第一个字节为长度数值,不识别
ldi ZL,Low(ControlHandle_Head*2);置控制操作指令开头标识字符串地址指针
ldi ZH,High(ControlHandle_Head*2)
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对控制操作指令开头标识字符串识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为控制操作指令开头标识字符串?
breq CTRLCOMM_USART_EAddr ;是,则继续
rjmp CTRLCOMM_USART_Error ;否,则转至接收错误处理
CTRLCOMM_USART_EAddr:
ldi ZL,Low(ControlHandle_Head*2);置控制操作指令开头标识字符串地址指针
ldi ZH,High(ControlHandle_Head*2)
lpm CTRLCOM_CNT,Z+ ;读取开头命令字长度数值
clr CTRLCOM_TEMP
add YL,CTRLCOM_CNT ;置 Y 指针为设备地址字符串的地址指针
adc YH,CTRLCOM_TEMP
ldi CTRLCOM_CNT,CTRLCDN_CharNI ;置循环计数器初值=设备地址字长度数值
ldi EEPROM_AddrL,Low(CC_EEPROM_DNAr)
ldi EEPROM_AddrH,High(CC_EEPROM_DNAr)
;置在 EEPROM 中的设备编号地址指针
CTRLCOMM_USART_EAddr1:
call EEPROM_ReadSingle ;读取 EEPROM 中的设备编号
ld CTRLCOM_TEMP2,Y+
cp EEPROM_Data,CTRLCOM_TEMP2 ;检查是否为本设备的编号数字?
brne CTRLCOMM_USART_Error ;否,转到接收错误处理
adiw EEPROM_AddrL,$01 ; EEPROM 中的设备编号地址指针 + 1
dec CTRLCOM_CNT ;设备地址字长度数值 — 1
brne CTRLCOMM_USART_EAddr1 ;所有编号识别完否?未完,则继续识别
rcall CTRLCOMM_IPFMCOM ;识别和执行控制操作指令处理
cpi CTRLCOM_MIPFM,CCOMMIPFM_RETI;检查指令识别和执行状态是否为返回?
breq CTRLCOMM_USART_RET ;是,转到返回
;否,则继续
cpi CTRLCOM_MIPFM,CCOMMIPFM_ENDI;检查指令识别和执行状态是否为结束?
breq CTRLCOMM_USART_End ;是,转到结束处理
rjmp CTRLCOMM_USART_Error ;否,转到接收错误处理
CTRLCOMM_USART_End:
ldi ZL,USARTAI_RCOMI ;置接收命令作业标志值
sts USARTAI_RXCOM,ZL
brts CTRLCOMM_USART_End1 ;向对方发送“接收数据正确”命令吗?
call USART_TX_COMM_AskTX ;否,发送“向对方请求发送”命令
rjmp CTRLCOMM_USART_End2
CTRLCOMM_USART_End1:
call USART_TX_COMM_DataOK ;是,向对方发送“接收数据正确”命令
CTRLCOMM_USART_End2:
clr ZL ;清除接收作业己更新标志
sts USARTAI_RXUPD,ZL
clr ZL ;清除允许处理 USART 端口的控制操作指令标志
sts CCOMALW_USART,ZL
rjmp CTRLCOMM_USART_RET ;返回
CTRLCOMM_USART_Error:
call USART_RXD_Error ;调用接收错误处理子程序
CTRLCOMM_USART_RET:
ret ;子程序返回
;*******************************************************************************
;*
;* 识别和执行控制操作指令处理子程序 - “CTRLCOMM_IPFMCOM”
;*
;* 说明:
;* 本子程序用于识别和执行控制操作指令处理。本子程序可供其他程序调用,只要在
;* Y 指针中置入相应的控制操作指令字即可执行对此指令的操作。本子程序共设置下列这
;* 些控制操作指令(指令的具体格式见各指令字符串的具体定义):
;* 1.[OpenFullPageADC] - 整页启动内部 ADC 转换指令
;* 2.[OpenSingleGroupADC] - 单组启动内部 ADC 转换指令
;* 3.[OpenSingleChannelADC:X] - 单通道启动内部 ADC 转换指令
;* 4.[TXD@FullPageADC] - 发送整页 ADC 转换结果数据指令
;* 5.[TXD@SingleGroupADC] - 发送单组 ADC 转换结果数据指令
;* 6.[TXD@SingleChannelADC] - 发送单通道 ADC 转换结果数据指令
;* 7.[ChangeDeviceNumber:XXXX] - 修改在 EEPROM 中的 4 个字节设备编号指令
;*
;* 注意:
;* 请慎用4、5、6这几条发送数据指令!如果在前面没有执行相应操作的指令,那
;* 么将会导致收到的数据错误,也可能导致其他程序得到错误的数据。
;*
;* 入口条件:
;* 在调用本程序前,需设置下面这个地址指针数值:
;* Y 指针 ----- 指向传送来的控制操作指令在 SRAM 中的存储地址
;* 出口条件:
;* 程序运行结束后,将会下面这个标志置不同的数值。
;* r21 --- 控制操作指令识别和执行状态寄存器(CTRLCOM_MIPFM)
;* ①.= $cc(CCOMMIPFM_RETI),为控制操作指令返回状态值
;* ②.= $c3(CCOMMIPFM_ENDI),为控制操作指令结束状态值
;* ③.= $00 ,为非上面两种状态值
;*
;*******************************************************************************
CTRLCOMM_IPFMCOM:
clr CTRLCOM_MIPFM ;清除控制操作指令识别和执行状态
CTRLCOMM_IPFMCOM1:
ldi ZL,Low(OpenFullPageADC*2)
ldi ZH,High(OpenFullPageADC*2)
;置整页启动内部 ADC 转换指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM2 ;否,则继续
rcall CTRLCOMM_OFPADC ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM11 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM11:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM2:
ldi ZL,Low(OpenSingleGroupADC*2)
ldi ZH,High(OpenSingleGroupADC*2)
;置单组启动内部 ADC 转换指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM3 ;否,则继续
rcall CTRLCOMM_OSGADC ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM21 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM21:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM3:
ldi ZL,Low(OpenSingleChannelADC_X*2)
ldi ZH,High(OpenSingleChannelADC_X*2)
;置单通道启动内部 ADC 转换指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM4 ;否,则继续
rcall CTRLCOMM_OSSCADC ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM31 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM31:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM4:
ldi ZL,Low(TXD_FullPageADC*2)
ldi ZH,High(TXD_FullPageADC*2)
;置发送整页 ADC 转换结果数据指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM5 ;否,则继续
rcall CTRLCOMM_TXDFPADC ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM41 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM41:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM5:
ldi ZL,Low(TXD_SingleGroupADC*2)
ldi ZH,High(TXD_SingleGroupADC*2)
;置发送单组 ADC 转换结果数据指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM6 ;否,则继续
rcall CTRLCOMM_TXDSGADC ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM51 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM51:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM6:
ldi ZL,Low(TXD_SingleChannelADC*2)
ldi ZH,High(TXD_SingleChannelADC*2)
;置发送单通道 ADC 转换结果数据指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM7 ;否,则继续
rcall CTRLCOMM_TXDSSCADC ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM61 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM61:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM7:
ldi ZL,Low(ChangeDeviceNumber_XXXX*2)
ldi ZH,High(ChangeDeviceNumber_XXXX*2)
;置修改设备编号指令地址指针
lpm CTRLCOM_CNT,Z+ ;置循环计数器初值=指令字长度数值
rcall CTRLCOMM_IdentifyCOM ;对此条控制操作指令进行识别
cpi CCTSSDV_Right,CCTSSDV_RightI;检查是否为此条控制操作指令?
brne CTRLCOMM_IPFMCOM8 ;否,则继续
rcall CTRLCOMM_ChangeDN ;是,调用处理此条控制操作指令程序
cpi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;检查控制操作指令是否己经执行?
breq CTRLCOMM_IPFMCOM71 ;是,置控制操作指令结束状态标志值
ldi CTRLCOM_MIPFM,CCOMMIPFM_RETI ;否,置控制操作指令返回状态标志值
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM71:
ldi CTRLCOM_MIPFM,CCOMMIPFM_ENDI
rjmp CTRLCOMM_IPFMCOM_RET
CTRLCOMM_IPFMCOM8:
;此处可继续插入其他控制操作指令识别和执行程序
CTRLCOMM_IPFMCOM_RET:
ret ;子程序返回
;*******************************************************************************
;*
;* 识别控制操作指令子程序 - “CTRLCOMM_IdentifyCOM”
;*
;* 说明:
;* 本子程序用于使用识别控制操作指令。
;*
;* 注意:
;* 程序运行结束后,将恢复 Y 指针为原来的数值。而 Z 指针将更改为该指令
;* 在 Flash 中的存储地址的后一个字节位置。
;*
;* 入口条件:
;* 在调用本程序前,需设置下面这两个地址指针和循环计数器数值:
;* Z 指针 ----- 指向控制操作指令在 Flash 中的存储地址
;* Y 指针 ----- 指向传送来的控制操作指令在 SRAM 中的存储地址
;* r18 --- 循环计数器(CTRLCOM_CNT)= 控制操作指令字符串长度数值
;* 出口条件:
;* ①.经过识别后,如果是 Z 指针指向的控制操作指令,将对此标志置值。
;* r23 --- 控制操作指令正确(CCTSSDV_Right)= $af(CCTSSDV_RightI)
;* ②.经过识别后,如果不是 Z 指针指向的控制操作指令,将清除此标志。
;* r23 --- 控制操作指令正确(CCTSSDV_Right)= $00
;*
;*******************************************************************************
CTRLCOMM_IdentifyCOM:
push YL ;压入 Y 指针的数值到堆栈
push YH
clr CCTSSDV_Right ;清除控制操作指令正确标志
CTRLCOMM_IdentifyCOM1:
lpm CTRLCOM_TEMP,Z+ ;读控制操作指令字
ld CTRLCOM_TEMP2,Y+
cp CTRLCOM_TEMP,CTRLCOM_TEMP2 ;比较控制操作指令字是否相等?
brne CTRLCOMM_IdentifyCOM_RET ;否,直接返回
;是,则继续读下一控制操作指令字
dec CTRLCOM_CNT ;循环计数器 — 1
brne CTRLCOMM_IdentifyCOM1
ldi CCTSSDV_Right,CCTSSDV_RightI;置控制操作指令正确标志值
CTRLCOMM_IdentifyCOM_RET:
pop YH ;弹出堆栈中的 Y 指针数值
pop YL
ret ;子程序返回
;*******************************************************************************
;!!!注意:下面所有的控制操作指令处理程序,在返回时均不能修改 Y 指针数值。
;*******************************************************************************
;*******************************************************************************
;*
;* 所有控制操作指令开头标识字符串 - “ControlHandle_Head”
;*
;*******************************************************************************
ControlHandle_Head:
.DB $07,"Control" ;控制操作指令开头标识字符(Control)
; │ │
; │ 控制操作指令开头标识字符(Control)
; 本指令字符串字符长度数值(不包括自已在内共 7 个字符)
;*******************************************************************************
;*
;* 以整页方式启动内部 ADC 转换进行测量指令 - “OpenFullPageADC”
;*
;*******************************************************************************
OpenFullPageADC:
.DB $0f,"OpenFullPageADC"
; │ │
; │ 控制操作指令字(OpenFullPageADC)
; 本指令字符串字符长度数值(不包括自已在内共 15 个字符)
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_OFPADC:
clr CTRLCOM_MPFMS ;清除控制操作指令己经执行标志值
lds ZL,IADCI_StaFUP ;检查启动整页ADC转换是否己完成?
cpi ZL,IADCI_StaFUPI ;是,则继续
breq CTRLCOMM_OFPADC_RET ;否,直接返回
ldi CTRLCOM_TEMP,IADCI_StaFUPI ;置启动整页 ADC 转换标志值
sts IADCI_StaFUP,CTRLCOM_TEMP
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
set ;置 T 标志
CTRLCOMM_OFPADC_RET:
ret ;子程序返回
;*******************************************************************************
;*
;* 以单组方式启动内部 ADC 转换指令 - “OpenSingleGroupADC”
;*
;*******************************************************************************
OpenSingleGroupADC:
.DB $12,"OpenSingleGroupADC"
; │ │
; │ 控制操作指令字(OpenSingleGroupADC)
; 本指令字符串字符长度数值(不包括自已在内共 18 个字符)
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_OSGADC:
clr CTRLCOM_MPFMS ;清除控制操作指令己经执行标志值
lds ZL,IADCI_StaFUP ;检查启动整页ADC转换是否己完成?
cpi ZL,IADCI_StaFUPI ;是,则继续
breq CTRLCOMM_OSGADC_RET ;否,直接返回
lds ZL,IADCI_StaGro ;检查启动单组ADC转换是否己完成?
cpi ZL,IADCI_StaGroI ;是,则继续
breq CTRLCOMM_OSGADC_RET ;否,直接返回
ldi CTRLCOM_TEMP,IADCI_StaGroI ;置启动单组 ADC 转换标志值
sts IADCI_StaGro,CTRLCOM_TEMP
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
set ;置 T 标志
CTRLCOMM_OSGADC_RET:
ret ;子程序返回
;*******************************************************************************
;*
;* 以单通道方式启动内部 ADC 转换指令 - “OpenSingleChannelADC:X”
;*
;*******************************************************************************
OpenSingleChannelADC_X:
.DB $15,"OpenSingleChannelADC:",$00
; │ │ │
; │ │ ADC 模拟通道数与增益选择数值
; │ 控制操作指令字(OpenSingleChannelADC:X)
; 本指令字符串字符有效长度数值(不包括自已在内共 21 个字符)
; 注:最后这个“X”字符为 ADC 模拟通道数与增益选择数值,由传送方具体确定。
; 最后这个“X”字符为变量,不需要对其进行指令识别,因此不包括在本指令
; 字符串字符长度数值中。
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_OSSCADC:
push YL ;压入 Y 指针的数值到堆栈
push YH
clr CTRLCOM_MPFMS ;清除控制操作指令己经执行标志值
lds ZL,IADCI_StaFUP ;检查启动整页ADC转换是否己完成?
cpi ZL,IADCI_StaFUPI ;是,则继续
breq CTRLCOMM_OSSCADC_RET ;否,直接返回
lds ZL,IADCI_StaGro ;检查启动单组ADC转换是否己完成?
cpi ZL,IADCI_StaGroI ;是,则继续
breq CTRLCOMM_OSSCADC_RET ;否,直接返回
lds ZL,IADCI_SinEnd ;检查单通道 ADC 转换是否己结束?
cpi ZL,IADCI_SinEndI ;是,则继续
breq CTRLCOMM_OSSCADC_RET ;否,直接返回
ldi ZL,Low(OpenSingleChannelADC_X*2)
ldi ZH,High(OpenSingleChannelADC_X*2)
lpm CTRLCOM_CNT,Z ;置 Y 指针指向本指令字符串的最后一个字符,
clr CTRLCOM_TEMP ;根据定义传送来的最后一个字符,
add YL,CTRLCOM_CNT ;为要测量的 ADC 模拟通道数与增益选择值
adc YH,CTRLCOM_TEMP
ld CTRLCOM_TEMP,Y ;置 ADC 模拟通道数与增益选择值
sts IADCI_SMUXNum,CTRLCOM_TEMP
call IADCI_Start_SSingle ;启动单通道单个ADC转换
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
set ;置 T 标志
CTRLCOMM_OSSCADC_RET:
pop YH ;弹出堆栈中的 Y 指针数值
pop YL
ret ;子程序返回
;*******************************************************************************
;*
;* 要求发送整页 ADC 转换结果数据指令 - “TXD@FullPageADC”
;*
;*******************************************************************************
TXD_FullPageADC:
.DB $0f,"TXD@FullPageADC"
; │ │
; │ 控制操作指令字(TXD@FullPageADC)
; 本指令字符串字符长度数值(不包括自已在内共 15 个字符)
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_TXDFPADC:
clr CTRLCOM_MPFMS ;清除控制操作指令己经执行标志值
lds ZL,IADCI_StaFUP ;检查启动整页ADC转换是否己完成?
cpi ZL,IADCI_StaFUPI ;是,则继续
breq CTRLCOMM_TXDFPADC_RET ;否,直接返回
lds ZL,CCOMALW_USART ;检查是否允许处理 USART 端口的控制操作指令?
cpi ZL,CTRLCOM_ALWSI ;是,到相应处理
brne CTRLCOMM_TXDFPADC2 ;否,则继续
rcall CTRLCOMM_TXDFPADC_USART
rjmp CTRLCOMM_TXDFPADC_End
CTRLCOMM_TXDFPADC2:
;此处可继续插入由其他地方传来此条控制操作指令处理程序
CTRLCOMM_TXDFPADC_End:
clr ZL ;清除允许处理整页 ADC 转换结果数据标志
sts IADCI_PDPALW,ZL
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
clt ;清除 T 标志
CTRLCOMM_TXDFPADC_RET:
ret ;子程序返回
;此段程序用于[由 USART 端口送来此条控制操作指令]处理
CTRLCOMM_TXDFPADC_USART:
clr ZL ;清除允许更新发送数据标志
sts DataUPD_TXALW,ZL
ldi ZL,Low(IADCI_CDataPA) ;置整页 ADC 转换结果数据的地址指针
ldi ZH,High(IADCI_CDataPA)
ldi YL,Low(USARTAI_TXDAA) ;置从 USART 端口发送数据的地址指针
ldi YH,High(USARTAI_TXDAA)
ld CTRLCOM_CNT,Z ;置循环计数器初值
CTRLCOMM_TXDFPADC_USART1:
ld CTRLCOM_TEMP,Z+ ;读整页 ADC 转换结果数据
st Y+,CTRLCOM_TEMP ;写入从 USART 端口发送地址
dec CTRLCOM_CNT ;循环计数器 — 1
brne CTRLCOMM_TXDFPADC_USART1
ret ;子程序返回
;*******************************************************************************
;*
;* 要求发送单组 ADC 转换结果数据指令 - “TXD@SingleGroupADC”
;*
;*******************************************************************************
TXD_SingleGroupADC:
.DB $12,"TXD@SingleGroupADC"
; │ │
; │ 控制操作指令字(TXD@SingleGroupADC)
; 本指令字符串字符长度数值(不包括自已在内共 18 个字符)
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_TXDSGADC:
clr CTRLCOM_MPFMS ;清除控制操作指令己经执行标志值
lds ZL,IADCI_StaGro ;检查启动单组ADC转换是否己完成?
cpi ZL,IADCI_StaGroI ;是,则继续
breq CTRLCOMM_TXDSGADC_RET ;否,直接返回
lds ZL,CCOMALW_USART ;检查是否允许处理 USART 端口的控制操作指令?
cpi ZL,CTRLCOM_ALWSI ;是,到相应处理
brne CTRLCOMM_TXDSGADC2 ;否,则继续
rcall CTRLCOMM_TXDSGADC_USART
rjmp CTRLCOMM_TXDSGADC_End
CTRLCOMM_TXDSGADC2:
;此处可继续插入由其他地方传来此条控制操作指令处理程序
CTRLCOMM_TXDSGADC_End:
clr ZL ;清除允许处理单组 ADC 转换结果数据标志
sts IADCI_GDPALW,ZL
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
clt ;清除 T 标志
CTRLCOMM_TXDSGADC_RET:
ret ;子程序返回
;此段程序用于[由 USART 端口送来此条控制操作指令]处理
CTRLCOMM_TXDSGADC_USART:
clr ZL ;清除允许更新发送数据标志
sts DataUPD_TXALW,ZL
clr CTRLCOM_TEMP ;清除暂存寄存器
ldi CTRLCOM_CNT,((IADCI_CDGNumI-1)*2)
;置循环计数器初值= 测量的通道数目
lds ZL,IADCI_CDPPL ;置单组 ADC 转换结果数据最后存储地址指针
lds ZH,IADCI_CDPPH
sub ZL,CTRLCOM_CNT ; ADC 转换结果数据存储地址指针,
sbc ZH,CTRLCOM_TEMP ;返回单组数据首个数据存储地址
ldi YL,Low(USARTAI_TXDAA) ;置从 USART 端口发送数据的地址指针
ldi YH,High(USARTAI_TXDAA)
ldi CTRLCOM_TEMP,((IADCI_CDGNumI-1)*2+3)
;发送转换结果数据总长度数值
;= 测量的通道数目+ 3 个字节
st Y+,CTRLCOM_TEMP ;写入从 USART 端口发送首个数据地址中
ldi CTRLCOM_CNT,((IADCI_CDGNumI-1)*2)
;置循环计数器初值
CTRLCOMM_TXDSGADC_USART1:
ld CTRLCOM_TEMP,Z+ ;读整页 ADC 转换结果数据
st Y+,CTRLCOM_TEMP ;写入从 USART 端口发送地址
dec CTRLCOM_CNT ;循环计数器 — 1
brne CTRLCOMM_TXDSGADC_USART1
clr CTRLCOM_TEMP ;清除暂存寄存器
st Y+,CTRLCOM_TEMP ;清除最后两个字节
st Y+,CTRLCOM_TEMP
ldi DCRC2B_DLength,((IADCI_CDGNumI-1)*2+3)
;置校验的数据长度初值
ldi ZL,Low(USARTAI_TXDAA) ;Z 指针指向发送数据首个字节
ldi ZH,High(USARTAI_TXDAA)
call DataCheck_CRC2B ;生成发送数据序列的 CRC 码
ret ;子程序返回
;*******************************************************************************
;*
;* 要求发送单通道 ADC 转换结果数据指令 - “TXD@SingleChannelADC”
;*
;*******************************************************************************
TXD_SingleChannelADC:
.DB $14,"TXD@SingleChannelADC"
; │ │
; │ 控制操作指令字(TXD@SingleChannelADC)
; 本指令字符串字符长度数值(不包括自已在内共 20 个字符)
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_TXDSSCADC:
clr CTRLCOM_MPFMS ;清除控制操作指令己经执行标志值
lds ZL,IADCI_SinEnd ;检查单通道 ADC 转换是否己结束?
cpi ZL,IADCI_SinEndI ;是,则继续
breq CTRLCOMM_TXDSSCADC_RET ;否,直接返回
lds ZL,CCOMALW_USART ;检查是否允许处理 USART 端口的控制操作指令?
cpi ZL,CTRLCOM_ALWSI ;是,到相应处理
brne CTRLCOMM_TXDSSCADC2 ;否,则继续
rcall CTRLCOMM_TXDSSCADC_USART
rjmp CTRLCOMM_TXDSSCADC_End
CTRLCOMM_TXDSSCADC2:
;此处可继续插入由其他地方传来此条控制操作指令处理程序
CTRLCOMM_TXDSSCADC_End:
clr ZL ;清除允许处理单个 ADC 转换结果数据标志
sts IADCI_SDPALW,ZL
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
clt ;清除 T 标志
CTRLCOMM_TXDSSCADC_RET:
ret ;子程序返回
;此段程序用于[由 USART 端口送来此条控制操作指令]处理
CTRLCOMM_TXDSSCADC_USART:
clr ZL ;清除允许更新发送数据标志
sts DataUPD_TXALW,ZL
ldi YL,Low(USARTAI_TXDAA) ;置从 USART 端口发送数据的地址指针
ldi YH,High(USARTAI_TXDAA)
lds CTRLCOM_TEMP2,(IADCI_CDataSH+IADCI_CDSNumI*2-2)
;取二进制 ADC 转换结果数据
lds CTRLCOM_TEMP,(IADCI_CDataSH+IADCI_CDSNumI*2-1)
;--------------------------------------------------------------------------
;注:如果需要 BCD 码的 ADC 转换结果数据,用下面这两条指令代替上面两条指令。
; lds CTRLCOM_TEMP2,IADCI_CDataSH ;取 BCD 码单个 ADC 转换结果数据
; lds CTRLCOM_TEMP,(IADCI_CDataSH+1)
;--------------------------------------------------------------------------
ldi CTRLCOM_CNT,(1*2+3) ;置本次发送数据的总字节长度值
st Y+,CTRLCOM_CNT ;写入总字节长度值到 USART 端口发送地址
st Y+,CTRLCOM_TEMP2 ;写入数据高字节到 USART 端口发送地址
st Y+,CTRLCOM_TEMP ;写入数据低字节到 USART 端口发送地址
clr CTRLCOM_TEMP ;清除暂存寄存器
st Y+,CTRLCOM_TEMP ;清除最后两个字节
st Y+,CTRLCOM_TEMP
ldi DCRC2B_DLength,(1*2+3) ;置校验的数据长度初值
ldi ZL,Low(USARTAI_TXDAA) ;Z 指针指向发送数据首个字节
ldi ZH,High(USARTAI_TXDAA)
call DataCheck_CRC2B ;生成发送数据序列的 CRC 码
ret ;子程序返回
;*******************************************************************************
;*
;* 修改在 EEPROM 中的 4 个字节设备编号指令 - “ChangeDeviceNumber:XXXX”
;*
;*******************************************************************************
ChangeDeviceNumber_XXXX:
.DB $13,"ChangeDeviceNumber:",$36,$36,$38,$38
; │ │ │
; │ │ 4 个字节设备编号数值
; │ 控制操作指令字(ChangeDeviceNumber:XXXX)
; 本指令字符串字符有效长度数值(不包括自已在内共 19 个字符)
; 注:最后这 4 个“XXXX”字符为设备编号数值,由传送方具体确定。最后这 4 个
; “XXXXX”字符为设备编号数值,为变量,不需要对其进行指令识别,因此不包
; 括在本指令字符串字符长度数值中。
;*** 此段程序用于此条控制操作指令处理
CTRLCOMM_ChangeDN:
push YL ;压入 Y 指针的数值到堆栈
push YH
ldi ZL,Low(ChangeDeviceNumber_XXXX*2)
ldi ZH,High(ChangeDeviceNumber_XXXX*2)
lpm CTRLCOM_CNT,Z ;置 Y 指针指向本指令字符串的最后 4 个字符,
clr CTRLCOM_TEMP ;根据定义传送来的最后 4 个字符,
add YL,CTRLCOM_CNT ;为 4 个字节设备编号数值
adc YH,CTRLCOM_TEMP
mov ZL,YL
mov ZH,YH
ldi EEPROM_DNum,CTRLCDN_CharNI ;置写入到 EEPROM 中的数据个数
ldi EEPROM_AddrL,Low(CC_EEPROM_DNAr)
ldi EEPROM_AddrH,High(CC_EEPROM_DNAr)
;置在 EEPROM 中的设备编号地址指针
call EEPROM_Write_FSRAM ;写入设备编号数值到 EEPROM 中
ldi CTRLCOM_MPFMS,CTRLCOM_MPFMSI;置控制操作指令己经执行标志值
set ;置 T 标志
CTRLCOMM_ChangeDN_RET:
pop YH ;弹出堆栈中的 Y 指针数值
pop YL
ret ;子程序返回
;*******************************************************************************
;*
;* 子程序名: DataCheck_CRC2B.asm
;* 程序名称: 2字节数据循环冗余检测校验程序
;* 版本: 1.0
;* 适用 MCU 型号: AVR所有型号
;* 入口条件: 16
;* Z 指针(指向数据序列 X ×F(X) 的 SRAM 存储地址)
;* 16
;* DCRC2B_DLength (r20)(校验的 X ×F(X) 数据长度)
;* 出口条件:
;* 16
;* 余式R(X)(校验字节)在 YL:YH 中,亦在 X ×F(X)
;* 最后两个字节中。
;* 使用资源: r16,r17,r18,r19,r20,r28,r29,r30,r31
;*
;* 程序功能:
;* 本程序是用于数据循环冗余检测校验处理。校验用的为2位监督码(CRC码)
;*
;* 注意:
;* ①.校验用的为2位监督码(CRC码)必须放在数据序列的的最后两个位置。经
;* 本程序校验后这2位将为“$00,$O0”或恢复原来设置的数据值。
;* ②.生成的2位监督码(CRC码)也是放在数据序列的的最后两个位置。在调用
;* 本程序前,必须对这2位清为“$00,$O0”或设置校验的数据值。
;*
;* 注释:
;* ①.本子程序用于数据循环冗余检测校验处理。其生成 CRC 校验码的公式为:
;* 16
;* X ×F(X)/P(X)=Q(X)+R(X)/P(X)
;* 16
;* 其中:X ×F(X) 为数据序列 F(X) 后面再加 2 字节 $00
;* P(X) 为除数多项式
;* Q(X) 为商
;* R(X) 为余式,即生成的 CRC 校验码
;* 16 12 5
;* ②.本子程序选用的除数多项式:P(X)=X +X +X +1=$11021
;* 16 16
;* ③.发送时将 X ×F(X)+R(X) 发送出去。接收方再将 X ×F(X)除以 P(X) ,
;* 如果得到余式 R(X)=$0000,表示接收正确。
;* ④.本子程序的除以除数 P(X) 并非为通常的被除数除以除数的算术除法运算,
;* 而是用不计借位的减法,即位异或(半加)进行计算。程序中只将最高位
;* =1 的数据在 YL:YH 中与立即数 $8005 进行异或操作。
;* ⑤.本子程序最大校验数据序列 F(X) 的长度不超过 254 个字节,每字节为
;* 8 位二进制数。
;* 16
;* ⑥.两个校验字节必须放在数据序列 X ×F(X) 的最后两个位置。
;* 在本子程序运行后除放在最后两个位置外,亦放在 YL:YH 中。
;*
;* 编作者:
;* 编作者 E-Mail: PTZSW@163.COM
;* 编制日期: 2005年1月18日
;*
;*******************************************************************************
;*
;* 指令条数: 38 + return
;* 指令执行周期: 17611 + return (Min)
;* 18692 + return (Max)
;* 低位寄存器使用: None
;* 高位寄存器使用: 4 (r16,r17,r18,r19,r20)
;* 指针寄存器使用: Y,Z
;* 状态寄存器使用: None
;*
;*******************************************************************************
;******** 本程序寄存器变量定义:
.def DCRC2B_TEMP = r16 ;暂存寄存器
.def DCRC2B_RDIVH = r17 ;除数多项式的除数高字节
.def DCRC2B_RDIVL = r18 ;除数多项式的除数低字节
.def DCRC2B_BitNum = r19 ;校验的字节位数
.def DCRC2B_DLength = r20 ;校验的数据序列长度
;******** 程序指令代码清单:
DataCheck_CRC2B:
clr YL ;清除余式R(X)(校验字节)的寄存器
clr YH
ldi DCRC2B_RDIVH,$10 ; 16 12 5
ldi DCRC2B_RDIVL,$21 ;除数多项式P(X)=X +X +X +1=$11021
DataCheck_CRC2B1:
ldi DCRC2B_BitNum,$08 ; 8 位/每字节
ld DCRC2B_TEMP,Z+ ;取 Z 指针指向的 SRAM 中数据
DataCheck_CRC2B2:
lsl DCRC2B_TEMP
rol YH
rol YL
brcc DataCheck_CRC2B3 ;当移出位为 1 时,
eor YL,DCRC2B_RDIVH ;将寄存器 YL:YH 中的内容
eor YH,DCRC2B_RDIVL ;与立即数 $1021 异或
DataCheck_CRC2B3:
dec DCRC2B_BitNum ;位数-1
brne DataCheck_CRC2B2
dec DCRC2B_DLength ;数据长度-1
brne DataCheck_CRC2B1
st -Z,YH
st -Z,YL
ret ;子程序返回
;*******************************************************************************
;*
;* 子程序名: Access_EEPROM.asm
;* 程序名称: 存取 EEPROM (电可擦除只读存储器)程序
;* 版本: 1.0
;* 适用 MCU 型号: AVR所有型号
;* 使用资源: r16,r17,r24,r25,r30,r31
;*
;* 程序功能:
;* 本程序是向 EEPROM (电可擦除只读存储器)存取数据子程序,共包括四个子
;* 程序。二个为存取单个字节数据到 EEPROM 中的子程序,二个为与 SRAM (静态随
;* 机存储器)交换存取多个字节数据的子程序。
;*
;* 编作者:
;* 编作者 E-Mail: PTZSW@163.COM
;* 编制日期: 2005年3月8日
;*
;*******************************************************************************
;*
;* 指令条数: 66 + return
;* 指令执行周期: 0 + return
;* 低位寄存器使用: None
;* 高位寄存器使用: 4 (r16,r17,r24,r25)
;* 指针寄存器使用: Z
;*
;*******************************************************************************
;******** 本程序寄存器变量定义:
.def EEPROM_Data = r16 ;从 EEPROM 存取的数据
.def EEPROM_DNum = r17 ;存取 EEPROM 数据的个数
.def EEPROM_AddrL = r24 ;存取 EEPROM 地址低字节
.def EEPROM_AddrH = r25 ;存取 EEPROM 地址高字节
;******** 程序指令代码清单:
;*******************************************************************************
;* 本程序共包括下面四个子程序:
;*
;* “EEPROM_WriteSingle” -------- 写入单个字节数据到 EEPROM 中子程序
;* 入口条件: EEPROM_AddrL(r24)---- 写入到 EEPROM 的地址低字节
;* EEPROM_AddrH(r25)---- 写入到 EEPROM 的地址高字节
;* EEPROM_Data(r16)----- 写入到 EEPROM 中的数据
;*
;* “EEPROM_ReadSingle” --------- 从 EEPROM 中读取单个字节数据子程序
;* 入口条件: EEPROM_AddrL(r24)---- 从 EEPROM 中读取的地址低字节
;* EEPROM_AddrH(r25)---- 从 EEPROM 中读取的地址高字节
;* 出口条件: EEPROM_Data(r16)----- 从 EEPROM 中读取的数据
;*
;* “EEPROM_Write_FSRAM” -------- 从 SRAM 中写入多个字节数据到 EEPROM 中子程序
;* 入口条件: EEPROM_AddrL(r24)---- 写入到 EEPROM 的地址低字节
;* EEPROM_AddrH(r25)---- 写入到 EEPROM 的地址高字节
;* Z 指针 ---------------- 指向在 SRAM 中数据的起始地址
;* EEPROM_DNum(r17)----- 写入到 EEPROM 中的数据个数
;*
;* “EEPROM_Read_TSRAM” --------- 从 EEPROM 中读取多个字节数据到 SRAM 中子程序
;* 入口条件: EEPROM_AddrL(r24)---- 从 EEPROM 中读取的地址低字节
;* EEPROM_AddrH(r25)---- 从 EEPROM 中读取的地址高字节
;* Z 指针 ---------------- 指向在 SRAM 中数据的起始地址
;* EEPROM_DNum(r17)----- 从 EEPROM 中读取的数据个数
;* 出口条件: Z 指针 ---------------- 指向在 SRAM 中数据的起始地址
;*
;*******************************************************************************
;*******************************************************************************
;*
;* 写入单个字节数据到 EEPROM 中子程序 - “EEPROM_WriteSingle”
;*
;* 说明:
;* 本子程序是在等待 EEPROM 就绪后编程,使用两个寄存器地址变量“EEPROM_AddrL
;* :EEPROM_AddrH”(r24:r25),将寄存器变量“EEPROM_Data”(r16)中的单个字节数
;* 据写入到指定地址的 EEPROM 中。
;*
;* 入口条件:
;* 在调用本程序前,需设置下面这三个寄存器数值:
;* EEPROM_AddrL(r24)--------- 写入到 EEPROM 的地址低字节
;* EEPROM_AddrH(r25)--------- 写入到 EEPROM 的地址高字节
;* EEPROM_Data(r16)---------- 写入到 EEPROM 中的数据
;*
;* 指令条数: 9 + return
;* 指令执行周期: 13 + return
;* 低位寄存器使用: None
;* 高位寄存器使用: 3 (r16,r24,r25)
;* 指针寄存器使用: None
;*
;*******************************************************************************
EEPROM_WriteSingle:
sbic EECR,EEWE ;如果 EEWE 不清除
rjmp EEPROM_WriteSingle ;等待,上一次 EEPROM 写操作结束
out EEARH,EEPROM_AddrH ;输出写入的 EEPROM 地址高位
out EEARL,EEPROM_AddrL ;输出写入的 EEPROM 地址低位
out EEDR,EEPROM_Data ;输出写入的 EEPROM 数据
cli ;禁止全局中断
;此指令用于在写 EEPROM 时,如果发生中断,
;将导致写操作超时,造成写 EEPROM 失败。
sbi EECR,EEMWE ;设置 EEPROM 主机写使能
sbi EECR,EEWE ;设置 EEPROM 写使能
;该指令需 4 个时钟周期,
;由于它暂停 CPU 2 个时钟周期
sei ;打开全局中断
ret ;子程序返回
;*******************************************************************************
;*
;* 从 EEPROM 中读取单个字节数据子程序 - “EEPROM_ReadSingle”
;*
;* 说明:
;* 本子程序是在等待 EEPROM 就绪后编程,使用两个寄存器地址变量“EEPROM_AddrL
;* :EEPROM_AddrH”(r24:r25),将指定地址的 EEPROM 中的单个字节数据读取到寄存器
;* 变量“EEPROM_Data”(r16)中。
;*
;* 入口条件:
;* 在调用本程序前,需设置下面这两个寄存器数值:
;* EEPROM_AddrL(r24)--------- 从 EEPROM 中读取数据的地址低字节
;* EEPROM_AddrH(r25)--------- 从 EEPROM 中读取数据的地址高字节
;* 出口条件:
;* 程序运行结束后,将对会下面这个寄存器变量置值。
;* EEPROM_Data(r16)---------- 从 EEPROM 中读取的数据
;*
;* 指令条数: 6 + return
;* 指令执行周期: 9 + return
;* 低位寄存器使用: None
;* 高位寄存器使用: 3 (r16,r24,r25)
;* 指针寄存器使用: None
;*
;*******************************************************************************
EEPROM_ReadSingle:
sbic EECR,EEWE ;如果 EEWE 不清除
rjmp EEPROM_ReadSingle ;等待
out EEARH,EEPROM_AddrH ;输出读取的 EEPROM 地址高位
out EEARL,EEPROM_AddrL ;输出读取的 EEPROM 地址低位
sbi EECR,EERE ;设置 EEPROM 读使能
;该指令需 4 个时钟周期,
;由于它暂停 CPU 2 个时钟周期
in EEPROM_Data,EEDR ;从 EEPROM 中读取数据
ret ;子程序返回
;*******************************************************************************
;*
;* 从 SRAM 中写入多个字节数据到 EEPROM 中子程序 - “EEPROM_Write_FSRAM”
;*
;* 说明:
;* 本子程序是将从 Z 指针指向起始地址的在 SRAM 中多个字节数据,写入到由两个寄
;* 存器地址变量“EEPROM_AddrL:EEPROM_AddrH”(r24:r25)指向起始地址的 EEPROM 中。
;* 每次写入的数据字节数均不超过 255 个字节。
;*
;* 入口条件:
;* 在调用本程序前,需设置下面这几个寄存器数值:
;* EEPROM_AddrL(r24)--------- 写入到 EEPROM 的起始地址低字节
;* EEPROM_AddrH(r25)--------- 写入到 EEPROM 的起始地址高字节
;* Z 指针 --------------------- 指向在 SRAM 中多个字节数据的起始地址
;* EEPROM_DNum(r17)---------- 写入到 EEPROM 中的数据个数
;*
;* 指令条数: 29 + return
;* 指令执行周期: 26 + return(Min:EEPROM_DNum =$01)
;* 9676 + return(Max:EEPROM_DNum =$ff)
;* 低位寄存器使用: None
;* 高位寄存器使用: 4 (r16,r17,r24,r25)
;* 指针寄存器使用: Z
;*
;*******************************************************************************
EEPROM_Write_FSRAM:
sbic EECR,EEWE ;如果 EEWE 不清除
rjmp EEPROM_Write_FSRAM ;等待,上一次 EEPROM 写操作结束
ld EEPROM_Data,Z+ ;从 SRAM 中读取数据
out EEARH,EEPROM_AddrH ;输出写入的 EEPROM 起始地址高位
out EEARL,EEPROM_AddrL ;输出写入的 EEPROM 起始地址低位
out EEDR,EEPROM_Data ;将数据写入到 EEPROM 中
cli ;禁止全局中断
;此指令用于在写 EEPROM 时,如果发生中断,
;将导致写操作超时,造成写 EEPROM 失败。
sbi EECR,EEMWE ;设置 EEPROM 主机写使能
sbi EECR,EEWE ;设置 EEPROM 写使能
;该指令需 4 个时钟周期,
;由于它暂停 CPU 2 个时钟周期
sei ;打开全局中断
dec EEPROM_DNum ;数据个数 — 1
cpi EEPROM_DNum,$01
brlo EEPROM_Write_FSRAM_RET ;写完否?写完则结束
EEPROM_Write_FSRAM1:
sbic EECR,EEWE ;如果 EEWE 不清除
rjmp EEPROM_Write_FSRAM1 ;等待,上一次 EEPROM 写操作结束
ld EEPROM_Data,Z+ ;从 SRAM 中读取数据
in EEPROM_AddrL,EEARL ;获得地址低位
in EEPROM_AddrH,EEARH ;获得地址高位
adiw EEPROM_AddrL,0x01 ;地址 + 1
out EEARH,EEPROM_AddrH ;输出写入的 EEPROM 起始地址高位
out EEARL,EEPROM_AddrL ;输出写入的 EEPROM 起始地址低位
out EEDR,EEPROM_Data ;将数据写入到 EEPROM 中
cli ;禁止全局中断
;此指令用于在写 EEPROM 时,如果发生中断,
;将导致写操作超时,造成写 EEPROM 失败。
sbi EECR,EEMWE ;设置 EEPROM 主机写使能
sbi EECR,EEWE ;设置 EEPROM 写使能
;该指令需 4 个时钟周期,
;由于它暂停 CPU 2 个时钟周期
sei ;打开全局中断
dec EEPROM_DNum ;数据个数 — 1
brne EEPROM_Write_FSRAM1 ;写完否?未完则继续
EEPROM_Write_FSRAM_RET:
ret ;子程序返回
;*******************************************************************************
;*
;* 从 EEPROM 中读取多个字节数据到 SRAM 中子程序 - “EEPROM_Read_TSRAM”
;*
;* 说明:
;* 本子程序是将由两个寄存器地址变量“EEPROM_AddrL:EEPROM_AddrH”(r24:r25)
;* 指向起始地址的 EEPROM 中,读取多个字节数据到从 Z 指针指向起始地址的 SRAM 中。
;* 每次读取的数据字节数均不超过 255 个字节。
;*
;* 入口条件:
;* 在调用本程序前,需设置下面这几个寄存器数值:
;* EEPROM_AddrL(r24)--------- 从 EEPROM 中读取数据的地址低字节
;* EEPROM_AddrH(r25)--------- 从 EEPROM 中读取数据的地址高字节
;* Z 指针 --------------------- 指向在 SRAM 中多个字节数据的起始地址
;* EEPROM_DNum(r17)---------- 从 EEPROM 中读取的数据个数
;*
;* 指令条数: 22 + return
;* 指令执行周期: 22 + return(Min:EEPROM_DNum =$01)
;* 4084 + return(Max:EEPROM_DNum =$ff)
;* 低位寄存器使用: None
;* 高位寄存器使用: 4 (r16,r17,r24,r25)
;* 指针寄存器使用: Z
;*
;*******************************************************************************
EEPROM_Read_TSRAM:
sbic EECR,EEWE ;如果 EEWE 不清除
rjmp EEPROM_Read_TSRAM ;等待,上一次 EEPROM 写操作结束
out EEARH,EEPROM_AddrH ;输出读取的 EEPROM 地址高位
out EEARL,EEPROM_AddrL ;输出读取的 EEPROM 地址低位
sbi EECR,EERE ;设置 EEPROM 读使能
;该指令需 4 个时钟周期,
;由于它暂停 CPU 2 个时钟周期
in EEPROM_Data,EEDR ;从 EEPROM 中读取数据
st Z+,EEPROM_Data ;写入到 SRAM 中
dec EEPROM_DNum ;数据个数 — 1
cpi EEPROM_DNum,$01
brlo EEPROM_Read_TSRAM_RET ;写完否?写完则结束
EEPROM_Read_TSRAM1:
sbic EECR,EEWE ;如果 EEWE 不清除
rjmp EEPROM_Read_TSRAM1 ;等待,上一次 EEPROM 写操作结束
in EEPROM_AddrL,EEARL ;获得地址低位
in EEPROM_AddrH,EEARH ;获得地址高位
adiw EEPROM_AddrL,0x01 ;地址 + 1
out EEARH,EEPROM_AddrH ;输出读取的 EEPROM 地址高位
out EEARL,EEPROM_AddrL ;输出读取的 EEPROM 地址低位
sbi EECR,EERE ;设置 EEPROM 读使能
;该指令需 4 个时钟周期,
;由于它暂停 CPU 2 个时钟周期
in EEPROM_Data,EEDR ;从 EEPROM 中读取数据
st Z+,EEPROM_Data ;写入到 SRAM 中
dec EEPROM_DNum ;数据个数 — 1
brne EEPROM_Read_TSRAM1 ;读取完否?未完则继续
EEPROM_Read_TSRAM_RET:
ret ;子程序返回
;*************************************************************************
;*
;* 文件名: ATmega16def.inc
;* 文件标题: ATmega16 单片机内部寄存器名和位名定义文件
;* 版本: 1.0
;* 适用 MCU 型号: ATmega16 (ATMEL公司生产的单片机)
;*
;* 编作者:
;* 编作者联系电话:
;* 编作者 E-mail: PTZSW@163.com
;* 编制日期: 2004年8月8日
;*
;*************************************************************************
;* 说明:
;*
;* 如果在编制的汇编语言源程序文件中如果包括了此定义文件,则数据手册
;* 中列出的所有I/O寄存器名和I/O寄存器位名都能在编制的程序中使用。
;*
;* I/O寄存器名用十六进制地址表示。
;*
;* I/O寄存器位名用数字0~7表示位数。
;*
;* 另外,由六个寄存器组成的三个(对数据空间间接寻址用)地址指针
;* X、Y、Z也分别被命名为:XL:XH、YL:YH、ZL:ZH。
;*
;* 片内SRAM数据存储空间的最高地址数也被定义。
;*
;* 请注意在指令中使用的位名是意义不相同的。如指令"sbr"/"cbr"表示的是
;* 置/清除寄存器中的指定位和"sbrs"/"sbrc"表示的是如果寄存器中的指定位被
;* 置位/清除则跳一行执行。如下面这些指令例子:
;*
;* in r16,PORTB ;读取 PORTB 寄存器中的内容
;* sbr r16,(1<<PB6)+(1<<PB5) ;PB6 和 PB5 置1(使用屏蔽,而不是 bit# )
;* out PORTB,r16 ;输出到 PORTB 寄存器中
;*
;* in r16,TIFR ;读取定时器中断标志寄存器中的内容
;* sbrc r16,TOV0 ;检查溢出标志(使用 bit# )
;* rjmp TOV0_is_set ;如果被置1,则跳转到 TOV0_is_set 标号
;* ... ;否则转到此行执行其他指令……
;*
;*************************************************************************
;******** 单片机型号定义:
.device ATmega16
;******** I/O 寄存器定义:
.equ SREG =$3f ;状态寄存器
.equ SPH =$3e ;堆栈指针高字节
.equ SPL =$3d ;堆栈指针低字节
.equ OCR0 =$3c ;输出比较寄存器
.equ GIMSK =$3b ;通用中断屏蔽寄存器(为保持兼容性,两个名称都一同定义)
.equ GICR =$3b ;通用中断屏蔽寄存器(GIMSK 的新名称)
.equ GIFR =$3a ;通用中断标志寄存器
.equ TIMSK =$39 ;定时器中断屏蔽寄存器
.equ TIFR =$38 ;定时器中断标志寄存器
.equ SPMCR =$37 ;保存程序存储器控制寄存器
.equ I2CR =$36 ;TWI控制寄存器(为保持兼容性,两个名称都一同定义)
.equ TWCR =$36 ;TWI控制寄存器
.equ MCUCR =$35 ;MCU控制寄存器
.equ MCUSR =$34 ;MCU控制与状态寄存器(为保持兼容性,两个名称都一同定义)
.equ MCUCSR =$34 ;MCU控制与状态寄存器
.equ TCCR0 =$33 ;定时器/计数器0控制寄存器
.equ TCNT0 =$32 ;定时器/计数器0(8位)
.equ OSCCAL =$31 ;振荡器标定寄存器
.equ SFIOR =$30 ;特殊功能IO寄存器
.equ TCCR1A =$2f ;定时器/计数器1控制寄存器A
.equ TCCR1B =$2e ;定时器/计数器1控制寄存器B
.equ TCNT1H =$2d ;定时器/计数器1高字节
.equ TCNT1L =$2c ;定时器/计数器1低字节
.equ OCR1AH =$2b ;定时器/计数器1输出比较寄存器A高字节
.equ OCR1AL =$2a ;定时器/计数器1输出比较寄存器A低字节
.equ OCR1BH =$29 ;定时器/计数器1输出比较寄存器B高字节
.equ OCR1BL =$28 ;定时器/计数器1输出比较寄存器B低字节
.equ ICR1H =$27 ;定时器/计数器1输入捕获寄存器高字节
.equ ICR1L =$26 ;定时器/计数器1输入捕获寄存器低字节
.equ TCCR2 =$25 ;定时器/计数器2控制寄存器
.equ TCNT2 =$24 ;定时器/计数器2(8位)
.equ OCR2 =$23 ;定时器/计数器2输出比较寄存器
.equ ASSR =$22 ;异步方式状态寄存器
.equ WDTCR =$21 ;看门狗定时器控制寄存器
.equ UBRRHI =$20 ;USART波特率寄存器(为保持兼容性,两个名称都一同定义)
.equ UBRRH =$20 ;USART波特率寄存器(注意:UCSRC 等于 UBRRH)
.equ EEARH =$1f ;EEPROM地址寄存器高字节
.equ EEARL =$1e ;EEPROM地址寄存器低字节
.equ EEDR =$1d ;EEPROM数据寄存器
.equ EECR =$1c ;EEPROM控制寄存器
.equ PORTA =$1b ;端口A数据寄存器
.equ DDRA =$1a ;端口A数据方向寄存器
.equ PINA =$19 ;端口A输入引脚地址
.equ PORTB =$18 ;端口B数据寄存器
.equ DDRB =$17 ;端口B数据方向寄存器
.equ PINB =$16 ;端口B输入引脚地址
.equ PORTC =$15 ;端口C数据寄存器
.equ DDRC =$14 ;端口C数据方向寄存器
.equ PINC =$13 ;端口C输入引脚地址
.equ PORTD =$12 ;端口D数据寄存器
.equ DDRD =$11 ;端口D数据方向寄存器
.equ PIND =$10 ;端口D输入引脚地址
.equ SPDR =$0f ;SPI数据寄存器
.equ SPSR =$0e ;SPI状态寄存器
.equ SPCR =$0d ;SPI控制寄存器
.equ UDR =$0c ;USART I/O 数据寄存器
.equ USR =$0b ;USART控制和状态寄存器A(为保持兼容性,两个名称都一同定义)
.equ UCSRA =$0b ;USART控制和状态寄存器A
.equ UCR =$0a ;USART控制和状态寄存器B(为保持兼容性,两个名称都一同定义)
.equ UCSRB =$0a ;USART控制和状态寄存器B
.equ UCSRC =$20 ;USART控制和状态寄存器C(注意:UCSRC 等于 UBRRH)
.equ UBRR =$09 ;USART波特率寄存器(为保持兼容性,两个名称都一同定义)
.equ UBRRL =$09 ;USART波特率寄存器
.equ ACSR =$08 ;模拟比较器控制和状态寄存器
.equ ADMUX =$07 ;ADC多路选择寄存器
.equ ADCSR =$06 ;ADC控制和状态寄存器
.equ ADCH =$05 ;ADC数据寄存器高字节
.equ ADCL =$04 ;ADC数据寄存器低字节
.equ I2DR =$03 ;TWI数据寄存器为(为保持兼容性,两个名称都一同定义)
.equ TWDR =$03 ;TWI数据寄存器
.equ I2AR =$02 ;TWI(从机)地址寄存器(为保持兼容性,两个名称都一同定义)
.equ TWAR =$02 ;TWI(从机)地址寄存器
.equ I2SR =$01 ;TWI状态寄存器(为保持兼容性,两个名称都一同定义)
.equ TWSR =$01 ;TWI状态寄存器
.equ I2BR =$00 ;TWI比特率寄存器(为保持兼容性,两个名称都一同定义)
.equ TWBR =$00 ;TWI比特率寄存器
;******** 位定义:
; GIMSK / GICR —— 通用中断屏蔽寄存器
.equ INT1 =7 ;外部中断请求1使能位
.equ INT0 =6 ;外部中断请求0使能位
.equ INT2 =5 ;外部中断请求2使能位
.equ IVSEL =1 ;中断向量选择位
.equ IVCE =0 ;中断向量修改使能位
; GIFR —— 通用中断标志寄存器
.equ INTF1 =7 ;外部中断请求1标志位
.equ INTF0 =6 ;外部中断请求0标志位
.equ INTF2 =5 ;外部中断请求2标志位
; TIMSK —— 定时器中断屏蔽寄存器
.equ TOIE0 =0 ;T/C0溢出中断使能位
.equ OCIE0 =1 ;T/C0输出比较匹配中断使能位
.equ TOIE1 =2 ;T/C1溢出中断使能位
.equ OCIE1B =3 ;T/C1输出比较B匹配中断使能位
.equ OCIE1A =4 ;T/C1输出比较A匹配中断使能位
.equ TICIE1 =5 ;T/C1输入捕捉中断使能位
.equ TOIE2 =6 ;T/C2溢出中断使能位
.equ OCIE2 =7 ;T/C2输出比较匹配中断使能位
; TIFR —— 定时器中断标志寄存器
.equ TOV0 =0 ;T/C0溢出标志位
.equ OCF0 =1 ;T/C0输出比较匹配标志位
.equ TOV1 =2 ;T/C1溢出标志位
.equ OCF1B =3 ;T/C1输出比较B匹配标志位
.equ OCF1A =4 ;T/C1输出比较A匹配标志位
.equ ICF1 =5 ;T/C1输入捕捉标志位
.equ TOV2 =6 ;T/C2溢出标志位
.equ OCF2 =7 ;T/C2输出比较匹配标志位
; SPMCR —— 保存程序存储器控制寄存器
.equ SPMIE =7 ;SPM中断使能位
.equ ASB =6 ;RWW区忙标志位
.equ ASRE =4 ;RWW区读使能位
.equ BLBSET =3 ;BOOT锁定位设置
.equ PGWRT =2 ;页写入
.equ PGERS =1 ;页擦除
.equ SPMEN =0 ;存贮程序存储器使能位
; TWCR —— TWI控制寄存器
.equ TWINT =7 ;TWI中断标志
.equ TWEA =6 ;使能TWI应答
.equ TWSTA =5 ;TWI开始状态标志位
.equ TWSTO =4 ;TWI结束状态标志位
.equ TWWC =3 ;TWI写碰撞标志
.equ TWEN =2 ;TWI使能位
.equ TWIE =0 ;使能TWI 中断
; MCUCR —— MCU控制寄存器
.equ SM2 =7 ;休眠模式选择位2
.equ SE =6 ;休眠使能位
.equ SM1 =5 ;休眠模式选择位1
.equ SM0 =4 ;休眠模式选择位0
.equ ISC11 =3 ;INT1中断触发方式控制位1
.equ ISC10 =2 ;INT1中断触发方式控制位0
.equ ISC01 =1 ;INT0中断触发方式控制位1
.equ ISC00 =0 ;INT0中断触发方式控制位0
; MCUSR —— MCU控制与状态寄存器
.equ ISC2 =6 ;INT2中断触发方式控制位
;.equ JTRF =4 ;JATG复位标志位
.equ WDRF =3 ;看门狗复位标志位
.equ BORF =2 ;掉电检测复位标志位
.equ EXTRF =1 ;外部复位标志位
.equ PORF =0 ;上电复位标志位
; TCCR0 —— 定时器/计数器0控制寄存器
.equ FOC0 =7 ;强制输出比较
.equ PWM0 =6 ;此位名定义已经不再使用!要使用 WGM00
.equ WGM00 =6 ;波形产生模式控制位0
.equ COM01 =5 ;比较匹配输出模式控制位1
.equ COM00 =4 ;比较匹配输出模式控制位0
.equ CTC0 =3 ;此位名定义已经不再使用!要使用 WGM01
.equ WGM01 =3 ;波形产生模式控制位1
.equ CS02 =2 ;时钟选择控制位2
.equ CS01 =1 ;时钟选择控制位1
.equ CS00 =0 ;时钟选择控制位0
; SFIOR —— 特殊功能IO寄存器
.equ ADTS2 =7 ;ADC自动触发源控制位2
.equ ADTS1 =6 ;ADC自动触发源控制位1
.equ ADTS0 =5 ;ADC自动触发源控制位0
.equ ADHSM =4 ;
.equ ACME =3 ;模拟比较器多路复用器使能位
.equ PUD =2 ;禁用上拉电阻
.equ PSR2 =1 ;T/C2预分频复位
.equ PSR10 =0 ;T/C1与T/C0预分频器复位
; TCCR1A —— 定时器/计数器1控制寄存器A
.equ COM1A1 =7 ;通道A的比较输出模式控制位1
.equ COM1A0 =6 ;通道A的比较输出模式控制位0
.equ COM1B1 =5 ;通道B的比较输出模式控制位1
.equ COM1B0 =4 ;通道B的比较输出模式控制位0
.equ FOC1A =3 ;通道A强制输出比较
.equ FOC1B =2 ;通道B强制输出比较
.equ PWM11 =1 ;此位名定义已经不再使用!要使用 WGM11
.equ PWM10 =0 ;此位名定义已经不再使用!要使用 WGM10
.equ WGM11 =1 ;波形产生模式控制位1
.equ WGM10 =0 ;波形产生模式控制位0
; TCCR1B —— 定时器/计数器1控制寄存器B
.equ ICNC1 =7 ;输入捕捉噪声抑制器使能位
.equ ICES1 =6 ;输入捕捉触发沿选择位
.equ CTC11 =4 ;此位名定义已经不再使用!要使用 WGM13
.equ CTC10 =3 ;此位名定义已经不再使用!要使用 WGM12
.equ CTC1 =3 ;此位名定义已经不再使用!要使用 WGM12
.equ WGM13 =4 ;波形产生模式控制位3
.equ WGM12 =3 ;波形产生模式控制位2
.equ CS12 =2 ;时钟选择控制位2
.equ CS11 =1 ;时钟选择控制位1
.equ CS10 =0 ;时钟选择控制位0
; TCCR2 —— 定时器/计数器2控制寄存器
.equ FOC2 =7 ;强制输出比较
.equ PWM2 =6 ;此位名定义已经不再使用!要使用 WGM20
.equ WGM20 =6 ;波形产生模式控制位0
.equ COM21 =5 ;比较匹配输出模式控制位1
.equ COM20 =4 ;比较匹配输出模式控制位0
.equ CTC2 =3 ;此位名定义已经不再使用!要使用 WGM21
.equ WGM21 =3 ;波形产生模式控制位1
.equ CS22 =2 ;时钟选择控制位2
.equ CS21 =1 ;时钟选择控制位1
.equ CS20 =0 ;时钟选择控制位0
; ASSR —— 异步方式状态寄存器
.equ AS2 =3 ;异步T/C2
.equ TCN2UB =2 ;T/C2更新中
.equ OCR2UB =1 ;输出比较寄存器2更新中
.equ TCR2UB =0 ;T/C2控制寄存器更新中
; WDTCR —— 看门狗定时器控制寄存器
.equ WDTOE =4 ;看门狗修改使能位
.equ WDE =3 ;看门狗使能位
.equ WDP2 =2 ;看门狗定时器预分频器控制位2
.equ WDP1 =1 ;看门狗定时器预分频器控制位1
.equ WDP0 =0 ;看门狗定时器预分频器控制位0
; EECR —— EEPROM控制寄存器
.equ EERIE =3 ;使能EEPROM准备好中断
.equ EEMWE =2 ;EEPROM主机写使能
.equ EEWE =1 ;EEPROM写使能
.equ EERE =0 ;EEPROM读使能
; PORTA —— 端口A数据寄存器
.equ PA7 =7
.equ PA6 =6
.equ PA5 =5
.equ PA4 =4
.equ PA3 =3
.equ PA2 =2
.equ PA1 =1
.equ PA0 =0
; DDRA —— 端口A数据方向寄存器
.equ DDA7 =7 ;引脚7的方向(输入/输出)控制位
.equ DDA6 =6 ;引脚6的方向(输入/输出)控制位
.equ DDA5 =5 ;引脚5的方向(输入/输出)控制位
.equ DDA4 =4 ;引脚4的方向(输入/输出)控制位
.equ DDA3 =3 ;引脚3的方向(输入/输出)控制位
.equ DDA2 =2 ;引脚2的方向(输入/输出)控制位
.equ DDA1 =1 ;引脚1的方向(输入/输出)控制位
.equ DDA0 =0 ;引脚0的方向(输入/输出)控制位
; PINA —— 端口A输入引脚地址
.equ PINA7 =7
.equ PINA6 =6
.equ PINA5 =5
.equ PINA4 =4
.equ PINA3 =3
.equ PINA2 =2
.equ PINA1 =1
.equ PINA0 =0
; PORTB —— 端口B数据寄存器
.equ PB7 =7
.equ PB6 =6
.equ PB5 =5
.equ PB4 =4
.equ PB3 =3
.equ PB2 =2
.equ PB1 =1
.equ PB0 =0
; DDRB —— 端口B数据方向寄存器
.equ DDB7 =7 ;引脚7的方向(输入/输出)控制位
.equ DDB6 =6 ;引脚6的方向(输入/输出)控制位
.equ DDB5 =5 ;引脚5的方向(输入/输出)控制位
.equ DDB4 =4 ;引脚4的方向(输入/输出)控制位
.equ DDB3 =3 ;引脚3的方向(输入/输出)控制位
.equ DDB2 =2 ;引脚2的方向(输入/输出)控制位
.equ DDB1 =1 ;引脚1的方向(输入/输出)控制位
.equ DDB0 =0 ;引脚0的方向(输入/输出)控制位
; PINB —— 端口B输入引脚地址
.equ PINB7 =7
.equ PINB6 =6
.equ PINB5 =5
.equ PINB4 =4
.equ PINB3 =3
.equ PINB2 =2
.equ PINB1 =1
.equ PINB0 =0
; PORTC —— 端口C数据寄存器
.equ PC7 =7
.equ PC6 =6
.equ PC5 =5
.equ PC4 =4
.equ PC3 =3
.equ PC2 =2
.equ PC1 =1
.equ PC0 =0
; DDRC —— 端口C数据方向寄存器
.equ DDC7 =7 ;引脚7的方向(输入/输出)控制位
.equ DDC6 =6 ;引脚6的方向(输入/输出)控制位
.equ DDC5 =5 ;引脚5的方向(输入/输出)控制位
.equ DDC4 =4 ;引脚4的方向(输入/输出)控制位
.equ DDC3 =3 ;引脚3的方向(输入/输出)控制位
.equ DDC2 =2 ;引脚2的方向(输入/输出)控制位
.equ DDC1 =1 ;引脚1的方向(输入/输出)控制位
.equ DDC0 =0 ;引脚0的方向(输入/输出)控制位
; PINC —— 端口C输入引脚地址
.equ PINC7 =7
.equ PINC6 =6
.equ PINC5 =5
.equ PINC4 =4
.equ PINC3 =3
.equ PINC2 =2
.equ PINC1 =1
.equ PINC0 =0
; PORTD —— 端口D数据寄存器
.equ PD7 =7
.equ PD6 =6
.equ PD5 =5
.equ PD4 =4
.equ PD3 =3
.equ PD2 =2
.equ PD1 =1
.equ PD0 =0
; DDRD —— 端口D数据方向寄存器
.equ DDD7 =7 ;引脚7的方向(输入/输出)控制位
.equ DDD6 =6 ;引脚6的方向(输入/输出)控制位
.equ DDD5 =5 ;引脚5的方向(输入/输出)控制位
.equ DDD4 =4 ;引脚4的方向(输入/输出)控制位
.equ DDD3 =3 ;引脚3的方向(输入/输出)控制位
.equ DDD2 =2 ;引脚2的方向(输入/输出)控制位
.equ DDD1 =1 ;引脚1的方向(输入/输出)控制位
.equ DDD0 =0 ;引脚0的方向(输入/输出)控制位
; PIND —— 端口D输入引脚地址
.equ PIND7 =7
.equ PIND6 =6
.equ PIND5 =5
.equ PIND4 =4
.equ PIND3 =3
.equ PIND2 =2
.equ PIND1 =1
.equ PIND0 =0
; SPSR —— SPI状态寄存器
.equ SPIF =7 ;SPI中断标志位
.equ WCOL =6 ;写碰撞标志
.equ SPI2X =0 ;SPI倍速
; SPCR —— SPI控制寄存器
.equ SPIE =7 ;SPI中断使能位
.equ SPE =6 ;使能SPI
.equ DORD =5 ;发送数据次序(LSB/MSB字节先后顺序)
.equ MSTR =4 ;主/从机模式选择
.equ CPOL =3 ;时钟极性控制位
.equ CPHA =2 ;时钟相位控制位
.equ SPR1 =1 ;SPI时钟速率选择控制位1
.equ SPR0 =0 ;SPI时钟速率选择控制位0
; UCSRA —— USART控制和状态寄存器A
.equ RXC =7 ;USART接收结束
.equ TXC =6 ;USART发送结束
.equ UDRE =5 ;USART数据寄存器空
.equ FE =4 ;帧错误
;.equ OR =3 ;数据溢出
.equ DOR =3 ;数据溢出( OR 的新名称)
.equ PE =2 ;奇偶校验错误
.equ U2X =1 ;倍速发送
.equ MPCM =0 ;多处理器通信模式
; UCSRB —— USART控制和状态寄存器B
.equ RXCIE =7 ;接收结束中断使能位
.equ TXCIE =6 ;发送结束中断使能位
.equ UDRIE =5 ;数据寄存器空中断使能位
.equ RXEN =4 ;接收使能位
.equ TXEN =3 ;发送使能位
.equ CHR9 =2 ;字符长度
.equ UCSZ2 =2 ;字符长度控制位2( CHR9 的新名称)
.equ RXB8 =1 ;接收数据位8(接收数据的第9个数据位)
.equ TXB8 =0 ;发送数据位8(发送数据的第9个数据位)
;UCSRC —— USART控制和状态寄存器C
.equ URSEL =7 ;寄存器选择控制位
.equ UMSEL =6 ;USART模式选择控制位
.equ UPM1 =5 ;奇偶校验模式选择控制位1
.equ UPM0 =4 ;奇偶校验模式选择控制位0
.equ USBS =3 ;停止位的位数选择控制位
.equ UCSZ1 =2 ;字符长度控制位1
.equ UCSZ0 =1 ;字符长度控制位0
.equ UCPOL =0 ;时钟极性控制位
; ACSR —— 模拟比较器控制和状态寄存器
.equ ACD =7 ;模拟比较器禁用
.equ ACBG =6 ;模拟比较器的能隙基准源选择控制位
.equ ACO =5 ;模拟比较器输出
.equ ACI =4 ;模拟比较器中断标志位
.equ ACIE =3 ;模拟比较器中断使能位
.equ ACIC =2 ;模拟比较器输入捕捉使能位
.equ ACIS1 =1 ;模拟比较器中断模式选择控制位1
.equ ACIS0 =0 ;模拟比较器中断模式选择控制位0
; ADMUX —— ADC多路选择寄存器
.equ REFS1 =7 ;参考电压选择控制位1
.equ REFS0 =6 ;参考电压选择控制位0
.equ ADLAR =5 ;ADC转换结果数据存放形式控制位(左/右对齐)
.equ MUX4 =4 ;模拟通道与增益选择控制位4
.equ MUX3 =3 ;模拟通道与增益选择控制位3
.equ MUX2 =2 ;模拟通道与增益选择控制位2
.equ MUX1 =1 ;模拟通道与增益选择控制位1
.equ MUX0 =0 ;模拟通道与增益选择控制位0
; ADCSR —— ADC控制和状态寄存器
.equ ADEN =7 ;ADC使能位
.equ ADSC =6 ;ADC开始转换
.equ ADFR =5 ;ADC自动触发使能位
.equ ADATE =5 ;ADC自动触发使能位
.equ ADIF =4 ;ADC中断标志位
.equ ADIE =3 ;ADC中断使能位
.equ ADPS2 =2 ;ADC预分频器选择控制位2
.equ ADPS1 =1 ;ADC预分频器选择控制位1
.equ ADPS0 =0 ;ADC预分频器选择控制位0
; TWAR —— TWI(从机)地址寄存器
.equ TWGCE =0 ;TWI广播识别使能位
;******** 指针寄存器定义:
.def XL =r26 ;X指针寄存器低字节
.def XH =r27 ;X指针寄存器高字节
.def YL =r28 ;Y指针寄存器低字节
.def YH =r29 ;Y指针寄存器高字节
.def ZL =r30 ;Z指针寄存器低字节
.def ZH =r31 ;Z指针寄存器高字节
;******** 片内存储器空间定义:
.equ FLASHEND =$1fff ;程序存储器最大地址数【8K×16位字长】(Flash Memory)
.equ E2END =$1ff ;电可擦除只读存储器最大地址数【512×8位字长】(EEPROM)
.equ RAMEND =$45f ;数据存储器最大地址数【8位字长】(SRAM)
;(1K随机存储器+64个I/O寄存器+32个通用寄存器)
;******** 引导程序区空间定义:
; byte groups
; /\/--\/--\/--\
.equ BOOTSTART =$1e00 ;此定义已经不再使用!为保持兼容性暂时保留
;.equ LARGEBOOTSTART =$0c00 ;最大引导程序区大小为 2KB
;.equ SMALLBOOTSTART =$0f80 ;最小引导程序区大小为 256B
.equ SMALLBOOTSTART =0b1111110000000 ;($1F80)最小引导程序区大小为 256B(2页)
.equ SECONDBOOTSTART =0b1111100000000 ;($1F00)第二引导程序区大小为 512B(4页)
.equ THIRDBOOTSTART =0b1111000000000 ;($1E00)第三引导程序区大小为 1KB(8页)
.equ LARGEBOOTSTART =0b1110000000000 ;($1C00)最大引导程序区大小为 2KB(16页)
;******** 页字数定义:
.equ PAGESIZE =64 ;每页的字数为 64【16位字长】
;******** 中断向量地址定义:
.equ INT0addr =$002 ;外部中断请求0向量地址
.equ INT1addr =$004 ;外部中断请求1向量地址
.equ OC2addr =$006 ;定时器/计数器2比较匹配中断向量地址
.equ OVF2addr =$008 ;定时器/计数器2溢出中断向量地址
.equ ICP1addr =$00a ;定时器/计数器1输入捕获中断向量地址
.equ OC1Aaddr =$00c ;定时器/计数器1A比较匹配中断向量地址
.equ OC1Baddr =$00e ;定时器/计数器1B比较匹配中断向量地址
.equ OVF1addr =$010 ;定时器/计数器1溢出中断向量地址
.equ OVF0addr =$012 ;定时器/计数器0溢出中断向量地址
.equ SPIaddr =$014 ;SPI串行传输结束中断向量地址
.equ URXCaddr =$016 ;USART接收结束中断向量地址
.equ UDREaddr =$018 ;USART数据寄存器空中断向量地址
.equ UTXCaddr =$01a ;USART传送结束中断向量地址
.equ ADCCaddr =$01c ;ADC转换结束中断向量地址
.equ ERDYaddr =$01e ;EEPROM就绪中断向量地址
.equ ACIaddr =$020 ;模拟比较器中断向量地址
.equ TWIaddr =$022 ;两线串行接口中断向量地址
.equ INT2addr =$024 ;外部中断请求2向量地址
.equ OC0addr =$026 ;定时器/计数器0比较匹配中断向量地址
.equ SPMRaddr =$028 ;保存程序存储器内容就绪中断向量地址
;★★★★★ 定义文件结束!!! ★★★★★ |
|