打印
[技术问答]

SPI收发数据

[复制链接]
1379|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dragonjun|  楼主 | 2016-6-22 10:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
spi, ISO, ck, os
SPI自已发自已收,用库文件自带的SpiLoopbackTest()函数。
但用逻辑分析仪测试发现MOSI、MISO只有一个脚有信号,也就是只有发送,没有接收的数据,这是为什么?
沙发
稳稳の幸福| | 2016-6-30 16:46 | 只看该作者
换个例程试试,不是好几个的吗,看看都是这样吗

使用特权

评论回复
板凳
玛尼玛尼哄| | 2016-6-30 18:46 | 只看该作者
是不是因为自己发自己收,才出了问题,因为实际应用是不可能自发自收的。

使用特权

评论回复
地板
heisexingqisi| | 2016-6-30 21:33 | 只看该作者
新唐M051 spi使用程序
#include "SPI.h" 
#define DEBUGMSG printf
STATIC UINT32  g_unSpi0Rx0Data = 0, g_unSpi1Rx0Data = 0;
/****************************************
*函数名称:Spi0MasterInit
*输    入:无
*输    出:无
*功    能:SPI0初始化为主机模式
******************************************/
VOID Spi0MasterInit(VOID)
{                                    
    P1_MFP &= ~(P14_AIN4_SPI0SS | P15_AIN5_SPI0MOSI | P16_AIN6_SPI0MISO | P17_AIN7_SPI0CLK);
P1_MFP |= (SPI0SS | SPI0MOSI | SPI0MISO | SPI0CLK) ;      //使能SPI0相关引脚
ENABLE_SPI0_CLK;         //SPI0时钟使能                  
    SPI0_SSR &= ~LVL_H;           //从机选择选择信号通过低电平激活
    SPI0_CNTRL &= ~LSB_FIRST;    //优先发送/接收最高有效位
    SPI0_CNTRL &= ~CLKP_IDLE_H;      //SCLK空闲时为低电平
    SPI0_CNTRL |= TX_NEG_F;       //SDO 信号在SPICLK的下降沿改变
    SPI0_CNTRL &= ~RX_NEG_F;       //SDI 信号在SPICLK上升沿锁存
    CLKDIV &= 0xFFFFFFF0;               //HCLK_N = 0, Pclk = SYSclk/(HCLK_N+1)
    SPI0_DIVIDER &= 0xFFFF0000;         //SPIclk = Pclk/((HCLK_N+1)*2)
    SPI0_DIVIDER |= 0x00000002;   
    SET_SPI0_MASTER_MODE;            //SPI0工作在主机模式
    ENABLE_SPI0_AUTO_SLAVE_SLECT;    //使能自动从机选择
    SPI0_SSR |= SSR_ACT;      
}
/****************************************
*函数名称:Spi0Send1W
*输    入:ulData    发送的数据
          ucLength  数据长度
*输    出:无
*功    能:SPI0发送数据
******************************************/
VOID Spi0Send1W(UINT32 ulData, UINT8 ucLength)
{
    SPI0_CNTRL &= TX_NUM_ONE;      
    Spi0Length(ucLength);
    SPI0_TX0 = ulData;
    SPI0_CNTRL |= GO_BUSY;         
}

