本帖最后由 noctor 于 2018-9-30 13:54 编辑
上回我们说到了MG32F02A的SPI0通过标准四线制全双工方式进行数据通信。帖子详情:https://bbs.21ic.com/icview-2561446-1-1.html
这次我们就按照老样子,搭载DMA功能进行传输。
上次我们说过,UART的DMA功能感觉并没有多简化,然而我发现在SPI的发送端上也是一样的结果,同样需要手动每次传输数据之前使能一次DMA外设发送功能才能发送,而且一样要使用while等待TCF_FLAG的到来。、
主机发送代码:
#include "MG32x02z_DRV.H"
#include <stdio.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
#define Dummy_Data 0xFFFFFFFF
#define SPI_NSS PB0 // SPI_NSS
#define URTX URT0
#define MYBINARYIMAGE2_LENGTH 20
uint8_t SendBuf[MYBINARYIMAGE2_LENGTH]={0};//__attribute__((at(0x20001000)));
void CSC_Init (void)
{
CSC_PLL_TyprDef CSC_PLL_CFG;
UnProtectModuleReg(MEMprotect); // Setting flash wait state
MEM_SetFlashWaitState(MEM_FWAIT_ONE); // 50MHz> Sysclk >=25MHz
ProtectModuleReg(MEMprotect);
UnProtectModuleReg(CSCprotect);
CSC_CK_APB_Divider_Select(APB_DIV_1); // Modify CK_APB divider APB=CK_MAIN/1
CSC_CK_AHB_Divider_Select(AHB_DIV_1); // Modify CK_AHB divider AHB=APB/1
/* CK_HS selection */
CSC_IHRCO_Select(IHRCO_12MHz); // IHRCO Sel 12MHz
CSC_IHRCO_Cmd(ENABLE);
while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
CSC_ClearFlag(CSC_IHRCOF);
CSC_CK_HS_Select(HS_CK_IHRCO); // CK_HS select IHRCO
/* PLL */
/**********************************************************/
CSC_PLL_CFG.InputDivider=PLLI_DIV_2; // 12M/2=6M
CSC_PLL_CFG.Multiplication=PLLIx16; // 6M*16=96M
CSC_PLL_CFG.OutputDivider=PLLO_DIV_2; // PLLO=96M/2=48M
CSC_PLL_Config(&CSC_PLL_CFG);
CSC_PLL_Cmd(ENABLE);
while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
CSC_ClearFlag(CSC_PLLF);
/**********************************************************/
/* CK_MAIN */
CSC_CK_MAIN_Select(MAIN_CK_HS);
/* Configure ICKO function */
/* Configure peripheral clock */
CSC_PeriphProcessClockSource_Config(CSC_SPI0_CKS, CK_APB);
CSC_PeriphOnModeClock_Config(CSC_ON_SPI0,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_DMA,ENABLE);
ProtectModuleReg(CSCprotect);
}
void InitSPI0(void)
{
PIN_InitTypeDef PINX_InitStruct;
//===Set CSC init====
//MG32x02z_CSC_Init.h(Configuration Wizard)
//Select CK_HS source = CK_IHRCO
//Select IHRCO = 12Mz
//Select CK_MAIN Source = CK_HS
//Configure PLL->Select APB Prescaler = CK_MAIN/1
/*=== 1. Enable CSC to SPI clock ===*/
//[A] When Use Wizard
//Configure Peripheral On Mode Clock->SPI0 = Enable and Select SPI0_PR Source = CK_APB
//Configure Peripheral On Mode Clock->Port B = Enable
//[B] When Use Driver
// UnProtectModuleReg(CSCprotect); // Unprotect CSC module
// CSC_PeriphOnModeClock_Config(CSC_ON_SPI0, ENABLE); // Enable SPI0 module clock
// CSC_PeriphOnModeClock_Config(CSC_ON_PortB, ENABLE); // Enable PortB clock
// CSC_PeriphProcessClockSource_Config(CSC_SPI0_CKS, CK_APB); // CK_SPIx_PR = CK_APB = 12MHz
// ProtectModuleReg(CSCprotect); // protect CSC module
/*=== 2. Default Initial SPI ===*/
SPI_DeInit(SPI0);
/*=== 3. Configure clock divider ===*/ // SPI clock = 1MHz
SPI_Clock_Select(SPI0, SPI_CK_SPIx_PR); // CK_SPIx = CK_SPIx_PR
SPI_PreDivider_Select(SPI0, SPI_PDIV_2); // PDIV outpu = CK_SPIx /2
SPI_Prescaler_Select(SPI0, SPI_PSC_3); // Prescaler outpu = PDIV outpu /3
SPI_Divider_Select(SPI0, SPI_DIV_2); // DIV outpu = PDIV outpu /2
/*=== 4. Configure SPI data line, mode and data size... ===*/
SPI_DataLine_Select(SPI0, SPI_Standard); // SPI data line 1-line Bidirectional~ SPI0_MOSI
SPI_ModeAndNss_Select(SPI0, SPI_MasterWithNss); // Master
SPI_ClockPhase_Select(SPI0, SPI_LeadingEdge); // CPHA = 0
SPI_ClockPolarity_Select(SPI0, SPI_Low); // CPOL = 0
SPI_FirstBit_Select(SPI0, SPI_MSB); // MSB first
SPI_DataSize_Select(SPI0, SPI_8bits); // Data size 8bits
/*=== 5. Config SPI0 IO ===*/
PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; // Pin select pusu pull mode
PINX_InitStruct.PINX_PUResistant = PINX_PUResistant_Enable; // Enable pull up resistor
PINX_InitStruct.PINX_Speed = PINX_Speed_Low;
PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output driver full strength.
PINX_InitStruct.PINX_FilterDivider = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
PINX_InitStruct.PINX_Inverse = PINX_Inverse_Disable; // Pin input data not inverse
PINX_InitStruct.PINX_Alternate_Function = 2; // Pin AFS = 2
GPIO_PinMode_Config(PINB(2),&PINX_InitStruct); // CLK setup at PB2
PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; // Pin select pusu pull mode
PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output drive strength 1/4
GPIO_PinMode_Config(PINB(3),&PINX_InitStruct); // MOSI setup at PB3
PINX_InitStruct.PINX_Alternate_Function = 2; // Pin AFS = 0
GPIO_PinMode_Config(PINB(0),&PINX_InitStruct); // NSS setup at PB0
PINX_InitStruct.PINX_Mode = PINX_Mode_OpenDrain_O;
GPIO_PinMode_Config(PINB(1),&PINX_InitStruct); // MISO setup at PB1
PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; // Pin select Push Pull mode
PINX_InitStruct.PINX_Alternate_Function = 0; // Pin AFS = 0
GPIO_PinMode_Config(PINE(13),&PINX_InitStruct); // PE13
GPIO_PinMode_Config(PINE(14),&PINX_InitStruct); // PE14
GPIO_PinMode_Config(PINE(15),&PINX_InitStruct); // PE15
/*=== 6. Enable SPI ===*/
SPI_Cmd(SPI0, ENABLE);
}
void DMA_Init(void)
{
DMA_BaseInitTypeDef DMATestPattern;
// ------------------------------------------------------------------------
// 1.Enable DMA
DMA_Cmd(ENABLE);
// ------------------------------------------------------------------------
// 2.Enable Channel0
DMA_Channel_Cmd(DMAChannel0, ENABLE);
// ------------------------------------------------------------------------
DMA_BaseInitStructure_Init(&DMATestPattern);
// 3.initial & modify parameter
// DMA channel select
DMATestPattern.DMAChx = DMAChannel0;
// channel x source/destination auto increase address
DMATestPattern.SrcSINCSel = ENABLE;
DMATestPattern.DestDINCSel = DISABLE;
// DMA source peripheral config
DMATestPattern.SrcSymSel = DMA_MEM_Read;
// DMA destination peripheral config
DMATestPattern.DestSymSel = DMA_SPI0_TX;
// DMA Burst size config
DMATestPattern.BurstDataSize = DMA_BurstSize_1Byte;
// DMA transfer data count initial number
DMATestPattern.DMATransferNUM = MYBINARYIMAGE2_LENGTH;
// source/destination config
DMATestPattern.DMASourceAddr = (uint32_t *)&SendBuf;
DMATestPattern.DMADestinationAddr = &SPI0->TDAT;
SPI_DMASend_Cmd(SPI0, ENABLE);
DMA_Channel_Cmd(DMAChannel0, ENABLE);
DMA_Base_Init(&DMATestPattern);
}
int main()
{
u32 i;
u8 x,y;
PIN_InitTypeDef PINX_InitStruct;
CSC_Init();
InitSPI0();
PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; // Pin select digital input mode
PINX_InitStruct.PINX_PUResistant = PINX_PUResistant_Enable; // Enable pull up resistor
PINX_InitStruct.PINX_Speed = PINX_Speed_Low;
PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output driver full strength.
PINX_InitStruct.PINX_FilterDivider = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
PINX_InitStruct.PINX_Inverse = PINX_Inverse_Disable; // Pin input data not inverse
PINX_InitStruct.PINX_Alternate_Function = 0; // Pin AFS = 0
GPIO_PinMode_Config(PINE(15),&PINX_InitStruct); // D6 setup at PE15
DMA_Init();
DMA_StartRequest(DMAChannel0);
i=0;
while(1)
{
i++;
if(i>=500000)
{
SPI_DMASend_Cmd(SPI0, ENABLE); //每次发送前都要使能一次
SPI_NSS=1;
SPI_NSS=0;
PE15=0;
SendBuf[0]=0x05;
PE15=0;
i=1;
DMA_StartRequest(DMAChannel0);
while (DMA_GetSingleFlagStatus(DMA, DMA_FLAG_CH0_TCF) == DRV_UnHappened);
DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
DMA_Channel_Cmd(DMAChannel0, DISABLE);
DMA_SetSourceAddress(DMAChannel0, SendBuf);
DMA_Channel_Cmd(DMAChannel0, ENABLE);
memset(SendBuf,0,sizeof(u8));
PE15=1;
}
}
}
这样就能实现SPI的DMA发送功能了,但是要记住,NSS还是需要自己手动拉高拉低的。
从机接收程序:
#include "MG32x02z_DRV.H"
#define URTX URT0
#define SPI_NSS PB0 // SPI_NSS
#define MYBINARYIMAGE2_LENGTH 20
uint8_t RcvBuf[MYBINARYIMAGE2_LENGTH] = {0};// __attribute__((at(0x20003800)));
void CSC_Init (void)
{
CSC_PLL_TyprDef CSC_PLL_CFG;
UnProtectModuleReg(MEMprotect); // Setting flash wait state
MEM_SetFlashWaitState(MEM_FWAIT_ONE); // 50MHz> Sysclk >=25MHz
ProtectModuleReg(MEMprotect);
UnProtectModuleReg(CSCprotect);
CSC_CK_APB_Divider_Select(APB_DIV_1); // Modify CK_APB divider APB=CK_MAIN/1
CSC_CK_AHB_Divider_Select(AHB_DIV_1); // Modify CK_AHB divider AHB=APB/1
/* CK_HS selection */
CSC_IHRCO_Select(IHRCO_12MHz); // IHRCO Sel 12MHz
CSC_IHRCO_Cmd(ENABLE);
while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
CSC_ClearFlag(CSC_IHRCOF);
CSC_CK_HS_Select(HS_CK_IHRCO); // CK_HS select IHRCO
/* PLL */
/**********************************************************/
CSC_PLL_CFG.InputDivider=PLLI_DIV_2; // 12M/2=6M
CSC_PLL_CFG.Multiplication=PLLIx16; // 6M*16=96M
CSC_PLL_CFG.OutputDivider=PLLO_DIV_2; // PLLO=96M/2=48M
CSC_PLL_Config(&CSC_PLL_CFG);
CSC_PLL_Cmd(ENABLE);
while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
CSC_ClearFlag(CSC_PLLF);
/**********************************************************/
/* CK_MAIN */
CSC_CK_MAIN_Select(MAIN_CK_HS);
/* Configure ICKO function */
/* Configure peripheral clock */
CSC_PeriphProcessClockSource_Config(CSC_SPI0_CKS, CK_APB);
CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);
CSC_PeriphOnModeClock_Config(CSC_ON_SPI0,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_UART0,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);
CSC_PeriphOnModeClock_Config(CSC_ON_DMA,ENABLE);
ProtectModuleReg(CSCprotect);
}
void InitSPI0(void)
{
PIN_InitTypeDef PINX_InitStruct;
//===Set CSC init====
//MG32x02z_CSC_Init.h(Configuration Wizard)
//Select CK_HS source = CK_IHRCO
//Select IHRCO = 12Mz
//Select CK_MAIN Source = CK_HS
//Configure PLL->Select APB Prescaler = CK_MAIN/1
/*=== 1. Enable CSC to SPI clock ===*/
//[A] When Use Wizard
//Configure Peripheral On Mode Clock->SPI0 = Enable and Select SPI0_PR Source = CK_APB
//Configure Peripheral On Mode Clock->Port B = Enable
//[B] When Use Driver
// UnProtectModuleReg(CSCprotect); // Unprotect CSC module
// CSC_PeriphOnModeClock_Config(CSC_ON_SPI0, ENABLE); // Enable SPI0 module clock
// CSC_PeriphOnModeClock_Config(CSC_ON_PortB, ENABLE); // Enable PortB clock
// CSC_PeriphProcessClockSource_Config(CSC_SPI0_CKS, CK_APB); // CK_SPIx_PR = CK_APB = 12MHz
// ProtectModuleReg(CSCprotect); // protect CSC module
/*=== 2. Default Initial SPI ===*/
SPI_DeInit(SPI0);
/*=== 3. Configure clock divider ===*/ // SPI clock = 1MHz
SPI_Clock_Select(SPI0, SPI_CK_SPIx_PR); // CK_SPIx = CK_SPIx_PR
SPI_PreDivider_Select(SPI0, SPI_PDIV_2); // PDIV outpu = CK_SPIx /2
SPI_Prescaler_Select(SPI0, SPI_PSC_3); // Prescaler outpu = PDIV outpu /3
SPI_Divider_Select(SPI0, SPI_DIV_2); // DIV outpu = PDIV outpu /2
/*=== 4. Configure SPI data line, mode and data size... ===*/
SPI_DataLine_Select(SPI0, SPI_Standard); // SPI data line 1-line Bidirectional~ SPI0_MOSI
SPI_ModeAndNss_Select(SPI0, SPI_SlaveWithNss); // Slave with NSS
//SPI_ModeAndNss_Select(SPI0, SPI_Slave); // Slave
SPI_NSSInputSignal_Select(SPI0,SPI_NssPin); // Nss
SPI_ClockPhase_Select(SPI0, SPI_LeadingEdge); // CPHA = 0
SPI_ClockPolarity_Select(SPI0, SPI_Low); // CPOL = 0
SPI_FirstBit_Select(SPI0, SPI_MSB); // MSB first
SPI_DataSize_Select(SPI0, SPI_8bits); // Data size 8bits
SPI_SlaveModeReceivedThreshold_Select(SPI0, SPI_1Byte); // Set SPI0 received data buffer high threshold
/*=== 5. Config SPI0 IO ===*/
PINX_InitStruct.PINX_Mode = PINX_Mode_Digital_I; // Pin select digital input mode
PINX_InitStruct.PINX_PUResistant = PINX_PUResistant_Enable; // Enable pull up resistor
PINX_InitStruct.PINX_Speed = PINX_Speed_Low;
PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output driver full strength.
PINX_InitStruct.PINX_FilterDivider = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
PINX_InitStruct.PINX_Inverse = PINX_Inverse_Disable; // Pin input data not inverse
PINX_InitStruct.PINX_Alternate_Function = 2; // Pin AFS = 2
GPIO_PinMode_Config(PINB(0),&PINX_InitStruct); // NSS setup at PB0
GPIO_PinMode_Config(PINB(2),&PINX_InitStruct); // CLK setup at PB26
PINX_InitStruct.PINX_Mode = PINX_Mode_OpenDrain_O; ; //PINX_Mode_PushPull_O;// PINX_Mode_OpenDrain_O; // Pin select Push Pull mode
GPIO_PinMode_Config(PINB(3),&PINX_InitStruct); // MOSI setup at PB3
PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; //PINX_Mode_PushPull_O; // Setting pusu pull mode
GPIO_PinMode_Config(PINB(1),&PINX_InitStruct); // MISO setup at PB1
PINX_InitStruct.PINX_Alternate_Function = 0; // Pin AFS = 0
GPIO_PinMode_Config(PINE(13),&PINX_InitStruct); // D4 setup at PE13
GPIO_PinMode_Config(PINE(14),&PINX_InitStruct); // D4 setup at PE13
GPIO_PinMode_Config(PINE(15),&PINX_InitStruct); // D6 setup at PE15
/*=== 6. Enable SPI ===*/
SPI_Cmd(SPI0, ENABLE); // Enable SPI
SPI_IT_Config(SPI0, SPI_INT_RX,ENABLE);
// SPI_ITEA_Cmd(SPI0, ENABLE);
}
void Sample_URT0_Init(void)
{
URT_BRG_TypeDef URT_BRG;
URT_Data_TypeDef DataDef;
PIN_InitTypeDef PINX_InitStruct;
//==Set CSC init
//MG32x02z_CSC_Init.h(Configuration Wizard)
//Select CK_HS source = CK_IHRCO
//Select IHRCO = 11.0592M
//Select CK_MAIN Source = CK_HS
//Configure PLL->Select APB Prescaler = CK_MAIN/1
//Configure Peripheral On Mode Clock->Port B/URT0 = Enable
//Configure Peripheral On Mode Clock->URT0->Select URT0_PR Source = CK_APB(11.0592)
//==Set GPIO init
//MG32x02z_GPIO_Init.h(Configuration Wizard)->Use GPIOB->Pin8/9
//GPIO port initial is 0xFFFF
//Pin8 mode is PPO/Pin9 mode is ODO
//Pin8/9 pull-up resister Enable
//Pin8/9 function URT0_TX/RX
PINX_InitStruct.PINX_Mode = PINX_Mode_PushPull_O; // Pin select Push Pull mode
PINX_InitStruct.PINX_PUResistant = PINX_PUResistant_Enable; // Enable pull up resistor
PINX_InitStruct.PINX_Speed = PINX_Speed_Low;
PINX_InitStruct.PINX_OUTDrive = PINX_OUTDrive_Level0; // Pin output driver full strength.
PINX_InitStruct.PINX_FilterDivider = PINX_FilterDivider_Bypass; // Pin input deglitch filter clock divider bypass
PINX_InitStruct.PINX_Inverse = PINX_Inverse_Disable; // Pin input data not inverse
PINX_InitStruct.PINX_Alternate_Function = 3; // Pin AFS = URT0_TX
GPIO_PinMode_Config(PINB(8),&PINX_InitStruct); // TXD at PB8
PINX_InitStruct.PINX_Mode = PINX_Mode_OpenDrain_O; // Pin select Open Drain mode
PINX_InitStruct.PINX_Alternate_Function = 3; // Pin AFS = URT0_RX
GPIO_PinMode_Config(PINB(9),&PINX_InitStruct); // RXD at PB9
//=====Set Clock=====//
//---Set BaudRate---//
URT_BRG.URT_InteranlClockSource = URT_BDClock_PROC;
URT_BRG.URT_BaudRateMode = URT_BDMode_Separated;
URT_BRG.URT_PrescalerCounterReload = 0; //Set PSR
URT_BRG.URT_BaudRateCounterReload = 3; //Set RLR
URT_BaudRateGenerator_Config(URTX, &URT_BRG); //BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
URT_BaudRateGenerator_Cmd(URTX, ENABLE); //Enable BaudRateGenerator
//---TX/RX Clock---//
URT_TXClockSource_Select(URTX, URT_TXClock_Internal); //URT_TX use BaudRateGenerator
URT_RXClockSource_Select(URTX, URT_RXClock_Internal); //URT_RX use BaudRateGenerator
URT_TXOverSamplingSampleNumber_Select(URTX, 25); //Set TX OS_NUM
URT_RXOverSamplingSampleNumber_Select(URTX, 25); //Set RX OS_NUM
URT_RXOverSamplingMode_Select(URTX, URT_RXSMP_3TIME);
URT_TX_Cmd(URTX, ENABLE); //Enable TX
URT_RX_Cmd(URTX, ENABLE); //Enable RX
//=====Set Mode=====//
//---Set Data character config---//
DataDef.URT_TX_DataLength = URT_DataLength_8;
DataDef.URT_RX_DataLength = URT_DataLength_8;
DataDef.URT_TX_DataOrder = URT_DataTyped_LSB;
DataDef.URT_RX_DataOrder = URT_DataTyped_LSB;
DataDef.URT_TX_Parity = URT_Parity_No;
DataDef.URT_RX_Parity = URT_Parity_No;
DataDef.URT_TX_StopBits = URT_StopBits_1_0;
DataDef.URT_RX_StopBits = URT_StopBits_1_0;
DataDef.URT_RX_DataInverse = DISABLE;
DataDef.URT_RX_DataInverse = DISABLE;
URT_DataCharacter_Config(URTX, &DataDef);
//---Set Mode Select---//
URT_Mode_Select(URTX, URT_URT_mode);
//---Set DataLine Select---//
URT_DataLine_Select(URTX, URT_DataLine_2);
//=====Set Error Control=====//
// to do...
//=====Set Bus Status Detect Control=====//
// to do...
//=====Set Data Control=====//
URT_RXShadowBufferThreshold_Select(URTX, URT_RXTH_1BYTE);
URT_IdlehandleMode_Select(URTX, URT_IDLEMode_No);
URT_TXGaudTime_Select(URTX, 0);
//=====Enable URT Interrupt=====//
URT_IT_Cmd(URTX, URT_IT_RX, ENABLE);
URT_ITEA_Cmd(URTX, ENABLE);
NVIC_EnableIRQ(URT0_IRQn);
//=====Enable URT=====//
URT_Cmd(URTX, ENABLE);
//==See MG32x02z_URT0_IRQ.c when interrupt in
}
int fputc(int ch,FILE *f)
{
URT_SetTXData(URTX,1,ch);
while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
URT_ClearITFlag(URTX,URT_IT_TC);
return ch;
}
void UartSendByte(int ch)
{
URT_SetTXData(URTX,1,ch);
while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
URT_ClearITFlag(URTX,URT_IT_TC);
}
void DMA_Init(void)
{
DMA_BaseInitTypeDef DMATestPattern;
// ------------------------------------------------------------------------
// 1.Enable DMA
DMA_Cmd(ENABLE);
// ------------------------------------------------------------------------
// 2.Enable Channel0
DMA_Channel_Cmd(DMAChannel0, ENABLE);
// ------------------------------------------------------------------------
DMA_BaseInitStructure_Init(&DMATestPattern);
// 3.initial & modify parameter
// DMA channel select
DMATestPattern.DMAChx = DMAChannel0;
// channel x source/destination auto increase address
DMATestPattern.SrcSINCSel = DISABLE;//ENABLE;
DMATestPattern.DestDINCSel = ENABLE;
// DMA source peripheral config
DMATestPattern.SrcSymSel = DMA_SPI0_RX;
// DMA destination peripheral config
DMATestPattern.DestSymSel = DMA_MEM_Write;
// DMA Burst size config
DMATestPattern.BurstDataSize = DMA_BurstSize_1Byte;
// DMA transfer data count initial number
DMATestPattern.DMATransferNUM = MYBINARYIMAGE2_LENGTH;
// source/destination config
DMATestPattern.DMASourceAddr = &SPI0->RDAT;
DMATestPattern.DMADestinationAddr = (uint32_t *)&RcvBuf;//DMA_URT0_TX;// (uint8_t *)&RcvBuf;
SPI_DMAReceive_Cmd(SPI0, ENABLE);
DMA_Channel_Cmd(DMAChannel0, ENABLE);
DMA_Base_Init(&DMATestPattern);
}
int main()
{
u32 i;
PIN_InitTypeDef PINX_InitStruct;
CSC_Init();
InitSPI0();
Sample_URT0_Init();
DMA_Init();
DMA_StartRequest(DMAChannel0);
i=0;
while(1)
{
i++;
if(i>=100000)
{
i=0;
SPI_DMAReceive_Cmd(SPI0, ENABLE);
if(RcvBuf[0]!=0)printf("RX:0x%02X\n",RcvBuf[0]);
memset(RcvBuf,0,20*sizeof(u8));
DMA_ClearFlag(DMA, DMA_FLAG_CH0_TCF);
DMA_Channel_Cmd(DMAChannel0, DISABLE);
DMA_SetDestinationAddress(DMAChannel0, RcvBuf);
DMA_Channel_Cmd(DMAChannel0, ENABLE);
DMA_StartRequest(DMAChannel0);
}
}
}
|
|