XMEGA ADC部分遇到问题,ADC校准字节如何读取?
XMEGA ADC部分遇到问题,ADC校准字节如何读取?这几天读XMEGA文档,测试目前项目中,要用到的XMEGA的一些功能,越仔细读文档,越觉得XMEGA功能强大。开始试验还比较顺利,IO口、定时器、中断系统
、时钟系统、串行通信,都比较快试验通过了。昨天开始调阅读ADC部分,其中提到ADC开启前,必须对ADC进行校准,而校准字节就在XMEGA产品签名行
(Production Signature Row )中,于是翻到第4章,阅读存储器部分,然后再翻到 第30章,读存储器编程部分,看完过后,终于知道怎么读取ADC校准信息了
,今天开始写测试程序,麻烦来了,文档中给出的 Production Signature Row的地址都是偏移地址,那么其起始地址从何开始呢?
再读4.3.4,如下图所示,说 Production Signature Row 使用独立的存储器段,那么就假设其基地址是不是从0x00开始呢?
http://cache.amobbs.com/bbs_upload782111/files_22/ourdev_503121.JPG
(原文件名:Production Signature Row 说明.JPG)
再仔细看Production Signature Row 的偏移地址,晕,为什么还有重复的呢?共用地址?如下图所示,地址重复的地方还有好几个。
http://cache.amobbs.com/bbs_upload782111/files_22/ourdev_503122.JPG
(原文件名:批号(LOT Number)地址重复.JPG)
不管这么多,先写程序试验,试验程序如下。
;==========================================================================
; 主程序
;==========================================================================
MAIN: ;//
NOP ;//
CLI ;//
LDI R16, 0x2F ;// 堆栈指针初始化
OUT CPU_SPH, R16 ;//
LDI R16, 0xFF ;//
OUT CPU_SPL, R16 ;//
LDI R16, 0x47 ;// 1. 设置晶体参数
STS OSC_XOSCCTRL, R16 ;//
LDI R16, 0x08 ;//
STS OSC_CTRL, R16 ;// 开启外部晶体
WAIT_XOSC_READY: ;// 2. 等待外部晶体就绪
LDS R16, OSC_STATUS ;//
ANDI R16, 0x08 ;//
BREQ WAIT_XOSC_READY ;//
LDI R16, 0xD8 ;// 3. 设置外部晶体时钟为系统时钟
OUT CPU_CCP, R16 ;//
LDI R16, 0x03 ;// 设置时钟为外部晶体
STS CLK_CTRL, R16 ;//
CLR R16 ;// 4. 系统时钟分频设置,不分频
STS CLK_PSCTRL, R16 ;//
LDI R16, 0xD8 ;// 5. 关键IO寄存器修改允许,系统时钟锁定设置寄存器是 关键IO寄存器
OUT CPU_CCP, R16 ;//
LDI R16, 0x01 ;// 系统时钟锁定设置,锁定系统时钟,禁止修改时钟选项
STS CLK_LOCK, R16 ;//
CALL Sub_System_IO_Init ;//
CALL Sub_System_TCC0_Init ;//
CALL Sub_System_UARTE0_Init ;//
CLR R30 ;// 这里测试读取Production Signature Row
CLR R31 ;//
LDI R20, 0x02 ;//
test_loop: ;//
INC R30 ;//
LDI R21, 0x31 ;// 地址范围 0x00 - 0x31
SUB R21, R30 ;//
BRCC Test_Entry ;//
CLR R30 ;//
Test_Entry: ;//
CALL Sub_Read_Signature_Rows ;//
RJMP test_loop ;//
;==========================================================================
; 函数名称:Sub_Read_Signature_Rows
; 函数功能:读取产品签名、用户签名信息
; 入口参数:Z(R31 R30):签名信息地址; R20:读取命令
; 出口参数:R0?
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-14
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_Read_Signature_Rows: ;// 读取签名信息
NOP ;//
Wait_NVM_Operate_End: ;// 1. 等待 NVM 操作完毕
LDS R16, NVM_STATUS ;//
TST R16 ;//
BRNE Wait_NVM_Operate_End ;//
STS NVM_CMD, R20 ;// 2. 设置命令
LPM ;// 3. 读取
NOP ;//
RET ;//
使用仿真器,获取 Production Signature Row 的读取结果,分别使用了两个模块测试,其数据表如下所示。
http://cache.amobbs.com/bbs_upload782111/files_22/ourdev_503123.JPG
(原文件名:测试结果.JPG)
昨天在官方网站上,看到一篇读取 XMEGA 的 Production Signature Row 的文章,当时没注意,结果今天上不了 ATMEL 网站了。
目前问题仍未解决,特向 傻孩子、技术火腿 求助,同时请知道的朋友指点一下,谢谢。
1. Production Signature Row 的基地址是从 0x00开始的吗?
2. Production Signature Row 的偏移地址为何有重复的?
3. 如何确定读出的信息就是需要的信息?(1、2确认后,3应该不难解决)。 ;==========================================================================
; 函数名称:Sub_System_UARTE0_Init
; 函数功能:E0 串口初始化函数,9600bps、8N1,异步模式
; 入口参数:无
; 出口参数:无
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-12
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_System_UARTE0_Init: ;//
NOP ;// 1. 串口对应的IO口设置
LDI R16, 0x08 ;// PE3 = 1
STS PORTE_OUTSET, R16 ;//
STS PORTE_DIRSET, R16 ;//
LDI R16, 0x18 ;//
STS PORTE_PIN3CTRL, R16 ;// PE3 上拉
LDI R16, 0x18 ;// PE2 上拉输入
STS PORTE_PIN2CTRL, R16 ;//
LDI R16, 0x04 ;//
STS PORTE_DIRCLR, R16 ;//
LDI R16, 0x03 ;// 2. 数据格式设置,异步模式 8N1
STS USARTE0_CTRLC, R16 ;//
CLR R16 ;// 3. 波特率设置,9600bps (系统时钟:3.6864MHz)
STS USARTE0_BAUDCTRLB, R16 ;//
LDI R16, 0x17 ;//
STS USARTE0_BAUDCTRLA, R16 ;//
LDI R16, 0x10 ;// 4. 设置中断优先级为低
STS USARTE0_CTRLA, R16 ;//
LDI R16, 0x18 ;// 5. 开始接收、发送允许
STS USARTE0_CTRLB, R16 ;//
LDS R16, PMIC_CTRL ;// 6. 开启低中断优先级中断允许
ORI R16, 0x01 ;//
STS PMIC_CTRL, R16 ;//
NOP ;//
RET ;// ;==========================================================================
; 函数名称:Sub_System_TCC0_Init
; 函数功能:定时器TCC0初始化,中断时间1ms,中断优先级低
; 入口参数:无
; 出口参数:无
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-11
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_System_TCC0_Init: ;//
NOP ;//
LDI R16, 0x0F ;// 1. 重启定时器,各个寄存器恢复为 0x00
STS TCC0_CTRLFCLR, R16 ;// 清零
LDI R16, 0x08 ;// 重启
STS TCC0_CTRLFSET, R16 ;//
LDI R16, 0x0F ;// 清零
STS TCC0_CTRLFCLR, R16 ;//
CLI ;// 2. 关中断,准备设置 16bit 寄存器,注意,当有有效中断标志时,CBI不能清零 I 标志
LDI R16, 0x66 ;// 3. 设置PER(TOP)寄存器,数值 0x0E66 ,定时时间 1ms
STS TCC0_TEMP, R16 ;//
LDI R16, 0x0E ;//
STS (TCC0_PER+1), R16 ;//
CLR R16 ;// 4. 清零 CNT 初时值
STS TCC0_TEMP, R16 ;//
STS (TCC0_CNT+1), R16 ;//
LDI R16, 0x01 ;// 5. 开启定时中断0溢出中断,优先级低
STS TCC0_INTCTRLA, R16 ;//
LDI R16, 0x01 ;// 6. 设置定时器时钟,系统时钟不分频
STS TCC0_CTRLA, R16 ;//
SEI ;// 7. 开启全局中断
LDS R16, PMIC_CTRL ;// 8. 开启低中断优先级中断允许
ORI R16, 0x01 ;//
STS PMIC_CTRL, R16 ;//
NOP ;//
RET ;// ;==========================================================================
; 文件名称: XXX
; 程序功能: XMega32A4 中断向量表,以及中断程序
; 微控制器: ATXMega32A4-AU
; 版权所有: XXX
; 编辑软件: UE13.0
; 编写时间: 2009-11-10
; 程序版本: 1.0
; 程序作者: XXX
; 程序修改: 无
; 修改日期:
; 修改内容:
;==========================================================================
;==========================================================================
; 程序统一规定:
; 1. 所有IO口定义,以 i 开头
; 2. 所有位变量定义,以 b 开头
; 3. 所有SRAM寄存器变量定义,以 d 开头
; 4. 常数定义,以 c 开头
; 5. EEPROM空间定义,以 e 开头
; 6. 寄存器 R0 - R15 R16 R17 R18 R19 R20 R21 Y Z 为后台程序专用
; 7. 寄存器 R22 R23 R24 R25 R26 R27 中断使用,后台程序不使用
; 8. 函数名称:Sub_Name
; 9. 中断服务程序:Name_INT
;==========================================================================
.CSEG
;==========================================================================
; 复位中断
;==========================================================================
.ORG 0x000 ;// 复位
JMP MAIN ;//
;==========================================================================
; 外部晶体实效中断
;==========================================================================
.ORG 0x002 ;// 外部晶体失效中断(NMI)
RETI ;//
; JMP OSC_XOSCF_INT ;//
;==========================================================================
; PORTC 外部中断
;==========================================================================
.ORG 0x004 ;// PORTC 外部中断0
RETI ;//
; JMP PORTC_EINT0_INT ;//
.ORG 0x006 ;// PORTC 外部中断1
RETI ;//
; JMP PORTC_EINT1_INT ;//
;==========================================================================
; PORTR 外部中断
;==========================================================================
.ORG 0x008 ;// PORTR 外部中断0
RETI ;//
; JMP PORTR_EINT0_INT ;//
.ORG 0x00A ;// PORTR 外部中断1
RETI ;//
; JMP PORTR_EINT1_INT ;//
;==========================================================================
; DMA中断
;==========================================================================
.ORG 0x00C ;// DMA通道 0 中断
RETI ;//
; JMP DMA_CH0_INT ;//
.ORG 0x00E ;// DMA通道 1 中断
RETI ;//
; JMP DMA_CH1_INT ;//
.ORG 0x010 ;// DMA通道 2 中断
RETI ;//
; JMP DMA_CH2_INT ;//
.ORG 0x012 ;// DMA通道 3 中断
RETI ;//
; JMP DMA_CH3_INT ;//
;==========================================================================
; 实时时钟 RTC 中断
;==========================================================================
.ORG 0x014 ;// RTC溢出中断
RETI ;//
; JMP RTC_OVF_INT ;//
.ORG 0x016 ;// RTC比较中断
RETI ;//
; JMP RTC_COMP_INT ;//
;==========================================================================
; TWIC 中断
;==========================================================================
.ORG 0x018 ;// TWI Slave 中断
RETI ;//
; JMP TWIC_SLAVE_INT ;//
.ORG 0x01A ;// TWI Master 中断
RETI ;//
; JMP TWIC_MASTER_INT ;//
;==========================================================================
; TCC0 中断
;==========================================================================
.ORG 0x01C ;// TCC0 溢出中断
; RETI ;//
JMP TCC0_OVF_INT ;//
.ORG 0x01E ;// TCC0 错误中断
RETI ;//
; JMP TCC0_ERR_INT ;//
.ORG 0x020 ;// TCC0 比较或捕获 A 中断
RETI ;//
; JMP TCC0_CCA_INT ;//
.ORG 0x022 ;// TCC0 比较或捕获 B 中断
RETI ;//
; JMP TCC0_CCB_INT ;//
.ORG 0x024 ;// TCC0 比较或捕获 C 中断
RETI ;//
; JMP TCC0_CCC_INT ;//
.ORG 0x026 ;// TCC0 比较或捕获 D 中断
RETI ;//
; JMP TCC0_CCD_INT ;//
;==========================================================================
; TCC1 中断
;==========================================================================
.ORG 0x028 ;// TCC1 溢出中断
RETI ;//
; JMP TCC1_OVF_INT ;//
.ORG 0x02A ;// TCC1 错误中断
RETI ;//
; JMP TCC1_ERR_INT ;//
.ORG 0x02C ;// TCC1 比较或捕获 A 中断
RETI ;//
; JMP TCC1_CCA_INT ;//
.ORG 0x02E ;// TCC1 比较或捕获 B 中断
RETI ;//
; JMP TCC1_CCB_INT ;//
;==========================================================================
; SPIC 中断
;==========================================================================
.ORG 0x030 ;// SPI中断
RETI ;//
; JMP SPIC_INT_INT ;//
;==========================================================================
; PORTC USART0 中断
;==========================================================================
.ORG 0x032 ;// PORTC USART0 接收完毕中断
RETI ;//
; JMP USARTC0_RXC_INT ;//
.ORG 0x034 ;// PORTC USART0 数据缓冲区空中断
RETI ;//
; JMP USARTC0_DRE_INT ;//
.ORG 0x036 ;// PORTC USART0 发射完毕中断
RETI ;//
; JMP USARTC0_TXC_INT ;//
;==========================================================================
; PORTC USART1 中断
;==========================================================================
.ORG 0x038 ;// PORTC USART1 接收完毕中断
RETI ;//
; JMP USARTC1_RXC_INT ;//
.ORG 0x03A ;// PORTC USART1 数据缓冲区空中断
RETI ;//
; JMP USARTC1_DRE_INT ;//
.ORG 0x03C ;// PORTC USART1 发射完毕中断
RETI ;//
; JMP USARTC1_TXC_INT ;//
;==========================================================================
; AES 中断
;==========================================================================
.ORG 0x03E ;// AES 中断
RETI ;//
; JMP AES_INT_INT ;//
;==========================================================================
; NVW 中断
;==========================================================================
.ORG 0x040 ;// NVW EE 中断
RETI ;//
; JMP NVM_EE_INT ;//
.ORG 0x042 ;// NVW SPM 中断
RETI ;//
; JMP NVM_SPM_INT ;//
;==========================================================================
; PORTB 外部中断
;==========================================================================
.ORG 0x044 ;// PORTB 外部中断0
RETI ;//
; JMP PORTB_EINT0_INT ;//
.ORG 0x046 ;// PORTB 外部中断1
RETI ;//
; JMP PORTB_EINT1_INT ;//
;==========================================================================
; PORTE 外部中断
;==========================================================================
.ORG 0x056 ;// PORTE 外部中断0
RETI ;//
; JMP PORTE_EINT0_INT ;//
.ORG 0x058 ;// PORTE 外部中断1
RETI ;//
; JMP PORTE_EINT1_INT ;//
;==========================================================================
; TWIE 中断
;==========================================================================
.ORG 0x05A ;// TWIE SLAVE 中断
RETI ;//
; JMP TWIE_SLAVE_INT ;//
.ORG 0x05C ;// TWIE MASTER 中断
RETI ;//
; JMP TWIE_MASTER_INT ;//
;==========================================================================
; TCE0 中断
;==========================================================================
.ORG 0x05E ;// TCE0 溢出中断
RETI ;//
; JMP TCE0_OVF_INT ;//
.ORG 0x060 ;// TCE0 错误中断
RETI ;//
; JMP TCE0_ERR_INT ;//
.ORG 0x062 ;// TCE0 比较或捕获 A 中断
RETI ;//
; JMP TCE0_CCA_INT ;//
.ORG 0x064 ;// TCE0 比较或捕获 B 中断
RETI ;//
; JMP TCE0_CCB_INT ;//
.ORG 0x066 ;// TCE0 比较或捕获 C 中断
RETI ;//
; JMP TCE0_CCC_INT ;//
.ORG 0x068 ;// TCE0 比较或捕获 D 中断
RETI ;//
; JMP TCE0_CCD_INT ;//
;==========================================================================
; PORTE USART0 中断
;==========================================================================
.ORG 0x074 ;// PORTE USART0 接收完毕中断
; RETI ;//
JMP USARTE0_RXC_INT ;//
.ORG 0x076 ;// PORTE USART0 数据缓冲区空中断
RETI ;//
; JMP USARTE0_DRE_INT ;//
.ORG 0x078 ;// PORTE USART0 发射完毕中断
RETI ;//
; JMP USARTE0_TXC_INT ;//
;==========================================================================
; PORTD 外部中断
;==========================================================================
.ORG 0x080 ;// PORTD 外部中断0
RETI ;//
; JMP PORTD_EINT0_INT ;//
.ORG 0x082 ;// PORTD 外部中断1
RETI ;//
; JMP PORTD_EINT1_INT ;//
;==========================================================================
; PORTA 外部中断
;==========================================================================
.ORG 0x084 ;// PORTA 外部中断0
RETI ;//
; JMP PORTA_EINT0_INT ;//
.ORG 0x086 ;// PORTA 外部中断1
RETI ;//
; JMP PORTA_EINT1_INT ;//
;==========================================================================
; ACA 中断
;==========================================================================
.ORG 0x088 ;// AC0 中断
RETI ;//
; JMP ACA_AC0_INT ;//
.ORG 0x08A ;// AC1 中断
RETI ;//
; JMP ACA_AC1_INT ;//
.ORG 0x08C ;// ACW 窗模式中断
RETI ;//
; JMP ACA_ACW_INT ;//
;==========================================================================
; ACA 中断
;==========================================================================
.ORG 0x08E ;// ADCA通道 0 中断
RETI ;//
; JMP ADCA_CH0_INT ;//
.ORG 0x090 ;// ADCA通道 1 中断
RETI ;//
; JMP ADCA_CH1_INT ;//
.ORG 0x092 ;// ADCA通道 2 中断
RETI ;//
; JMP ADCA_CH2_INT ;//
.ORG 0x094 ;// ADCA通道 3 中断
RETI ;//
; JMP ADCA_CH3_INT ;//
;==========================================================================
; TCD0 中断
;==========================================================================
.ORG 0x09A ;// TCD0 溢出中断
RETI ;//
; JMP TCD0_OVF_INT ;//
.ORG 0x09C ;// TCD0 错误中断
RETI ;//
; JMP TCD0_ERR_INT ;//
.ORG 0x09E ;// TCD0 比较或捕获 A 中断
RETI ;//
; JMP TCD0_CCA_INT ;//
.ORG 0x0A0 ;// TCD0 比较或捕获 B 中断
RETI ;//
; JMP TCD0_CCB_INT ;//
.ORG 0x0A2 ;// TCD0 比较或捕获 C 中断
RETI ;//
; JMP TCD0_CCC_INT ;//
.ORG 0x0A4 ;// TCD0 比较或捕获 D 中断
RETI ;//
; JMP TCD0_CCD_INT ;//
;==========================================================================
; TCD1 中断
;==========================================================================
.ORG 0x0A6 ;// TCD1 溢出中断
RETI ;//
; JMP TCD1_OVF_INT ;//
.ORG 0x0A8 ;// TCD1 错误中断
RETI ;//
; JMP TCD1_ERR_INT ;//
.ORG 0x0AA ;// TCD1 比较或捕获 A 中断
RETI ;//
; JMP TCD1_CCA_INT ;//
.ORG 0x0AC ;// TCD1 比较或捕获 B 中断
RETI ;//
; JMP TCD1_CCB_INT ;//
;==========================================================================
; SPID 中断
;==========================================================================
.ORG 0x0AE ;// SPID 中断
RETI ;//
; JMP SPID_INT_INT ;//
;==========================================================================
; PORTD USART0 中断
;==========================================================================
.ORG 0x0B0 ;// PORTD USART0 接收完毕中断
RETI ;//
; JMP USARTD0_RXC_INT ;//
.ORG 0x0B2 ;// PORTD USART0 数据缓冲区空中断
RETI ;//
; JMP USARTD0_DRE_INT ;//
.ORG 0x0B4 ;// PORTD USART0 发射完毕中断
RETI ;//
; JMP USARTD0_TXC_INT ;//
;==========================================================================
; PORTD USART1 中断
;==========================================================================
.ORG 0x0B6 ;// PORTD USART1 接收完毕中断
RETI ;//
; JMP USARTD1_RXC_INT ;//
.ORG 0x0B8 ;// PORTD USART1 数据缓冲区空中断
RETI ;//
; JMP USARTD1_DRE_INT ;//
.ORG 0x0BA ;// PORTD USART1 发射完毕中断
RETI ;//
; JMP USARTD1_TXC_INT ;//
;==========================================================================
; ------------------------------中断向量表结束------------------------------
;==========================================================================
.ORG 0xC0 ;// 向量表结束,代码区从 0xC0 开始
;==========================================================================
; 中断名称:TCC0_OVF_INT
; 函数功能:定时器 TCC0 溢出中断,中断时间1ms,中断优先级低
; 入口参数:无
; 出口参数:无
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-11
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
TCC0_OVF_INT: ;//
PUSH R22 ;// XMEGA支持中断嵌套,中断专用寄存器必须压栈保护
PUSH R23 ;//
PUSH R24 ;//
PUSH R25 ;//
PUSH R26 ;//
PUSH R27 ;//
IN R22, CPU_SREG ;// 标志寄存器保护
PUSH R22 ;//
ADC_Test_Delay: ;//
LDS R22, dADCDelay ;//
TST R22 ;//
BREQ ADC_Test_Delay_End ;//
DEC R22 ;//
STS dADCDelay, R22 ;//
ADC_Test_Delay_End: ;//
TCC0_OVF_INT_END: ;//
POP R22 ;// 恢复标志寄存器
OUT CPU_SREG, R22 ;//
POP R27 ;// 恢复中断使用的寄存器
POP R26 ;//
POP R25 ;//
POP R24 ;//
POP R23 ;//
POP R22 ;//
RETI ;//
;==========================================================================
; 中断名称:USARTE0_RXC_INT
; 函数功能:USARTE0 接收完毕中断
; 入口参数:无
; 出口参数:无
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-12
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
USARTE0_RXC_INT: ;//
PUSH R22 ;// XMEGA支持中断嵌套,中断专用寄存器必须压栈保护
PUSH R23 ;//
PUSH R24 ;//
PUSH R25 ;//
PUSH R26 ;//
PUSH R27 ;//
IN R22, CPU_SREG ;// 标志寄存器保护
PUSH R22 ;//
LDS R22, USARTE0_DATA ;//
LDI R23, 0x11 ;//
ADD R22, R23 ;//
STS USARTE0_DATA, R22 ;// 接收数据加 0x11 返回
USARTE0_RXC_INT_END: ;//
POP R22 ;// 恢复标志寄存器
OUT CPU_SREG, R22 ;//
POP R27 ;// 恢复中断使用的寄存器
POP R26 ;//
POP R25 ;//
POP R24 ;//
POP R23 ;//
POP R22 ;//
RETI ;// 汇编感觉和avr的差不多?? 楼主应该读一下application note
在ADC例程里面
写得很清楚了 void ADC_CalibrationValues_Load(ADC_t * adc)
{
if(&ADCA == adc){
/* Get ADCACAL0 from production signature . */
adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL0_offset );
adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL1_offset );
}else {
/* Get ADCBCAL0 from production signature*/
adc->CALL = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCBCAL0_offset );
adc->CALH = SP_ReadCalibrationByte( PROD_SIGNATURES_START + ADCACAL1_offset );
}
}
uint8_t SP_ReadCalibrationByte( uint8_t index )
{
uint8_t result;
/* Load the NVM Command register to read the calibration row. */
NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
result = pgm_read_byte(index);
/* Clean up NVM Command register. */
NVM_CMD = NVM_CMD_NO_OPERATION_gc;
return result;
}
SP_ReadCalibrationByte:
ldi r20, NVM_CMD_READ_CALIB_ROW_gc ; Prepare NVM command in R20.
mov ZL, r16 ; Load byte index into low byte of Z.
clr ZH ; Clear high byte of Z.
sts NVM_CMD, r20 ; Load prepared command into NVM Command register.
lpm r16, Z ; Preform a LPM to read out byte to R16
ldi r20, NVM_CMD_NO_OPERATION_gc ; Clear NVM Command register
sts NVM_CMD, r20
ret
ENDMOD 谢谢【6楼】 ralfak 。
在 WinAVR 头文件 iox32a4.h 找到了基地址的定义,果然是 0x0000,也就是说,如果偏移地址正确的话,LZ位读取的校准值是正确的。
#define PROD_SIGNATURES_START (0x0000)
iox32a4.h 中,没有找到相应的偏移地址的定义,按 datasheet 来说,ADCA的校准值应该是在 0x20 0x21 ,先用这个地址的值校准了。怀疑XMEGA的datasheet 偏移地址有误(如LZ位图所示),还是有点不放心。 读取函数更改如下:
;==========================================================================
; 函数名称:Sub_Read_Signature_Rows
; 函数功能:读取产品签名、用户签名信息
; 入口参数:Z(R31 R30):签名信息地址; R20:读取命令
; 出口参数:R0
; 用寄存器: ……
; 程序版本:1.0
; 编写日期:2009-11-14
; 修改次数:0
; 修改日期:
; 修改内容:
;==========================================================================
Sub_Read_Signature_Rows: ;// 读取签名信息
NOP ;//
Wait_NVM_Operate_End: ;// 1. 等待 NVM 操作完毕
LDS R16, NVM_STATUS ;//
TST R16 ;//
BRNE Wait_NVM_Operate_End ;//
STS NVM_CMD, R20 ;// 2. 设置命令
LPM ;// 3. 读取,(Z)---> R0
LDI R16, 0x00 ;//
STS NVM_CMD, R16 ;// 4. 设置命令寄存器为空
RET ;// Read User Signature Row / Calibration Row
The Read User Signature Row and Red Calibration Row commands are used to read one byte
from the User Signature Row or Calibration Row.
1. Load the Z-pointer with the byte address to read.
2. Load the NVM CMD register with the Read User Signature Row / Calibration Row
command
3. Execute the LPM instruction.
The destination register will be loaded during the execution of the LPM instruction.
我看这个datasheet的意思是基地址是由NVM命令决定的,Z寄存器里面放置偏移地址就可以了。
至于偏移地址定义
由driver.h给出来的
没有附上
#ifndef ADCACAL0_offset
#define ADCACAL0_offset 0x20
#define ADCACAL1_offset 0x21
#define ADCBCAL0_offset 0x24
#define ADCBCAL1_offset 0x25
#endif
参考avr1300
我很纳闷,楼主怎么这么喜欢用汇编写程序。
难道程序总是很小,没有用到math和stdlib等库操作。
就算没有,汇编也太费劲了。
汇编我一般只用来做临界处理和调试时分析。 【9楼】 ralfak
我很纳闷,楼主怎么这么喜欢用汇编写程序。
难道程序总是很小,没有用到math和stdlib等库操作。
就算没有,汇编也太费劲了。
汇编我一般只用来做临界处理和调试时分析。
-------------------------------------------------------
目前只是用汇编做试验,当用汇编把需要的各个功能模块跑通顺了过后,再考虑用C还是用汇编开发。
X32A4这个项目分为三个部分,是针对电力系统故障监测的一个无线网络,在组网的时候,时隙定位要求比较严格,另外要求功耗很低,使用低速率晶体减低功耗,再用汇编也可以提高一些效率。不过话说回来,也不是不能用C,我们的另外一个电力集抄的网络系统,全部代码都是用C做的(除了BootLoader外),目前也跑得很好。XMEGA这个项目,最终用什么语言开发,还没过多的去分析。个人绝得汇编用多了,感觉汇编也不麻烦,AVR射频方面函数库,C的和汇编的都很好移植,修改一些IO的定义和宏即可。另外、AVR的32位乘法、除法,CRC8 CRC16 CRC32校验等,汇编函数库也都是现成的。 终于找到XMEGA的汇编程序了。才买了几片XMEGA32,只会用汇编,想点个灯没头绪,百度了一下找回来了。
感觉XMEGA的I/O端口设置和ARM很像。 感谢楼主。 谢了。也正在用XMEGA32D4的片子。
页:
[1]