Barry
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # STM32 G4 Series ###### tags: `STM32` ## [STM32G4 MCU Series 32-bit Arm M4(DSP+FPU)-170MHz](https://www.st.com/en/microcontrollers-microprocessors/stm32g4-series.html) ![](https://i.imgur.com/zkqQO7a.png) ### [STM32G4x4](https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-mainstream-mcus/stm32g4-series/stm32g4x4.html#documentation) * RM0440 Reference manual - STM32G4 Series advanced Arm®-based 32-bit MCUs - Table 2. Product specific features (continued) ![](https://i.imgur.com/xjnxsYR.png) * 1.5 Availability of peripherals ![](https://i.imgur.com/aMh6y1I.png) ![](https://i.imgur.com/9kupfib.png) ![](https://i.imgur.com/vZjRsX6.png) * IO registers * 2.4.2 CCM SRAM Write protection * 7.4 RCC registers * 9.4 GPIO registers * 10.2 SYSCFG registers * 12.6 DMA registers * 21.7 ADC registers (for each ADC) * 22.7 DAC registers * 28.6 TIM1/TIM8/TIM20 registers * 29.5 TIM2/TIM3/TIM4/TIM5 registers * 29.4.28 TIM2/TIM3/TIM4/TIM5 low-power modes * 37.8 USART registers * 41.7 I2C registers * [RM0440STM32G4 Series advanced Arm®-based 32-bit MCUs](https://www.st.com/resource/en/reference_manual/rm0440-stm32g4-series-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) ![](https://i.imgur.com/FOyFcaU.png) #### Memory map * 2.2.2 Memory map and register boundary addresses * STM32G474XX.H ## [STM32CubeG4 - STM32Cube MCU Package for STM32G4 series (HAL, Low-Layer APIs and CMSIS, USB, File system, RTOS, Graphic - and examples running on ST boards)](https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-mcu-mpu-packages/stm32cubeg4.html#documentation) * STM32G4 Documentation * Datasheet ### [STM32CubeG4 firmware components](https://www.st.com/resource/en/user_manual/um2492-getting-started-with-stm32cubeg4-for-stm32cubeg4-series-stmicroelectronics.pdf) * UM2492 Getting started with STM32CubeG4 for STM32CubeG4 Series 2.0 25 Jun 2020 ![](https://i.imgur.com/oaKR37y.png) ![](https://i.imgur.com/mEgNOjU.png) ![](https://i.imgur.com/VjcIcgB.png) ## [Description of STM32G4 HAL and low-layer drivers](https://www.st.com/resource/en/user_manual/um2570-description-of-stm32g4-hal-and-lowlayer-drivers--stmicroelectronics.pdf) * UM2570 Description of STM32G4 HAL and low-layer drivers 2.0 10 Aug 2020 * The HAL drivers are designed to offer a rich set of APIs and to interact easily with the application upper layers. * Each driver consists of a set of functions covering the most common peripheral features. * The development of each driver is driven by a common API which standardizes the driver structure, the functions and the parameter names. * The HAL drivers include a set of driver modules, each module being linked to a standalone peripheral. However, in some cases, the module is linked to a peripheral functional mode. As an example, several modules exist for the USART peripheral: UART driver module, USART driver module, SMARTCARD driver module and IRDA driver module. ## Systemy Clock * UM2570 Description of STM32G4 HAL and low-layer drivers 2.0 10 Aug 2020 ### RCC Firmware driver API description * 45.2.2 Initialization and de-initialization functions * 767 * This section provides functions allowing to configure the internal and external oscillators (HSE, HSI, LSE, LSI,PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB1 and APB2). Internal/external clock and PLL configuration * HSI (high-speed internal): 16 MHz factory-trimmed RC used directly or through the PLL as System clock source. * LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC clock source. * HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or through the PLL as System clock source. Can be used also optionally as RTC clock source. * LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source. * PLL (clocked by HSI, HSE) providing up to three independent output clocks: * The first output is used to generate the high speed system clock (up to 170 MHz). * The second output is used to generate the clock for the USB (48 MHz), the QSPI (<= 48 MHz), the FDCAN, the SAI and the I2S. * The third output is used to generate a clock for ADC * CSS (Clock security system): once enabled, if a HSE clock failure occurs (HSE used directly or through PLL as System clock source), the System clock is automatically switched to HSI and an interrupt is generated if enabled. * The interrupt is linked to the Cortex-M4 NMI (Non-Maskable Interrupt) exception vector. * MCO (microcontroller clock output): used to output LSI, HSI, LSE, HSE, main PLL clock, system clock or RC48 clock (through a configurable prescaler) on PA8 pin. System, AHB and APB busses clocks configuration * Several clock sources can be used to drive the System clock (SYSCLK): HSI, HSE and main PLL. The AHB clock (HCLK) is derived from System clock through configurable prescaler and used to clock the CPU, memory and peripherals mapped on AHB bus (DMA, GPIO...). APB1 (PCLK1) and APB2 (PCLK2) clocks are derived from AHB clock through configurable prescalers and used to clock the peripherals mapped on these busses. * You can use "HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks. ### PLL configuration register (RCC_PLLCFGR) * Address offset: 0x0C * Reset value: 0x0000 1000 * Access: no wait state, word, half-word and byte access * This register is used to configure the PLL clock outputs according to the formulas: ``` * f(VCO clock) = f(PLL clock input) × (PLLN / PLLM) * f(PLL_P) = f(VCO clock) / PLLP * f(PLL_Q) = f(VCO clock) / PLLQ * f(PLL_R) = f(VCO clock) / PLLR ``` #### Clock Source / (PLLM + 1) * PLLN / PLL * PLL = 240000000 / (5+1) * 85 / 2 = 170000000 Hz -> 170 MHz * PLL = 480000000 / (11+1) *85 / 2 = 170000000 Hz -> 170 Mhz ### Clock Register - PLLP: Main PLL division factor for PLL “P” clock. - Set and cleared by software to control the frequency of the main PLL output clock PLL “P” clock. These bits can be written only if PLL is disabled. - When the PLLPDIV[4:0] is set to “00000”PLL “P” output clock frequency = VCO frequency / PLLP with PLLP =7, or 17 - 0: PLLP = 7 1: PLLP = 17 - PLLM[3:0]: Division factor for the main PLL input clock Set and cleared by software to divide the PLL input clock before the VCO. These bits can be written only when all PLLs are disabled. VCO input frequency = PLL input clock frequency / PLLM with 1 <= PLLM <= 16 - 0000: PLLM = 1 0001: PLLM = 2 0010: PLLM = 3 0011: PLLM = 4 0100: PLLM = 5 0101: PLLM = 6 0110: PLLM = 7 0111: PLLM = 8 1000: PLLSYSM = 9 ... 1111: PLLSYSM = 16 * PLLN[6:0]: Main PLL multiplication factor for VCO Set and cleared by software to control the multiplication factor of the VCO. These bits can be written only when the PLL is disabled. * VCO output frequency = VCO input frequency x PLLN with 8 =< PLLN =< 127 - 0000000: PLLN = 0 wrong configuration 0000001: PLLN = 1 wrong configuration 0000111: PLLN = 7 wrong configuration ... 0001000: PLLN = 8 0001001: PLLN = 9 ... 1111111: PLLN = 127 * Bits 22:21 PLLQ[1:0]: Main PLL division factor for PLL “Q” clock. - Set and cleared by software to control the frequency of the main PLL output clock PLL “Q” clock. This output can be selected for USB, RNG, SAI (48 MHz clock). These bits can be written only if PLL is disabled. - PLL “Q” output clock frequency = VCO frequency / PLLQ with PLLQ = 2, 4, 6, or 8 - 00: PLLQ = 2 - 01: PLLQ = 4 - 10: PLLQ = 6 - 11: PLLQ = 8 - PLLR[1:0]: Main PLL division factor for PLL “R” clock (system clock) Set and cleared by software to control the frequency of the main PLL output clock PLLCLK. - This output can be selected as system clock. These bits can be written only if PLL is disabled. - PLL “R” output clock frequency = VCO frequency / PLLR with PLLR = 2, 4, 6, or 8 - 00: PLLR = 2 01: PLLR = 4 10: PLLR = 6 11: PLLR = 8 ### Internal and External ```= /** * @brief System Clock Configuration * The system Clock is configured as follows : * System Clock source = PLL (MSI) * SYSCLK(Hz) = 1700000000 * HCLK(Hz) = 1700000000 * AHB Prescaler = 1 * APB1 Prescaler = 1 * APB2 Prescaler = 1 * HSI Frequency(Hz) = 4000000 * PLL_M = 4 * PLL_N = 85 * PLL_R = 2 * PLL_P = 2 * PLL_Q = 2 * Flash Latency(WS) = 4 * @param None * @retval None */ ``` #### HSI ##### HSI 16MHZ + PLL 170MHZ ```= #if !defined (HSI_VALUE) #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ ``` ```= RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV12; RCC_OscInitStruct.PLL.PLLN = 85; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 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_4) != HAL_OK) { Error_Handler(); } /** Initializes the peripherals clocks */ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } ``` #### HSE ##### HSE 24 + PLL 170M * 開啟外部震盪 48M * 開啟外部振盪器 * stm32g4xx_hal_conf.h ```= #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)24000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ ``` ```= void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6; RCC_OscInitStruct.PLL.PLLN = 85; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 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_4) != HAL_OK) { Error_Handler(); } } ``` ##### HSE 48 + PLL 170M * 開啟外部震盪 48M * 開啟外部振盪器 * stm32g4xx_hal_conf.h ```= #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)48000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ ``` * Setting Clock ```= void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV12; RCC_OscInitStruct.PLL.PLLN = 85; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 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_4) != HAL_OK) { Error_Handler(); } } ``` ## GPIO ### GPIO register * RM0440 STM32G4 Series advanced Arm®-based 32-bit MCUs * P361 9.4 ![](https://i.imgur.com/M4EuuW4.png) ### GPIO Function ## Interrupts Management ### NVIC ![](https://hackmd.io/_uploads/H1vPgGmh2.png) * STM32 MCU(例如TIME、UARTS 等)及 MCU 外部的外設。來自最後一種外設的中斷是 MCU I/O,它可以配置為通用 I/O(例如,連接到配置為輸入的引腳的開關)或驅動外部高級外圍設備(例如,配置為通過RMII 接口與ethernet phyther 交換數據的I/O)。稱為外部中斷/事件控制器 (EXTI) 的專用可編程控制器負責外部 I/O 信號和 NVIC 控制器之間的互連。 ## TIME * ![](https://hackmd.io/_uploads/HJ2pCf5s2.png) ### G4 TIME * 高級TIME(TIM1、TIM8、TIM20)。 * 一般TIME: 16BIT(TIM3、TIM4),32BIT(TIM2、TIM5)。 * 基本TIME: (TIM6、TIM7)。 * 通用TIME(TIM14):只有1個或者2個通道。 * 2-通道互補輸出:(TIM15)。 * 1-通道互補輸出:(TIM16、TIM17)。 * 高速TIME(HRTIM1)。 * 低速TIME(LPTM1、LPTM2)。 ### G0 TIME * 高級TIME(TIM1)。 * 一般TIME: 16BIT(TIM3),32BIT(TIM2)。 * 基本TIME: (TIM6、TIM7)。 * 通用TIME(TIM14):只有1個或者2個通道。 * 2-通道互補輸出:(TIM15)。 * 1-通道互補輸出:(TIM16、TIM17)。 * 低速TIME(LPTM1、LPTM2)。 ### Using Timers in Interrupt Mode ![](https://hackmd.io/_uploads/SkoZRxcon.png) * 是一個自由運行的計數器,它從 0 計數到 TIM_Base_InitTypeDef 初始化結構中的Period字段中指定的值,該值可以採用最大值 0xFFFF(對於 32 位定時器為 0xFFFF FFFF); * 計數頻率取決於定時器所連接的總線速度,通過設置初始化結構中的預分頻寄存器,最多可降低計數頻率65536 倍。 * 當定時器達到週期值時,它會溢出,並且更新事件(UEV) 標誌被設置;計時器自動從初始值(對於基本計時器始終為零)重新開始計數 ![](https://hackmd.io/_uploads/r1I9KX5i2.png) * 例如,假設一個定時器連接到 STM32F072 MCU 中的 APB1 總線,HCLK 設置為 48MHz,預分頻器值等於 47999,週期值等於 499。我們認為該定時器將在以下時間溢出 * STM32G474 MCU中的APB1總線,預分頻器值等於169999,週期值等於699 ![](https://hackmd.io/_uploads/B1ittm5oh.png) ## ADC ![](https://hackmd.io/_uploads/r15uim5ih.png) ### ADC register * Table 178. ADC register map and reset values for each ADC (offset = 0x000 for master ADC, 0x100 for slave ADC) - 21.8.2 ADCx common control register (ADCx_CCR) ```= _ADC12_CCR.bit.CKMODE = 0; // ADC clock = adc_ker_ck = PLL P = 48.57 MHz _ADC12_CCR.bit.PRESC = 0; // ADC prescaler _ADC12_CCR.bit.MDMA = 0; // Dual mode DMA disable, 0 = disable, 2 = 12-bit resolution _ADC12_CCR.bit.DMACFG = 0; // Dual mode circular DMA mode _ADC12_CCR.bit.DELAY = 0; // Cycle delay between two sampling phase in dual interlaeved mode _ADC12_CCR.bit.DUAL = 0; // Mode select = Regular simultaneous _ADC1_CFGR.bit.ALIGN = 0; // Right alignment _ADC1_CFGR.bit.CONT = 0; // Single conversion mode _ADC1_CFGR.bit.OVRMOD = 1; // Overrun enable _ADC1_CFGR.bit.EXTEN = 1; // Trigger at rising edge _ADC1_CFGR.bit.EXTSEL = 21; // Trigger source _ADC1_CFGR.bit.RES = 0; // 12-bit resolution _ADC1_CFGR.bit.DMACFG = 1; // Circular DMA _ADC1_CFGR.bit.DMAEN = 1; // DMA Enble ``` #### ADC暫存器中,需要設置以下參數 * ADC12_CCR 暫存器 - ADC_CCR_ADEN: 使能 ADC 轉換。 - ADC_CCR_ADDIS: 關閉 ADC 轉換。 - ADC_CCR_ADSTART: 開始 ADC 轉換。 - ADC_CCR_SWSTART: 緩起動 ADC 轉換。 - ADC_CCR_EXTTRIG: 外部觸發 ADC 轉換。 - ADC_CCR_EXTSEL: 外部觸發 ADC 轉換的源。 - ADC_CCR_DDS:: 轉換數據格式。 - ADC_CCR_DMA:: 使能 DMA 轉換輸出。 - ADC_CCR_DDS:: 轉換數據格式。 - ADC345_CCR 暫存器 * ADC345_CCR 暫存器: - ADC_CCR_ADEN: 使能 ADC 轉換。 - ADC_CCR_ADDIS: 關閉 ADC 轉換。 - ADC_CCR_ADSTART: 開始 ADC 轉換。 - ADC_CCR_SWSTART: 軟啟動 ADC 轉換。 - ADC_CCR_EXTTRIG: 外部觸發 ADC 轉換。 - ADC_CCR_EXTSEL: 外部觸發 ADC 轉換的源。 - ADC_CCR_DDS: 轉換數據格式。 - ADC_CCR_DMA: 使能 DMA 轉換輸出。 - ADC_CCR_DDS: 轉換數據格式。 * 多通道 * ADCx_CR1:控制暫存器 1 * ADCx_CR2:控制暫存器 2 * ADCx_SMPR1:採樣時間分频器暫存器 1 * ADCx_SMPR2:採樣時間分频器暫存器 2 * ADCx_SQR1:序列模式寄存器 1 * ADCx_SQR2:序列模式寄存器 2 * ADCx_SQR3:序列模式寄存器 3 * ADCx_DR:数据寄存器 * ADCx_JSQR:多通道模式序列模式暫存器 * ADCx_JDR1:多通道模式數據暫存器 1 * ADCx_JDR2:多通道模式數據暫存器 2 * ADCx_JDR3:多通道模式數據暫存器 3 * ADCx_JDR4:多通道模式數據暫存器 4 * ADCx_JDR5:多通道模式數據暫存器 5 * ADCx_JDR6:多通道模式數據暫存器 6 * ADCx_JDR7:多通道模式數據暫存器 7 ```= // ADC1 _ADC1_CR.bit.ADCALDIF = 0; // ADC calibration _ADC1_CFGR.all = 0; _ADC1_CFGR.bit.JQDIS = 1; _ADC1_CFGR.bit.ALIGN = 0; // Right alignment _ADC1_CFGR.bit.CONT = 0; // Single conversion mode _ADC1_CFGR.bit.OVRMOD = 1; // Overrun enable _ADC1_CFGR.bit.EXTEN = 1; // Trigger at rising edge _ADC1_CFGR.bit.EXTSEL = 22; // Trigger source _ADC1_CFGR.bit.RES = 0; // 12-bit resolution _ADC1_CFGR.bit.DMACFG = 1; // Circular DMA _ADC1_CFGR.bit.DMAEN = 1; // DMA enable ``` * 11.3.8 From internal analog source to ADC (ADCx), comparator (COMPx)and OPAMP (OPAMPx) * Table 69. Interconnect 21 * SQ1 : 0~4 * SQ2 : 5~9 ```= // ADC 1 // Regular ADC conversion count = N+1 _ADC1_SQR1.bit.L = 3; _ADC1_SQR1.bit.SQ1 = 15; // uC_DCH_IOUT2 _ADC1_SQR1.bit.SQ2 = 3; // uC_VBAT _ADC1_SQR1.bit.SQ3 = 6; // uC_12VBUS _ADC1_SQR1.bit.SQ4 = 8; // uC_CHG_VIN // Sample time, 0 = 2.5 ADC cycles _ADC1_SMPR2.bit.SMP15 = 0; _ADC1_SMPR1.bit.SMP3 = 0; _ADC1_SMPR1.bit.SMP6 = 0; _ADC1_SMPR1.bit.SMP8 = 0; ``` * 21.4.4 ADC1/2/3/4/5 connectivity * Figure 84. ADC1 connectivity * Figure 85. ADC2 connectivity * Figure 86. ADC3 connectivity * Figure 87. ADC4 connectivity * Figure 88. ADC5 connectivity ## DAC * RCC->APB1ENR |= RCC_APB1ENR_DACEN; ```= // Set the DAC output voltage to 1.5 V DAC->DHR12R1 = 0x0FFF; ``` * DAC_CR:控制暫存器 * DAC_SR:裝態暫存器 * DAC_DHR12R1:數據暫存器 1 * DAC_DHR12R2:數據暫存器 2 * 11.3.8 From internal analog source to ADC (ADCx), comparator (COMPx)and OPAMP (OPAMPx) * Table 66. Interconnect 20 (continued) ![image](https://hackmd.io/_uploads/BkpU49rIp.png) ## DMA * STM32G4-System-Direct_Memory_Access_DMA-DMAMUX.pdf ![](https://i.imgur.com/CT7cpsf.png) ### DMA 暫存器中,需要設置以下參數: * 12.6.3 DMA channel x configuration register (DMA_CCRx) * DMA_CCRx 寄存器包含以下位字段: - MSIZE: 指定 DMA 傳輸數據的大小。可選值為 DMA_MSIZE_8BIT、DMA_MSIZE_16BIT 和 DMA_MSIZE_32BIT。 - PSIZE: 指定 DMA 傳輸數據的大小。可選值為 DMA_PSIZE_8BIT、DMA_PSIZE_16BIT 和 DMA_PSIZE_32BIT。 - PL: 指定 DMA 通道的優先級,選11: very high11. - MINC: 指定 DMA 傳輸數據的增量方式。可選值為 DMA_MINC_ENABLE 和 DMA_MINC_DISABLE。 - CIRC: 指定 DMA 傳輸是否為循環模式,選 1: enabled - DIR: 指定 DMA 傳輸方向。可選 0: read from peripheral. - TCIE: 使能 DMA 傳輸完成中斷,選disabled。 - PSIZE: 指定 DMA 傳輸數據的大小。可選值為 DMA_PSIZE_8BIT、DMA_PSIZE_16BIT 和 DMA_PSIZE_32BIT。 - NDT: _DMA1_CNDTR1.bit.NDT ~ _DMA1_CNDTR8.bit.NDT; 通道內數值假設 ADC1有5組,NDT就需要填 5。 ```= // ADC12 -> DMA1_CH1 _DMA1_CCR2.bit.DIR = 0; _DMA1_CCR2.bit.CIRC = 1; // Read data from peripheral _DMA1_CCR2.bit.MINC = 1; _DMA1_CCR2.bit.PSIZE = 2; // Set peripheral size to 16-bits _DMA1_CCR2.bit.MSIZE = 2; // Set memory size to 16-bits _DMA1_CCR2.bit.PL = 3; _DMA1_CCR2.bit.TCIE = 0; // Disable DMA TC ISR _DMA1_CNDTR1.bit.NDT = 10; // Number of data need to be transfer _DMA1_CPAR2.bit.PA = (unsigned long)_ADC12_CDR.all; // address of _ADC12_CDR.all or (0x5000030C) _DMA1_CMAR2.bit.MA = (unsigned long)adc12RawData; _DMAMUX1_C0CR.bit.DMAREQ_ID = 5; // Set ADC12 as the DMA request source _DMA1_CCR2.bit.EN = 1; ``` ### DMA Channels and DMAMUX * 13.3 DMAMUX implementation * DMAMUX is used with DMA1 and DMA2: * For category 3 and category 4 devices: - DMAMUX channels 0 to 7 are connected to DMA1 channels 1 to 8 - DMAMUX channels 8 to 15 are connected to DMA2 channels 1 to 8 - Table 91. DMAMUX: assignment of multiplexer inputs to resources(1) * DMA Channels: * 每一個通道只能選擇一個bus,且不能有衝突. * 每一個通道在選擇bus時,可以在Table 91選擇所需要的bus. * _DMAMUX1_C0CR.bit.DMAREQ_ID ~ _DMAMUX1_C15CR.bit.DMAREQ_ID,共16組可以使用. ![image](https://hackmd.io/_uploads/r10Rz7NjR.png) ![image](https://hackmd.io/_uploads/rJjemQNsA.png) ![image](https://hackmd.io/_uploads/HyafQmNi0.png) ## UART * USART functional description ![image](https://hackmd.io/_uploads/S1av4B2E6.png) ### UART 暫存器 * stm32g474re.pdf * 4.11 Alternate functions ```= /*************** UART ***************/ /* PC4 For USART1_TX */ _GPIOC_MODER.bit.MODE4 = 2; // Alternate function _GPIOC_OTYPER.bit.OT4 = 0; // Push-pull _GPIOC_OSPEEDR.bit.OSPEED4 = 3; // Very fast _GPIOC_PUPDR.bit.PUPD4 = 1; // Pull-up _GPIOC_AFRL.bit.AFSEL4 = 7; /* PC5 For USART1_RX */ _GPIOC_MODER.bit.MODE5 = 2; // Alternate function _GPIOC_OTYPER.bit.OT5 = 0; // Push-pull _GPIOC_OSPEEDR.bit.OSPEED5 = 3; // Very fast _GPIOC_PUPDR.bit.PUPD4 = 1; // Pull-up _GPIOC_AFRL.bit.AFSEL5 = 7; /* PA2 For USART2_TX */ _GPIOA_MODER.bit.MODE2 = 2; // Alternate function _GPIOA_OTYPER.bit.OT2 = 0; // Push-pull _GPIOA_OSPEEDR.bit.OSPEED2 = 3; // Very fast _GPIOA_PUPDR.bit.PUPD2 = 1; // Pull-up _GPIOC_AFRL.bit.AFSEL2 = 7; /* PA3 For USART2_RX */ _GPIOA_MODER.bit.MODE3 = 2; // Alternate function _GPIOA_OTYPER.bit.OT3 = 0; // Push-pull _GPIOA_OSPEEDR.bit.OSPEED3 = 3; // Very fast _GPIOA_PUPDR.bit.PUPD3 = 1; // Pull-up _GPIOC_AFRL.bit.AFSEL3 = 7; /* PC10 For USART3_TX */ _GPIOC_MODER.bit.MODE10 = 2; // Alternate function _GPIOC_OTYPER.bit.OT10 = 0; // Push-pull _GPIOC_OSPEEDR.bit.OSPEED10 = 3; // Very fast _GPIOC_PUPDR.bit.PUPD10 = 1; // Pull-up _GPIOC_AFRH.bit.AFSEL10 = 7; /* PC11 for USART3_RX */ _GPIOC_MODER.bit.MODE11 = 2; // Alternate function _GPIOC_OTYPER.bit.OT11 = 0; // Push-pull _GPIOC_OSPEEDR.bit.OSPEED11 = 3; // Very fast _GPIOC_PUPDR.bit.PUPD11 = 1; // Pull-up _GPIOC_AFRH.bit.AFSEL11 = 7; ``` ### UART CubeAPI #### UART printf * setting printf, use single write ![](https://i.imgur.com/1QJeZb7.png) ##### add pin define ``` void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(huart->Instance==USART1) { __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /* Peripheral clock enable */ /**USART1 GPIO Configuration PC4 ------> USART1_TX PC5 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } } /** * @brief UART MSP De-Initialization * This function freeze the hardware resources used in this example * @param huart: UART handle pointer * @retval None */ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) { if(huart->Instance==USART1) { /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PC4 ------> USART1_TX PC5 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_4); HAL_GPIO_DeInit(GPIOC, GPIO_PIN_5); } } ``` ##### add function ``` #include "main.h" UART_HandleTypeDef uart_deg; static void hal_uart_Init(void); #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) PUTCHAR_PROTOTYPE { HAL_UART_Transmit(&uart_deg, (uint8_t*)&ch, 1, HAL_MAX_DELAY); return ch; } #endif static void hal_uart_Init(void){ #if 0 uart_deg.Instance = USART1; uart_deg.Init.BaudRate = 115200; uart_deg.Init.WordLength = UART_WORDLENGTH_8B; uart_deg.Init.StopBits = UART_STOPBITS_1; uart_deg.Init.Parity = UART_PARITY_NONE; uart_deg.Init.Mode = UART_MODE_TX_RX; uart_deg.Init.HwFlowCtl = UART_HWCONTROL_NONE; uart_deg.Init.OverSampling = UART_OVERSAMPLING_16; uart_deg.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; uart_deg.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; #else uart_deg.Instance = USART1; uart_deg.Init.BaudRate = 115200; uart_deg.Init.WordLength = UART_WORDLENGTH_8B; uart_deg.Init.StopBits = UART_STOPBITS_1; uart_deg.Init.Parity = UART_PARITY_NONE; uart_deg.Init.Mode = UART_MODE_TX_RX; uart_deg.Init.HwFlowCtl = UART_HWCONTROL_NONE; uart_deg.Init.OverSampling = UART_OVERSAMPLING_16; uart_deg.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; uart_deg.Init.ClockPrescaler = UART_PRESCALER_DIV1; uart_deg.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; #endif if (HAL_UART_Init(&uart_deg) != HAL_OK) { Error_Handler(); } if (HAL_HalfDuplex_Init(&uart_deg) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetTxFifoThreshold(&uart_deg, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetRxFifoThreshold(&uart_deg, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_DisableFifoMode(&uart_deg) != HAL_OK) { Error_Handler(); } } ``` ## COMP * 11.3.8 From internal analog source to ADC (ADCx), comparator (COMPx)and OPAMP (OPAMPx) * Table 70. Interconnect 22 (continued) * Table 71. Interconnect 23 * Table 72. Interconnect 24 ## I2C * tSCL = tSYNC1 + tSYNC2 + {[(SCLH+1) + (SCLL+1)] x (PRESC+1) x tI2CCLK} * tSYNC1 + {[SDADEL x (PRESC+1) + 1] x tI2CCLK } ### I2C_TIMINGR register for I2C Clock * 41.4.10 I2C_TIMINGR register configuration examples * Examples of timing settings for fI2CCLK = 8 MHz ![image](https://hackmd.io/_uploads/rkAoGwWw6.png) * Examples of timings settings for fI2CCLK = 16 MHz ![image](https://hackmd.io/_uploads/BJo3-vWPa.png) * Examples of timings settings for fI2CCLK = 48 MHz ![image](https://hackmd.io/_uploads/HkTaWwbvp.png) * 41.7.5 I2C timing register (I2C_TIMINGR) * tPRESC = (PRESC+1) x tI2CCLK * SCLDEL = (SCLDEL+1) x tPRESC * tSDADEL= SDADEL x tPRESC * SCLH = (SCLH+1) x tPRESC * tSCLL = (SCLL+1) x tPRESC ## CAN * STM32G4 CAN可以支援到CAN FD、也可向下支援CAN 2.0B and CAN 2.0A - Conform with CAN protocol version 2.0 part A, B and ISO 11898-1: 2015, -4 - CAN FD with maximum 64 data bytes supported - CAN error logging - AUTOSAR and J1939 support - Improved acceptance filtering - Two receive FIFOs of three payloads each (up to 64 bytes per payload) - Separate signaling on reception of high priority messages - Configurable Transmit FIFO / queue of three payload (up to 64 bytes per payload) - Transmit event FIFO - Programmable loop-back test mode - Maskable module interrupts - Two clock domains: APB bus interface and CAN core kernel clock - Power down support ## CCM ![image](https://hackmd.io/_uploads/rJ5cBL3i0.png) ## LIN * STM32直接從UART的方式改成LIN bus即可 * LIN bus 是單線半雙工,工作電壓約 0V(dominant)~12V(recessive),屬於車載 12V 系統。 - 單主多從(single-master, multi-slave)。 - 跟CAN一樣有,發送header(標頭),包括同步訊號與識別碼(ID)。 - 由主機以排程方式輪詢從機,通訊有較高的確定性(predictability)。 ```= unsigned char Protected_identifier_field(unsigned char linId); unsigned char Lin_Transmit(unsigned char Id, unsigned char *data, unsigned char size, unsigned long enhanced_mode); void Lin_Receive(unsigned char Id, unsigned char *data, unsigned char size, unsigned long enhanced_mode); unsigned char LIN_Checksum(unsigned char pid, unsigned char *data, unsigned char size, unsigned long enhanced_mode); unsigned char FT7781_linbus_01[1] = {0x01}; unsigned char FT7781_linbus_02[2] = {0x52,0x20}; unsigned char FT7781_linbus_03[3] = {0xE5,0x20,0x52}; unsigned char FT7781_linbus_04[4] = {0x10, 0x20, 0x30, 0x40}; unsigned char FT7781_linbus_05[5] = {0x10, 0x20, 0x30, 0x40, 0x50}; unsigned char FT7781_linbus_06[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; unsigned char FT7781_linbus_07[7] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70}; unsigned char FT7781_linbus_08[8] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}; unsigned char FT7781_linbus_18[4] = {0x10, 0x20, 0x30, 0x40}; unsigned char FT7781_linbus_1F[5] = {0x10, 0x20, 0x30, 0x40, 0x50}; unsigned char FT7781_linbus_24[5] = {0x10, 0x20, 0x30, 0x40, 0x50}; unsigned char FT7781_linbus_28[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; unsigned char FT7781_linbus_2C[6] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; unsigned char FT7781_linbus_30[7] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; unsigned char FT7781_linbus_3B[7] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x60}; unsigned char FT7781_linbus_3C[8] = {0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, 0x86}; unsigned char FT7781_linbus_3D[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned char rxdata[1]; unsigned char TxData[20]; unsigned char rx_data[2]; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART3_UART_Init(); MX_USART1_UART_Init(); Init_Interrupt(); BSP_LED_Init(LED_GREEN); /* Initialize led */ /* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/ BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI); /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */ BspCOMInit.BaudRate = 115200; BspCOMInit.WordLength = COM_WORDLENGTH_8B; BspCOMInit.StopBits = COM_STOPBITS_1; BspCOMInit.Parity = COM_PARITY_NONE; BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE; if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE) { Error_Handler(); } while (1) { Lin_Transmit(0x01, FT7781_linbus_01, 1, true); Lin_Transmit(0x02, FT7781_linbus_02, 2, true); Lin_Transmit(0x03, FT7781_linbus_03, 3, true); Lin_Transmit(0x04, FT7781_linbus_04, 4, true); Lin_Transmit(0x05, FT7781_linbus_05, 5, true); Lin_Transmit(0x06, FT7781_linbus_06, 6, true); Lin_Transmit(0x07, FT7781_linbus_07, 7, true); Lin_Transmit(0x08, FT7781_linbus_08, 8, true); Lin_Transmit(0x3C, FT7781_linbus_3C, 8, false); //Lin_Transmit(0x0E, FT7781_linbus_08, 8, true); //Lin_Receive(0x0C, rxdata, 1, true); Lin_Transmit(0x0C, rxdata, 1, true); Lin_Transmit(0x0D, rxdata, 2, true); Lin_Receive(0x0C, rxdata, 1, true); Lin_Receive(0x0D, rxdata, 2, true); Lin_Receive(0x0E, rxdata, 3, true); Lin_Receive(0x0F, rxdata, 4, true); Lin_Receive(0x10, rxdata, 5, true); Lin_Receive(0x11, rxdata, 6, true); Lin_Receive(0x12, rxdata, 7, true); Lin_Receive(0x13, rxdata, 8, true); Lin_Receive(0x3D, rxdata, 8, false); } } ``` ```= unsigned char Lin_Transmit(unsigned char Id, unsigned char *data, unsigned char size, unsigned long enhanced_mode) { unsigned char sync = 0x55; unsigned char pid = Protected_identifier_field(Id); unsigned char checksum = LIN_Checksum(pid, data, size, enhanced_mode); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); // enable transmitter HAL_LIN_SendBreak(&huart3); HAL_UART_Transmit(&huart3, &sync, 1, 300); HAL_UART_Transmit(&huart3, &pid, 1, 300); HAL_UART_Transmit(&huart3, data, size, 1000); HAL_UART_Transmit(&huart3, &checksum, 1, 1000); HAL_Delay(30); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); // disable transmitter return 0; } void Lin_Receive(unsigned char id, unsigned char *data, unsigned char size, unsigned long enhanced_mode) { unsigned char pid = Protected_identifier_field(id); unsigned char checksum_received; unsigned char checksum_calculated; if (size > 8) return; unsigned char rx_buffer[9] = {0}; if (HAL_UART_Receive(&huart3, rx_buffer, size + 1, 300) == HAL_OK) { memcpy(data, rx_buffer, size); checksum_received = rx_buffer[size]; checksum_calculated = LIN_Checksum(pid, data, size, enhanced_mode); if (checksum_received != checksum_calculated) { Error_Handler(); } } HAL_Delay(40); } ``` * Checksum and PID(LIN Bus ID) ```= unsigned char LIN_Checksum(unsigned char pid, unsigned char *data, unsigned char size, unsigned long enhanced_mode) { unsigned short sum = 0; if (enhanced_mode) sum += pid; // LIN 2.x:PID for (int i = 0; i < size; i++) { sum += data[i]; if (sum > 0xFF) sum -= 0xFF; } return (unsigned char)(0xFF - sum); } unsigned char Protected_identifier_field(unsigned char linId) { unsigned char LIN_ID = linId & 0x3Fu; LIN_ID |= ( (linId >> 0u & 0x1u) ^ (linId >> 1u & 0x1u) ^ (linId >> 2u & 0x1u) ^ (linId >> 4u & 0x1u)) << 6u; LIN_ID |= ( (linId >> 1u & 0x1u) ^ (linId >> 3u & 0x1u) ^ (linId >> 4u & 0x1u) ^ (linId >> 5u & 0x1u) ^ 0x1u) << 7u; return LIN_ID; } void Init_Interrupt(void) { uint32_t encodePriority = NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0); NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); NVIC_SetPriority(USART3_IRQn, encodePriority); NVIC_EnableIRQ(USART3_IRQn); } ``` ## Device ID * 47.6 ID codes and locking mechanism ![image](https://hackmd.io/_uploads/SkNeA4njC.png) ## 參考

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully