2013-09-05 02:34 PM
Hi,
I work with STM32F100RB chip and i got a little problem with editting registers of some peripheral. I got a problem with edit DMA registers. Even if I use code from DMA example in my project and build it, then flash it, I can not see any changes in registers(just zeros) or memory. But if i try built an example, it works well. But when i copy the code of DMA Configuration I got this problem. i've tried 3 independent chips and i've tried made it in Keil, Atollic TrueStudio and IAR. But i got same results. What is really wierd is that at first time it work with no problem, but next day nothing work. Could anyone please help me?2013-09-05 03:47 PM
The most probable cause of peripheral registers sticking at zero is the lack of a clock. The clock is either not enabled, or has been enabled on the wrong bus, ie APB1, APB2, AHB, etc., or a Reset vs Clock command.
If you want the code critiqued then you'll need to post a complete example.2013-09-06 02:48 AM
Ok, here is whole code:
#include <stdint.h>#include ''stm32f10x_gpio.h''#include ''stm32f10x_flash.h''#include ''stm32f10x_rcc.h'' #include ''stm32f10x_adc.h''#include ''stm32f10x_dma.h''#include ''stm32f10x_conf.h''#define __EFI_ACR_Val 0x00000012 //adress for flash#define ADC1_DR_Address ((uint32_t)0x4001244C) //register's adress DR ADC1 for DMAvoid embedded_flash_config(void);void clock_setup(void);void GPIO_Configuration(void);void ADC_Configuration(void);void DMA_Configuration(void);void Delay(vu32 nCount);__IO uint16_t ADCConvertedValue=0;DMA_InitTypeDef DMA_InitStructure;int main(void){ clock_setup(); embedded_flash_config(); DMA_Configuration(); ADC_Configuration(); GPIO_Configuration(); /*start conversion*/ ADC_SoftwareStartConvCmd(ADC1, ENABLE); /*waiting for end */ while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);//just for test that all have done while(1) { };}void clock_setup(void){RCC_HSICmd(ENABLE); // HSI src of clk = 8MHzRCC_AdjustHSICalibrationValue(16); // HSI trimingRCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12); // src of PLL = 12 * HSI/2 = 48MHzRCC_PLLCmd(ENABLE); // PLL onRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Sysclock = PLLCLK = 48MHzRCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = sysclock = 48MHzRCC_PCLK1Config(RCC_HCLK_Div2); // ABP1 = HCLK/2 = 24MHzRCC_PCLK2Config(RCC_HCLK_Div1); // ABP2 = HCLK/1 = 48MHzRCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); // USBclk = PLLCLK/1 = 48MHzRCC_ADCCLKConfig(RCC_PCLK2_Div4); // ADCclk = ABP2/4 =12MHzRCC_LSEConfig(RCC_LSE_OFF); // LSE off// enable clk for peripherals. all ports+ ADC1 + DMA1RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1 | RCC_AHBPeriph_DMA1, ENABLE); } ; void embedded_flash_config(void){FLASH->ACR = __EFI_ACR_Val;} ;void GPIO_Configuration(void){ /*struct fo init */ GPIO_InitTypeDef GPIO_InitStructure; /* conf pin PC7 as output push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure);}void ADC_Configuration(void){ ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent ; //mode independent ADC_InitStructure.ADC_ScanConvMode = disable; //dasiable scant ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //disable continously conversion ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //no ext trig ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // right LSB ADC_InitStructure.ADC_NbrOfChannel = 1; //number of channels ADC_Init(ADC1, &ADC_InitStructure); //init DC_InitStructure//configuration of channel 14 ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_1Cycles5); ADC_DMACmd(ADC1, ENABLE); //enable DMA for ADC1 /*set the pin 4, port C as analog input*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //ADC vstup GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //speed GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //pin mode GPIO_Init(GPIOC, &GPIO_InitStructure); ADC_Cmd(ADC1, ENABLE);//turn on ADC /* reset calibration data */ ADC_ResetCalibration(ADC1); /* waiting for end cal */ while(ADC_GetResetCalibrationStatus(ADC1)); /*start calibration*/ ADC_StartCalibration(ADC1); /*waiting for end of cal*/ while(ADC_GetCalibrationStatus(ADC1)); } void DMA_Configuration(void){ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE);} void Delay(vu32 nCount){ while (nCount--);}2013-09-06 03:37 AM
// enable clk for peripherals. all ports+ ADC1 + DMA1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1 | RCC_AHBPeriph_DMA1, ENABLE);
That doesn't match.
2013-09-06 03:44 AM
Well a couple of issues immediately evident here.
What tool chain and library are you using here? The current CMSIS library normally sets up the PLL etc in SystemInit() in system_stm32f10x.c. The current code does not dwell waiting for clocks, PLL, etc to start. Note as pointed out before that DMA1 is on AHB not APB2, thus the clock on the WRONG bus is being enabled. If you expect the ADC conversion to be repeatedly loaded to memory via DMA, then you'd need to use the Continuous mode. A sample rate of 1.5 cycles is going to give very noisy results2013-09-06 04:22 AM
A thank you clive1, it works now. I see no reason to use continously mode for ADC, cause through DMA i send only one packet just for example. But thank you guys much again!