10 裸机imx6ull与jz2440通过spi连接,数据出现丢码问题

主机是jz2440,从机是imx6ull,现在从机传来的数据主机接收不全,中间总是出现丢码的状况,不知道问题的原因........

jz2440和imx6ull都是裸机,6ull是野火的pro开发板。我将imx6ull的ECSPI3配置成slave模式,速率5Mhz,片选使用的是ECSPI3_SS0,硬件片选,ECSPI3中的CONFIGREG寄存器全部为零(POL=PHA=0)代码如下:

#include "spi.h"

void spi_master_init(void){
}

void spi_slave_init(void){
	/*初始化SPI从机引脚*/
	IOMUXC_SetPinMux(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0);    /*复用为ECSPI3_SCLK */
    IOMUXC_SetPinMux(IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0);       /*复用为ECSPI3_MOSI */
	IOMUXC_SetPinMux(IOMUXC_UART2_RTS_B_ECSPI3_MISO, 0);      /*复用为ECSPI3_MISO*/
	IOMUXC_SetPinMux(IOMUXC_UART2_TX_DATA_ECSPI3_SS0, 0);        /*复用为ECSPI3_SS0*/
   
    IOMUXC_SetPinConfig(IOMUXC_UART2_RX_DATA_ECSPI3_SCLK, 0x10B0);
    IOMUXC_SetPinConfig(IOMUXC_UART2_CTS_B_ECSPI3_MOSI, 0x10B0);
	IOMUXC_SetPinConfig(IOMUXC_UART2_RTS_B_ECSPI3_MISO, 0x1090);
    IOMUXC_SetPinConfig(IOMUXC_UART2_TX_DATA_ECSPI3_SS0, 0x10B0);

	//GPIO2->GDIR &= ~(1<<15);
	
	ECSPI3->CONREG = 0;  //清零
	ECSPI3->CONREG |= (1<<0) | (11<<12) | (7<<20);     //只有使能spi模块才能设置其他寄存器,设置通道0,
	                                                    //从模式,突发访问8位,速率5Mhz
	ECSPI3->CONFIGREG = 0;
}

void spi_slave_write(unsigned int data){
	unsigned int txdata = data;
	ECSPI3->CONREG &= ~(3<<18);
	ECSPI3->CONREG |= (0<<18);
	while(!(ECSPI3->STATREG));
	ECSPI3->TXDATA = txdata;
}

然后imx6ull的main函数中,先为测试用的data2[1000]数组创建了测试数据,数组是全局变量;在while循环中将测试数据发送出去,每次发送成功就打印一次“transfer”;代码如下:

int main(){
	
	clk_root();    /*spi根时钟为60Mhz*/
	clk_enable();   /* 使能外设时钟 */
        led_init();     /* 初始化LED */
	uart_init();
	spi_slave_init();
	
	put_s("spi test start........\n\r");
	unsigned int i =0;
	for(i = 0; i<1000; ++i){
		data2[i] = i;        //设置data2数组中的数据
	}
	put_s("data completed........\n\r");
	i = 0;
	put_s("start spi slave transfer.\n\r");
	while(i<1000){
		spi_slave_write(data2[i]);
		put_s("transfer\n\r");
		++i;
	}
	put_s("spi slave transfer end.\n\r");
	return 0;
}
在jz2440上,设置spi1为master模式,速率5Mhz,GPG2配置为输出IO作为片选引脚,配置代码如下:
#include "s3c2440_soc.h"
#include "adc.h"

void SPI_init(void){
	/*总共有4条线
	*cs        GPG2    output
	*SPIMISO1  GPG5    
	*SPIMOSI1  GPG6
	*SPICLK1   GPG7
	*/	
	GPGCON &= ~((3<<4)|(3<<10)|(3<<12)|(3<<14));
	GPGCON |= ((1<<4)|(3<<10)|(3<<12)|(3<<14));
	GPGDAT |= (1<<2);   //空闲时为高
	
	
	/*设置spi控制器*/
	 /* [6:5] : 00, polling mode
    * [4]   : 1 = enable 
    * [3]   : 1 = master
    * [2]   : 0  sclk初值为0
    * [1]   : 0 = format A SCLK上升沿有效 
    * [0]   : 0 = normal mode
    */
        SPCON1 = 0;
	SPCON1 = (1<<3)|(1<<4);
	SPPRE1 = 4;      //5M
		
}

unsigned char SPIRecvByte(void){
    SPTDAT1 = 0xff;    
    while (!(SPSTA1 & 1)); 
    return SPRDAT1;    
}
jz2440的main函数用来接收imx6ull发来的1000个测试数据,代码如下:
#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"
#include "timer.h"
#include "adc.h"    //包涵spi的相关函数

unsigned char a[1000] = {0};
int main(void)
{
	unsigned int i = 0;
	SPI_init();
	timer_init();
	print1();     //打印语句,此处查看代码运行到哪
	while(i < 1000){
		/*cs片选信号为低时imx6ull被选中,之后cs信号输出为低,直到下一轮转换*/
		GPGDAT &= ~(1<<2);
		a[i] = SPIRecvByte();
		puts("now is work\n\r");      //每次传输成功后的打印语句,不加会出现问题2
	        GPGDAT |= (1<<2);
		++i;
	}
	
	i = 0;
	for(i=0;i<1000;i++){
		printHex(a[i]);      //将数据以16进制输出
		puts(" ");
	}

	return 0;
}
目前有两个问题:问题1  连线完好后,先启动imx6ull,会打印一次 transfer ,然后等待主机信号;接下来启动jz2440,然后得到的数据中间可以明显看出来丢码。结果如下图1,后面输出的 94 应该是imx6ull通电时 MOSI引脚上的电平状态,因为我在imx6ull运行完毕后没有断电,直接重新启动jz2440得到的串口输出也都是 94(有时候也是E7)而且在实验时我观察到imx6ull打印的 transfer 会比jz2440打印的 now is work 提前一会儿结束;请问该如何解决丢码的问题?
      问题2:在jz2440的main函数中,如果不在while中加入 now is work 打印语句,jz2440就很快打印出其他的数据,如图2,很多重复项,不知道是怎么回事?
希望老师能指点迷津!!!
图一:
attachments-2020-05-UgPcwgIJ5ebd15dab7635.png
图二:
attachments-2020-05-0LEFFhyS5ebd163d62299.png





请先 登录 后评论

最佳答案 2020-05-20 09:11

已解决,主机加入一毫秒延时即可

请先 登录 后评论

其它 1 个回答

星星之火 - 嵌入式工程师
擅长:答疑助手

如果有示波器建议抓波形看看 调SPI和II2一般离不开

请先 登录 后评论