- CO3009 -
- Embedded C Programming -
CO3009 – Embedded C Programming 2
A Simple C program
void FSM(); /**
void main(void){ * @brief Period elapsed callback in non blocking mode
// initialize the device * @param htim : TIM handle
System_Initialization(); * @retval None */
while (1) { void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef
FSM(); *htim) {
} SCH_Update();
} }
/**
* @brief This function handles TIM interrupt request.
* @param None
* @retval None */
void TIM3_IRQHandler(void){
HAL_TIM_IRQHandler(&TimHandle);
}
[email protected]
CO3009 – Embedded C Programming 3
A main() Function
§ System initialization
▫ Oscillator
▫ Input/Output
▫ Special peripherals/modules: Timers, CCP, ADC
▫ Disable/Enable interrupt
§ A super loop while(1)
§ One or more finite state machine (FSM)
[email protected]
CO3009 – Embedded C Programming 4
System Initialization
[email protected]
CO3009 – Embedded C Programming 5
HAL_Init
§ This function is used to initialize the HAL Library; it must be the first
instruction to be executed in the main program (before to call any other HAL
function), it performs the following:
▫ Configure the Flash prefetch.
▫ Configures the SysTick to generate an interrupt each 1 millisecond, which is clocked by
the HSI (at this stage, the clock is not yet configured and thus the system is running from
the internal HSI at 16 MHz).
▫ Set NVIC Group Priority to 4.
▫ Calls the HAL_MspInit() callback function defined in user file "stm32f1xx_hal_msp.c" to
do the global low level hardware initialization
▫ @note SysTick is used as time base for the HAL_Delay() function, the application need
to ensure that the SysTick time base is always set to 01 millisecond to have correct HAL
operation.
▫ @retval HAL status
[email protected]
CO3009 – Embedded C Programming 6
HAL_Init
[email protected]
CO3009 – Embedded C Programming 7
SystemClock_Config
[email protected]
CO3009 – Embedded C Programming 8
Clocks
Three different clock sources can be used to drive the system clock (SYSCLK):
• HIS (High-Speed Internal) oscillator clock
• HSE (High-Speed External) oscillator clock
• PLL (Phase-Locked Loop) clock
The devices have the following two secondary clock sources:
• 40 kHz low speed internal RC (LSI RC), which drives the independent watchdog and optionally
the RTC used for Auto-wakeup from Stop/Standby mode.
• 32.768 kHz low speed external crystal (LSE crystal), which optionally drives the real-time clock
(RTCCLK)
Each clock source can be switched on or off independently when it is not used, to
optimize power consumption.
[email protected]
CO3009 – Embedded C Programming 9
STM32F103 Family
Clockc Diagram
[email protected]
CO3009 – Embedded C Programming 10
MX_GPIO_Init
[email protected]
CO3009 – Embedded C Programming 11
Input Output Pins Initialization
[email protected]
CO3009 – Embedded C Programming 12
UART3_Init
[email protected]
CO3009 – Embedded C Programming 13
Timer_Init
Configure the TIM peripheral
In this example TIM3 input clock (TIM3CLK) is set to APB1 clock (PCLK1) x2, since APB1 prescaler is set to
4 (0x100).
TIM3CLK = PCLK1*2
§ PCLK1 = HCLK/2
§ => TIM3CLK = PCLK1*2 = (HCLK/2)*2 = HCLK = SystemCoreClock
§ To get TIM3 counter clock at 10 KHz, the Prescaler is computed as following:
§ Prescaler = (TIM3CLK / TIM3 counter clock) - 1
§ Prescaler = (SystemCoreClock /10 KHz) - 1
Note:
§ SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f1xx.c file.
§ Each time the core clock (HCLK) changes, user had to update SystemCoreClock variable value.
Otherwise, any configuration based on this variable will be incorrect.
§ This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetSysClockFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
[email protected]
CO3009 – Embedded C Programming 14
An FSM Function
enum {St_Intro, St_Voltmeter, St_Temperature, St_Clock,} State_Machine;
unsigned char State = St_Intro;
void FSM(){
switch (State)
{
case St_Intro:
Intro();
break;
case St_Voltmeter:
Voltmeter();
break;
case St_Temperature:
Temperature();
break;
case St_Clock:
Clock();
break;
}
}
[email protected]