EBI SRAM驱动"/>
M480 EBI SRAM驱动
M480 驱动SRAM非常容易,但是官方这个开发板有点坑,将最高3位地址线接了IO口,导致只能访问128KB的内存空间,原理图如下:
上代码
/************************************************************************************************************** 文件名 : m48x_ebi.c* 功能 : m48X EBI驱动* 作者 : cp1300@139* 创建时间 : 2021-09-29* 最后修改时间 : 2021-09-29* 详细 : 用于外部SRAM驱动
*************************************************************************************************************/
#include "m48x_map.h"
#include "system.h"
#include "m48x_ebi.h"/*************************************************************************************************************************
* 函数 : void EBI_EnableWriteBuff(bool isEnable)
* 功能 : EBI总线写buff使能设置-全局设置
* 参数 : isEnable:是否使能
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139
* 时间 : 2021-09-30
* 最后修改时间 : 2021-09-30
* 说明 :
*************************************************************************************************************************/
void EBI_EnableWriteBuff(bool isEnable)
{SYS_DeviceClockEnable(DEV_EBI, TRUE); //使能EBI时钟if (isEnable){EBI->CTL0 |= 1<<24; //使能}else{EBI->CTL0 &= ~(1 << 24);}}/*************************************************************************************************************************
* 函数 : void EBI_SetALE(u8 tALE)
* 功能 : EBI总线地址锁存周期设置-全局设置
* 参数 : tALE:地址锁存周期,0-7
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139
* 时间 : 2021-09-30
* 最后修改时间 : 2021-09-30
* 说明 :
*************************************************************************************************************************/
void EBI_SetALE(u8 tALE)
{SYS_DeviceClockEnable(DEV_EBI, TRUE); //使能EBI时钟EBI->CTL0 &= ~(7 << 16);EBI->CTL0 |= (u32)(tALE & 0x07) << 16;
}/*************************************************************************************************************************
* 函数 : void EBI_Enable(EBI_CH ch, bool isEnable)
* 功能 : EBI总线使能
* 参数 : ch:EBI通道0-2;isEnable:是否使能
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139
* 时间 : 2021-09-30
* 最后修改时间 : 2021-09-30
* 说明 :
*************************************************************************************************************************/
void EBI_Enable(EBI_CH ch, bool isEnable)
{SYS_DeviceClockEnable(DEV_EBI, TRUE); //使能EBI时钟switch (ch){case EBI_CH0:{if (isEnable){EBI->CTL0 |= (1 << 0);}else{EBI->CTL0 &= ~(1 << 0);}}break;case EBI_CH1:{if (isEnable){EBI->CTL1 |= (1 << 0);}else{EBI->CTL1 &= ~(1 << 0);}}break;case EBI_CH2:{if (isEnable){EBI->CTL2 |= (1 << 0);}else{EBI->CTL2 &= ~(1 << 0);}}break;default:break;}
}/*************************************************************************************************************************
* 函数 : void EBI_Config(EBI_CH ch, const EBI_CONFIG* pConfig)
* 功能 : EBI总线配置(配置完后会自动使能EBI)
* 参数 : ch:EBI通道0-2;pConfig:配置结构体
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139
* 时间 : 2021-09-30
* 最后修改时间 : 2021-09-30
* 说明 :
*************************************************************************************************************************/
void EBI_Config(EBI_CH ch, const EBI_CONFIG* pConfig)
{u32 CTL = 0, TCTL = 0;CTL |= (u32)(pConfig->MCLKDIV & 0x07) << 8; //外部输出时钟分频器CTL |= pConfig->isDataAccessEn ? (1 << 4) : 0; //连续数据访问模式使能CTL |= pConfig->isAddDataSeparEn ? (1 << 3) : 0;//EBI地址/数据总线分离模式使能CTL |= pConfig->isCS_H_En ? (1 << 2) : 0; //芯片选择引脚极性反转使能CTL |= pConfig->is16bitDataWidth ? (1 << 1) : 0;//16bit数据宽度使能TCTL |= (u32)(pConfig->ReadToReadIdle & 0xF) << 24;//读取间隔,插入空闲时间TCTL |= pConfig->isDisAccessWrite ? (1 << 23) : 0;//EBI写入期间的数据访问保持时间(tAHD)已禁用。TCTL |= pConfig->isDisAccessRead ? (1 << 22) : 0;//EBI读取期间的数据访问保持时间(tAHD)已禁用TCTL |= (u32)(pConfig->WriteToWriteIdle & 0xF) << 12;//写入间隔,插入空闲时间TCTL |= (u32)(pConfig->tAHD & 0x7) << 8; //EBI数据访问保持时间TCTL |= (u32)(pConfig->tACC & 0x1F) << 3; //EBI数据访问时间SYS_DeviceClockEnable(DEV_EBI, TRUE); //使能EBI时钟EBI_Enable(ch, FALSE); //先关闭EBIswitch(ch){case EBI_CH0 :{CTL |= EBI->CTL0 & 0xFFFF0000; //CTL0保留高16位设置EBI->CTL0 = CTL;EBI->TCTL0 = TCTL;}break;case EBI_CH1 :{EBI->CTL1 = CTL;EBI->TCTL1 = TCTL;}break;case EBI_CH2 :{EBI->CTL2 = CTL;EBI->TCTL2 = TCTL;}break;default:break;}EBI_Enable(ch, TRUE); //使能EBI
}
/************************************************************************************************************** 文件名 : m48x_ebi.h* 功能 : m48X EBI驱动* 作者 : cp1300@139* 创建时间 : 2021-09-29* 最后修改时间 : 2021-09-29* 详细 : 用于外部SRAM驱动
*************************************************************************************************************/
#ifndef _M48X_EBI_H_
#define _M48X_EBI_H_
#include "m48x_system.h"//FLASH起始地址
#define M48X_EBI_RAM_BASE0 0x60000000 //EBI nCS0对应映射内存起始地址
#define M48X_EBI_RAM_BASE1 0x60100000 //EBI nCS1对应映射内存起始地址
#define M48X_EBI_RAM_BASE2 0x60200000 //EBI nCS2对应映射内存起始地址//EBI控制器选择
typedef enum
{EBI_CH0 = 0,EBI_CH1 = 1,EBI_CH2 = 2,
}EBI_CH;//MCLK分频设置(针对HCLK进行分频)
typedef enum
{EBI_MCLKDIV_1 = 0, //HCLK/1EBI_MCLKDIV_2 = 1, //HCLK/2EBI_MCLKDIV_4 = 2, //HCLK/4EBI_MCLKDIV_8 = 3, //HCLK/8EBI_MCLKDIV_16 = 4, //HCLK/16EBI_MCLKDIV_32 = 5, //HCLK/32EBI_MCLKDIV_64 = 6, //HCLK/64EBI_MCLKDIV_128 = 7, //HCLK/128
}EBI_MCLKDIV;//EBI总线配置
typedef struct
{bool isDataAccessEn; //连续访问模式使能bool isAddDataSeparEn; //地址/数据总线分离模式使能bool isCS_H_En; //片选高有效使能bool is16bitDataWidth; //使能16bit数据宽度bool isDisAccessWrite; //禁用EBI写入期间的数据访问保持时间(tAHD)bool isDisAccessRead; //禁用EBI读取期间的数据访问保持时间(tAHD)u8 ReadToReadIdle; //读取空闲时间,0-0xFu8 WriteToWriteIdle; //写入数据空闲时间,0-15u8 tAHD; //数据访问保持时间0-7 tAHD = (TAHD +1) * EBI_MCLK.u8 tACC; //数据访问时间0-15 tACC = (TACC +1) * EBI_MCLK.EBI_MCLKDIV MCLKDIV; //时钟分频设置
}EBI_CONFIG;void EBI_EnableWriteBuff(bool isEnable);//EBI总线写buff使能设置-全局设置
void EBI_SetALE(u8 tALE);//EBI总线地址锁存周期设置-全局设置
void EBI_Enable(EBI_CH ch, bool isEnable);//EBI总线使能
void EBI_Config(EBI_CH ch, const EBI_CONFIG* pConfig);//EBI总线配置(配置完后会自动使能EBI)#endif //_M48X_EBI_H_
/************************************************************************************************************** 文件名 : m48x_sram.c* 功能 : m48X 外部SRAM驱动* 作者 : cp1300@139* 创建时间 : 2021-09-30* 最后修改时间 : 2021-09-30* 详细 : 用于外部SRAM驱动
*************************************************************************************************************/
#include "m48x_map.h"
#include "system.h"
#include "m48x_ebi.h"
#include "m48x_sram.h"#define SRAM_EBI_CH EBI_CH1//配置
static const EBI_CONFIG scg_SRAM_CONFIG =
{FALSE, //连续访问模式不要开启FALSE, //地址/数据总线分离模式使能FALSE, //片选高有效使能TRUE, //使能16bit数据宽度FALSE, //禁用EBI写入期间的数据访问保持时间(tAHD)FALSE, //禁用EBI读取期间的数据访问保持时间(tAHD)3, //读取空闲时间,0-0xF3, //写入数据空闲时间,0-153, //数据访问保持时间0-7 tAHD = (TAHD +1) * EBI_MCLK.3, //数据访问时间0-15 tACC = (TACC +1) * EBI_MCLK.EBI_MCLKDIV_2 //时钟分频设置
};/*************************************************************************************************************************
* 函数 : static void EBI_SRAM_IO_Init(void)
* 功能 : 外部SRAM所需IO初始化
* 参数 : 无
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139
* 时间 : 2021-09-30
* 最后修改时间 : 2021-09-30
* 说明 :
*************************************************************************************************************************/
static void EBI_SRAM_IO_Init(void)
{//AD0-AD7SYS_GPIOx_SetAF(GPIO_PG9_EBI_AD0);SYS_GPIOx_SetAF(GPIO_PG10_EBI_AD1);SYS_GPIOx_SetAF(GPIO_PG11_EBI_AD2);SYS_GPIOx_SetAF(GPIO_PG12_EBI_AD3);SYS_GPIOx_SetAF(GPIO_PG13_EBI_AD4);SYS_GPIOx_SetAF(GPIO_PG14_EBI_AD5);SYS_GPIOx_SetAF(GPIO_PD8_EBI_AD6);SYS_GPIOx_SetAF(GPIO_PD9_EBI_AD7);//AD8-AD15SYS_GPIOx_SetAF(GPIO_PE14_EBI_AD8);SYS_GPIOx_SetAF(GPIO_PE15_EBI_AD9);SYS_GPIOx_SetAF(GPIO_PE1_EBI_AD10);SYS_GPIOx_SetAF(GPIO_PE0_EBI_AD11);SYS_GPIOx_SetAF(GPIO_PH8_EBI_AD12);SYS_GPIOx_SetAF(GPIO_PH9_EBI_AD13);SYS_GPIOx_SetAF(GPIO_PH10_EBI_AD14);SYS_GPIOx_SetAF(GPIO_PH11_EBI_AD15);//A16-A18//ALE,nCS1,nWR,nRD,nWRH,nWRLSYS_GPIOx_SetAF(GPIO_PA8_EBI_ALE);SYS_GPIOx_SetAF(GPIO_PD11_EBI_nCS1);SYS_GPIOx_SetAF(GPIO_PE4_EBI_nWR);SYS_GPIOx_SetAF(GPIO_PE5_EBI_nRD);SYS_GPIOx_SetAF(GPIO_PG8_EBI_nWRH);SYS_GPIOx_SetAF(GPIO_PG7_EBI_nWRL);}/*************************************************************************************************************************
* 函数 : bool EBI_SRAM_Init(void)
* 功能 : 外部SRAM初始化
* 参数 : 无
* 返回 : 无
* 依赖 : 底层
* 作者 : cp1300@139
* 时间 : 2021-09-30
* 最后修改时间 : 2021-09-30
* 说明 :
*************************************************************************************************************************/
bool EBI_SRAM_Init(void)
{EBI_SRAM_IO_Init();EBI_EnableWriteBuff(FALSE);//EBI总线写buff使能设置-全局设置EBI_SetALE(4);//EBI总线地址锁存周期设置-全局设置EBI_Config(SRAM_EBI_CH, &scg_SRAM_CONFIG);//EBI总线配置(配置完后会自动使能EBI)return TRUE;
}
/************************************************************************************************************** 文件名 : m48x_sram.h* 功能 : m48X 外部SRAM驱动* 作者 : cp1300@139* 创建时间 : 2021-09-30* 最后修改时间 : 2021-09-30* 详细 : 用于外部SRAM驱动
*************************************************************************************************************/
#ifndef _M48X_SRAM_H_
#define _M48X_SRAM_H_
#include "m48x_system.h"bool EBI_SRAM_Init(void); //外部SRAM初始化#endif //_M48X_SRAM_H_
//测试代码
/************************************************************************************************************** 文件名: ebi_sram_test.c* 功能: 外部sram测试* 作者: cp1300@139* 创建时间: 2021-09-30* 最后修改时间: 2021-09-30* 详细:
*************************************************************************************************************/
#include "system.h"
#include "m48x_system.h"
#include "test.h"
#include "m48x_sram.h"#define EBI_SRAM_BASE 0x60100000 //EBI nCS1对应映射内存起始地址 //外部sram测试
void ebi_sram_test(void)
{u32* p = (u32*)EBI_SRAM_BASE;u32 i;SYS_GPIOx_OneInit(GPIOA, 9, OUT_PP, SPEED_40M);SYS_GPIOx_OneInit(GPIOA, 10, OUT_PP, SPEED_40M);SYS_GPIOx_OneInit(GPIOA, 11, OUT_PP, SPEED_40M);PAout(9) = 0;PAout(10) = 0;PAout(11) = 0; //由于开发板高3位地址接的IO口,此处测只能都给低电平,只有128KB的内存访问空间SYS_DelayMS(1000);uart_printf("开始EBI SRAM测试\r\n");EBI_SRAM_Init();SYS_DelayMS(100);uart_printf("开始EBI SRAM读取测试\r\n");for (i = 0; i < 32; i++){uart_printf("%d ", p[i]);}uart_printf("\r\n");uart_printf("开始EBI SRAM写入测试\r\n");for (i = 0; i < 32; i++){p[i] = i;}uart_printf("开始EBI SRAM读取测试\r\n");for (i = 0; i < 32; i++){uart_printf("%d ", p[i]);}uart_printf("\r\n");uart_printf("EBI SRAM测试结束\r\n");SYS_DelayMS(1000*1000);
}
测试结果:
开始EBI SRAM测试
开始EBI SRAM读取测试
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
开始EBI SRAM写入测试
开始EBI SRAM读取测试
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
EBI SRAM测试结束
更多推荐
M480 EBI SRAM驱动
发布评论