Microchip
直播中

胡劝侨

7年用户 135经验值
私信 关注
[问答]

SPI接收数据移位,误差解不起作用,无极性误差

您好,我正试图通过SPICI与微芯片上的23 LC1024 SRAM进行通信,用一个DSPIC33 E。我可以在几个不同的插件上写入和读取数据,我的示波器总是给我显示正确的数据(我在某个地址写的东西,在同一个地址上是可读的),但是,当我得到这个数据时收到的数据在我的PIC,所有的数据是一个位移到右边。我的第一个想法是:也许时机不对。但是,我尝试了所有不同的定时,我尝试了所有组合的输入采样相位,时钟边沿和时钟极性。(SMP,CKE和CKP),但问题仍然存在。我在勘误表中看了一下,在那里,当帧模式被启用时,SMP=1(输入数据在末尾被采样),那么可能出现的问题是接收到的数据由一位移位到右边。我没有启用帧模式,我执行了清除SMP的命令。例如:我将以下小数写入SRAM:120, 7, 9、100(十六进制示波器:78, 07、09, 64)=0B01111000、0B000、0111、0B000、1001、0B01100100,我在LCD(小数)上得到:60, 3, 132、178=0B0111100、0B00 000、11、0B10000、0B10110010,所以整个数据一起我从示波器上附加了两个截图。我还把SPI时钟速度从20MHz降低到10,没有改进。因为范围是读取正确的数据,所以我假设整个事情是正确的。这是我的代码和配置:CONFIG:TestCal码。一个解决方案是接收所有数据并将它们转换,但我认为这不是一个好的解决方案。LCD工作正常。我也像数据表中的命令一样做了电源接通状态,所以可能有人知道一个工作区,甚至一个我看不到的错误。感谢任何帮助,多谢!我不能上传图片,这就是为什么我在DoopPoad上直接上传它们:DoDopRAPAD.NET/FILE/U/70818/NMZSKRNKKPNG.HTMDECTURPLADAD.NET/FILE/U/70818/O27 D7S2JYPNG.HTM
                    
                    
以上来自于百度翻译

               
                                                                                      以下为原文

                                                                            Hello at all,

