打印

请帮我看看这个51模拟SPI的程序出了什么问题

[复制链接]
1680|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jyynl|  楼主 | 2014-4-8 18:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 jyynl 于 2014-4-8 18:52 编辑

时序图如下




我是用的51单片机做MCU,模拟SPI,用的是11.0592的晶振
我写的程序如下


//写入控制寄存器
void Write_CommandReg(uchar add,uchar com)
{
        
        uchar i;
        uchar mark;
        cs=0;
        mark=0x80;
        _nop_();
        for(i=0;i<8;i++)
        {
                sck=0;
                if(add&mark)
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
                sck=1;
                mark>>=1;
        }
        mark=0x80;
        for(i=0;i<8;i++)
        {
                sck=0;
                if(com&mark)
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }

                sck=1;
                mark>>=1;
        }
        _nop_();
        cs=1;
}

//读取控制寄存器
uchar Read_CommandReg(uchar add)
{
        
        uchar i;
        uchar mark;
        uchar readdata;
        cs=0;
        mark=0x80;
        readdata=0;
        _nop_();
        for(i=0;i<8;i++)
        {
                sck=0;
                if(add&mark)
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
                sck=1;
                mark>>=1;
        }
        _nop_();
        for(i=0;i<8;i++)
        {
                readdata<<=1;        
                sck=0;
                sck=1;
                if(MISO)
                {
                        readdata|=0x01;
                }               
        }
        _nop_();
        cs=1;
        return(readdata);
        
}



//写入数据寄存器
void Write_DataReg(uchar add,uint dat)
{
        
        uchar i;
        uchar mark;
        uint marklong;
        cs=0;
        mark=0x80;
        marklong=0x8000;
        _nop_();
        for(i=0;i<8;i++)
        {
                sck=0;
                if(add&mark)
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
                sck=1;
                mark>>=1;
        }

        for(i=0;i<16;i++)
        {
                sck=0;
                if(dat&marklong)
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }

                sck=1;
                marklong>>=1;
        }
        _nop_();
        cs=1;
}

//读取数据寄存器
uint Read_DataReg(uchar add)
{

        uchar i;
        uchar mark;
        uint readdata;
        cs=0;
        mark=0x80;
        readdata=0;
        _nop_();
        for(i=0;i<8;i++)
        {
                sck=0;
                if(add&mark)
                {
                        MOSI=1;
                }
                else
                {
                        MOSI=0;
                }
                sck=1;
                mark>>=1;
        }
        _nop_();
        for(i=0;i<16;i++)
        {
                readdata<<=1;        
                sck=0;
                sck=1;
                if(MISO)
                {
                        readdata|=0x0001;
                }               
        }
        _nop_();
        cs=1;
        return(readdata);
        
}

希望各位高手给指正一下

相关帖子

沙发
jyynl|  楼主 | 2014-4-8 18:47 | 只看该作者
为什么底色是绿的……

使用特权

评论回复
板凳
cer1991| | 2014-4-8 20:42 | 只看该作者
SCK=0,SCK=1后面都需要加个延迟函数

使用特权

评论回复
地板
cer1991| | 2014-4-8 20:50 | 只看该作者
检查下 MOSI和MISO线是否定义反了

使用特权

评论回复
5
jyynl|  楼主 | 2014-4-8 20:55 | 只看该作者
本帖最后由 jyynl 于 2014-4-8 20:56 编辑
cer1991 发表于 2014-4-8 20:50
检查下 MOSI和MISO线是否定义反了

加了延时函数也不行,因为怕弄反所以每次MOSI和MISO我都是先用一种试试然后再把这两引脚定义互换一下,比如MOSI=P^0;MISO=P^1;然后互换变成MOSI=P^1;MISO=P^0;这样应该就排除了这个可能了吧

使用特权

评论回复
6
cer1991| | 2014-4-8 20:58 | 只看该作者
MOSI=P^0;MISO=P^1 这是什么语句?现在情况是编译成功,实际烧写过后没反应么?

使用特权

评论回复
7
jyynl|  楼主 | 2014-4-8 21:04 | 只看该作者
cer1991 发表于 2014-4-8 20:58
MOSI=P^0;MISO=P^1 这是什么语句?现在情况是编译成功,实际烧写过后没反应么? ...