/****************************************
*函数名称:GetSlaveID
*输    入:无
*输    出:无
*功    能:获取从机ID
******************************************/
VOID GetSlaveID(VOID)
{
    Spi0Send1W(0x00000055, 0x08);
    while((SPI0_CNTRL & GO_BUSY)!=0);
    Spi0Send1W(0x00000000, 0x08);
    while((SPI0_CNTRL & GO_BUSY)!=0);
    g_unSpi0Rx0Data = SPI0_RX0;
}
/****************************************
*函数名称:Spi0Length
*输    入:ucLength 数据长度
*输    出:无
*功    能:设置SPI0数据长度
******************************************/
VOID Spi0Length(UINT8 ucLength)
{
     if(ucLength <= 0x20)
    {
        if((ucLength & 0x01) == 0)
            SPI0_CNTRL &= ~(1<<3);
        else
            SPI0_CNTRL |= (1<<3);
        if((ucLength & 0x02) == 0)
            SPI0_CNTRL &= ~(1<<4);
        else
            SPI0_CNTRL |= (1<<4);
        if((ucLength & 0x04) == 0)
            SPI0_CNTRL &= ~(1<<5);
        else
            SPI0_CNTRL |= (1<<5);
        if((ucLength & 0x08) == 0)
            SPI0_CNTRL &= ~(1<<6);
        else
            SPI0_CNTRL |= (1<<6);
        if((ucLength & 0x10) == 0)
            SPI0_CNTRL &= ~(1<<7);
        else
            SPI0_CNTRL |= (1<<7);
    }
}
/****************************************
*函数名称:Spi1SlaveInit
*输    入:无
*输    出:无
*功    能:SPI1初始化为从机
******************************************/
VOID Spi1SlaveInit(VOID)
{                              
    P0_MFP &= ~(P04_AD4_SPI1SS | P05_AD5_SPI1MOSI | P06_AD6_SPI1MISO | P07_AD7_SPI1CLK);  

P0_MFP |= (SPI1SS | SPI1MOSI | SPI1MISO | SPI1CLK) ;      //使能SPI1相关引脚
ENABLE_SPI1_CLK;
SPI1_SSR &= LTRIG_EDG;         //从机输入边沿触发
    SPI1_SSR &= ~LVL_H;          //从机选择选择信号通过低电平激活
    SPI1_CNTRL &= ~LSB_FIRST;      //优先发送/接收最高有效位
    SPI1_CNTRL &= ~CLKP_IDLE_H;      //SCLK空闲时为低电平
    SPI1_CNTRL |= TX_NEG_F;       //SDO 信号在SPICLK的下降沿改变
    SPI1_CNTRL &= ~RX_NEG_F;       //SDI 信号在SPICLK上升沿锁存
    CLKDIV &= 0xFFFFFFF0;               //HCLK_N = 0, Pclk = SYSclk/(HCLK_N+1)
    SPI1_DIVIDER &= 0xFFFF0000;         //SPIclk = Pclk/((HCLK_N+1)*2)
    SPI1_DIVIDER |= 0x00000002;
    SET_SPI1_SLAVE_MODE;          //SPI1工作在从机模式
   
    ENABLE_SPI1_INTERRUPT;        //使能SPI1中断
    NVIC_ISER |= SPI1_INT;      
    Spi1Length(8);         //设置SPI1数据长度
    SPI1_GO_BUSY;                 //等待SPI1 RX0接收信号
}   
/****************************************
*函数名称:Spi1Length
*输    入:ucLength 数据长度
*输    出:无
*功    能:设置SPI1数据长度
******************************************/
VOID Spi1Length(UINT8 ucLength)
{
     if(ucLength <= 0x20)
    {
        if((ucLength & 0x01) == 0)
            SPI1_CNTRL &= ~(1<<3);
        else
            SPI1_CNTRL |= (1<<3);
        if((ucLength & 0x02) == 0)
            SPI1_CNTRL &= ~(1<<4);
        else
            SPI1_CNTRL |= (1<<4);
        if((ucLength & 0x04) == 0)
            SPI1_CNTRL &= ~(1<<5);
        else
            SPI1_CNTRL |= (1<<5);
        if((ucLength & 0x08) == 0)
            SPI1_CNTRL &= ~(1<<6);
        else
            SPI1_CNTRL |= (1<<6);
        if((ucLength & 0x10) == 0)
            SPI1_CNTRL &= ~(1<<7);
        else
            SPI1_CNTRL |= (1<<7);
    }
}
/****************************************
*函数名称:PrintGetData
*输    入:无
*输    出:无
*功    能:打印SPI0/1接收到的数据
******************************************/
VOID PrintGetData(VOID)
{
    DEBUGMSG("Slave Get Command = %X\n", g_unSpi1Rx0Data);
    DEBUGMSG("Master Get Feed Back Data = %X\n", g_unSpi0Rx0Data);
}
/*****************************************
*函数名称:SPI1_IRQHandler
*输    入:无
*输    出:无
*功    能:SPI1中断服务函数
******************************************/
VOID SPI1_IRQHandler(VOID)
{
    SPI1_CNTRL |= SPI_IF;       //清除中断标志
    if(SPI1_RX0 == 0x55)
    {
        g_unSpi1Rx0Data = SPI1_RX0;
        SPI1_TX0 = 0x000000DA;
    }
    else
        SPI1_TX0 = 0x00000000;
    SPI1_GO_BUSY;                //等待SPI1 RX0接收信号
}
/****************************************
*函数名称:main
*输    入:无
*输    出:无
*功    能:函数主体
******************************************/
INT32 main(VOID)
{
    PROTECT_REG                //ISP下载时保护FLASH存储器
(
   PWRCON |= XTL12M_EN;      //默认时钟源为外部晶振
   while((CLKSTATUS & XTL12M_STB) == 0);   //等待12MHz时钟稳定  
      CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //设置外部晶振为系统时钟  
)
UartInit(12000000,9600);      //波特率设置为9600bps  
    Spi0MasterInit();        //SPI0初始化为主机模式
    Spi1SlaveInit();        //SPI1初始化为从机模式   
    while(1)
    {
        DEBUGMSG("Master will send 0x55 data to slave and receive 0xDA data\r\n");
        DEBUGMSG("Put AnyKey to Start Test\r\n");
        GetSlaveID();
        PrintGetData();
        printf("\r\n\r\n");
  Delayms(1000);
    }
}



使用特权

评论回复
5
neeringstu| | 2016-7-2 22:05 | 只看该作者
自己发自己收的话时钟clk能对上吗?

使用特权

评论回复
6
dentsgot| | 2016-7-3 21:33 | 只看该作者
你的这两个脚有没有连在一起呢

使用特权

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

本版积分规则

20

主题

26

帖子

0

粉丝