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

📄 access_extended_sram.c

📁 本程序是用于访问空间大于 64 KB (即:地址指针数大于两个字节)外部扩展随机存取存储器的源程序文件。
💻 C
📖 第 1 页 / 共 4 页
字号:
  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 + -