Atmega328P Datasheet 17. External Interrupt

  • 28 Replies
  • 1647 Views
*

Offline tha

  • *****
  • 1073
    • View Profile
Re: Atmega328P Datasheet 17. External Interrupt
« Reply #24 on: August 24, 2019, 08:17:37 am »
พรายกระซิบบอกมาอีกแล้ว ให้ไปดูที่ ไฟล์ delay.h ใน C:\avr8-gnu-toolchain\avr\include\util ดูแล้วปรากฎว่า ฟังชั่น _delay_ms(); ประกาศตัวแปรเป็น double เลย เท่าไหร่นะ 32 บิทเลยใช่ไหม ส่วนโปรแกรมย่อยของผม ประกาศตัวแปรแค่ unsigned int 16 บิท ซึ่งน้อยกว่า แต่ว่าไม่เกินนี่ก็น่าจะใช้ได้นะใช่ไหม

Quote
void
_delay_ms(double __ms)
{
   double __tmp ;
#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
  !defined(__DELAY_BACKWARD_COMPATIBLE__) &&      \
  __STDC_HOSTED__
   uint32_t __ticks_dc;
   extern void __builtin_avr_delay_cycles(unsigned long);
   __tmp = ((F_CPU) / 1e3) * __ms;

   #if defined(__DELAY_ROUND_DOWN__)
      __ticks_dc = (uint32_t)fabs(__tmp);

   #elif defined(__DELAY_ROUND_CLOSEST__)
      __ticks_dc = (uint32_t)(fabs(__tmp)+0.5);

   #else
      //round up by default
      __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
   #endif

   __builtin_avr_delay_cycles(__ticks_dc);

#else
   uint16_t __ticks;
   __tmp = ((F_CPU) / 4e3) * __ms;
   if (__tmp < 1.0)
      __ticks = 1;
   else if (__tmp > 65535)
   {
      //   __ticks = requested delay in 1/10 ms
      __ticks = (uint16_t) (__ms * 10.0);
      while(__ticks)
      {
         // wait 1/10 ms
         _delay_loop_2(((F_CPU) / 4e3) / 10);
         __ticks --;
      }
      return;
   }
   else
      __ticks = (uint16_t)__tmp;
   _delay_loop_2(__ticks);
#endif
}


ของ winavr ก็จะเหมือนกัน ที่เรา include file มาที่หัวโปรแกรม ไฟล์ก็จะอยู่แถวนี้ ในโปรแกรมของผม ผมก็จะบอกไว้นะว่าไฟล์เหล่านี้อยู่ที่ไหน ลองไล่เช็คทำความเข้าใจดูนะ ดูบ่อยๆสักวันคงจะเข้าใจ ก็จะเก่งการเขียนโปรแกรมครับ

*

Offline tha

  • *****
  • 1073
    • View Profile
Re: Atmega328P Datasheet 17. External Interrupt
« Reply #25 on: August 24, 2019, 08:27:27 am »
พรายกระซิบบอกมาให้ประกาศตัวแปรให้เป็น double เหมือนกันไว้ พอ build ปรากฎว่า code size ลดจาก 1646 bytes เหลือ 1582 bytes

*

Offline tha

  • *****
  • 1073
    • View Profile
Re: Atmega328P Datasheet 17. External Interrupt
« Reply #26 on: August 24, 2019, 09:41:26 am »
ถ้าเราไม่ optimize code (ตั้ง project->configuration options->optimization = -O0) เวลา build ก็จะขึ้น warning เหลืองเตือนว่า  # warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
ผมเลยเช็คโดยการตั้งให้เวลาเยอะๆ อย่าง 5000ms แล้วใช้แท๊บเล็ตจับเวลาดู เวลาหลอด LED ติดก็ใกล้เคียงกับ 5 วินะ คงจะใช้ได้ใช่ไหม ลองเช็ตดูกัน

แต่พอเราบีบอัด optimize code (ตั้ง project->configuration options->optimization = -Os) เวลา build ก็จะขึ้น error เลย build ไม่ผ่านที่โปรแกรมย่อย delay_ms อย่างนี้หมายถึงว่า ถ้าเรา optimization = -Os เราก็ใช้ฟังชั่น   _delay_ms(500); ในส่วนต่างๆของโปรแกรมได้เลย เวลา build มันก็จะ potimize code ให้เราเอง


*

Offline tha

  • *****
  • 1073
    • View Profile
Re: Atmega328P Datasheet 17. External Interrupt
« Reply #27 on: August 24, 2019, 10:31:24 am »
แต่ต่อไปโปรแกรมเราจะตั้งไม่ให้ optimize (ไม่ตั้ง optimization = -Os) นะ จะตั้ง optimization = -O0 นะ ถ้าตั้งบีบอัด flag ที่เราตั้งจะถูกบีบอัดเช็ค flag ไม่ได้เลย (มั่วเหมือนกัน GCC) ตกลงตามนี้นะ เจอปัญหาก็แก้ไปเรื่อยๆครับ

*

Offline tha

  • *****
  • 1073
    • View Profile
Re: Atmega328P Datasheet 17. External Interrupt
« Reply #28 on: August 28, 2019, 01:49:59 pm »
ตัวอย่างที่ให้ไปมันผิดอยู่นะ ให้ประกาศตัวแปร global variable ประกาศเป็น volatile ขึ้นหน้านะครับ
อย่างเช่นโปรแกรม Test_PCINT_Board2_2 ก็ประกาศอย่างนี้
Quote
volatile uint8_t a = 0;
volatile uint8_t b = 0;
   เพื่อให้มันไม่ optimize ตัวแปร a, b เวลาตอนเราบีบอัด code นะ
   คราวนี้เราก็มาตั้งให้ optimize (บีบอัดโค๊ด) อย่างนี้ได้ (project->configuration options->optimization = -Os) ขนาดของ code size ก็จะลดลงมาเยอะเลย

ส่วนฟังชั่นการดีเลย์ก็ให้กลับมาใช้ฟังชั่น _delay_ms(100); ได้ตามปกติครับ

ส่วนตัว compiler ก็กลับมาใช้ winavr ก็ได้ครับ

ปล. ไม่ได้ทำมานานชักจะลืมเลยผิดพลาด ต้องขออภัยด้วย
      ขอโฆษณาหน่อย ก็เคยบวชเรียนมา ก็ว่านั่งสมาธิ พุท-โธๆ นี้ดี ทำให้ลมหายใจนี้ยาวลึกละเอียด เป็นผลดีต่อสุขภาพไม่ค่อยเป็นหวัดเป็นไอ
      อ่านหนังสือก็มีสมาธิดี เพราะนิวรณ์มันลดลง เราก็จะมีสุขมากขึ้น สุขที่ใจสงบ ชีวิตเราก็จะดีขึ้น ก็ทำง่ายๆเราหัดทำเองก็ได้ วันละนิดวันละ
      หน่อย เดี๋ยวเราก็จะรู้เองว่าควรทำอย่างไร มันก็จะดีขึ้นเรื่อยๆเองครับ
       http://www.84000.org/tipitaka/dic/d_item.php?i=225