มีใครเคยแสดงค่าการ Interrupt บนจอ LCD บ้างครับ

  • 13 Replies
  • 4934 Views
ตอนนี้ผมกำลังหาทางแสดงค่า Interrupt บนจอ LCD อยู่ครับ เนื่องจากผมใช้ ADC ทำการแซมปลิ้งคลื่นรูป sine ที่มีความถี่ 50Hz ด้วยความถี่ 50MHz (20us) ทีนี้ผมต้องการทราบว่า ADC ของผมนั้น ทำการแซมปลิ้งค่าทั้งหมด 1000 ค่าจริงหรือเปล่า ซึ่งค่าที่ได้นั้นต้องการนำไปบันทึกใน array ค่าหนึ่ง ซึ่งต้องการบันทึกทั้งหมด 10000 ค่า เพื่อนำไปหาค่า RMS ไม่ทราบว่าใครพอจะมีไอเดียไหมครับ ขอบคุณครับ ทีนี้ไม่แน่ใจว่าต้องสร้างฟังก์ชั่น interrupt เพิ่มเติมเพื่อทำการบันทึกค่าหรือเปล่าครับ

*

Offline firmware.c

  • *****
  • 181
  • Firmware Design
    • View Profile
ผมมองว่าน่าจะต้อง detect zoro crossing ให้ได้ก่อนหรือป่าวครับ
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+

พอดีฟังก์ชั่นการเขียนข้อมูลของ LCD มันมีดีเลย์ด้วยครับ ทีน้จะทำอย่างไรดีที่จะให้สามารถแสดงผลบนจอ LCD โดยไม่กระทบต่อการทำงานครับ

*

Offline firmware.c

  • *****
  • 181
  • Firmware Design
    • View Profile
LCD ควรอยู่ที่ main ครับ จับค่าที่ต้องการแสดงลง buffer แล้ว main ทำการดึงค่านั้นออกมา display
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+

ตอนนี้แก้ไขเรื่อง LCD ติดดีเลได้แล้วครับ แต่ตอนนี้ผมต้องการนับจำนวนครั้งการแซมปลิ้ง -> แสดงผล และเอาค่าที่แซมปลิ้งได้ทุกค่า ทุกๆ 20us มาบันทึกลงใน array แต่ละค่า เป็นจำนวน 10000 ค่าครับ ซึ่งขั้นต้นผมใช้การ count N ใน main loop แต่ดูเหมือนจะใช้แทนค่าจำนวนการแซมปลิ้งไม่ได้ครับ เพราะผมต้องบันทึกค่าลงใน array แล้วคำนวนค่า rms ซึ่งการนับ N ในเมนลูปทำให้การบันทึกค่าไม่สอดคล้องกับการแซมปลิ้ง ค่า rms ที่ได้เลยเพี้ยนบานเลยครับ ไม่ทราบว่าใครพอจะมีไอเดียในการจับค่าของการแซมปลิ้งทีละครั้งบ้างไหมครับ

*

Offline firmware.c

  • *****
  • 181
  • Firmware Design
    • View Profile
ต้องเก็บตอน sampling เลยครับ
IAR Embedded Workbench for ARM
AVR-Studio + AVR-GCC
CodeBlocks + MinGw
CodeBlocks + Gtk+

*

Offline pa_ul

  • ***
  • 247
    • View Profile
{
Interrupt_Routine()
{
    output_array[index++] = sampling();
}
...
...

main()
{
   ...
   ...
   while(index < 10000)
      {}
    // ถ้าโปรแกรมทำงานถึงตรงนี้ แสดงว่า sampling ได้แล้ว 10000 ค่า
   ...

}


ถ้าตามที่ถามมา มันไม่เห็นจำเป็นที่จะต้องแสดงค่า N ทีละค่า แต่แสดงแค่ว่าได้ครบทุกค่าก็ใช้ได้แล้ว
แต่ถ้าเป็นผม ผมจะทดสอบการทำงานทีละส่วนก่อน เช่นทดสอบ Interrupt_Routine ว่าทำงานถูกต้องแน่ๆ โดยการให้มันทำงานทุกๆ วินาทีก่อนก็ได้ เมื่อทุกอย่างถูกต้อง
จึงค่อยปรับค่าระยะเวลาการอินเตอร์รัพให้เร็วขึ้นจากทุกๆ 1 วินาทีขึ้นมาเป็นทุกๆ 20 uS ซึ่งสามารถทำได้ง่ายๆโดยการปรับค่า timer

{
Interrupt_Routine()
{
    output_array[index++] = sampling();
}
...
...

main()
{
   ...
   ...
   while(index < 10000)
      {}
    // ถ้าโปรแกรมทำงานถึงตรงนี้ แสดงว่า sampling ได้แล้ว 10000 ค่า
   ...

}


ถ้าตามที่ถามมา มันไม่เห็นจำเป็นที่จะต้องแสดงค่า N ทีละค่า แต่แสดงแค่ว่าได้ครบทุกค่าก็ใช้ได้แล้ว
แต่ถ้าเป็นผม ผมจะทดสอบการทำงานทีละส่วนก่อน เช่นทดสอบ Interrupt_Routine ว่าทำงานถูกต้องแน่ๆ โดยการให้มันทำงานทุกๆ วินาทีก่อนก็ได้ เมื่อทุกอย่างถูกต้อง
จึงค่อยปรับค่าระยะเวลาการอินเตอร์รัพให้เร็วขึ้นจากทุกๆ 1 วินาทีขึ้นมาเป็นทุกๆ 20 uS ซึ่งสามารถทำได้ง่ายๆโดยการปรับค่า timer

ตอนนี้ผมใช้แค่ Interrupt TIM3 เป็นตัวกำหนดการทำงานอยู่ครับ ไม่ทราบว่า

Interrupt_Routine()
{
    output_array[index++] = sampling();
}

เป็นฟังก์ชั่นที่ต้องสร้างขึ้นมาใหม่หรือเป็นฟังก์ชั่นในตัว Interrupt ครับ