OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3640|回复: 5

STM32F407 读写 AT93C86 ,始终返回0xffff

[复制链接]

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-12-26
在线时间
8 小时
发表于 2017-11-18 21:58:28 | 显示全部楼层 |阅读模式
1金钱
芯片ORG引脚接VCC,16位数据,地址为A9---A0
主要代码如下:
// Write enable must precede all programming modes.
void EEPROM_Ewen(void)
{
                u16 i,InData;
                EEPROM_CS_0( );
                EEPROM_SCLK_0( );
                delay_us(100);
                EEPROM_CS_1( );
                InData=0x4C0; // 100 11XX XXXX
                for(i = 0; i < 11; i++)
                { // 9
                        if(InData&0x400)
                        {                               
                                EEPROM_MOSI_1( );
                        }
                        else
                                EEPROM_MOSI_0( );
                        delay_us(100);
                        EEPROM_SCLK_1( );
                        delay_us(100);
                        EEPROM_SCLK_0( );
                        delay_us(100);
                        InData <<= 1;
                }
                EEPROM_CS_0( );
}

// Write enable must precede all programming modes.
void EEPROM_Ewds(void)
{
                unsigned int i,InData;
                EEPROM_CS_0( );  
                EEPROM_SCLK_0( );
                delay_us(100);
                EEPROM_CS_1( );
                InData=0x400; // 100 00XX XXXX
                for(i = 0; i < 11; i++)
                { // 9
                        if(InData & 0x400)
                        {                               
                                EEPROM_MOSI_1( );
                        }
                        else EEPROM_MOSI_0( );
                        delay_us(100);
                        EEPROM_SCLK_1( );
                        delay_us(100);
                        EEPROM_SCLK_0( );
                        delay_us(100);
                        InData <<= 1;
                }
                EEPROM_CS_0( );
}
void EEPROM_Earse(u16 address)
{
        unsigned char i;
        u16 result = 0;
        EEPROM_SCLK_0( );
        EEPROM_CS_0( );
        delay_us(100);
        EEPROM_CS_1( );
        address=(address&0x3FF)|0x1C00;
        for(i = 0; i < 13; i++ )
        { // 8
                if(address & 0x1000) EEPROM_MOSI_1( );
                else EEPROM_MOSI_0( );
                delay_us(100);
                EEPROM_SCLK_1( );
                delay_us(100);
                EEPROM_SCLK_0( );
                delay_us(100);
                address <<= 1;
        }
        delay_us(100);
        EEPROM_CS_0( );
        //EEPROM_SCLK_0( );
        delay_us(1); // 1  
        EEPROM_CS_1( );
        delay_us(1);
        //while(!EEPROM_MISO_IS_HIGH())
        while(!PBin(4))
        { // busy test
                EEPROM_SCLK_0( );
                delay_us(100);
                EEPROM_SCLK_1( );
                delay_us(100);
        }
        EEPROM_SCLK_0( );
        EEPROM_CS_0( );
}


// Reads data stored in memory, at specified address.
u16 EEPROM_Read(u16 address)
{
        unsigned char i;
        u16 result = 0;
        EEPROM_Ewen();
        EEPROM_SCLK_0( );
        EEPROM_CS_0( );
        delay_us(100);
        EEPROM_CS_1( );
        address=(address&0x3FF)|0x1800;
        for(i = 0; i < 13; i++ )
        { // 8
                if(address & 0x1000) EEPROM_MOSI_1( );
                else EEPROM_MOSI_0( );
                delay_us(100);
                EEPROM_SCLK_1( );
                delay_us(100);
                EEPROM_SCLK_0( );
                delay_us(100);
                address <<= 1;
        }
        EEPROM_SCLK_1( );
        delay_us(100);
        EEPROM_SCLK_0( );
        delay_us(100); // 1
        //DO=1;
        delay_us(100);
        for(i = 0; i < 16; i++)
        { // 16
                EEPROM_SCLK_1( );
                delay_us(100);
                result = result << 1;
                if (EEPROM_MISO_IS_HIGH())
                {
                        result++;
                }
                EEPROM_SCLK_0( );
                delay_us(100);
        }
        EEPROM_CS_0( );
        EEPROM_Ewds();
        return(result);
}

