⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 access_extended_sram.c

📁 AVR单片机访问大于64K的外部RAM. .
💻 C
📖 第 1 页 / 共 3 页
字号:
    // 目标器件芯片为 ATmega64 和 ATmega128 的条件编译 
{ 
      asm("cli") ;                       // 禁止全局中断 
      asm("MOV r24, r18") ;              // R24 = 入口参数 data_length 的低字节 
      asm("MOV r25, r19") ;              // R25 = 入口参数 data_length 的高字节 
      // 赋值寻址低位指针值为上一次的尾部地址值 
      asm("LDI r30, LOW(??es_addr_read_index)") ; 
      asm("LDI r31, HIGH(??es_addr_read_index)") ; 
      asm("LD r26, Z") ;                 // R26 = 寻址低位指针值的低字节 
      asm("LDD r27, Z+1") ;              // R27 = 寻址低位指针值的高字节 
      // 赋值寻址高位指针值为上一次的尾部地址值 
      asm("LDI r30, LOW(??es_addr_read_h_index)") ; 
      asm("LDI r31, HIGH(??es_addr_read_h_index)") ; 
      asm("LD r18, Z") ;                 // R18 = 寻址高位指针值 
      asm("MOV r30, r16") ;              // R30 = 入口参数 *first_data_address 的低字节 
      asm("MOV r31, r17") ;              // R31 = 入口参数 *first_data_address 的高字节 
      asm("LDI r19, 0x80") ;             // R19 = [EXTSRAM_ADDR_H_START]的值 
      asm("LDI r20, 0xFF") ;             // R20 = [EXTSRAM_ADDR_END]值的低字节 
      asm("LDI r21, 0xFF") ;             // R21 = [EXTSRAM_ADDR_END]值的高字节 
  asm("ESB_READ_ASM1:") ; 
      asm("OUT 0x12, r18") ;             // 置寻址高位在超过 64KB 空间地址内 
                                           // ▲ 注:高位地址总线引脚为[PORTD] 
      asm("LD r16, X+") ;                // 读取下一个读取数据序列中的数据 
      asm("OUT 0x12, r19") ;             // 置寻址高位在 64KB 空间地址内 
                                           // ▲ 注:高位地址总线引脚为[PORTD] 
      asm("ST Z+, r16") ;                // 将读取的数据存储到目标的空间内 

      // 如果本 64KB 页内空间读取完毕,那么将寻址高位加1和将寻址低位指针归零; 
      // 后将寻址高位的值存储到EEPROM中(防止掉电时丢失操作地址)。 
      asm("CP r26, r20") ;               // 寻址低位指针值是否超过 64KB ? 
      asm("CPC r27, r21") ; 
      asm("BREQ ESB_READ_ASM2") ;       // 是,转至相应处理 
      asm("RJMP ESB_READ_ASM8") ;       // 否,继续写入下一个数据 
  asm("ESB_READ_ASM2:") ; 
      asm("LDI r26, LOW(0x1100)") ;      // 寻址低位指针值归回每页的起始地址值 
      asm("LDI r27, HIGH(0x1100)") ; 
                                           // ▲ 注:起始地址值为[EXTSRAM_ADDR_START] 
      asm("INC r18") ;                   // 寻址高位指针值加1 
      asm("MOV r2, r30") ;               // 暂存寄存器 r30 的数值到 r2 中 
      asm("MOV r3, r31") ;               // 暂存寄存器 r31 的数值到 r3 中 
      asm("LDI r30, LOW(??es_addr_read_h_index)") ; 
      asm("LDI r31, HIGH(??es_addr_read_h_index)") ; 
      asm("ST Z, r18") ;                 // 将寻址高位指针值赋值回静态变量中 
      // 将寻址高位指针值存储到EEPROM中 
      asm("LDI r30, LOW(es_addr_read_h_index_eep)") ; 
      asm("LDI r31, HIGH(es_addr_read_h_index_eep)") ; 
  asm("ESBW_EEPROM_READ1:") ; 

      asm("sbic 0x1C,1") ;               // 如果 EEWE 不清除 
                                           // ▲ 注:寄存器[EECR]、位[EEWE] 
      asm("rjmp ESBW_EEPROM_READ1") ;   // 等待,上一次 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] 
      // 下面这两条条件判断语句用于执行此操作:如果寻址高位己到扩展存储空间尾部,那么将 
      // 寻址高位归零;后将寻址高位的值存储到EEPROM中(防止掉电时丢失操作地址)。 
      asm("LDI r30, LOW(??es_addr_read_h_index_status)") ; 
      asm("LDI r31, HIGH(??es_addr_read_h_index_status)") ; 
      asm("LD r16, Z") ;                 // 取寻址高位指针状态的数值 
      asm("CPI r16, 0") ;                // 寻址寻址高位指针状态是否为 0 ? 
      asm("BRNE ESB_READ_ASM3") ;       // 否,转至相应处理 
      asm("RJMP ESB_READ_ASM4") ;       // 是,继续 
  asm("ESB_READ_ASM3:") ; 
      asm("LDI r30, LOW(??es_addr_read_h_index)") ; 
      asm("LDI r31, HIGH(??es_addr_read_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_read_h_index_eep)") ; 
      asm("LDI r31, HIGH(es_addr_read_h_index_eep)") ; 
  asm("ESBW_EEPROM_READ2:") ; 
      asm("sbic 0x1C,1") ;               // 如果 EEWE 不清除 
                                           // ▲ 注:寄存器[EECR]、位[EEWE] 
      asm("rjmp ESBW_EEPROM_READ2") ;   // 等待,上一次 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_read_h_index_status)") ; 
      asm("LDI r31, HIGH(??es_addr_read_h_index_status)") ; 
      asm("LDI r16, 0") ;                // 寻址高位指针状态值清为 0 
      asm("ST Z, r16") ;                 // 将寻址高位指针状态值赋值回静态变量中 
      // 将寻址高位指针状态值存储到EEPROM中 
      asm("LDI r30, LOW(es_addr_read_h_index_status_eep)") ; 
      asm("LDI r31, HIGH(es_addr_read_h_index_status_eep)") ; 
  asm("ESBW_EEPROM_READ3:") ; 
      asm("sbic 0x1C,1") ;               // 如果 EEWE 不清除 
                                           // ▲ 注:寄存器[EECR]、位[EEWE] 
      asm("rjmp ESBW_EEPROM_READ3") ;   // 等待,上一次 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_READ_ASM4:") ; 
      asm("CPI r18, 0xFF") ;             // 寻址高位指针值是否超过终止地址值? 
                                           // ▲ 注:终止地址值为[EXTSRAM_ADDR_H_END] 
      asm("BRNE ESB_READ_ASM6") ;       // 否,转至下一段;是,继续 
      asm("LDI r16, 0xA9") ;             // 置寻址高位指针状态值为非0 
      asm("LDI r30, LOW(??es_addr_read_h_index_status)") ; 
      asm("LDI r31, HIGH(??es_addr_read_h_index_status)") ; 
      asm("ST Z, r16") ;                 // 将寻址高位指针状态值赋值回静态变量中 
      // 将寻址高位指针状态值存储到EEPROM中 
      asm("LDI r30, LOW(es_addr_read_h_index_status_eep)") ; 
      asm("LDI r31, HIGH(es_addr_read_h_index_status_eep)") ; 
  asm("ESBW_EEPROM_READ4:") ; 
      asm("sbic 0x1C,1") ;               // 如果 EEWE 不清除 
                                           // ▲ 注:寄存器[EECR]、位[EEWE] 
      asm("rjmp ESBW_EEPROM_READ4") ;   // 等待,上一次 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_READ_ASM6:") ; 
      asm("MOV r30, r2") ;               // 从暂存寄存器 r2 中复原回 r30 的值 
      asm("MOV r31, r3") ;               // 从暂存寄存器 r3 中复原回 r31 的值 
  asm("ESB_READ_ASM8:") ; 
      asm("SBIW r24, 1") ;               // 写入的数据长度-1 
      asm("BREQ ESB_READ_ASM9") ;       // 如果己全部完成读取数据,则转至结束处理; 
      asm("RJMP ESB_READ_ASM1") ;         // 否则,继续读取下一个数据。 
  asm("ESB_READ_ASM9:") ; 
      asm("OUT 0x12, r19") ;             // 置寻址高位在 64KB 空间地址内 
                                           // ▲ 注:高位地址总线引脚为[PORTD] 
      asm("LDI r30, LOW(??es_addr_read_index)") ; 
      asm("LDI r31, HIGH(??es_addr_read_index)") ; 
      asm("ST Z, r26") ;                 // 将寻址低位指针值的低字节赋值回静态变量中 
      asm("STD Z+1, r27") ;              // 将寻址低位指针值的高字节赋值回静态变量中 
      // 将寻址低位指针值存储到EEPROM中 
      asm("LDI r30, LOW(es_addr_read_index_eep)") ; 
      asm("LDI r31, HIGH(es_addr_read_index_eep)") ; 
  asm("ESBW_EEPROM_READ5:") ; 
      asm("sbic 0x1C,1") ;               // 如果 EEWE 不清除 
                                           // ▲ 注:寄存器[EECR]、位[EEWE] 
      asm("rjmp ESBW_EEPROM_READ5") ;   // 等待,上一次 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_READ6:") ; 
      asm("sbic 0x1C,1") ;               // 如果 EEWE 不清除 
                                           // ▲ 注:寄存器[EECR]、位[EEWE] 
      asm("rjmp ESBW_EEPROM_READ6") ;   // 等待,上一次 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_Read "  错误!函数体没有可执行部分,无法调用入口参数和返回函数值。 
#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_)" 条件编译结束 


/* 
**************************************************************************************** 
                           本C语言源程序文件到此结束 
**************************************************************************************** 
*/ 
 
   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -