N32G430学习笔记21--- SPI1 使用中断发送数据 SPI2 使用dma接收数据

SPI1 使用中断发送数据 SPI2 使用dma接收数据

  • 这个例子spi1使用中断发送数据
  • spi2使用dma的方式接收数据
  • 传输数位位宽是16bit,2个字节
#include "n32g430.h"
#include "bsp_spi.h"
#include "stdio.h"
#include "string.h"
#include "bsp_delay.h"
#define BufferSize 32
uint16_t RxIdx=0,TxIdx=0;
static uint16_t SPI_Master_Buffer_Tx[BufferSize] = {0x0102, 0x0304, 0x0506, 0x0708, 0x090A, 0x0B0C, 0x0D0E, 0x0F10,
                                             0x1112, 0x1314, 0x1516, 0x1718, 0x191A, 0x1B1C, 0x1D1E, 0x1F20,
                                             0x2122, 0x2324, 0x2526, 0x2728, 0x292A, 0x2B2C, 0x2D2E, 0x2F30,
                                             0x3132, 0x3334, 0x3536, 0x3738, 0x393A, 0x3B3C, 0x3D3E, 0x3F40};
static uint16_t SPI_Slave_Buffer_Tx[BufferSize] = {0x5152, 0x5354, 0x5556, 0x5758, 0x595A, 0x5B5C, 0x5D5E, 0x5F60,
                                            0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70,
                                            0x7172, 0x7374, 0x7576, 0x7778, 0x797A, 0x7B7C, 0x7D7E, 0x7F80,
                                            0x8182, 0x8384, 0x8586, 0x8788, 0x898A, 0x8B8C, 0x8D8E, 0x8F90};
static uint16_t SPI_Master_Buffer_Rx[BufferSize], SPI_Slave_Buffer_Rx[BufferSize];

static void bsp_spi_it_rcc_cinfig(void)
{
    /* 时钟分频PCLK2 = HCLK/2 */
    RCC_Pclk2_Config(RCC_HCLK_DIV2);

    /* Enable peripheral clocks --------------------------------------------------*/
    /* spi 时钟 enable */
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_SPI1 | RCC_APB2_PERIPH_SPI2);

    /* GPIO 外设 时钟 enable */
    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB);
	
		/*dma 时钟设置*/
	  RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_DMA);
}
//配置gpio
static void bsp_spi_it_gpio_config(void)
{
    GPIO_InitType GPIO_InitStructure;

    GPIO_Structure_Initialize(&GPIO_InitStructure);
    /* 配置主设备 master pins: NSS, SCK, MISO and MOSI */

    GPIO_InitStructure.Pin        = GPIO_PIN_5;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_FAST;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF1_SPI1;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.Pin        = GPIO_PIN_3 | GPIO_PIN_4;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_SPI1;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);


    /* 配置从设备 slave pins: NSS, SCK, MISO and MOSI */
    /* Confugure SPI pins as Input Floating */
    GPIO_InitStructure.Pin        = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_AF_PP;
    GPIO_InitStructure.GPIO_Alternate = GPIO_AF1_SPI2;
    GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
}
//配置spi的nvic
static void bsp_spi_it_nvic_config(void)
{
    NVIC_InitType NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure);
    //使能外设spi1的发送为空的中断
    SPI_I2S_Interrupts_Enable(SPI1, SPI_I2S_INT_TE);



}

/*
配置spi1 spi2外设
又是单工模式发送 接收数据
使用硬件NSS
注意这里使用的16位数据传输,也就是一次传输2的字节
*/
static void bsp_spi_it_config(void)
{
    SPI_InitType SPI_InitStructure;
    SPI_Initializes_Structure(&SPI_InitStructure);
    SPI_InitStructure.DataDirection = SPI_DIR_SINGLELINE_TX;//发送模式  
    SPI_InitStructure.SpiMode       = SPI_MODE_MASTER;//主模式
    SPI_InitStructure.DataLen       = SPI_DATA_SIZE_16BITS;//数据16位宽
    SPI_InitStructure.CLKPOL        = SPI_CLKPOL_LOW; //时钟默认电平是低
    SPI_InitStructure.CLKPHA        = SPI_CLKPHA_SECOND_EDGE;//第二个边沿采集数据
    SPI_InitStructure.NSS           = SPI_NSS_HARD;//硬件NSS
    /* It is recommended that the SPI master mode of the C version chips should not exceed 18MHz */
    SPI_InitStructure.BaudRatePres  = SPI_BR_PRESCALER_64;//时钟分频
    SPI_InitStructure.FirstBit      = SPI_FB_MSB;//MSB
    SPI_InitStructure.CRCPoly       = 7;
    SPI_Initializes(SPI1, &SPI_InitStructure);
    //SPI_NSS_Config(SPI1, SPI_NSS_SOFT);
    SPI_Set_Nss_Level(SPI1, SPI_NSS_HIGH);
      SPI_SS_Output_Enable(SPI1);//NSS 使能


    /* SPI_SLAVE configuration ------------------------------------------------------*/
    SPI_InitStructure.SpiMode = SPI_MODE_SLAVE;
    SPI_InitStructure.DataDirection = SPI_DIR_SINGLELINE_RX; //单工 接收模式
    SPI_Initializes(SPI2, &SPI_InitStructure);
    SPI_NSS_Config(SPI2, SPI_NSS_SOFT);
		 SPI_Set_Nss_Level(SPI1, SPI_NSS_LOW);
    //  SPI_SS_Output_Enable(SPI2);//NSS 使能
    //SPI_CRC_Disable(SPI2);
}

