中级会员
 
- 积分
- 334
- 金钱
- 334
- 注册时间
- 2012-8-21
- 在线时间
- 27 小时
|
93C46是一种EPROM,接口用的是SPI接口,
但是,在实际驱动的时候,不能用硬件SPI接口驱动,因为DO是要做状态判断的,
因为这是一个EEPROM,所以,它内部是没有状态寄存器的,那要判断总线是忙或者不忙,两种状态的话,就需要用IO来检查,这个检查就通过判断DO的状态,
93C46 有两种数据方式,一种是16位,一种是8位的,
在驱动命令里面有7个,
READ
WRITE
ERASE
EWEN
EWDS
ERAL
WRAL
而一般用的有这几个
READ
WRITE
EWEN
EWDS
以8位数据模式为例
另外在写驱动的时候,一定要注意时钟周期是多少个,一般的认为都是8的倍数,这个是错误的
READ 一个完整的读,所需要的完整周期为18个周期,
WRITE 读一个BYTE同样所需要18个周期
而
EWEN
EWDS
则为10个周期
另外需要注意的是,93C46在写数据的时候,一定要在写数据之前打开写使能命令
如果需要连续的写数据的话,需要注意的是,在每写完一个数据之后需要加上一定的延时,具体延时多少可以根据自己系统需要的反应速度去配置,而读数据的话,可以通过
一个循环连续的读
IO配置如下,
CS ,CK,DI 配置为输出模式
DO 配置为上拉输入模式
驱动代码如下
GPIO_InitTypeDef GPIO_InitStructure;
#define hal_spi_ck_h GPIOC->ODR |= GPIO_Pin_10
#define hal_spi_ck_l GPIOC->ODR &=~ GPIO_Pin_10
#define hal_spi_do_h GPIOA->ODR |= GPIO_Pin_11
#define hal_spi_do_l GPIOA->ODR &=~ GPIO_Pin_11
#define hal_spi_cs_en GPIOC->ODR |= GPIO_Pin_11
#define hal_spi_cs_dis GPIOC->ODR &=~ GPIO_Pin_11
#define read_spi_hal_di_l GPIOA->IDR & GPIO_Pin_12
void spi_eprom_hal_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void eprom_write_en(void)
{
u16 temp_data,i;
temp_data = 0x98;
temp_data <<=2;
hal_spi_cs_en;
for(i = 0;i < 10;i++)
{
if(temp_data & 0x200)
{
hal_spi_do_h;
}
else
{
hal_spi_do_l;
}
hal_spi_ck_h;
hal_spi_ck_l;
temp_data <<= 1;
}
hal_spi_cs_dis;
}
void eprom_write_byte(u8 addr,u8 data)
{
u16 temp_data,i;
temp_data = 0xa0;
temp_data<<=2;
temp_data |= addr;
hal_spi_cs_en;
for(i = 0;i < 10;i++)
{
if(temp_data & 0x200)
{
hal_spi_do_h;
}
else
{
hal_spi_do_l;
}
hal_spi_ck_h;
hal_spi_ck_l;
temp_data <<= 1;
}
for(i = 0;i < 8;i++)
{
if(data & 0x80)
{
hal_spi_do_h;
}
else
{
hal_spi_do_l;
}
hal_spi_ck_h;
hal_spi_ck_l;
data <<= 1;
}
hal_spi_cs_dis;
hal_spi_cs_en;
while(!read_spi_hal_di_l);//{hal_spi_ck_h;hal_spi_ck_l;}
hal_spi_cs_dis;
}
u8 eprom_read_byte(u8 addr)
{
u8 temp;
u16 temp_data,i;
temp = 0;
temp_data = 0xc0;
temp_data <<=2;
temp_data |= addr;
hal_spi_cs_en;
for(i = 0;i < 10;i++)
{
if(temp_data & 0x200)
{
hal_spi_do_h;
}
else
{
hal_spi_do_l;
}
hal_spi_ck_h;
hal_spi_ck_l;
temp_data <<= 1;
}
hal_spi_ck_h;
hal_spi_ck_l;
for(i = 0;i < 8;i++)
{
hal_spi_ck_h;
if(read_spi_hal_di_l)
{
temp |= (1 <<(7-i));
}
hal_spi_ck_l;
}
hal_spi_cs_dis;
return temp;
} |
|