// Writes memory location An - A0.
void EEPROM_Write(u16 address,u16 InData)
{
        unsigned char i;
        EEPROM_Ewen(); //3&#245;ê&#188;&#187;ˉê±&#214;′DDò&#187;′&#206;&#190;íDDá&#203;£&#172;
        delay_us(5);
        // 101 A9-A0
        EEPROM_Earse(address);//&#188;ó2&#187;&#188;ó&#213;aDD&#189;á1&#251;&#182;&#188;ò&#187;&#209;ù
        delay_us(5);
        EEPROM_CS_0( );
        EEPROM_SCLK_0( );
        delay_us(100);
        EEPROM_CS_1( );
        address=(address&0x3FF)|0x1400;
        for(i = 0; i < 13; i++)
        { // 8
                if(address & 0x1000)
                        EEPROM_MOSI_1( );
                else
                        EEPROM_MOSI_0( );
                delay_us(100);
                EEPROM_SCLK_1( );
                delay_us(100);
                EEPROM_SCLK_0( );
                delay_us(100);
                address<<=1;
        }
        for(i = 0; i< 16; i++)
        { // 16

                if(InData & 0x8000)
                        EEPROM_MOSI_1( );
                else
                        EEPROM_MOSI_0( );
                delay_us(100);
                EEPROM_SCLK_1( );
                delay_us(100);
                EEPROM_SCLK_0( );
                delay_us(100);
                InData<<=1;
        }
        //EEPROM_SCLK_1( );
        delay_us(100);
        EEPROM_CS_0( );
        //EEPROM_SCLK_0( );
        delay_us(1); // 1  
        EEPROM_CS_1( );
        delay_us(1);
        //while(!EEPROM_MISO_IS_HIGH())
        while(!PBin(4))
        { // busy test
                EEPROM_SCLK_0( );
                delay_us(100);
                EEPROM_SCLK_1( );
                delay_us(100);
        }
        EEPROM_SCLK_0( );
        delay_us(100);
        EEPROM_CS_0( );
        delay_us(100);
        EEPROM_Ewds(); //2&#187;DèòaD′íê&#190;íEWDS
}



在主函数中做如下测试:
        EEPROM_Ewen();
        while (1)
        {
                EEPROM_Write(0x01,0x01);
                data_read_test = EEPROM_Read(0x01);
                }

data_read_test始终返回 0xffff。
通过万用表测试 do引脚,发现该引脚始终为高,怎么都不会进入到busy状态。
请熟悉的同志帮忙看看,代码中有什么问题吗?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2017-11-19 00:36:31 | 显示全部楼层
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2017-11-19
在线时间
0 小时
发表于 2017-11-19 22:22:31 | 显示全部楼层
AT93C86 執行 Ewen, InData 應該是 1_0011_XXXX_XXXX (13 bits). 你只有送 11 bits.
回复

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2017-11-19
在线时间
0 小时
发表于 2017-11-20 01:00:57 | 显示全部楼层
AT93C86 執行 Ewen, InData 應該是 1_0011_XXXX_XXXX (13 bits). 你只有送 11 bits.
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-12-26
在线时间
8 小时
 楼主| 发表于 2017-11-21 13:50:59 | 显示全部楼层
本帖最后由 imagewxg 于 2017-11-21 13:52 编辑

datasheet上要求是11位的,100 11 xxxxxx,ORG是置高,按16位访问的。
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2016-12-26
在线时间
8 小时
 楼主| 发表于 2017-11-25 22:13:56 | 显示全部楼层
当org接高电平时,16位数据宽度,datasheet上明明写的是是10011 xxxxxx,就是不行,始终无法读写,最后改成 10011 xxxx xxxx,多加2个bit,就ok了,谢谢v100wtb,对datasheet很无语,不知自己理解的哪里有错。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-19 09:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表