I am trying to communicate with the 23LC1024 SRAM from Microchip over SPI with a dsPIC33E.
I can write and read data at several different adresses, my oscilloscope always shows me the correct data(what I've written at a certain adress, is readable at the same adress)
BUT, when I get this received data in my pic, all the data is shifted one bit to the right. My first thought was: maybe the timings are wrong. But then I tried all different timings, I tried all combinations for the Input Sample Phase, Clock Edge and Clock Polarity. (SMP, CKE and CKP) but the problem still persits. I had a look in the errata, where it says that when frame Mode is enabled AND SMP=1 (input data sampled at the end) then there could be the trouble that received data is shifted to the right by one bit. I don't have frame Mode enabled and I did the recommandation to clear SMP. Problem still there.

For example: I write the following decimals into the SRAM:
120, 7, 9, 100   ( hex oscilloscope: 78, 07, 09, 64)
= 0b01111000, 0b00000111, 0b00001001, 0b01100100

What I get on my LCD (decimals):
60, 3, 132, 178
= 0b00111100, 0b00000011, 0b10000100, 0b10110010

So the whole data together is shifted one bit to the right.

I attached two screenshots from my oscilloscope.
Also I reduced the SPI Clock Speed from 20Mhz down to 10-no amelioration.
Since the Scope is reading the correct data, I am assuming that the whole thing works correctly.
Here is my code and configurations:

Config:
    SPI1STATbits.SPIEN=0;
    SPI1CON1bits.DISSCK=0; // internal spi clock enabled
    SPI1CON1bits.DISSDO=0; // SDO pin used by SPI
    SPI1CON1bits.MODE16=0; // 8 bits communication
   
    SPI1CON1bits.MSTEN=1; // master mode
   
    SPI1CON1bits.CKP=0; // idle Low
    SPI1CON1bits.SMP=0; // sampled at the middle of output data time
    SPI1CON1bits.CKE=1; // falling edge
   
    // 20MHz ?
    SPI1CON1bits.SPRE=0b110; // secondary 2:1
    SPI1CON1bits.PPRE=0b11; // primary 1:1
   
    SPI1CON2bits.FRMEN=0;
    SPI1CON2bits.SPIBEN=0; //enhanced mode disabled
    SPI1BUF=0x00; // buffer to zero
    SPI1STATbits.SPITBF=0; // clear BF
    SPI1STATbits.SPIEN=1; // enable spi
    SPI1STATbits.SPITBF=0; // clear BF

void Write_RAM(long adress, uint8_t data[], unsigned int n_bytes){
    long adresscut;
   
    CS_RAM=0;
    transmit_SPI1(RAM_WRITE);
   
    //write Adress 3 bytes
    adresscut=((adress & 0xFF0000) >> 16);
    transmit_SPI1(adresscut);
    //
    adresscut=((adress & 0x00FF00) >> 8);
    transmit_SPI1(adresscut);
    //
    adresscut=((adress & 0x00FF00) >> 0);
    transmit_SPI1(adresscut);
   
    int i;
    for(i=0;i         transmit_SPI1(data);
    }
        
    CS_RAM=1;
}

void Read_RAM(long adress, uint8_t data[], unsigned int n_bytes){
    long adresscut;

    CS_RAM=0;
    transmit_SPI1(RAM_READ);
   
    //write Adress 3 bytes
    adresscut=((adress & 0xFF0000) >> 16);
    transmit_SPI1(adresscut);
    //
    adresscut=((adress & 0x00FF00) >> 8);
    transmit_SPI1(adresscut);
    //
    adresscut=((adress & 0x00FF00) >> 0);
    transmit_SPI1(adresscut);
   
    int i;

    for(i=0;i         data=Receive_SPI1();
    }

    CS_RAM=1;
}

void transmit_SPI1(uint8_t wert){
   
    unsigned char dummy;
   
    dummy=SPI1BUF;
    SPI1BUF=wert;
    while(SPI1STATbits.SPIRBF==0)
        ; //wait
    dummy=SPI1BUF;
}

uint8_t Receive_SPI1(){
    unsigned char dummy;
    //SPI1STATbits.SPIRBF=0;
    //dummy=SPI1BUF; //
   
    dummy=SPI1BUF;
    SPI1BUF=0xFF; // Dummy byte
    while(SPI1STATbits.SPIRBF==0)
        ; //wait
    //SPI1STATbits.SPIRBF=0;
   // dummy=SPI1BUF;
    return SPI1BUF;
}

test code:

    init_RAM();
   
    uint8_t datax[]={120,7,9,100};
    uint8_t receivedata[10];
   
    Write_RAM(0x100111, datax, 4);
     
    Read_RAM(0x100111,receivedata,4);

    int i;
    for(i=0;i<4;i++){
        writeINTLCD(receivedata);
        writeLCD(";");
        waitms(2000);
    }

One solution would be to receive all the data and shift them, but thats in my opinion not a nice solution.

The LCD works right. Also I did the power on state like recommanded in the datasheet.
So maybe anyone knows a workarround or even an error I can't see ?
Would appreciate any help,

Many thanks!

I can't upload pictures, thats why I uploaded them on directupload:
directupload.net/file/u/70818/nmzskrnk_png.htm
directupload.net/file/u/70818/o27d7s2j_png.htm

回帖(2)

薄坤坤

2018-8-28 15:47:21
就我个人而言,我不喜欢创建两个函数来与SPI外设交互——只使用一个,或者通过一个哑参数和/或忽略返回结果。需要猜测SMP、CKP和CKE设置。看看数据表中的时序图(它通常显示了组合的AL,而不是麻烦地查找您尚未指定的设备的数据表),并将其与来自SRAM的信号的时序图进行比较。线路)到SRAM的线路。SCK线与从属活动的杂散跃迁可能造成浩劫。苏珊
                    
                    
以上来自于百度翻译

               
                                                                                      以下为原文

                                                                            Personally I don't like creating two functions to interact with a SPI peripheral - just use one and either pass a dummy parameter and/or ignore the return result.
What you describe is almost certainly to do with the relationship between the clock edges and when the MCU is sampling the SDI line.
You never need to guess the SMP, CKP and CKE settings. Look at the timing diagram in the data sheet (which normally shows al of the combinations - not bothered to look up the data sheet for your device which you have not specified anyway) and compare that to the timing diagram of the signals from the SRAM.
Also make sure that you use the CS (or equivalent) line to the SRAM. Stray transitions on the SCK line with the slave active can cause havoc.
Susan
举报

薄坤坤

2018-8-28 16:15:15
我认为勘误表36更可能是你的问题。(勘误表38)可以应用位与你所说的CKP/CKE组合不匹配。在这种情况下,你应该远离框架模式。)至于“CS”行,回过头来看,我看到你有'CSYRAM=0 '等,我没有解释为控制连接到SRAM的CPIN的端口引脚——现在是有意义的。(我个人喜欢用PIN的名字来编程的原因之一,并用注释来说明PIN的功能是什么。)苏珊
                    
                    
以上来自于百度翻译

               
                                                                                      以下为原文

                                                                            I think that Errata #36 is more likely your problem. (Errata #38 may apply bit doesn't match the CKP/CKE combination you say you are using. You should be staking well away from framing mode in this situation.)
AS for the CS line, looking back I see that you have 'CS_RAM=0' etc. which I didn't interpret as controlling the port pin connected to the CS pin of the SRAM - makes sense now though. (One of the reasons why I personally like to program with the name of the pin and use comments to say what the pin's function is.)
Susan
举报

更多回帖

发帖
×
20
完善资料,
赚取积分