DSP280049C初学(2)-关于DSP280049C与STM32F103C8T6之间的SPI通讯记录

关于DSP24049C与STM32F103C8T6之间的SPI通讯记录

所用材料:
STM32F103C8T6(最小系统板)
DSPF280049C
VOFA+ (串口调试助手)

背景介绍:
DSP作为主设备,STM32作为从设备。目前仅要求主设备向从设备发送数据能够被接收并且通过STM32的串口打印至上位机即可。

第一步:DSP280049C的SPI配置

void SPIA_int (void)
{
    //GPIO配置
    // SPISOMIB.
    //
    GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinOptions(17, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPISIMOB clock pin.
    //
    GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinOptions(16, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPICLKB.
    //
    GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 7);
    GPIO_SetupPinOptions(9, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPICSB.
    //
    GPIO_SetupPinMux(33, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(33, GPIO_OUTPUT, GPIO_ASYNC);
    GPIO_WritePin(33, 1);
    //SPI配置
    // Set reset low before configuration changes
    // Clock polarity (0 == rising, 1 == falling)
    // 16-bit character
    // Disable loop-back
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpiaRegs.SPICCR.bit.SPICHAR = (16 - 1);
    SpiaRegs.SPICCR.bit.SPILBK = 0;

    //
    // Enable master (0 == slave, 1 == master)
    // Enable transmission (Talk)
    // Clock phase (0 == normal, 1 == delayed)
    // SPI interrupts are disabled
    //
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
    SpiaRegs.SPICTL.bit.TALK = 1;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;

    //
    // Set the baud rate using a 2 MHz SPICLK
    // BRR = (LSPCLK / SPICLK) - 1
    //
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((25000000 / 2000000) - 1);

    //
    // Set FREE bit
    // Halting on a breakpoint will not halt the SPI
    //
    SpiaRegs.SPIPRI.bit.FREE = 1;

    //
    // Release the SPI from reset
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;

}

uint16_t  SPIA_sendone(uint16_t txdata)
{
    uint16_t rxdata;
    GPIO_WritePin(33, 0);
    SpiaRegs.SPITXBUF = txdata;
    while (!SpiaRegs.SPISTS.bit.INT_FLAG){}
    GPIO_WritePin(33, 1);
    rxdata = SpiaRegs.SPIRXBUF;
    return  rxdata;
}

然后是在主程序中进行定时发送的:

void main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER=0x0000;
    IFR=0x0000;
    InitPieVectTable();
    DELAY_US(1000L);

    LED_int();
    SPIA_int ();
    TIM0_int ();
    SCIA_int();
    ADC_int();
    QEP_int();
    //EPWM1_int();
    EINT;                                       //使能全局中断
    ERTM;

    while (1)
    {
        rData = SPIA_sendone(12345);
        DELAY_US(200L);
    }
}

第二步:STM32基于HAL库的SPI配置

在这里插入图片描述

从设备端我开启了SPI接收中断,在CUBEMX配置之后只需要添加一下程序。

在spi.c中添加如下:
void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */
	HAL_SPI_Receive_IT(&hspi1,&rdata, 1);//添加部分
  /* USER CODE END SPI1_Init 2 */

}
然后在中断函数中进行接收:找到**stm32f1xx_it.c**中的
void SPI1_IRQHandler(void)
{
  /* USER CODE BEGIN SPI1_IRQn 0 */
  uint8_t rdata;
  uint16_t rxdata;
  /* USER CODE END SPI1_IRQn 0 */
  HAL_SPI_IRQHandler(&hspi1);
  /* USER CODE BEGIN SPI1_IRQn 1 */
  HAL_SPI_Receive_IT(&hspi1,&rdata, 1);
  rxdata = *(&rdata) + *(&rdata+1)*256;
  printf ("%d\r\n",rxdata);
  /* USER CODE END SPI1_IRQn 1 */
}

配置STM32的具体步骤不在此细讲了,观众们看到这里就结束了,接来下是个人学习记录部分了。

碰到的问题记录:

由于主设备DSP所需要发送的数据是大于256的,所以需要定义一个Uint16_t型的数据,同时DSP的SPI也设置为了16bit为一字节发送。

但是这里存在一个问题就是,STM32作为从设备,接收数据时的数据类型只能是Uint8_t,也就是说STM32在接收数据(假设发送的数据为:12345)后,会将数据拆分为两个8bit的字节,分别存储在&rdata与&(rdata+1)两个相邻的地址中。

因此想到了这一步:在未来的其他通讯方式中也能够借鉴使用

	rxdata = *(&rdata) + *(&rdata+1)*256;

截止2023/7/3 关于DSP280049C与STM32F103C8T6的SPI通讯改进

改进目标:为了满足DSP能够在200us时间内,发送两个数据至STM32并且STM32能够通过串口打印到上位机串口软件VOFA+

DSP280049C的SPI主机配置

void SPIA_int (void)
{
    //GPIO配置
    // SPISOMIB.
    //
    GPIO_SetupPinMux(17, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinOptions(17, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPISIMOB clock pin.
    //
    GPIO_SetupPinMux(16, GPIO_MUX_CPU1, 1);
    GPIO_SetupPinOptions(16, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPICLKB.
    //
    GPIO_SetupPinMux(9, GPIO_MUX_CPU1, 7);
    GPIO_SetupPinOptions(9, GPIO_PULLUP, GPIO_ASYNC);
    //
    // SPICSB.
    //
    GPIO_SetupPinMux(33, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(33, GPIO_OUTPUT, GPIO_ASYNC);
    GPIO_WritePin(33, 1);
    //SPI配置
    // Set reset low before configuration changes
    // Clock polarity (0 == rising, 1 == falling)
    // 16-bit character
    // Enable loop-back
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 0;
    SpiaRegs.SPICCR.bit.CLKPOLARITY = 0;
    SpiaRegs.SPICCR.bit.SPICHAR = (8 - 1);
    SpiaRegs.SPICCR.bit.SPILBK = 0;

    //
    // Enable master (0 == slave, 1 == master)
    // Enable transmission (Talk)
    // Clock phase (0 == normal, 1 == delayed)
    // SPI interrupts are disabled
    //
    SpiaRegs.SPICTL.bit.MASTER_SLAVE = 1;
    SpiaRegs.SPICTL.bit.TALK = 1;
    SpiaRegs.SPICTL.bit.CLK_PHASE = 0;
    SpiaRegs.SPICTL.bit.SPIINTENA = 0;

    //
    // Set the baud rate using a 2 MHz SPICLK
    // BRR = (LSPCLK / SPICLK) - 1
    //
    SpiaRegs.SPIBRR.bit.SPI_BIT_RATE = ((25000000 / 1000000) - 1);

    //
    // Set FREE bit
    // Halting on a breakpoint will not halt the SPI
    //
    SpiaRegs.SPIPRI.bit.FREE = 1;

    //
    // Release the SPI from reset
    //
    SpiaRegs.SPICCR.bit.SPISWRESET = 1;

}

void SPISendData(uint8_t *data, unsigned int len)
{
    int i;
    uint16_t rxdata;
    GPIO_WritePin(33, 0);
    for (i = 0; i < len; i++)
    {
        // 写入数据到SPI缓冲区
        SpiaRegs.SPITXBUF = data[i]<<8;

        // 等待数据发送完成
        while (SpiaRegs.SPISTS.bit.INT_FLAG != 1);
        rxdata = SpiaRegs.SPIRXBUF;
    }
    GPIO_WritePin(33, 1);
}

uint16_t  SPIA_sendtwo(uint16_t txdata1,uint16_t txdata2)
{
    uint8_t data[6];
    data[0] = 1;
    data[5] = 255;
    data[1] = txdata1/256;
    data[2] = txdata1%256;
    data[3] = txdata2/256;
    data[4] = txdata2%256;
    SPISendData(data, 6);
}

STM32的SPI从机配置(轮询接收)

void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

//main函数轮询接收
  while (1)
  {
			
	  	HAL_SPI_TransmitReceive(&hspi1,Txdata,Rxdata,6,0xffff);
			if (Rxdata[0]==1 && Rxdata[5]==255)
			{
				data1 = Rxdata[1]*256+Rxdata[2];
				data2 = Rxdata[3]*256+Rxdata[4];
				Sendtwodata(data1,data2);	
			}
			else
			{
				MX_SPI1_Init();
			}
			
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

//串口发送函数
void Sendtwodata(uint16_t data0,uint16_t data1)
{
	uint8_t indata0=44;
	uint8_t indata1=10;
	uint8_t indata2=13;
	uint8_t cdata[8];
	cdata[0] = (data0/1000)+48;
	cdata[1] = ((data0%1000)/100)+48;
	cdata[2] = ((data0%100)/10)+48;
	cdata[3] = ((data0%10))+48;
	cdata[4] = (data1/1000)+48;
	cdata[5] = ((data1%1000)/100)+48;
	cdata[6] = ((data1%100)/10)+48;
	cdata[7] = ((data1%10))+48;
	HAL_UART_Transmit(&huart1, &cdata[0], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[1], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[2], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[3], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &indata0, 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[4], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[5], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[6], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &cdata[7], 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &indata2, 1, 10);//HAL库串口发送函数
	HAL_UART_Transmit(&huart1, &indata1, 1, 10);//HAL库串口发送函数
}
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tony0925

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值