灵动微MM32F003硬件最小系统 --- SPI+DMA查询模式自发自收例程解析【28】

本例程需要用杜邦线将MISO和MOSI两个GPIO短路,即可完成自发自收的测试程序。

1 SPI初始化

void SPIM_Init(SPI_TypeDef* SPIx, unsigned short spi_baud_div)
{
    SPI_InitTypeDef SPI_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_3);                      //SPI_NSS  PA0
#ifdef DISSWDIO
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource13, GPIO_AF_4);                       //SPI_MISO
#else
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);                       //SPI_MISO
#endif
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_4);                       //SPI_MOSI
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_3);                       //SPI_SCK

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;                                //SPI_NSS PA0
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                             //Push to avoid multiplexing output
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13 | GPIO_Pin_14;                   //SPI_MOSI | SPI_SCK
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

#ifdef DISSWDIO
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13;                                 //SPI_MISO
#else
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_12;                                 //SPI_MISO
#endif
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                               //Pull-up input
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_DataWidth = SPI_DataWidth_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = spi_baud_div;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_Init(SPIx, &SPI_InitStructure);

    SPI_Cmd(SPIx, ENABLE);
    SPIM_TXEn(SPIx);
    SPIM_RXEn(SPIx);
}
void SPI_DMA_RX_Init()
{
    DMA_InitTypeDef  DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //ʹÄÜDMA´«Êä
    DMA_DeInit(DMA1_Channel4);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->RXREG); //SPI½ÓÊÕÊý¾Ý¼Ä´æÆ÷
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rxdata; //SPI½ÓÊÕµ½µÄÊý¾Ý´æ·Å»ùµØÖ·
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//Êý¾Ý´ÓÍâÉèµ½memory
    DMA_InitStructure.DMA_BufferSize = 20;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);//SPI2 RXΪDMAͨµÀ4
}
void SPI_DMA_TX_Init()
{
    DMA_InitTypeDef  DMA_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  //ʹÄÜDMA´«Êä
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (SPI2->TXREG); //SPI·¢ËÍÊý¾Ý¼Ä´æÆ÷
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)txdata;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//Êý¾Ý´Ómemoryµ½ÍâÉè
    DMA_InitStructure.DMA_BufferSize = 8;//·¢ËÍÊý¾Ý¸öÊý
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//ÍâÉèµØÖ·²»¸Ä±ä
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//memoryµØÖ·µÝÔö¿ªÆô
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//ÆÕͨģʽ
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);//SPI RXΪDMAͨµÀ5
}

2 SPI读写接口函数

void SPI2MasterReadWritebuf(u8 *ptx_buf, u8 *prx_buf, u32 len)
{
    DRV_DMA_TransmitPacket(DMA1_Channel5, (u32)ptx_buf, len);
    DRV_DMA_TransmitPacket(DMA1_Channel4, (u32)prx_buf, len);
    SPIM_CSLow(SPI2);
    SPI_DMACmd(SPI2, SPI_DMAReq_EN, ENABLE);
    while(!DMA_GetFlagStatus(DMA1_FLAG_TC5));
    DMA_ClearFlag(DMA1_FLAG_TC5);
    while(!DMA_GetFlagStatus(DMA1_FLAG_TC4));
    DMA_ClearFlag(DMA1_FLAG_TC4);
    SPI_DMACmd(SPI2, SPI_DMAReq_EN, DISABLE);
    SPIM_CSHigh(SPI2);
}

3 自发自收的测试函数

void SPI_master_DMA_TXRXloop_Test(void)
{
    unsigned int i, j;



    SPIM_Init(SPI2, 4); //SPI CLK = 48/2/4 =6MHz
    SPI_DMA_RX_Init();
    SPI_DMA_TX_Init();


    UartSendGroup((u8*)printBuf, sprintf(printBuf, "SPI2 test\r\n"));
    //while(1)
    {
        for(i = 1; i <= LENGTH; i++) {
            for(j = 0; j < LENGTH; j++) {
                rxdata[j] = 0x0;
            }
            //memset(rxdata,0,sizeof(rxdata));
            SPI2MasterReadWritebuf(txdata, rxdata, i);

        }
    }
    for(i = 0; i < LENGTH; i++) {
        UartSendGroup((u8*)printBuf, sprintf(printBuf, "rx[%d]=0x%x\r\n", i, rxdata[i]));
    }
    j = 0;
    for(i = 0; i < LENGTH; i++) {
        if(rxdata[i] != txdata[i]) {
            j = 1;
            break;
        }

    }
    if(j == 1) {
        UartSendGroup((u8*)printBuf, sprintf(printBuf, "SPI2 TxRx Loopback test fail\r\n"));
    } else {
        UartSendGroup((u8*)printBuf, sprintf(printBuf, "SPI2 TxRx Loopback test Sucessful\r\n"));
    }
    UartSendGroup((u8*)printBuf, sprintf(printBuf, "SPI2 test over\r\n"));

}

4 串口打印信息

sprintf ok

Start SPI test
SPI2 test
rx[0]=0x55
rx[1]=0xaa
rx[2]=0xbb
rx[3]=0xdd
rx[4]=0x33
rx[5]=0x77
rx[6]=0x22
rx[7]=0x11
rx[8]=0x55
rx[9]=0xaa
rx[10]=0xbb
rx[11]=0xdd
rx[12]=0x33
rx[13]=0x77
rx[14]=0x22
rx[15]=0x11
SPI2 TxRx Loopback test Sucessful
SPI2 test over
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容