哦,回复的时候打错了,是MOSI=P1^1;MISO=P1^0;以及MOSI=P1^0;MISO=P1^1;这样互换。是的,编译通过可是写完没反应

使用特权

评论回复
8
cer1991| | 2014-4-8 21:11 | 只看该作者
你在在开发板上调试?还是自己设计的硬件调试?你确定硬件方面没有问题吧?

使用特权

评论回复
9
cer1991| | 2014-4-8 21:13 | 只看该作者
你确定CS线,和SCK线 IO口选择没有问题吧?

使用特权

评论回复
10
jyynl|  楼主 | 2014-4-8 21:21 | 只看该作者
cer1991 发表于 2014-4-8 21:11
你在在开发板上调试?还是自己设计的硬件调试?你确定硬件方面没有问题吧? ...

是用的51开发板和电力线载波芯片连接,芯片是按典型连接弄的。因为是开发板上面的接口有些是复用的,不知道会产生多大的影响,我用的P1这几个接口在开发板上是接锁存器的,应该没什么大的影响吧

使用特权

评论回复
11
jyynl|  楼主 | 2014-4-10 10:11 | 只看该作者
cer1991 发表于 2014-4-8 21:13
你确定CS线,和SCK线 IO口选择没有问题吧?

给他们芯片公司的人看了说是spi的时序不对,但是怎么改不给讲……

使用特权

评论回复
12
nickyamw| | 2014-4-10 10:37 | 只看该作者
MOSI=P1^1;
这个是怎样定义的?sbit MOSI=P1^1;?

使用特权

评论回复
13
jyynl|  楼主 | 2014-4-10 18:39 | 只看该作者
nickyamw 发表于 2014-4-10 10:37
MOSI=P1^1;
这个是怎样定义的?sbit MOSI=P1^1;?

恩,是的。程序的问题应该是时序上的

使用特权

评论回复
14
cer1991| | 2014-4-10 21:16 | 只看该作者
jyynl 发表于 2014-4-10 10:11
给他们芯片公司的人看了说是spi的时序不对,但是怎么改不给讲……

仔细看了时序图,估计问题出在SDO线上。看时序的样子,读数据的时候应该在SCK=0的时期的一半的时候读,不应该在SCK=1的时候读,你按照这个思路改下:SCK=0;_NOP_();读MISO信号高低;_nop_();SCK=1;_nop_();_nop_();

使用特权

评论回复
15
cer1991| | 2014-4-10 21:20 | 只看该作者
jyynl 发表于 2014-4-10 18:39
恩,是的。程序的问题应该是时序上的

还有就每个SCK=0或者SCK=1后面加2个nop函数吧

使用特权

评论回复
16
jyynl|  楼主 | 2014-4-11 11:06 | 只看该作者
cer1991 发表于 2014-4-10 21:16
仔细看了时序图,估计问题出在SDO线上。看时序的样子,读数据的时候应该在SCK=0的时期的一半的时候读,不 ...

调试出来了,问题出在等待时间不够上面…它倒不是说是在SCK等于0的一半时读,因为SCK是MCU控制,而SDO是从设备用来输出给主设备的,这中间有个时间差,它的意思是当SCK的下降沿到来从设备会将数据输出到SDO线上,主设备读,这中间需要一个时间等信号稳定的输出了再读,而上升沿不会对从设备产生什么影响,把SCK=1放到后面我也试过不行,多加几个延时才行…本来看着他的那个时间要求表都是ns级的,觉得51用11.0592的晶振足够慢了就没多加延时……

使用特权

评论回复
17
chuying1990| | 2014-4-12 12:10 | 只看该作者
jyynl 发表于 2014-4-11 11:06
调试出来了,问题出在等待时间不够上面…它倒不是说是在SCK等于0的一半时读,因为SCK是MCU控制,而SDO是 ...

请问,您说的等待时间不够,那是把延时加到CS=0;之后吗?还有就是,我看了你的程序,有一个地方不明白,你说全发送1来检验是否能工作,这种检测应该需要两片MI200E吧?一个发送,一个接受?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

102

帖子

0

粉丝