📄 access_extended_sram.c
字号:
asm(" mov r2, r30 "); // 暂存寄存器 r30 的数值到 r2 中
asm(" mov r3, r31 "); // 暂存寄存器 r31 的数值到 r3 中
asm(" ldi r30, LOW(??es_addr_write_h_index)");
asm(" ldi r31, HIGH(??es_addr_write_h_index)");
asm(" st Z, r18 "); // 将寻址高位指针值赋值回静态变量中
asm(" ldi r30, LOW(es_addr_write_h_index_eep)");// 将寻址高位指针值存储到EEPROM中
asm(" ldi r31, HIGH(es_addr_write_h_index_eep)");
asm("ESBW_EEPROM_WRITE1:");
asm(" sbic 0x1C,1 "); // 如果[▲ :EECR]的位[▲ :EEWE]不清除
asm(" rjmp ESBW_EEPROM_WRITE1 "); // 等待,上一次 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(" 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 "); // 将寻址高位指针值赋值回静态变量中
asm(" ldi r30, LOW(es_addr_write_h_index_eep)");// 将寻址高位指针值存储到EEPROM中
asm(" ldi r31, HIGH(es_addr_write_h_index_eep)");
asm("ESBW_EEPROM_WRITE2: ");
asm(" sbic 0x1C,1 "); // 如果[▲ :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 "); // 将寻址高位指针状态值赋值回静态变量中
asm(" ldi r30, LOW(es_addr_write_h_index_status_eep)");// 将寻址高位指针状态值存到EEPROM
asm(" ldi r31, HIGH(es_addr_write_h_index_status_eep)");
asm("ESBW_EEPROM_WRITE3: ");
asm(" sbic 0x1C,1 "); // 如果[▲ :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 "); // 将寻址高位指针状态值赋值回静态变量中
asm(" ldi r30, LOW(es_addr_write_h_index_status_eep)");// 将寻址高位指针状态值存到EEPROM
asm(" ldi r31, HIGH(es_addr_write_h_index_status_eep)");
asm("ESBW_EEPROM_WRITE4: ");
asm(" sbic 0x1C,1 "); // 如果[▲ :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 "); // 置寻址高位[▲ :PORTD]在 64KB 空间地址内
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 "); // 将寻址低位指针值的高字节赋值回静态变量中
asm(" ldi r30, LOW(es_addr_write_index_eep)");// 将寻址低位指针值存储到EEPROM中
asm(" ldi r31, HIGH(es_addr_write_index_eep)");
asm("ESBW_EEPROM_WRITE5: ");
asm(" sbic 0x1C,1 "); // 如果[▲ :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 "); // 如果[▲ :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 ; // 将读取的数据存储到目标的空间内
if ((unsigned int)addr == EXTSRAM_ADDR_END)// 本 64KB 页内空间是否读完?
{
addr = (unsigned char *)EXTSRAM_ADDR_START;// 寻址低位指针归零
es_addr_read_h_index++ ; // 寻址高位指针加1
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;// 存进EEPROM中
es_addr_read_h_index_status = 0 ; // 寻址高位指针状态清零
es_addr_read_h_index_status_eep[0]=es_addr_read_h_index_status;// 存进EEPROM中
}
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;// 存进EEPROM中
}
}
}
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_Read>错误!页的起始地址[EXTSRAM_ADDR_START]不等于\
[0x1100],在汇编函数中做相应修改。
#endif // "(EXTSRAM_ADDR_START != 0x1100)"条件编译结束
#if (EXTSRAM_ADDR_END != 0xFFFF) // "(EXTSRAM_ADDR_END != 0xFFFF)"条件编译开始
#error 函数<ExtSRAM_Black_Read>错误!页的终止地址[EXTSRAM_ADDR_END]不等于\
[0xFFFF],在汇编函数中做相应修改。
#endif // "(EXTSRAM_ADDR_END != 0xFFFF)"条件编译结束
#if (EXTSRAM_ADDR_H_START != 0x80) // "(EXTSRAM_ADDR_H_START != 0x80)"条件编译开始
#error 函数<ExtSRAM_Black_Read>错误!高位的起始地址[EXTSRAM_ADDR_H_START]\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -