2016-06-18 11:19 PM
hi
I wanna use external ADS7816 ADC with serial (SPI) interface. I wrote the following code but it doesn't work! spi sclk pin has clock and I use PA0 to manage ADS1768 comunication as slave (SS). the problem is that I see output of ADS7816 on oscilloscope but DMA has no interrupt! where is the wrong in my code?!&sharpdefine SPI1_RX_BUFF_SIZE 32__IO uint8_t ExtAdcRxBuff[SPI1_RX_BUFF_SIZE];void SPI_Config(void){ SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); /*!< Enable GPIO clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /*!< SPI pins configuration *************************************************/ /*!< Connect SPI pins to AF5 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1 ); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1 ); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1 ); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; /*!< SPI SCK pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_Init(GPIOA, &GPIO_InitStructure); /*!< SPI MOSI pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); /*!< SPI MISO pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_Init(GPIOA, &GPIO_InitStructure); /*!< Configure CS pin in output pushpull mode ********************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /*!< SPI configuration */ SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; // APB2 / 8 = 10.5 MHz SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; SPI_Init(SPI1, &SPI_InitStructure); /*!< Enable the SPI */ SPI_Cmd(SPI1, ENABLE); }void ADS1768_DMA_Init(void){ DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* Enable RCC clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); /* Disable stream if it was in use */ DMA_DeInit(DMA2_Stream0); while(RESET != DMA_GetCmdStatus(DMA2_Stream0)); /* Initiliaze DMA2 Channel 3 Stream 0 */ DMA_InitStructure.DMA_Channel = DMA_Channel_3; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1->DR); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) (ExtAdcRxBuff); DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_BufferSize = SPI1_RX_BUFF_SIZE; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); /* Inialize NVIC for the DMA interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Connect SPI and DMA2 */ SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable DMA2 Channel 3 Stream 0 for the SPI1 RX */ DMA_Cmd(DMA2_Stream0, ENABLE);}void SPI_PORT_DMA_RX_IRQHandler(void) // 2 Hz - for CPP use extern ''C''{ /* Test on DMA Stream Transfer Complete interrupt */ if (DMA_GetITStatus(DMA2_Stream0, SPI_I2S_DMAReq_Rx)) { /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream0, SPI_I2S_DMAReq_Rx); /* End of RX */ GPIO_ToggleBits(GPIOF,GPIO_Pin_7); // Add code here to process things }} #spi #stm32f4 #external-adc2016-06-18 11:52 PM
I change the last of code as follow. DAM interrupt is run but it doesn't seem to relate to the MISO pin! because I disconnect ADS7816 data out pin and the DMA has interrupt!!
/* Connect SPI and DMA2 */
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);
/* Enable DMA transfer complete interrupt */
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); //ADD THIS LINE IN NEW CODE
/* Enable DMA2 Channel 3 Stream 0 for the SPI1 RX */
DMA_Cmd(DMA2_Stream0, ENABLE);
}
void DMA2_Stream0_IRQHandler(void)
{
/* Test on DMA Stream Transfer Complete interrupt */
if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) //CHANG THIS PART IN NEW CODE
{
/* Clear DMA Stream Transfer Complete interrupt pending bit */
DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
/* Toggle LED3 : End of Transfer */
GPIO_ToggleBits(GPIOF,GPIO_Pin_7); //discovery board
// Add code here to process things
}
}
2016-06-19 12:10 AM
Could that be because you are still clocking the SPI interface and the STM32 just latches the voltage it sees associates with the pin regardless of what you have attached to it?
2016-06-19 01:12 AM
I didn't understand what you mean! I disconnect the clock pin too, but interrupt is running! is my code right? I think I make some mistake in my code!
2016-06-19 05:31 AM
If the STM32 is the SPI master it is generating ALL the clocks IT is using internally. The TX and RX share the same clock, being that SPI is symetrical.
It is going to function regardless of what you attach externally, you'll just get bogus data returned in your buffer if nothing is supplying valid data.2016-06-19 09:49 PM
you'll just get bogus data returned in your buffer if nothing is supplying valid data
how can i fix this bug? can you please correct it?
ADS7816 is a signle chanel adc. it has just 3 pin for communication. it just send data to uc after sampling. so i don't need to send any data to it. i use spi just for receive data. I config its 3 pins as follow:closk pin of ads7816 --> uc sckchip seclect of ads7816 --> PA0 (when this pin is 0 adc start sampling and send it)data out of ads7816 -->MISO of ucI see the data that send from ads7816 when its chip select pin is 0. I don't know how can i buffer its data now! ,my code that I write it at forst post, don't work correctly, its DMA interrupt even when I power off the ads7816!!!