STM32F1 ADC HAL

Started by tha, September 17, 2020, 09:42:20 AM

Previous topic - Next topic

tha


tha


tha



dec

Quote from: tha on September 19, 2020, 03:38:14 PM
ผมลองเปลี่ยนชื่อฟังชั่นใหม่เป็นอย่างนี้  void HAL_ADC_MspInit1(ADC_HandleTypeDef* hadc); แล้วมันไม่ทำงานนะ จอขาวเลย ผมเอา 1 ออก ก็ทำงานได้ปกติ แสดงว่าของเขาทำมาถูกแล้ว ผมก็ยังมือใหม่ยังต้องงม HAL ไปอีกนาน คุณ dec พอจะทราบการทำงานของมันมั๊ย ท่านใดพอจะทราบ ช่วยอธิบายหน่อยครับ

ถ้าลองไปดูฟังชั่น HAL_ADC_Init ในไฟล์ stm32fxxx_hal_adc.c ลองไล่ดูจะเห็นว่ามันมีการเรียก HAL_ADC_MspInit
ิอยู่ครับ เวลาเรียก HAL_ADC_Init มันจะไปเรียก HAL_ADC_MspInit ให้ด้วยเลย

แล้วทีนี้ถ้าเปลี่ยนชื่อเป็น HAL_ADC_MspInit1 มันยัง compile ได้ปกติ ไม่ได้ฟ้อง error อะไร ลองไล่ code ไปอีกหน่อย
จะเจอ

__weak void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hadc);

  /* NOTE : This function should not be modified. When the callback is needed,
            function HAL_ADC_MspInit must be implemented in the user file.
   */
}


มันคือ HAL_ADC_MspInit นั่นแหละครับ แต่มี attribute __weak นำหน้า (สำหรับ GNU C Compiler และ IAR ตัวใหม่ๆ จะใช้ __attribute__((weak)) )
มันหมายถึงถ้าทั้ง project ไม่มี HAL_ADC_MspInit อยู่เลย linker จะใช้ฟังชั่นนี้ แต่ถ้ามีการนิยาม HAL_ADC_MspInit ไว้ที่อื่นอีก
อันที่มี attribute __weak จะถูกตัดออก


การเขียน code ลักษณะนี้ยังใช้ในไฟล์ startup ที่มี vector table อีกด้วยครับ

g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
        ....


ปกติเวลาเราจะประกาศฟังชั่น interrupt เราก็แค่ประกาศชื่อให้ตรงกับชื่อที่อยู่ใน vector table แต่ฟังชั่นไหน
ไม่ได้ประกาศมันก็ไม่ได้ error อะไรเพราะมันมี weak ฟังชั่นอยู่เหมือนกัน แต่จะแตกต่างจากภาษาซีนิดหน่อยตรง
assembly มันไม่ได้ประกาศฟังชั่นมาทั้งอัน มันประกาศ alias ของฟังชั่นได้


  .weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler

  .weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler

  .weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler

  .weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler

.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler

.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler

.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler

.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
       
        ...

.weak CRS_IRQHandler
.thumb_set CRS_IRQHandler,Default_Handler

.weak I2C4_EV_IRQHandler
.thumb_set I2C4_EV_IRQHandler,Default_Handler

.weak I2C4_ER_IRQHandler
.thumb_set I2C4_ER_IRQHandler,Default_Handler


หรือพูดง่ายๆ ก็คือมันสามารถประกาศ Default_Handler ให้มีหลายๆ ชื่อได้นั่นเอง แล้วชื่่ออื่นๆ ก็มี attribute weak กำกับไว้
เวลาเราไปประกาศฟังชั่น interrupt ในไฟล์ stm32xxxx_it.c ซ้ำกับชื่อฟังชั่น interrupt ในไฟล์ startup มันก็จะตัดชื่อในไฟล์ startup ออก
แล้วไปใช้ฟังชั่น interrupt ในไฟล์ stm32xxxx_it.c แทน

tha

ขอบคุณครับ คุณ dec เรื่อง interrupt ผมก็จะลืมแล้ว เดี๋ยวไปไล่เรื่อง interrupt มาก่อน

tha

11.3.7 Analog watchdog
The AWD analog watchdog status bit ถูกเซ็ตถ้า the analog voltage ที่แปลงโดย the ADC อยู่ต่ำกว่าขอบเขตทางต่ำ( low threshold)หรืออยู่เหนือกว่าขอบเขตทางสูง( high threshold). thresholds เหล่านี้ถูกโปรแกรมใน the 12 least significant bits(12 บิตทางต่ำ) ของ the ADC_HTR และ ADC_LTR 16-bit registers. An interrupt สามารถถูกเปิดการใช้งานโดยการใช้ the AWDIE bit ใน the ADC_CR1 register.

ค่าของขอบเขตเป็นอิสระจากการวางแนว(ชิดขวา/ชิดซ้าย)ที่เลือกโดย the ALIGN bit ใน the ADC_CR2 register. การเปรียบเทียบถูกทำก่อนที่จะวางแนว (ดู Section 11.5).

The analog watchdog สามารถถูกเปิดการใช้งานบนหนึ่งชาแนลหรือมากกว่าหนึ่งโดยการกำหนดค่า the ADC_CR1 register ดังแสดงในตาราง 66.




tha


tha

11.3.8 Scan mode
mode ถูกใช้สแกนกลุ่มของ analog channels. Scan mode สามารถถูกเลือกโดยการเซ็ต the SCAN bit ใน the ADC_CR1 register. เมื่อบิตนี้ถูกเซ็ต, ADC จะสแกน the channels ทั้งหมดที่ถูกเลือกใน the ADC_SQRx registers (สำหรับ regular channels) หรือใน the ADC_JSQR (สำหรับ injected channels). การแปลงเพียงครั้งเดียวถูกกระทำสำหรับแต่ละชาแนลของกลุ่ม. หลังจากจบแต่ละการแปลง ชาแนลถัดไปของกลุ่มจะถูกแปลงโดยอัตโนมัติ. ถ้า the CONT bit ถูกเซ็ต, conversion จะไม่หยุดที่่ชาแนลสุดท้ายที่เลือกของกลุ่ม แต่จะทำการแปลงต่ออีกจากชาแนลแรกที่เลือกของกลุ่ม เมื่อใช้ scan mode, DMA bit ต้องถูกเซ็ตและ the direct memory access controller ถูกใช้เพื่อ transfer data ที่แปลงแล้วของ regular group channels ไปยัง SRAM หลังจากแต่ละข้อมูลใหม่ของ the ADC_DR register.
The injected channel converted data ถูกเก็บไว้ใน the ADC_JDRx registers เสมอ.