📄 access_extended_sram.c
字号:
asm("LDI r31, HIGH(??es_addr_write_h_index_status)") ;
asm("LD r16, Z") ; // 取寻址高位指针状态的数值
asm("CPI r16, 0") ; // 寻址寻址高位指针状态是否为 0 ?
asm("BRNE ESB_WRITE_ASM3") ; // 否,转至相应处理
asm("RJMP ESB_WRITE_ASM4") ; // 是,继续
asm("ESB_WRITE_ASM3:") ;
asm("LDI r30, LOW(??es_addr_write_h_index)") ;
asm("LDI r31, HIGH(??es_addr_write_h_index)") ;
asm("INC r19") ;
asm("MOV R18, r19") ; // 寻址高位指针值归回寻址高位的起始地址值
// ▲ 注:起始值为[EXTSRAM_ADDR_H_START+1]
asm("DEC r19") ;
asm("ST Z, r18") ; // 将寻址高位指针值赋值回静态变量中
// 将寻址高位指针值存储到EEPROM中
asm("LDI r30, LOW(es_addr_write_h_index_eep)") ;
asm("LDI r31, HIGH(es_addr_write_h_index_eep)") ;
asm("ESBW_EEPROM_WRITE2:") ;
asm("sbic 0x1C,1") ; // 如果 EEWE 不清除
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("rjmp ESBW_EEPROM_WRITE2") ; // 等待,上一次 EEPROM 写操作结束
asm("out 0x1F,r31") ; // 输出写入的 EEPROM 地址高位
// ▲ 注:寄存器[EEARH]
asm("out 0x1E,r30") ; // 输出写入的 EEPROM 地址低位
// ▲ 注:寄存器[EEARL]
asm("out 0x1D,r18") ; // 输出写入的 EEPROM 数据
// ▲ 注:寄存器[EEDR]
asm("sbi 0x1C,2") ; // 设置 EEPROM 主机写使能
// ▲ 注:寄存器[EECR]、位[EEMWE]
asm("sbi 0x1C,1") ; // 设置 EEPROM 写使能
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("LDI r30, LOW(??es_addr_write_h_index_status)") ;
asm("LDI r31, HIGH(??es_addr_write_h_index_status)") ;
asm("LDI r16, 0") ; // 寻址高位指针状态值清为 0
asm("ST Z, r16") ; // 将寻址高位指针状态值赋值回静态变量中
// 将寻址高位指针状态值存储到EEPROM中
asm("LDI r30, LOW(es_addr_write_h_index_status_eep)") ;
asm("LDI r31, HIGH(es_addr_write_h_index_status_eep)") ;
asm("ESBW_EEPROM_WRITE3:") ;
asm("sbic 0x1C,1") ; // 如果 EEWE 不清除
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("rjmp ESBW_EEPROM_WRITE3") ; // 等待,上一次 EEPROM 写操作结束
asm("out 0x1F,r31") ; // 输出写入的 EEPROM 地址高位
// ▲ 注:寄存器[EEARH]
asm("out 0x1E,r30") ; // 输出写入的 EEPROM 地址低位
// ▲ 注:寄存器[EEARL]
asm("out 0x1D,r16") ; // 输出写入的 EEPROM 数据
// ▲ 注:寄存器[EEDR]
asm("sbi 0x1C,2") ; // 设置 EEPROM 主机写使能
// ▲ 注:寄存器[EECR]、位[EEMWE]
asm("sbi 0x1C,1") ; // 设置 EEPROM 写使能
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("ESB_WRITE_ASM4:") ;
asm("CPI r18, 0xFF") ; // 寻址高位指针值是否超过终止地址值?
// ▲ 注:终止地址值为[EXTSRAM_ADDR_H_END]
asm("BRNE ESB_WRITE_ASM6") ; // 否,转至下一段;是,继续
asm("LDI r16, 0xA9") ; // 置寻址高位指针状态值为非0
asm("LDI r30, LOW(??es_addr_write_h_index_status)") ;
asm("LDI r31, HIGH(??es_addr_write_h_index_status)") ;
asm("ST Z, r16") ; // 将寻址高位指针状态值赋值回静态变量中
// 将寻址高位指针状态值存储到EEPROM中
asm("LDI r30, LOW(es_addr_write_h_index_status_eep)") ;
asm("LDI r31, HIGH(es_addr_write_h_index_status_eep)") ;
asm("ESBW_EEPROM_WRITE4:") ;
asm("sbic 0x1C,1") ; // 如果 EEWE 不清除
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("rjmp ESBW_EEPROM_WRITE4") ; // 等待,上一次 EEPROM 写操作结束
asm("out 0x1F,r31") ; // 输出写入的 EEPROM 地址高位
// ▲ 注:寄存器[EEARH]
asm("out 0x1E,r30") ; // 输出写入的 EEPROM 地址低位
// ▲ 注:寄存器[EEARL]
asm("out 0x1D,r16") ; // 输出写入的 EEPROM 数据
// ▲ 注:寄存器[EEDR]
asm("sbi 0x1C,2") ; // 设置 EEPROM 主机写使能
// ▲ 注:寄存器[EECR]、位[EEMWE]
asm("sbi 0x1C,1") ; // 设置 EEPROM 写使能
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("ESB_WRITE_ASM6:") ;
asm("MOV r30, r2") ; // 从暂存寄存器 r2 中复原回 r30 的值
asm("MOV r31, r3") ; // 从暂存寄存器 r3 中复原回 r31 的值
asm("ESB_WRITE_ASM8:") ;
asm("SBIW r24, 1") ; // 写入的数据长度-1
asm("BREQ ESB_WRITE_ASM9") ; // 如果己全部完成写入数据,则转至结束处理;
asm("RJMP ESB_WRITE_ASM1") ; // 否则,继续写下一个数据。
asm("ESB_WRITE_ASM9:") ;
asm("OUT 0x12, r19") ; // 置寻址高位在 64KB 空间地址内
// ▲ 注:高位地址总线引脚为[PORTD]
asm("LDI r30, LOW(??es_addr_write_index)") ;
asm("LDI r31, HIGH(??es_addr_write_index)") ;
asm("ST Z, r26") ; // 将寻址低位指针值的低字节赋值回静态变量中
asm("STD Z+1, r27") ; // 将寻址低位指针值的高字节赋值回静态变量中
// 将寻址低位指针值存储到EEPROM中
asm("LDI r30, LOW(es_addr_write_index_eep)") ;
asm("LDI r31, HIGH(es_addr_write_index_eep)") ;
asm("ESBW_EEPROM_WRITE5:") ;
asm("sbic 0x1C,1") ; // 如果 EEWE 不清除
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("rjmp ESBW_EEPROM_WRITE5") ; // 等待,上一次 EEPROM 写操作结束
asm("out 0x1F,r31") ; // 输出写入的 EEPROM 地址高位
// ▲ 注:寄存器[EEARH]
asm("out 0x1E,r30") ; // 输出写入的 EEPROM 地址低位
// ▲ 注:寄存器[EEARL]
asm("out 0x1D,r26") ; // 输出写入的 EEPROM 数据
// ▲ 注:寄存器[EEDR]
asm("sbi 0x1C,2") ; // 设置 EEPROM 主机写使能
// ▲ 注:寄存器[EECR]、位[EEMWE]
asm("sbi 0x1C,1") ; // 设置 EEPROM 写使能
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("ADIW r30, 1") ; // 写入EEPROM的地址+1
asm("ESBW_EEPROM_WRITE6:") ;
asm("sbic 0x1C,1") ; // 如果 EEWE 不清除
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("rjmp ESBW_EEPROM_WRITE6") ; // 等待,上一次 EEPROM 写操作结束
asm("out 0x1F,r31") ; // 输出写入的 EEPROM 地址高位
// ▲ 注:寄存器[EEARH]
asm("out 0x1E,r30") ; // 输出写入的 EEPROM 地址低位
// ▲ 注:寄存器[EEARL]
asm("out 0x1D,r27") ; // 输出写入的 EEPROM 数据
// ▲ 注:寄存器[EEDR]
asm("sbi 0x1C,2") ; // 设置 EEPROM 主机写使能
// ▲ 注:寄存器[EECR]、位[EEMWE]
asm("sbi 0x1C,1") ; // 设置 EEPROM 写使能
// ▲ 注:寄存器[EECR]、位[EEWE]
asm("sei") ; // 打开全局中断
}
#else // 目标器件芯片的条件编译
#error 函数 " ExtSRAM_Black_Write " 错误!函数体没有可执行部分,无法调用入口参数和返回函数值。
#endif // 目标器件芯片的条件编译结束
#endif // "USE_ASM_EXTSRAM_BLACK_ACCESS"条件编译结束
#if defined(_IAR_EW_AVR_) // "IAR Embedded Workbench AVR 编译器"条件编译开始
#pragma diag_default=Pe826,Pe940 // Pe826,Pe940 消息复原为默认设置
#endif // "defined(_IAR_EW_AVR_)" 条件编译结束
/*----------------------------------------------------------------------------
函数功能: 本函数用于以块方式访问空间大于 64 KB 外部随机存储器的读取数据操作。
函数入口参数:*first_data_address ------ 将读取的数据存储到目标的首个地址指针。
data_length -------------- 读取的数据长度。
全局静态变量:es_addr_read_h_index ---------- 读取数据操作访问地址的寻址低位指针数值变量
es_addr_read_index ------------ 读取数据操作访问地址的寻址高位指针数值变量
es_addr_read_h_index_status --- 读取数据操作访问地址的寻址高位指针状态变量
备注: ▲.本函数用于外部扩展随机存取存储器寻址指针不超过2个字节。
▲.本函数读取的源存储器空间将循环操作,即到达空间尾部时又返回到起始处,
继续执行读取数据操作。
----------------------------------------------------------------------------*/
#if defined(_IAR_EW_AVR_) // "IAR Embedded Workbench AVR 编译器"条件编译开始
#pragma diag_suppress=Pe826,Pe940 // 禁止编译时产生 Pe826,Pe940 消息
#endif // "defined(_IAR_EW_AVR_)" 条件编译结束
void ExtSRAM_Black_Read(unsigned char *first_data_address,
// 将读取的数据存储到目标的首个地址指针
unsigned int data_length)
// 读取的数据长度
#ifndef USE_ASM_EXTSRAM_BLACK_ACCESS // "USE_ASM_EXTSRAM_BLACK_ACCESS"条件编译开始
{
register unsigned char *addr ; // 数据指针临时寄存器变量
register unsigned char data ; // 临时寄存器变量
register unsigned int j ; // 临时寄存器变量
addr = (unsigned char *)es_addr_read_index ; // 赋值寻址低位指针为上一次的尾部地址值
j = data_length ; // 赋值临时寄存器变量为写入的数据长度
while (j-- != 0)
{
EXTSRAM_ADDR_PORT = es_addr_read_h_index ; // 置寻址高位在超过 64KB 空间地址内
data = *(addr++) ; // 在超过 64KB 空间内读取数据
EXTSRAM_ADDR_PORT = EXTSRAM_ADDR_H_START ; // 置寻址高位在 64KB 空间地址内
*(first_data_address++) = data ; // 将读取的数据存储到目标的空间内
// 如果本 64KB 页内空间读完,那么将寻址高位加1和将寻址低位指针归零;后将寻址高位
// 的值存储到EEPROM中(防止掉电时丢失操作地址)。
if ((unsigned int)addr == EXTSRAM_ADDR_END)
{
addr = (unsigned char *)EXTSRAM_ADDR_START ;
es_addr_read_h_index++ ;
es_addr_read_h_index_eep[0] = es_addr_read_h_index ;
// 下面这两条条件判断语句用于执行此操作:如果寻址高位己到扩展存储空间尾部,那么将
// 寻址高位归零;后将寻址高位的值存储到EEPROM中(防止掉电时丢失操作地址)。
if (es_addr_read_h_index_status != 0)
{
es_addr_read_h_index = (EXTSRAM_ADDR_H_START+1) ;
es_addr_read_h_index_eep[0] = es_addr_read_h_index ;
es_addr_read_h_index_status = 0 ;
es_addr_read_h_index_status_eep[0] = es_addr_read_h_index_status ;
}
if (es_addr_read_h_index == EXTSRAM_ADDR_H_END)
{
es_addr_read_h_index_status = 0xA9 ;
es_addr_read_h_index_status_eep[0] = es_addr_read_h_index_status ;
}
}
}
EXTSRAM_ADDR_PORT = EXTSRAM_ADDR_H_START ; // 置寻址高位在 64KB 空间地址内
es_addr_read_index = (unsigned int)addr ; // 存储本次操作寻址低位指针的尾部地址值
es_addr_read_index_eep[0] = es_addr_read_index ;// 将寻址低位指针值存储到 EEPROM 中
}
#else // "USE_ASM_EXTSRAM_BLACK_ACCESS"条件编译
#if (EXTSRAM_ADDR_START != 0x1100) // "(EXTSRAM_ADDR_START != 0x1100)"条件编译开始
#error 函数 " ExtSRAM_Black_Write " 错误!页的起始地址[EXTSRAM_ADDR_START]不等于[0x1100],在汇编函数中做相应修改。
#endif // "(EXTSRAM_ADDR_START != 0x1100)"条件编译结束
#if (EXTSRAM_ADDR_END != 0xFFFF) // "(EXTSRAM_ADDR_END != 0xFFFF)"条件编译开始
#error 函数 " ExtSRAM_Black_Write " 错误!页的终止地址[EXTSRAM_ADDR_END]不等于[0xFFFF],在汇编函数中做相应修改。
#endif // "(EXTSRAM_ADDR_END != 0xFFFF)"条件编译结束
#if (EXTSRAM_ADDR_H_START != 0x80) // "(EXTSRAM_ADDR_H_START != 0x80)"条件编译开始
#error 函数 " ExtSRAM_Black_Write " 错误!高位的起始地址[EXTSRAM_ADDR_H_START]不等于[0x80],在汇编函数中做相应修改。
#endif // "(EXTSRAM_ADDR_H_START != 0x80)"条件编译结束
#if (EXTSRAM_ADDR_H_END != 0xFF) // "(EXTSRAM_ADDR_H_END != 0xFF)"条件编译开始
#error 函数 " ExtSRAM_Black_Write " 错误!高位的终止地址[EXTSRAM_ADDR_H_END]不等于[0xFF],在汇编函数中做相应修改。
#endif // "(EXTSRAM_ADDR_H_END != 0xFF)"条件编译结束
#if defined(MCU_TYPE_IS_ATMEGA64) || defined(MCU_TYPE_IS_ATMEGA128)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -