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

📄 access_extended_sram.c

📁 AVR单片机访问大于64K的外部RAM. .
💻 C
📖 第 1 页 / 共 3 页
字号:
      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 + -