void SPI1_IRQHandler(void)
{
    if (SPI_I2S_Interrupt_Flag_Status_Get(SPI1, SPI_I2S_INT_FLAG_TE) != RESET)
    {
        /* 发送数据 */
        SPI_I2S_Data_Transmit(SPI1, SPI_Master_Buffer_Tx[TxIdx++]);
        if (TxIdx == BufferSize)
        {
            /* 关闭中断,停止发送数据 */
            SPI_I2S_Interrupts_Disable(SPI1, SPI_I2S_INT_TE);

        }
    }
}


/*
	spi2的dma配置,spi2 使用dma方式接收数据
*/
static void bps_spi_dma_config(void)
{
 DMA_InitType DMA_InitStructure;
  
    DMA_Reset(DMA_CH1);

    /* SPI_MASTER TX DMA config */
    DMA_InitStructure.MemAddr = (uint32_t)&SPI_Slave_Buffer_Rx[0];//接收数据的内部地址设置
    DMA_InitStructure.MemDataSize = DMA_MEM_DATA_WIDTH_HALFWORD;//一次传输位半字(2个字节)
    DMA_InitStructure.MemoryInc = DMA_MEM_INC_MODE_ENABLE;
    DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.PeriphAddr = (uint32_t)&SPI2->DAT;//spi2的data寄存器作为源地址
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_HALFWORD;
    DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_MODE_DISABLE;
    DMA_InitStructure.BufSize = BufferSize;
    DMA_InitStructure.CircularMode = DMA_CIRCULAR_MODE_DISABLE;
    DMA_InitStructure.Mem2Mem = DMA_MEM2MEM_DISABLE;
    DMA_InitStructure.Priority = DMA_CH_PRIORITY_MEDIUM;
    DMA_Initializes(DMA_CH1, &DMA_InitStructure);
    DMA_Channel_Request_Remap(DMA_CH1, DMA_REMAP_SPI2_RX);
		
    DMA_Channel_Enable(DMA_CH1);
    //spi2 的中断传输使能
    SPI_I2S_DMA_Transfer_Enable(SPI2, SPI_I2S_DMA_RX);
    
	}

/*spi 中断模式接收发送数据测试*/
void bsp_spi_it_init(void)
{
    //外设时钟使能
    bsp_spi_it_rcc_cinfig();
    //外设gpio设置
    bsp_spi_it_gpio_config();
    //中断配置
    bsp_spi_it_nvic_config();
    //spi外设配置
    bsp_spi_it_config();
    /* 使能spi外设 */
	 bps_spi_dma_config();
    SPI_ON(SPI1);
    SPI_ON(SPI2);
}

static int Buffercmp(uint16_t *pBuffer1, uint16_t *pBuffer2, uint16_t BufferLength)
{
    while (BufferLength--)
    {
        if (*pBuffer1 != *pBuffer2)
        {
            return 0;
        }

        pBuffer1++;
        pBuffer2++;
    }

    return 1;
}
void bsp_spi_it_test(void)
{

	//判断是否传输完成
	while(DMA_Flag_Status_Get(DMA, DMA_CH1_TXCF) == RESET);

    for (int i = 0; i < BufferSize; i++)
    {
        printf("%02x ", SPI_Slave_Buffer_Rx[i]);
    }
    printf("\r\n");
    /* Check the received data with the send ones */
    int s = Buffercmp(SPI_Slave_Buffer_Rx, SPI_Master_Buffer_Tx, BufferSize);

    if (s)
    {
        printf("Test PASS!\r\n");
    }
    else
    {
        printf("Test ERR!\r\n");
    }
}


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Car12

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

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

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

打赏作者

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

抵扣说明:

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

余额充值