查看: 2926|回复: 6

[原创] 【LPC11U68】15. SSP:SPI模式

[复制链接]
  • TA的每日心情
    慵懒
    2024-4-9 17:01
  • 签到天数: 1478 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    92609
    最后登录
    2024-4-9
    发表于 2018-11-21 08:52:55 | 显示全部楼层 |阅读模式
    本帖最后由 stm1024 于 2018-11-21 09:44 编辑

    这次测试了一下LPC11U68的SSP接口,该接口可以实现多种协议:SPI、SSI或者Microwire 。其中SPI应该是应用的比较多的一种串行协议。使用SPI需要做的就是打开时钟,配置波特率,设置工作模式等。以SSP0为例,测试代码:
    1. void SPI0_Init(uint8_t mode)
    2. {
    3. uint8_t x=0;
    4.     LPC_IOCON->PIO0[2]=IOCON_FUNC1|IOCON_MODE_PULLUP;//CS  
    5.     LPC_IOCON->PIO1[29]=IOCON_FUNC1|IOCON_MODE_PULLUP;//CLK
    6.     LPC_IOCON->PIO0[9]=IOCON_FUNC1|IOCON_MODE_PULLUP;//MOSI
    7.     LPC_IOCON->PIO0[8]=IOCON_FUNC1|IOCON_MODE_PULLUP;//MISO   
    8.     LPC_SYSCTL->SYSAHBCLKCTRL|=(1UL<<11);//SSP0   
    9.     LPC_SYSCON->SSP0CLKDIV=0x01;//Peripheral clock
    10.     LPC_SYSCON->PRESETCTRL|=(1UL<<0);//Reset
    11.     LPC_SSP0->CPSR=0x08;//prescaler
    12.     //8-bit transfer,SPI, MODE3   
    13.     LPC_SSP0->CR0=0x07|(mode<<6)|(59<<8);
    14.     //baudrate=SYSCLK/SSP0CLKDIV/CPSR/(SCR+1)
    15.     //so:48000000/1/8/(59+1)=100kbps  
    16.     LPC_SSP0->ICR=0x03;
    17.     LPC_SSP0->CR1|=1UL<<1;//enable
    18.     //clear RX FIFO
    19.     while((LPC_SSP0->SR & (1UL<<2))!=0x00)x=LPC_SSP0->SR;
    20. }
    复制代码
    其实CS、MISO、MOSI或SCLK有多个针脚可供配置:
        SSP0_SSEL:    P0.2(FUNC1) P1.15(FUNC1)
        SSP0_SCK:     P0.6(FUNC2) P0.10(FUNC2)    P1.29(FUNC1)    P2.7(FUNC1)
        SSP0_MOSI:    P0.9(FUNC1) P1.12(FUNC1)
        SSP0_MISO:    P0.8(FUNC1) P1.16(FUNC1)

    这里选用的是P0.2,P1.29,P0.8,P0.9,因为这四个位置刚好在开发板的Arduino插口上挨着的:
    2018-11-21_083412.png

    然后是通讯的波特率,通过SSP时钟分频、预分频和SCR,配置为100kbps,当然配置为400kbps也行,这应该是应用的最多的两种波特率。
    由于SPI的工作原理类似于主从之间形成了一个循环移位寄存器,你给多少位数据,就能获取多少位数据,非常有意思的一种协议,以下是交换数据代码:
    1. uint8_t SPI0_SwapByte(uint8_t dat)
    2. {
    3.     uint8_t x;
    4.     LPC_SSP0->DR=dat;
    5.     while((LPC_SSP0->SR & (1UL<<2))!=0x00)//only need the most recent 1 byte
    6.         x=LPC_SSP0->DR & 0xff;
    7.     while((LPC_SSP0->SR & (1UL<<4))!=0x00);//wait to idle
    8.     return x;
    9. }
    复制代码
    上面的代码,交换完字节后,CS就会被硬件拉高。由于SPI总线的CS是由硬件拉低和拉高的,在时序上似乎并没有像STM32那样,使用软件控制的方式那么直观,通读了user manual整章节,也没有发现关于SSEL的软件控制方式,这个代码并不能实现多字节的传输,在多字节发送的时候就有点麻烦。

    在帖子:https://www.nxpic.org.cn/module/forum/thread-606606-1-1.html?qd中,提到了用一般的GPIO口做CS,这个自然没问题,但是我总感觉NXP作为一个具有这么多年芯片设计的大厂,不会想到用这种ugly的方式来实现,肯定有别的方法。

    经过测试,我认为我找到了一个合理的解决方法,那就是监控总线状态,只要FIFO中有数据,SSP就会传输,则总线在处于Busy,CS一定是拉低的,一旦传输完成,下一个时钟周期CS就会被硬件拉高,标识传输完成。
    首先, 丢出多字节发送的代码:
    1. //len<=8
    2. void SPI0_Swap(uint8_t* txbuff,uint8_t* rxbuff,int8_t len)
    3. {
    4.     uint8_t i;
    5.     for(i=0;i<len;i++)
    6.     {
    7.         LPC_SSP0->DR=txbuff[i];
    8.         rxbuff[i]=LPC_SSP0->DR & 0xff;
    9.     }
    10.     while((LPC_SSP0->SR & (1UL<<4))!=0x00);//wait to idle
    11. }
    复制代码
    LPC11U68的SSP带有FIFO,好像是8帧,如果你不停地给DR寄存器中写入数据,则在FIFO为空之前,CS是会一直被拉低的,直到总线传输完成。
    以W25Q32这种SPI接口的Flash为例:
    2018-11-17_081704.png

    读取JEDEC ID的代码:
    1. uint32_t W25Q32_JEDEC_ID(void)
    2. {
    3.     uint8_t cc[4]={0x9f,0x00,0x00,0x00};
    4.     SPI0_Swap(cc,cc,4);
    5.     return (cc[1]<<16)|(cc[2]<<8)|(cc[3]);
    6. }
    复制代码
    结果应该是:
    2018-11-17_081518.png


    通过逻辑分析仪抓数据:
    如果采用反复调用单字节交换的方式:
    2018-11-16_200653.png

    可以看到,MISO中的数据是不对的,因为CS有短暂的时间被拉高。
    如果换第二种方式,就没有什么问题了:
    2018-11-16_201512.png

    同样可以看到,CS在这四个字节传输时一直处于拉低状态,而且返回的字节也符合文档的说明。最后还有一个写字节的时序,涉及到了三个操作,前面0x06和后面的0x04分别是允许写入和锁止写入,中间是实际的写字节,看CS的确实都拉高了
    2018-11-20_171904.png


    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-4-9 17:01
  • 签到天数: 1478 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    92609
    最后登录
    2024-4-9
     楼主| 发表于 2019-4-6 10:56:13 | 显示全部楼层
    自己顶一下
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-4-9 17:01
  • 签到天数: 1478 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    92609
    最后登录
    2024-4-9
     楼主| 发表于 2019-4-6 10:56:21 | 显示全部楼层
    自己顶一下
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-18 10:54
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    40

    主题

    262

    帖子

    0

    高级会员

    Rank: 4

    积分
    977
    最后登录
    2024-3-10
    发表于 2020-9-18 23:02:50 | 显示全部楼层
    谢谢你
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-4-9 17:01
  • 签到天数: 1478 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    92609
    最后登录
    2024-4-9
     楼主| 发表于 2020-9-18 23:03:38 | 显示全部楼层
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-18 10:54
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    40

    主题

    262

    帖子

    0

    高级会员

    Rank: 4

    积分
    977
    最后登录
    2024-3-10
    发表于 2020-9-19 14:37:05 | 显示全部楼层
    spi的速率可以达到1M级别的啊,哪里仅仅是k的速率
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2020-12-18 10:54
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    40

    主题

    262

    帖子

    0

    高级会员

    Rank: 4

    积分
    977
    最后登录
    2024-3-10
    发表于 2020-9-19 14:51:39 | 显示全部楼层
    还是gpio控制cs比较灵活了
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-20 13:26 , Processed in 0.124275 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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