精华内容
下载资源
问答
  • S32K144 SPI速率

    2020-03-17 15:49:45
    S32K144单片机的SPI速率的调试与提升,将遇到的困惑与问题和怎么解决的跟大家分享,让程序猿们少走弯路。
  • S32K144_SPI.zip

    2019-08-16 17:59:14
    S32K144SPI的驱动程序代码,已调试通过。
  • S32K144芯片基于FreeRTOS的SPI通信,有问题可以联系我
  • 手头的项目要使用NXP的S32K144,之前从没用过,这个芯片的技术支持不是很多,LPSPI的使用,自己分析了官方的HAL库,慢慢调试总结的配置详解,里面有代码和我用示波器检测的波形图,很清晰,一看就明白了;
  • 基于S32K144的CANbootloader.自己实现的s32k144库函数和IAP(CAN)功能. 目录中包含自己编写的CANbootloader上位机,CANbootloader工程文件和APP工程测试文件.
  • S32K系列S32K144学习笔记——模拟SPI

    千次阅读 2019-04-12 09:07:47
    S32K系列S32K144学习笔记——模拟SPI 本例程基以下如图所示接口操作,MCU为S32K144,开发平台S32DSworkspace 功能描述:模拟SPI,MSIO–>PTD16,MOSI–>PTB4,SCLK–>PTD15,CSB–>PTB5,FSCB–>PTE12 ...

    一用S32K144苦似海,道友,能不用,千万不去用。

    本例程基以下如图所示接口操作,MCU为S32K144,开发平台S32DSworkspace
    功能描述:模拟SPI,MSIO–>PTD16,MOSI–>PTB4,SCLK–>PTD15,CSB–>PTB5,FSCB–>PTE12
    如有错误,麻烦帮忙指出,谢谢!
    在这里插入图片描述

    #include "S32K144.h" /* include peripheral declarations S32K144 */
    #include "s32_core_cm4.h"
        
    #define CMT_SCLK_GPIO 15 //PD15
    #define CMT_CSB_GPIO  5  //PB5
    #define CMT_FCSB_GPIO 12  //PE12
    #define CMT_MIOS_GPIO 16 //PD16
    #define CMT_MOIS_GPIO 4  //PB4
    
    #define cmt_spi_csb_1()        (PTB-> PDOR |= 1<<CMT_CSB_GPIO)
    #define cmt_spi_csb_0()        (PTB-> PDOR &= ~(1<<CMT_CSB_GPIO))
    
    #define cmt_spi_fcsb_1()       (PTE-> PDOR |= 1<<CMT_FCSB_GPIO)
    #define cmt_spi_fcsb_0()       (PTE-> PDOR &= ~(1<<CMT_FCSB_GPIO))
    
    #define cmt_spi_sclk_1()       (PTD-> PDOR |= 1<<CMT_SCLK_GPIO)
    #define cmt_spi_sclk_0()       (PTD-> PDOR &= ~(1<<CMT_SCLK_GPIO))
    
    #define cmt_spi_sdio_1()       (PTB-> PDOR |= 1<<CMT_MOIS_GPIO)
    #define cmt_spi_sdio_0()       (PTB-> PDOR &= ~(1<<CMT_MOIS_GPIO))
    #define cmt_spi_sdio_read()    (PTB->PDIR & (1<<CMT_MOIS_GPIO))
    
    #define cmt_spi_sdio_in()      {PCC->PCCn[PCC_PORTB_INDEX ] |= PCC_PCCn_CGC_MASK;PTB->PDDR &= ~(1<<4);PORTB->PCR[4] = 0x00000100;}
    #define cmt_spi_sdio_out()     {PCC->PCCn[PCC_PORTB_INDEX ] |= PCC_PCCn_CGC_MASK;PTB->PDDR |= (1<<4);PORTB->PCR[4] = 0x00000100;}
    
    void WDOG_disable (void)
    {
    	WDOG->CNT=0xD928C520; 	 //解锁看门狗
    	WDOG->TOVAL=0x0000FFFF;	 //把时间配置为最大
    	WDOG->CS = 0x00002100;   //关闭看门狗
    }
    
    void SOSC_init_8MHz(void)
    {
      	SCG->SOSCDIV=0x00000101;  //SOSCDIV1 & SOSCDIV2 =1:  分频/1
      	SCG->SOSCCFG=0x00000024;  //Range=2: 选择晶体振荡器的中频范围 (SOSC 1MHz-8MHz)
                                  // HGO=0:   控制晶体振荡器的工作功率模式 --低功率模式
                                  // EREFS=1: 外部参考选择OSC内部晶体振荡器
      	while(SCG->SOSCCSR & SCG_SOSCCSR_LK_MASK); //等待SOSCCSR解锁 寄存器解锁后才可写入
      	SCG->SOSCCSR=0x00000001;  // LK=0:  SOSCCSR可以写
                                  // SOSCCM=0: 系统OSC时钟监视器被禁用
                                  // SOSCEN=1: 启用系统OSC
      	while(!(SCG->SOSCCSR & SCG_SOSCCSR_SOSCVLD_MASK)); //等待系统OSC成功启用,输出时钟有效
    }
    
    
    void SPLL_init_160MHz(void)
    {
      	while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); //等待SPLLCSR寄存器解锁  寄存器解锁后才可写入
      	SCG->SPLLCSR = 0x00000000;  // LK=0: SPLLCSR可以写入
      	  	  	  	  	  	  	    // SPLLEN=0: SPLL禁用
      	SCG->SPLLDIV = 0x00000302;  // SPLLDIV1 分频/2; SPLLDIV2 分频/4
      	SCG->SPLLCFG = 0x00180000;  // PREDIV=0: 锁相环参考时钟分频因子
                                    // MULT=24:  SPLL时钟频率的乘法因子
                                    // SPLL_CLK = 8MHz / 1 * 40 / 2 = 160 MHz    SPLL_CLK = (VCO_CLK)/2  VCO_CLK = SPLL_SOURCE/(PREDIV+1)*(MULT+16)
      	while(SCG->SPLLCSR & SCG_SPLLCSR_LK_MASK); //等待SPLLCSR寄存器解锁  寄存器解锁后才可写入
      	SCG->SPLLCSR = 0x00000001;  // LK=0: SPLLCSR可以写入
                                    // SPLLCM=0: SPLL时钟监视器被禁用
                                    // SPLLEN=1: 开启SPLL
      	while(!(SCG->SPLLCSR & SCG_SPLLCSR_SPLLVLD_MASK)); //等待SPLL成功启用,输出时钟有效
    }
    
    void NormalRUNmode_40MHz (void)
    {
    	SCG->RCCR=SCG_RCCR_SCS(6)   // SPLL做为系统时钟源
    	|SCG_RCCR_DIVCORE(0b11)     // DIVCORE=3, 分频/4: Core clock = 160/4 MHz = 40 MHz
    	|SCG_RCCR_DIVBUS(0b11)      // DIVBUS=3, 分频/4: bus clock = 160/4 MHz = 40 MHz
    	|SCG_RCCR_DIVSLOW(0b111);   // DIVSLOW=7, 分频/8: SCG slow, flash clock= 160/8 MHz = 20MHZ
    	while (((SCG->CSR & SCG_CSR_SCS_MASK) >> SCG_CSR_SCS_SHIFT ) != 6) {}//等待系统时钟源成功选择SPLL
    }
    /*********************************************************************
    * 函数原型:void SPI_GPIO_Init(void)
    * 功   能:SPI接口实始化
    * 输入参数:无
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void SPI_GPIO_Init(void)
    {
    	PCC->PCCn[PCC_PORTB_INDEX ] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTB */
    	PTB->PDDR |= (1<<4) | (1<<5);    /* Port B4/B5: Data Direction= output */
    	PORTB->PCR[4] = 0x00000100; /* Port B4: MUX = GPIO */
    	PORTB->PCR[5] = 0x00000100; /* Port B5: MUX = GPIO */
    
    	PCC->PCCn[PCC_PORTD_INDEX ] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTD */
    	PTD->PDDR |= (1<<15);    /* Port D15: Data Direction= output */
    	PORTD->PCR[15] = 0x00000100; /* Port D15: MUX = GPIO */
    	PTD->PDDR &= ~(1<<16);    /* Port D16: Data Direction= input */
    	PORTD->PCR[16] = 0x00000110; /* Port D16: MUX = GPIO, input filter enabled */
    
    	PCC->PCCn[PCC_PORTE_INDEX ] |= PCC_PCCn_CGC_MASK; /* Enable clock for PORTE */
    	PTE->PDDR |= (1<<12);    /* Port E8: Data Direction= output */
    	PORTE->PCR[12] = 0x00000100; /* Port E8: MUX = GPIO */
    	//FCSB拉高
    }
    /*********************************************************************
    * 函数原型:void cmt_spi_delay(void)
    * 功   能:不精准的简单延时
    * 输入参数:无
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_delay(void)
    {
    	long int n = 20;
    	while(n--);
    }
    /*********************************************************************
    * 函数原型:void cmt_spi_delay_us(void)
    * 功   能:不精准的简单延时
    * 输入参数:无
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_delay_us(void)
    {
    	volatile int n = 8;
    	while(n--);
    }
    /*********************************************************************
    * 函数原型:void cmt_spi_init(void)
    * 功   能:SPI初始化
    * 输入参数:无
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_init(void)
    {
    	SPI_GPIO_Init();
    
    	cmt_spi_csb_1();   /* CSB has an internal pull-up resistor */
    
    	cmt_spi_sclk_0();   /* SCLK has an internal pull-down resistor */
    
    	cmt_spi_sdio_out();
    	cmt_spi_sdio_1();
    
    	cmt_spi_fcsb_1();  /* FCSB has an internal pull-up resistor */
    
    	cmt_spi_delay();
    }
    /*********************************************************************
    * 函数原型:void cmt_spi_send(char data8)
    * 功   能:SPI发送一个BYTE
    * 输入参数:data8--需要发送的数据
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_send(char data8)
    {
    	char i;
    
    	for(i=0; i<8; i++)
    	{
     		cmt_spi_sclk_0();
    
        	/* Send byte on the rising edge of SCLK */
        	if(data8 & 0x80)
            	cmt_spi_sdio_1();
        	else
            	cmt_spi_sdio_0();
    
        	cmt_spi_delay();
    
        	data8 <<= 1;
        	cmt_spi_sclk_1();
        	cmt_spi_delay();
    	}
    }
    
    /*********************************************************************
    * 函数原型:char cmt_spi_recv(void)
    * 功   能:SPI接收一个数据
    * 输入参数:无
    * 返回参数:接收的数据
    *
    * 其他说明:
    *********************************************************************/
    char cmt_spi_recv(void)
    {
    	char i;
    	char data8 = 0xFF;
    
    	for(i=0; i<8; i++)
    	{
        	cmt_spi_sclk_0();
        	cmt_spi_delay();
        	data8 <<= 1;
    
        	cmt_spi_sclk_1();
    
        	/* Read byte on the rising edge of SCLK */
        	if(cmt_spi_sdio_read())
            	data8 |= 0x01;
        	else
            	data8 &= ~0x01;
    
        	cmt_spi_delay();
    	}
    
    	return data8;
    }
    
    /*********************************************************************
    * 函数原型:void cmt_spi_write(char addr, char dat)
    * 功   能:SPI写数据到指定地址
    * 输入参数:addr--地址   dat--数据
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_write(char addr, char dat)
    {
    
    	cmt_spi_sdio_1();
    	cmt_spi_sdio_out();
    
    	cmt_spi_sclk_0();
    
    	cmt_spi_fcsb_1();
    
    	cmt_spi_csb_0();
    
    	/* > 0.5 SCLK cycle */
    	cmt_spi_delay();
    	cmt_spi_delay();
    
    	/* r/w = 0 */
    	cmt_spi_send(addr&0x7F);
    
    	cmt_spi_send(dat);
    
    	cmt_spi_sclk_0();
    
    	/* > 0.5 SCLK cycle */
    	cmt_spi_delay();
    	cmt_spi_delay();
    
    	cmt_spi_csb_1();
    
    	cmt_spi_sdio_1();
    	cmt_spi_sdio_in();
    
    	cmt_spi_fcsb_1();
    }
    
    /*********************************************************************
    * 函数原型:void cmt_spi_read(char addr, char* p_dat)
    * 功   能:SPI读取指定地址的数据
    * 输入参数:addr--地址  p_dat--数据包
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_read(char addr, char* p_dat)
    {
    	cmt_spi_sdio_1();
    	cmt_spi_sdio_out();
    
    	cmt_spi_sclk_0();
    
    	cmt_spi_fcsb_1();
    
    	cmt_spi_csb_0();
    
    	/* > 0.5 SCLK cycle */
    	cmt_spi_delay();
    	cmt_spi_delay();
    
    	/* r/w = 1 */
    	cmt_spi_send(addr|0x80);
    
    	cmt_spi_sdio_in();
    
    	*p_dat = cmt_spi_recv();
    
    	cmt_spi_sclk_0();
    
    	/* > 0.5 SCLK cycle */
    	cmt_spi_delay();
    	cmt_spi_delay();
    
    	cmt_spi_csb_1();
    
    	cmt_spi_sdio_1();
    	cmt_spi_sdio_in();
    
    	cmt_spi_fcsb_1();
    }
    
    /*********************************************************************
    * 函数原型:void cmt_spi_write_fifo(const char* p_buf, int len)
    * 功   能:SPI写FIFO数据
    * 输入参数:p_buf--FIFO数据包  len--长度
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_write_fifo(const char* p_buf, int len)
    {
    	int i;
    
    	cmt_spi_fcsb_1();
    
    	cmt_spi_csb_1();
    
    	cmt_spi_sclk_0();
    
    	cmt_spi_sdio_out();
    
    	for(i=0; i<len; i++)
    	{
        	cmt_spi_fcsb_0();
    
        	/* > 1 SCLK cycle */
        	cmt_spi_delay();
        	cmt_spi_delay();
    
        	cmt_spi_send(p_buf[i]);
    
        	cmt_spi_sclk_0();
    
        	/* > 2 us */
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
    
        	cmt_spi_fcsb_1();
    
        	/* > 4 us */
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
    	}
    
    	cmt_spi_sdio_in();
    
    	cmt_spi_fcsb_1();
    }
    
    /*********************************************************************
    * 函数原型:void cmt_spi_read_fifo(char* p_buf, int len)
    * 功   能:SPI读取FIFO数据
    * 输入参数:p_buf--数据包  len--长度
    * 返回参数:无
    *
    * 其他说明:
    *********************************************************************/
    void cmt_spi_read_fifo(char* p_buf, int len)
    {
    	int i;
    
    	cmt_spi_fcsb_1();
    
    	cmt_spi_csb_1();
    
    	cmt_spi_sclk_0();
    
    	cmt_spi_sdio_in();
    
    	for(i=0; i<len; i++)
    	{
        	cmt_spi_fcsb_0();
    
        	//* > 1 SCLK cycle
        	cmt_spi_delay();
        	cmt_spi_delay();
    
        	p_buf[i] = cmt_spi_recv();
    
        	cmt_spi_sclk_0();
    
        	//* > 2 us
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
    
        	cmt_spi_fcsb_1();
    
        	//* > 4 us
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
        	cmt_spi_delay_us();
    	}
    
    	cmt_spi_sdio_in();
    
    	cmt_spi_fcsb_1();
    }
    
    int main(void)
    {
    	char read_data = 0xff;
    	
    	WDOG_disable();                   //关闭看门狗
    	SOSC_init_8MHz();                 //配置系统振荡器为外部8MHZ
    	SPLL_init_160MHz();               //使用SOSC 8MHZ配置SPLL 为160 MHz
    	NormalRUNmode_40MHz();            //配置系列时钟40MHz, 40MHz总线时钟
    	
    	cmt_spi_init();                   //模拟SPI初始化
    	cmt_spi_write(0x01,0xaa);         //写0xaa到0X01这个地址
    	cmt_spi_read(0x01, &read_data);   //读取0x01地址的值
    	for(;;)
    	{
    	}
    
    	return 0;
    }
    
    展开全文
  • 骇客S32K144 简介 S32K144是NXP推出的车规等级的MCU,ARM架构的内核。芯片在设计上考虑了功能安全的设计,可以达到ASIL B的等级。但是一下SDK的使用,我也没有太多经验。这次hack过程中研究一下这里面的技巧。除了...
  • 0. 引言 ...SPI在我们的系统架构中是S32K和ADAS之间做数据传输用的,毕竟速率够高,数据量能传的比较大。 1. 准备 1.1 SPI基础知识 1.2 开发环境 1.2.1 软件开发环境 1.2.2 硬件环境 SPI 2. Demo ...

    0. 引言

    与第二篇can对应,第三篇本来想写lin的,毕竟都是车身上常用的总线。但是lin比较麻烦,所以先拖后一下,先把SPI记录一下。
    SPI在我们的系统架构中是S32K和ADAS之间做数据传输用的,毕竟速率够高,一般都是上M,数据量能传的比较大。

    1. 准备

    1.1 SPI基础知识

    这部分不再赘述了,可以参见SPI基础要点
    SPI是个全双工的总线,在发送的时候同时也在接收。

    1.2 开发环境

    1.2.1 软件开发环境

    SDK: S32 DESIGN STUDIO for ARM,Version : 2018.R1。
    Lib: RTM3.0.0。
    Compnent:can_pal。

    1.2.2 硬件环境

    为了通用,硬件没用项目的硬件,还是使用的就是官网的黄色长条开发板,在第一篇里介绍过。

    因为手头已经没有SPI的调试环境了,这一篇我就纯写分析和一些问题记录,不上板实测了,如果哪里有问题,可以一起讨论。

    2. Demo

    2.1 Demo工程选择

    SPI相关的自带demo有3个,如下:
    在这里插入图片描述

    • LPSPI_S32K144:主要是基于寄存器来做的,用的不是SDK的库,先略过。
    • lpspi_dma_s32k144: 使用DMA来做的SPI数据接收。
    • lpspi_transfer_s32k144:最基本的SPI的传输例程

    另外,去网上下载了一个例程,也比较有参考性。

    • spi_pal_s32k144:忘了从哪找到的了,貌似是从NXP的社区下载的。原地址找不到了,

    注意,如果导入demo之后编译不过,可以重新生成一下代码,再编译。
    在这里插入图片描述
    在这里插入图片描述

    2.2 Demo分析

    这里选用最简单的lpspi_transfer_s32k144工程来做分析。
    程序说明很简单;
    在这里插入图片描述
    从SPI0 发送 数据到SPI1,使用引脚如下:
    在这里插入图片描述

    2.3 接口分析

    其实SPI的接口很简单,除去GPIO的初始化之外,跟SPI的控制器有关系的且常用就是:

    1. LPSPI_DRV_MasterInit
    2. LPSPI_DRV_MasterTransfer(Blocking)
    3. LPSPI_DRV_SlaveInit
    4. LPSPI_DRV_SlaveTransfer(Blocking)

    因为我们只用从模式,这里分析一下从机的两个接口,master其实类似,就是主机提供时钟,直接发送,从机准备数据,等待时钟再发送。

    2.3.1 LPSPI_DRV_SlaveInit

    这个接口其实就是把在pe中图像化配置的参数都init进去,没啥特别要说的。
    在这里插入图片描述

    2.3.2 LPSPI_DRV_SlaveTransfer(Blocking)

    这个就是传输数据的接口,Blocking是有一个发送超时的机制。注意,这个接口只是把要发送的数据的地址和长度配置进去,并不是真的发送掉了。
    从机的发送需要等主机给时钟才能发送。
    需要注意的就是:
    要发送的buffer的数据,不要调用完发送接口就修改,因为这个时候还没真正的发掉,一旦修改了,等主机的时钟过来的时候,真正发出去的就是修改后的数据了。
    这个真正发送的过程,可以在来时钟的时候使用中断实现或者dma实现,这个是库里做好的,我们只要选择功能即可。
    在这里插入图片描述

    3. 调试实际遇到的问题

    3.1 SPI波形很丑

    因为我们是S32K做从机,前期调试的时候,是从网上买了一个USB转SPI的设备,Ginkgo USB-SPI来调试的。
    就是这个第三方设备发送,S32K接收,但是波形一直很丑。
    想不出来为什么,各种波形都实验了。
    后来发现要把时钟频率降低。。
    36Mhz做不出来。
    估计买的调试器太垃圾了。

    之前调试:
    在这里插入图片描述

    频率调低之后:
    在这里插入图片描述

    3.2 模式配置异常

    S32K是和xilinx的7020通信的,7020是linux做主,S32k做从。
    linux这边,使用的模式mode1,即CPOL = 0,CPHA = 0。
    但是S32K这边同模式配置来接收,一直异常。
    S32K这边的CPOL要配置成1才能接收对。
    没办法,这个问题一直遗留着,还没解。

    3.3 总线busy,无法发送

    在实际使用中,Spi总线上有时候会偶现出现错误,一旦出现了错误,就会导致控制器认为总线是busy态,上一次的数据没有发送完,新的SPI一直发不出去。
    调试遇到的实际情况就是在调用发送接口是,进去获取总线状态就是busy,然后就return了,不会进发送的流程。
    我们最后采用的方案是:
    在发送之前获取一些总线状态,如果不是预期的状态,就采用强制中断,重新初始化的方式来进行恢复。

    LPSPI_DRV_SlaveAbortTransfer(LPSPICOM1);
    LPSPI_DRV_SlaveDeinit(LPSPICOM1);
    LPSPI_DRV_SlaveInit(LPSPICOM1,&lpspiCom1State,&lpspiCom1_SlaveConfig0);    			//SPI
    

    逻辑如下:
    在这里插入图片描述

    展开全文
  • S32K144裸机跑--CAN

    2019-04-02 09:51:09
    S32K144裸机跑--CAN,基本S32D平台,寄存器操作,CAN总线收发
  • S32K144 + FreeRTOS + SPI + IAR

    千次阅读 2018-10-02 18:46:03
    三、配置IO、使能DMA、SPI 四、创建任务、开启任务调度 一、移植FreeRTOS 从官网下载FreeRTOS源码 将..\FreeRTOS_v10_1_0\Source目录下的FreeRTOS源码复制到工程目录下 将..\FreeRTOS_v10_1_0\Sour...

    开发环境:IAR 8.30

    FreeRTOS版本:10.1

     

    • 一、移植FreeRTOS
    • 二、配置IAR
    • 三、配置IO、使能DMA、SPI
    • 四、创建任务、开启任务调度

    一、移植FreeRTOS

    1. 从官网下载FreeRTOS源码
    2. 将..\FreeRTOS_v10_1_0\Source目录下的FreeRTOS源码复制到工程目录下
    3. 将..\FreeRTOS_v10_1_0\Source\portable\IAR\ARM_CM4F下的文件添加到工程目录下
    4. 将..\FreeRTOS_v10_1_0\Source\portable\MemMang下的一种内存管理文件添加到工程目录下
    5. 打开S32DS下FreeRTOS例程的文件夹,复制其中的FreeRTOSConfig.h到工程目录下
    6. 复制S32DS中的连接文件以及脚本文件

      

    二、配置IAR

     三、配置IO、使能DMA、SPI

    配置IO

           PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

    使能DMA

    #define EDMA_CHN0_NUMBER   0U
    #define EDMA_CHN1_NUMBER   1U
    #define EDMA_CHN2_NUMBER   2U
    #define EDMA_CHN3_NUMBER   3U
    #define EDMA_CONFIGURED_CHANNELS_COUNT   4U
    
    edma_state_t dmaController1_State;
    edma_chn_state_t dmaController1Chn0_State;
    edma_chn_state_t dmaController1Chn1_State;
    edma_chn_state_t dmaController1Chn2_State;
    edma_chn_state_t dmaController1Chn3_State;
    edma_chn_state_t * const edmaChnStateArray[] = {
        &dmaController1Chn0_State,
        &dmaController1Chn1_State,
        &dmaController1Chn2_State,
        &dmaController1Chn3_State
    };
    void SPI_EDMA_init(void)
    {
        edma_channel_config_t dmaController1Chn0_Config = {
            .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
            .virtChnConfig = EDMA_CHN0_NUMBER,
            .source = EDMA_REQ_LPSPI0_RX,
            .callback = NULL,
            .callbackParam = NULL
        };
        
        edma_channel_config_t dmaController1Chn1_Config = {
            .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
            .virtChnConfig = EDMA_CHN1_NUMBER,
            .source = EDMA_REQ_LPSPI0_TX,
            .callback = NULL,
            .callbackParam = NULL
        };
        
        edma_channel_config_t dmaController1Chn2_Config = {
            .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
            .virtChnConfig = EDMA_CHN2_NUMBER,
            .source = EDMA_REQ_LPSPI1_RX,
            .callback = NULL,
            .callbackParam = NULL
        };
        
        edma_channel_config_t dmaController1Chn3_Config = {
            .channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
            .virtChnConfig = EDMA_CHN3_NUMBER,
            .source = EDMA_REQ_LPSPI1_TX,
            .callback = NULL,
            .callbackParam = NULL
        };
        
        const edma_channel_config_t * const edmaChnConfigArray[] = {
            &dmaController1Chn0_Config,
            &dmaController1Chn1_Config,
            &dmaController1Chn2_Config,
            &dmaController1Chn3_Config
        };
        
        const edma_user_config_t dmaController1_InitConfig0 = {
          .chnArbitration = EDMA_ARBITRATION_FIXED_PRIORITY,
          .notHaltOnError = false,
        };
        
        EDMA_DRV_Init(&dmaController1_State, &dmaController1_InitConfig0, edmaChnStateArray, 
                     edmaChnConfigArray, EDMA_CONFIGURED_CHANNELS_COUNT);
    }

    初始化Master--SPI

    lpspi_state_t SendState;
    void SPIMasterInit(void)
    {
    	uint32_t ret = 0;
    	
    	const lpspi_master_config_t Send_MasterConfig0 = {
    	  .bitsPerSec = 10000000U,
    	  .whichPcs = LPSPI_PCS0,
    	  .pcsPolarity = LPSPI_ACTIVE_HIGH,
    	  .isPcsContinuous = false,
    	  .bitcount = 8U,
    	  .lpspiSrcClk = 48000000U,
    	  .clkPhase = LPSPI_CLOCK_PHASE_1ST_EDGE,
    	  .clkPolarity = LPSPI_SCK_ACTIVE_HIGH,
    	  .lsbFirst = false,
    	  .transferType = LPSPI_USING_DMA,
    	  .rxDMAChannel = 0U,
    	  .txDMAChannel = 1U,
    	  .callback = NULL,
    	  .callbackParam = NULL,
    	};
    	
    	/* SPI master configuration: clock speed: 500 kHz, 8 bits/frame, MSB first */
    	ret = LPSPI_DRV_MasterInit(0, &SendState, &Send_MasterConfig0);
    	
    	printf("\r\n SPI Master Init : 0x%x ", ret);
    	
    	/* Configure delay between transfer, delay between SCK and PCS and delay between PCS 
           and SCK */
    	LPSPI_DRV_MasterSetDelay(0, 1, 1, 1);
    }

    初始化Slave--SPI

    lpspi_state_t ReceiveState;
    void SPISlaveInit(void)
    {
    	uint32_t ret = 0;
    	
    	const lpspi_slave_config_t Receive_SlaveConfig0 = {
          .pcsPolarity = LPSPI_ACTIVE_HIGH,
          .bitcount = 8U,
          .clkPhase = LPSPI_CLOCK_PHASE_1ST_EDGE,
          .whichPcs = LPSPI_PCS0,
          .clkPolarity = LPSPI_SCK_ACTIVE_HIGH,
          .lsbFirst = false,
          .transferType = LPSPI_USING_DMA,
          .rxDMAChannel = 2U,
          .txDMAChannel = 3U,
          .callback = NULL,
          .callbackParam = NULL,
        };
    	
    	
    	ret = LPSPI_DRV_SlaveInit(0, &ReceiveState, &Receive_SlaveConfig0);
    	
    	printf("\r\n SPI SlaveInit : 0x%x ", ret);
    }

    四、创建任务、开启任务调度

    特别注意:

        1、关于systick:由于FreeRTOS中的时间片调度已经使能设置了systick,故不必在设置

        2、设置中断的组别:NVIC_SetPriorityGrouping(0x3);

        3、由于FreeRTOS的中断优先级较低,会影响到正常的信号量的获取等,故需在程序刚开始时调用INT_SYS_SetPriority();修改系统中所有中断的优先级

    创建任务

        xTaskCreate((TaskFunction_t )IPC_task,               //任务函数 
                    (const char*    )"IPC_task",             //任务名称
                    (uint16_t       )IPC_TASK_STK_SIZE,      //任务堆栈大小
                    (void*          )NULL,                   //传递给任务函数的参数
                    (UBaseType_t    )IPC_TASK_STK_PRIO,      //任务优先级       
                    (TaskHandle_t*  )&IPC_Task_Handler);     //任务句柄    
    
        vTaskStartScheduler();                               //开启任务调度

    Master--SPI任务函数

    void IPC_task(void *pvParameters)
    {
        uint8_t TXBuffer[10] = {0,1,2,3,4,5,6,7,8,9};
        uint8_t RXBuffer[10] = {0};
        
        while(1)
        {
            LPSPI_DRV_MasterTransferBlocking(0, TXBuffer, RXBuffer, sizeof(TXBuffer), 10U);
            printf("\r\n Master recever 0x%x 0x%x 0x%x 0x%x ", RXBuffer[0], RXBuffer[1], 
                                                               RXBuffer[2], RXBuffer[3]);
            vTaskDelay(1000);
        }
    }

    Slave--SPI任务函数

    void IPC_task(void *pvParameters)
    {
        uint8_t TXBuffer[10] = {9,8,7,6,5,4,3,2,1,0};
        uint8_t RXBuffer[10] = {0};
        
        while(1)
        {
            LPSPI_DRV_SlaveTransfer(0, TXBuffer, RXBuffer, sizeof(RXBuffer), 10U);
            printf("\r\n Master recever 0x%x 0x%x 0x%x 0x%x ", RXBuffer[0], RXBuffer[1], 
                                                               RXBuffer[2], RXBuffer[3]);
            vTaskDelay(1000);
        }
    }

     

     

    展开全文
  • S32K144 keil 例程.zip

    2020-04-16 23:01:47
    包含S32K144的几个常用外设,包括ADC、DMA、CAN、SPI、UART、CLOCK等DEMO程序,手写代码,方便使用和理解,亲测可用!
  • S32K144_KEIL_DMA_FREEROTS

    2018-09-06 20:01:06
    源码程序测试成功使用的是源开发版,或者蓝宙S32k。 代码含有 LPSPI LPTMR FTM DMA Freertos -- 重新调整分数 为大家提供便利 - 使用后记得回来评论喔
  • S32K144(17)LPSPI

    2021-05-31 09:31:06
    1、简介 字大小= 32位 可配置时钟极性和时钟相位 主操作支持最多4个外设芯片选择 奴隶操作 ...主机请求输入可以用来控制SPI总线传输的开始时间(仅用于主) 支持数据匹配唤醒的接收数据匹配逻辑 ...

    1、简介

    • 字大小= 32位
    • 可配置时钟极性和时钟相位
    • 主机最多支持4个外设芯片选择
    • 命令/发送4字的FIFO
    • 接收4个字的FIFO
    • 主模式下灵活的定时参数,包括SCK频率和PCS与SCK边缘之间的延迟
    • 支持全双工传输,支持1位发送和接收在每个时钟边缘
    • 支持半双工传输,支持1位发送或接收在每个时钟边缘
    • 支持半双工传输,支持2位或4位发送或接收在每个时钟边缘(仅主机)
    • 主机请求输入可以用来控制SPI总线传输的开始时间(仅主机)
    • 支持数据匹配唤醒的接收数据匹配逻辑

    2、信号方向

    Signal

    NameDescription
    SCKSerial clock
    • 从机输入
    • 主机输出
    PCS[0]外围芯片选择
    • 从机输入
    • 主机输出
    PCS[1]/HREQ

    外围芯片选择

    或者

    主机请求
    当HREN=1, HRSEL=0时选择主机请求引脚
    • 输入从模式或当使用作为主机请求
    • 主模式输出
    PCS[2]/DATA[2]

    外围芯片选择

    或者

    4位数据传输引脚2

    • 从机输入
    • 主机输出
    • 四数据传输输入
    • 四数据传输输出
    PCS[1]/DATA[3]外围芯片选择

    或者

    4位数据传输引脚3

    • 从机输入
    • 主机输出
    • 四数据传输输入
    • 四数据传输输出
    SOUT/DATA[0]串行数据输出可以配置为串行数据输入信号吗
    • 用作四数据传输中的数据引脚0
    • 用于双数据传输中的数据引脚0
    SIN/DATA[1]串行数据输入可以配置为串行数据输入信号吗
    • 用作四数据传输中的数据引脚0
    • 用于双数据传输中的数据引脚0

    3、寄存器

    3.1、Version ID Register (VERID)

    版本寄存器

    3.2、Parameter Register (PARAM)

    发送和接受的FIFO大小

    3.3、Control Register (CR)

    0

    MEN

    模块使能

    1

    RST

    软件复位

    2

    DOZEN

    Doze模式使能

    3

    DEGEN

    调试模式使能

    8

    RTF

    复位发送FIFO

    9

    RRF

    复位接收FIFO

    3.4、Status Register (SR)

    0

    TDF

    发送数据标志

    0:没有请求发送数据

    1:请求发送数据

    1

    RDF

    接收数据标志

    0:没有准备好的接收数据

    1:接收数据就绪

    8

    WCF

    word 完成标志

    0:传输和接收word未完成

    1:传输和接收word完成

    9

    FCF

    帧数据完成标志

    0:传输帧数据未完成

    1:传输帧数据完成

    10

    TCF

    传输完成标志

    0:所有数据传输未完成

    1:所有数据传输完成

    11

    TEF

    传输错误标志

    12

    REF

    接收错误标志

    13

    DMF

    数据接收匹配标志

    24

    MBF

    模块忙标志

    3.5、Interrupt Enable Register (IER)

    0

    TDIE

    传输中断使能

    1

    RDIE

    接收中断使能

    8

    WCIE

    word 完成中断

    9

    FCIE

    帧数据完成中断

    10

    TCIE

    传输完成中断

    11

    TEIE

    传输错误中断

    12

    REIE

    接收错误中断

    13

    DMIE

    数据接收匹配中断

    3.6、DMA Enable Register (DER)

    发送和接收DMA使能

    3.7、Configuration Register 0 (CFGR0)

    0

    HREN

    主机请求使能

    1

    HRPOL

    配置主机请求引脚电平

    2

    HRSEL

    主机请求选择

    8

    CIRFIFO

    循环FIFO使能

    9

    RDMO

    只接收数据匹配

    3.8、Configuration Register 1 (CFGR1)

    0

    MASTER

    主从机模式选择

    1

    SAMPLE

    采样数据设置

    2

    AUTOPCS

    自动PCS

    3

    NOSTALL

    溢出时的操作

    8-11

    PCSPOL

    外围芯片片选电平

    16-18

    MATCFG

    匹配设置

    24-25

    PINCFG

    引脚设置

    26

    OUTCFG

    输出配置

    27

    PCSCFG

    外围芯片选择配置

    3.9、Data Match Register 0 (DMR0)

    匹配0的值

    3.10、Data Match Register 1 (DMR1)

    匹配1的值

    3.11、Clock Configuration Register (CCR)

    时钟配置

    3.12、FIFO Control Register (FCR)

    接收和发送的FIFO 水印配置

    3.13、FIFO Status Register (FSR)

    接收和发送的FIFO计数

    3.14、Transmit Command Register (TCR)

    0-11

    FRAMESZ

    帧大小

    16-17

    WIDTH

    发送宽度

    18

    TXMSK

    发送数据掩码

    19

    RXMASK

    接收数据掩码

    20

    CONTC

    发送应答,继续发送还是停止发送

    21

    CONT

    连续传输

    22

    BYSW

    字节交换

    23

    LSBF

    高位还是低位先发

    24-25

    PCS

    外围芯片选择配置

    27-29

    PRESCALE

    分频值

    30

    CPHA

    时钟相位

    31

    CPOL

    时钟极性

    3.15、Transmit Data Register (TDR)

    发送数据

    3.16、Receive Status Register (RSR)

    接收状态

    3.17、Receive Data Register (RDR)

    接收数据

    4、代码搬运工

    void LPSPI1_init_master(void)
    {
    	/*Disable clocks to modify PCS ( default)  */
    	PCC->PCCn[PCC_LPSPI1_INDEX] = 0;          
    	/*(default) Peripheral is present.	
    	 * Enable PCS=SPLL_DIV2 (40 MHz func'l clock) */
    	PCC->PCCn[PCC_LPSPI1_INDEX] = PCC_PCCn_PR_MASK	
    								 |PCC_PCCn_CGC_MASK	
    								 |PCC_PCCn_PCS(6);
    	/*LPSPI1 Initialization
    	 * Disable module for configuration
    	 * Interrupts not used
    	 * DMA not used  
    	 * Defaults: 
    	 * RDM0=0: rec'd data to FIFO as normal
    	 * CIRFIFO=0; Circular FIFO is disabled
    	 * HRSEL, HRPOL, HREN=0: Host request disabled
    	 * */
    	LPSPI1->CR    = 0x00000000;
    	LPSPI1->IER   = 0x00000000;
    	LPSPI1->DER   = 0x00000000;
    	LPSPI1->CFGR0 = 0x00000000;
    	/* Configurations: master mode
    	 * PCSCFG=0: PCS[3:2] are enabled
    	 * OUTCFG=0: Output data retains last value when CS negated
    	 * PINCFG=0: SIN is input, SOUT is output  
    	 * MATCFG=0: Match disabled
    	 * PCSPOL=0: PCS is active low
    	 * NOSTALL=0: Stall if Tx FIFO empty or Rx FIFO full
    	 * AUTOPCS=0: does not apply for master mode
    	 * SAMPLE=0: input data sampled on SCK edge 
    	 * MASTER=1: Master mode*/
    	LPSPI1->CFGR1 = LPSPI_CFGR1_MASTER_MASK;  
    	/* Transmit cmd: PCS3, 16 bits, prescale func'l clk by 4, etc
    	 * CPOL=0: SCK inactive state is low 
    	 * CPHA=1: Change data on SCK lead'g, capture on trail'g edge
    	 * PRESCALE=2: Functional clock divided by 2**2 = 4
    	 * PCS=3: Transfer using PCS3
    	 * LSBF=0: Data is transfered MSB first
    	 * BYSW=0: Byte swap disabled
    	 * CONT, CONTC=0: Continuous transfer disabled
    	 * RXMSK=0: Normal transfer: rx data stored in rx FIFO
    	 * TXMSK=0: Normal transfer: data loaded from tx FIFO
    	 * WIDTH=0: Single bit transfer
    	 * FRAMESZ=15: # bits in frame = 15+1=16 */
    	LPSPI1->TCR   = LPSPI_TCR_CPHA_MASK
    				  |LPSPI_TCR_PRESCALE(2)
    				  |LPSPI_TCR_PCS(3)
    				  |LPSPI_TCR_FRAMESZ(15);
    	/* Clock dividers based on prescaled func'l clk of 100 nsec
    	 * SCKPCS=4: SCK to PCS delay = 4+1 = 5 (500 nsec)
    	 * PCSSCK=4: PCS to SCK delay = 9+1 = 10 (1 usec) 
    	 * DBT=8: Delay between Transfers = 8+2 = 10 (1 usec) 
    	 * SCKDIV=8: SCK divider =8+2 = 10 (1 usec: 1 MHz baud rate) */
    	LPSPI1->CCR   = LPSPI_CCR_SCKPCS(4)
    				  |LPSPI_CCR_PCSSCK(4)
    				  |LPSPI_CCR_DBT(8)
    				  |LPSPI_CCR_SCKDIV(8); 
    	/* RXWATER=0: Rx flags set when Rx FIFO >0
    	 * TXWATER=3: Tx flags set when Tx FIFO <= 3  */
    	LPSPI1->FCR   = LPSPI_FCR_TXWATER(3);
    	/* Enable module for operation
    	 * DBGEN=1: module enabled in debug mode 
    	 * DOZEN=0: module enabled in Doze mode
    	 * RST=0: Master logic not reset
    	 * MEN=1: Module is enabled  */
    	LPSPI1->CR    = LPSPI_CR_MEN_MASK
    				  |LPSPI_CR_DBGEN_MASK;
    }
    
    void LPSPI1_transmit_16bits (uint16_t send)
    {
    	/* Wait for Tx FIFO available */
    	while((LPSPI1->SR & LPSPI_SR_TDF_MASK)>>LPSPI_SR_TDF_SHIFT==0);
    	/* Transmit data */
    	LPSPI1->TDR = send;
    	/* Clear TDF flag */
    	LPSPI1->SR |= LPSPI_SR_TDF_MASK;
    }
    
    uint16_t LPSPI1_receive_16bits (void)
    {
    	uint16_t recieve = 0;
    	/* Wait at least one RxFIFO entry */
    	while((LPSPI1->SR & LPSPI_SR_RDF_MASK)>>LPSPI_SR_RDF_SHIFT==0);
    	/* Read received data */
    	recieve= LPSPI1->RDR;
    	/* Clear RDF flag  */
    	LPSPI1->SR |= LPSPI_SR_RDF_MASK;
    	return recieve;
    }
    

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 关于S32K系列驱动之SPI(SDK144/6芯片)的demo版开发测试结果分享,内附SPI关于S32DS PE的如何配置说明、使用demo版测试的代码分享 ,调试过程遇到的问题以及目前的解决方案,可以保证正常使用SPI
  • S32K144_FreeRTOS_Fatfs

    2017-10-31 10:05:19
    S32K144 外设测试程序, 移植了FreeRTOS和Fatfs,支持3路UART和3路CAN接口,以及通过SPI读取SD卡文件系统.
  • 完整的S32K144的学习汇总如下: https://github.com/GreyZhang/g_s32k144 继续S32K144的学习,这一次看一下FreeRTOS的工作时钟修改。其实,这就是一个简单的power-mode的切换。但是,在效果上能够看得出FreeRTOS...
  • 试用基于S32K144平台的AutoSAR4.2.1的MCAL

    千次阅读 2020-09-03 17:11:20
    NXP的S32K1xx系列MCU在汽车电子应用非常广泛,同时NXP也将S32K1xx的MCAL发布在官网,但是相关使用说明较少。本文主要引导客户如何安装S32K1xx的MCAL以及相应的配件,同时也讲解了如何使用GCC编译运行MCAL自带的例程...
  • 334_S32K144 CAN的DMA收发模式

    千次阅读 2020-04-04 15:10:21
    完整的S32K144的学习汇总如下: https://github.com/GreyZhang/g_s32k144 继续S32K144的学习,昨天稍微深入学习测试了一下FIFO的接收模式,使用的是中断接收的方式,最终感觉让我打开了一扇新的学习大门。原来这...
  • 264_S32K144的DMA串口发送模式

    千次阅读 2020-02-21 22:21:13
    完整的S32K144的学习汇总如下: https://github.com/GreyZhang/g_s32k144 继续学习S32K144,这次的学习小结对象还是UART串口功能。除此之外,还会涉及到一个DMA的功能,使用的也就是芯片上的EDMA模块。 SDK的...
  • S32K144实现自己的DEBUG调试

    千次阅读 2019-05-07 16:54:33
    由于IAR下S32K144的开发环境没有控制台,所以需要自己实现一个串口,将输出重定向到对应的串口下。 1、将需要重定向的串口初始化,并且完成该串口的uart_send接口。 void uart_init_hal(uint8_t uartinstance,uint32...
  • S32K SPI调试

    2020-10-27 17:07:59
    S32KSPI 叫LPSPI,和其他单片机差不多,涉及到的寄存器还比较多。 配置时钟 在使用LPSPI之前,必须要配置时钟。 PCC->PCCn[PCC_LPSPI0_INDEX] |= PCC_PCCn_PCS(1) | PCC_PCCn_CGC_MASK PCC_PCCn_CGC_...
  • S32K144 EVB之Bootloader

    千次阅读 热门讨论 2017-10-31 17:44:18
    开发环境IAR7.8 + S32K144-EVB这一次建立了2个工程,一个Bootloader的,一个APP的: 具体Flash的分配见S32K1xx_memory_map.xlsxBootloader预留的空间是0x00000000-0x00001FFFF APP 预留的空间为0x00002000-0xXXXXX...
  • 本套代码是在S32K146芯片实现LPSPI 通信的驱动代码,可以方便的移植到S32K14X的系统中。
  • S32K144(19)FlexIO

    2021-05-31 14:05:43
    FlexIO可仿真串行通讯协议,包括但不限于:UART、I2C、SPI、I2S、PWM,可提供16位的定时器 FlexIO提供以下主要功能: 32位移位寄存器发送,接收和数据匹配模式 双缓冲移位操作连续数据传输 移位连接,以支持...
  • 算起来,接触S32K144有1个月了,突发的项目需求让使用这个片子,当时真是一头雾水。 在此之前的自己是一直使用ST的片子,感觉这个片子的好处就是系列比较全,不同的需求去找不同的型号就行,而且坑被人踩的差不多了...
  • S32K144_KEIL_lpspi

    2018-09-06 20:05:14
    常规的时间片OS系统,底层代码基本为GPIO AD SPI FTM LPTMR 没有加入RTOS 可以参考我的另一个历程
  • 上一篇介绍了S32K 的LinStack组件,其实这个组件正常用起来除了觉得有些约束,倒没有其他问题。 直到有一次遇到一个超声波雷达,要发 的ID,这个是属于诊断帧的,使用LinStack怎么也不知道该怎么配进去了,还有切换...
  • S32K142 KEIL 串口程序可以实现发送和接收,参照https://blog.csdn.net/weixin_41700578/article/details/84958274编写 模板程序
  • S32K144(18)LPI2C

    2021-05-31 11:31:13
    If LPI2C master/slave are configured to use separate pins, then this the LPI2C slave SDA pin 2.1、2-wire接法 2.2、4-wire接法 3、寄存器 与SPI极度相似 3.1、Version ID Register (VERID) 版本id寄存器 3.2...
  • 316_S32K144 EVB 标准CAN配置

    千次阅读 2020-03-14 21:42:14
    完整的S32K144的学习汇总如下: https://github.com/GreyZhang/g_s32k144 继续S32K144的学习,这一次来做一下CAN通信功能的一个小结。说起来,这算是一个迟到的小结,因为这个SBC uja11691耗费了我一点时间,中间...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 224
精华内容 89
关键字:

s32k144spi