Sida 77 av 81
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 15:10:44
av DanielM
Nu har jag lött ihop kortet och hittade 1 fel. LSE vägrar starta.
Skärmklipp.PNG
Det jag har gjort är.
- Se till så att VBAT ha 3.3V - OK
- Se till så att LSE kristallen är korrekt lött - OK
- Testa köra utan LSE och istället med LSI och kolla om processorn startar, vilket den gör - OK
- Lött om kondensatorerna då det var JLCPCB som lödde åt mig - OK
- Testat köra LSE utan kondensatorer, vilket gav samma fel, dvs processorn startade inte. - OK
- Testade köra med ett exakt likadant kort, gav samma fel - OK
- Jag har testat ändra rotation på kristallen, samma resultat som ovan - OK
Kristallen har 15pF avkopplingskondensatorer och kristallen är en FC-12M 32.7680KA-A5. Vad tror ni är orsaken?
Skärmklipp.PNG
https://www.mouser.se/ProductDetail/Eps ... AKdVirMQ==
Skärmklipp.PNG
Jag har till och med valt rekommenderad LSE kristall från STM32.
https://www.st.com/resource/en/applicat ... ronics.pdf
Skärmklipp.PNG
Jag har även följt deras rekommendation.
Skärmklipp.PNG
Skärmklipp.PNG
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 15:38:28
av rvl
Själv hade jag satt kristallen betydligt närmare processorn och kondensatorerna "utanför".
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 15:48:05
av DanielM
Hur det ser ut i verkligheten. Det är ca 10mm från processorn.
Skärmklipp.PNG
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 16:20:16
av rvl
Så C20 är ansluten till en pad där det står GND utan att vara ansluten någonstans i verkligheten???
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 16:36:31
av DanielM
C20 är ansluten till GND.
Skärmklipp.PNG
Nu gjorde jag ett ytterligare test med ett annat kort. Det visar sig att det andra kortet har exakt samma problem.

Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 20:33:35
av Rick81
Jag tror LSE startar vare sig du har kristall eller inte bara den inte blir så exakt. Så tror det är nåt i koden.
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 20:55:33
av DanielM
Ja. Det måste vara något i koden. Den kan väll inte vara så exakt? Eller så har jag bränt kristallen? Jag har på ca 350 grader på min lödpenna. Notera att 350 grader kanske är 250-280 grader ute i spetsen. Ja, lödpennan är gammal som gatan. 1987 har jag för mig. Men kristallen är inte svart eller liknande. Väldigt ren och fin. Lite ripig med tanke på att jag fick flytta den med pincetten.
Du menar att koden kräver överdrivet mycket preision och därmed så nekar den uppstartet?
Edit:
Jag testade att busa mig förbi detta, men det slutade med att jag hamnade i Never Ending Story, dvs error while(1).
Skärmklipp.PNG
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 20:56:14
av TomasL
Kondingarna bör väl vara runt 25pF styck, inte 15pF som du har ritat
1/Cl=1/C1+1/C2 -> 1/12,5 = 1/C1+1/C2 -> 0,08=2*1/C -> 1/C=0,04 -> C=25
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 21:07:36
av DanielM
Jag har bara gått ut efter denna manual.
Skärmklipp.PNG
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 21:27:36
av Rick81
Du menar att koden kräver överdrivet mycket preision och därmed så nekar den uppstartet?
Jag menar att du gör nåt fel med initieringen i koden. Har för mig jag felaktigt aktiverade LSE konfad för kristall på en STM32 men den funkade ändå trots jag inte hade kristall ansluten.
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 21:32:34
av DanielM
Jag har sökt ganska länge på hur jag ska göra, men det finns inte så mycket att välja när det kommer till LSE.
I detta fall så fungerar inte RTC om jag fuskar mig förbi LSE som jag visade ovan.
Då hamnar jag här.
Skärmklipp.PNG
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 22:46:01
av Klas-Kenny
Posta all relevant kod så kanske du kan få någon hjälp...
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 22:52:12
av DanielM
Här är första funktionen som programmet anropar.
Kod: Markera allt
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_HIGH);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) <------------------------------------------- Här kommer felet.
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB|RCC_PERIPHCLK_USART1
|RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_SDADC;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL;
PeriphClkInit.SdadcClockSelection = RCC_SDADCSYSCLK_DIV2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
HAL_PWREx_EnableSDADC(PWR_SDADC_ANALOG1);
HAL_PWREx_EnableSDADC(PWR_SDADC_ANALOG2);
HAL_PWREx_EnableSDADC(PWR_SDADC_ANALOG3);
}
Sedan vid denna kod.
Kod: Markera allt
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
Så kommer felet här.
Kod: Markera allt
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
Vid denna kod.
Kod: Markera allt
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
{
uint32_t tickstart;
uint32_t pll_config;
#if defined(RCC_CFGR_PLLSRC_HSI_PREDIV)
uint32_t pll_config2;
#endif /* RCC_CFGR_PLLSRC_HSI_PREDIV */
/* Check Null pointer */
if(RCC_OscInitStruct == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
/*------------------------------- HSE Configuration ------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
{
/* Check the parameters */
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
/* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSE)
|| ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE)))
{
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
{
return HAL_ERROR;
}
}
else
{
/* Set the new HSE configuration ---------------------------------------*/
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
#if defined(RCC_CFGR_PLLSRC_HSI_DIV2)
/* Configure the HSE predivision factor --------------------------------*/
__HAL_RCC_HSE_PREDIV_CONFIG(RCC_OscInitStruct->HSEPredivValue);
#endif /* RCC_CFGR_PLLSRC_HSI_DIV2 */
/* Check the HSE State */
if(RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till HSE is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
else
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till HSE is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
}
/*----------------------------- HSI Configuration --------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
{
/* Check the parameters */
assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_HSI)
|| ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && (__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI)))
{
/* When HSI is used as system clock it will not disabled */
if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON))
{
return HAL_ERROR;
}
/* Otherwise, just the calibration is allowed */
else
{
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
}
}
else
{
/* Check the HSI State */
if(RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
{
/* Enable the Internal High Speed oscillator (HSI). */
__HAL_RCC_HSI_ENABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till HSI is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
}
else
{
/* Disable the Internal High Speed oscillator (HSI). */
__HAL_RCC_HSI_DISABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till HSI is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
}
/*------------------------------ LSI Configuration -------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
{
/* Check the parameters */
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
/* Check the LSI State */
if(RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
{
/* Enable the Internal Low Speed oscillator (LSI). */
__HAL_RCC_LSI_ENABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSI is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
else
{
/* Disable the Internal Low Speed oscillator (LSI). */
__HAL_RCC_LSI_DISABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSI is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
/*------------------------------ LSE Configuration -------------------------*/
if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
{
FlagStatus pwrclkchanged = RESET;
/* Check the parameters */
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
/* Update LSE configuration in Backup Domain control register */
/* Requires to enable write access to Backup Domain of necessary */
if(__HAL_RCC_PWR_IS_CLK_DISABLED())
{
__HAL_RCC_PWR_CLK_ENABLE();
pwrclkchanged = SET;
}
if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
/* Enable write access to Backup domain */
SET_BIT(PWR->CR, PWR_CR_DBP);
/* Wait for Backup domain Write protection disable */
tickstart = HAL_GetTick();
while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
{
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
/* Set the new LSE configuration -----------------------------------------*/
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
/* Check the LSE State */
if(RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSE is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT; // <--------------------------------------- Här är felet
}
}
}
else
{
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till LSE is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
/* Require to disable power clock if necessary */
if(pwrclkchanged == SET)
{
__HAL_RCC_PWR_CLK_DISABLE();
}
}
/*-------------------------------- PLL Configuration -----------------------*/
/* Check the parameters */
assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE)
{
/* Check if the PLL is used as system clock or not */
if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
{
if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON)
{
/* Check the parameters */
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL));
#if defined(RCC_CFGR_PLLSRC_HSI_PREDIV)
assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV));
#endif
/* Disable the main PLL. */
__HAL_RCC_PLL_DISABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till PLL is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
#if defined(RCC_CFGR_PLLSRC_HSI_PREDIV)
/* Configure the main PLL clock source, predivider and multiplication factor. */
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
RCC_OscInitStruct->PLL.PREDIV,
RCC_OscInitStruct->PLL.PLLMUL);
#else
/* Configure the main PLL clock source and multiplication factor. */
__HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource,
RCC_OscInitStruct->PLL.PLLMUL);
#endif /* RCC_CFGR_PLLSRC_HSI_PREDIV */
/* Enable the main PLL. */
__HAL_RCC_PLL_ENABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till PLL is ready */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET)
{
if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
else
{
/* Disable the main PLL. */
__HAL_RCC_PLL_DISABLE();
/* Get Start Tick */
tickstart = HAL_GetTick();
/* Wait till PLL is disabled */
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET)
{
if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
}
else
{
/* Check if there is a request to disable the PLL used as System clock source */
if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
{
return HAL_ERROR;
}
else
{
/* Do not return HAL_ERROR if request repeats the current configuration */
pll_config = RCC->CFGR;
#if defined(RCC_CFGR_PLLSRC_HSI_PREDIV)
pll_config2 = RCC->CFGR2;
if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
(READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL) ||
(READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV))
#else
if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
(READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL))
#endif
{
return HAL_ERROR;
}
}
}
}
return HAL_OK;
}
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 22:57:53
av TomasL
DanielM skrev: ↑2 juni 2021, 21:07:36
Jag har bara gått ut efter denna manual.
Skärmklipp.PNG
Jag skulle nog öka kondingarna, du har utgått ifrån att du har 5pF strökapacitans, men det är ju bara ett exempel.
Sätt dit 20 -25 pF kondingar, och se om det funkar, om det funkar mät med oscilloscop för att se hur kurvformen ser ut.
Därefter kan du anpassa dig.
Re: Förslag på PWM, ADC, I/O och DAC IC kretsar med SPI?
Postat: 2 juni 2021, 23:36:31
av DanielM
Du har nog rätt.
Jag får köpa ett gäng kodensatorer, och kanske till och med andra kristaller. Testa mig fram.