Arduino MEGA328P

Started by tha, September 10, 2017, 10:04:41 AM

Previous topic - Next topic

tha

ส่วนคำสั่ง asm volatile ("nop" :: ); ถ้า GCC แล้วมาใช้คำสั่งภาษา Assembly ก็จะใช้รูปแบบนี้ ลองเสิร์จกูเกิ้ลดู หรือ หาตัวอย่างใน library C:\WinAVR-20100110\avr\include\avr ดูก็ได้ จะพบความเกี่ยวพันกันของ GCC โปรแกรมด้วยครับ

ส่วนตัว AVR ATmega328p มีภาษา Assembly มีอะไรบ้าง(จากภาษา C ก็ต้องคอมไพล์ไปเป็น assembly ก่อนใช่ใหม ลืมไปแล้วเหมือนกันนะ) ก็ดูที่บท 37. Instruction Set Summary ในดาต้าชีทใหม่ดู เอามาลงให้ดูก็ได้




tha

อย่างความเกี่ยวพันของไลบรารี่ในโปรแกรม ที่เรา

#include <avr/io.h>        // The file is in C:\WinAVR-20100110\avr\include\avr

ซึ่งตอนแรกที่เราสร้างโปเจ็คใหม่(new project) เรากำหนด เบอร์ไมโครเป็น ATmega328p ใช่ใหม ทำให้จาก library io.h ลิ้งค์มาที่ไฟล์ iom328p.h 

ที่ไฟล์ io.h ก็จะมีระบุว่า
Quote
#elif defined (__AVR_ATmega328P__) || defined (__AVR_ATmega328__)
#  include <avr/iom328p.h>

คราวนี้ที่ไฟล์ iom328p.h ก็จะระบุค่าตัวแปรต่างๆที่เราใช้ในโปรแกรมว่าเป็นรีจีสเตอร์ที่เท่าไหร่ แต่ละตัวแปรบิทมีค่าเป็นเท่าไหร่ ก็มีการกำหนดไว้ในไฟล์นี้ครับ
Quote
#define DDRD _SFR_IO8(0x0A)
#define DDD0 0
#define DDD1 1
#define DDD2 2
#define DDD3 3
#define DDD4 4
#define DDD5 5
#define DDD6 6
#define DDD7 7

ลองไล่เช็คดูความเกี่ยวพันของมันนะ ในนี้แหละ สักพักคงจะคล่อง ถ้ารู้แล้ว GCC นี้ก็จะง่ายขึ้นนะ ผมก็จะลืมๆบ้างแล้วสิ ไม่ได้ทำมานาน คงต้องทบทวนอีกสักหน่อยเหมือนกันครับ

tha

ตอนนี้บอร์ด(เจ้าสวิทช์แดง)ของเรา สัญญานนาฬิกาตั้งเป็น Calibrated Internal RC Oscillator อยู่ใช่ใหม คราวนี้เรามาลองตั้งสัญญานนาฬิกาเป็น 128kHz Internal Oscillator ดูบ้าง(ดูโพสต์นี้แถวที่11 13.7. 128kHz Internal Oscillator ประกอบนะ) เราก็เปลี่ยนโปรแกรมของเราให้สัญญานนาฬิกามันตรงกับ 128kHz ก่อน เพราะโปรแกรมเรามีใช้คำสั่ง _delay_ms(500); อยู่ เราก็ built ไป แล้วโปรแกรม hex ไฟล์เข้าไป หรือโปรแกรมหลังการโปรแกรม fuse bits ก็ได้
Quote
#define F_CPU 128000UL    // set to 128000Mhz because it effect to delay.h

ทีนี้เราก็มาดูว่า 128kHz Internal Oscillator (ดูโพสต์นี้แถวที่ 11 ประกอบนะ) ว่า บิท CKSEL[3:0] มีค่าเท่าไหร่ SUT[1:0] จะเอาค่าเท่าไหร่ดี ก็ดูในตาราง
          CKSEL[3:0] = 0011
          SUT[1:0]    = 00        จะเลือกเปิด brown out detection enable ตรวจจับว่าโวลท์ขึ้นมาสูงถึงระดับที่ตั้งไว้แล้วหรือยัง จะตั้งไว้ 2.7v ตั้งได้ที่ fuse bits(ด้านบน) ก็จะได้ค่า extended fuse bits = 0xFD (ดูโพสต์นี้แถวที่ 13 ประกอบ)

ส่วนบิท CKSEL[3:0], SUT[1:0] อยู่ตำแหน่งไหนใน fuse bits (fuse low byte) ก็ดูที่ตาราง fuse bits (ดูโพสต์นี้แถวที่ 13 ประกอบนะ) เราก็จะได้ค่า
           fuse low byte = 0xC3 = 0b1100 0011 ใช่ใหม



คราวนี้เราก็กดโปรแกรมไป yes ไปเลย คราวนี้มันจะติดต่อกับ ET-AVR ISP mk-II ไม่ได้ ขึ้น
Entering programming mode.. FAILED!
สาเหตุเป็นเพราะเราตั้ง programming mode and target setting ปกติอยู่ที่ 125kHz ใช่ใหม พอเรามาเปลี่ยนสัญญานาฬิกาเหลือแค่ 128kHz มันเลยติดต่อกันไม่ได้ คราวนี้เราก็มาเปลี่ยนค่า setting ให้เหลือสัก 6.478kHz แล้วกด write ไป เท่านี้ก็ติดต่อกันได้แล้วครับ




tha

ถามอะไรหน่อย โน๊ตบุ็คใหม่ๆสมัยนี้ที่มี win10 มาให้ด้วยนี่ ลง AVR studio 4.17 ได้หรือเปล่าครับ

tha

ตอนนี้บอร์ด(เจ้าสวิทช์แดง)ของเรา สัญญานนาฬิกาตั้งเป็น 128kHz Internal Oscillator อยู่ใช่ใหม คราวนี้เรามาลองตั้งสัญญานนาฬิกาเป็น External Clock ดูบ้าง(ดูโพสต์นี้แถวที่11 13.8. External Clock ประกอบ)

ทีนี้เราก็มาดูว่า External Clock  (ดูโพสต์นี้แถวที่ 11 ประกอบนะ) ว่า บิท CKSEL[3:0] มีค่าเท่าไหร่ SUT[1:0] จะเอาค่าเท่าไหร่ดี ก็ดูในตาราง
          CKSEL[3:0] = 0000
          SUT[1:0]    = 00        จะเลือกเปิด brown out detection enable ตรวจจับว่าโวลท์ขึ้นมาสูงถึงระดับที่ตั้งไว้แล้วหรือยัง จะตั้งไว้ 2.7v ตั้งได้ที่ fuse bits(ด้านบน) ก็จะได้ค่า extended fuse bits = 0xFD (ดูโพสต์นี้แถวที่ 13 ประกอบ) จะตั้งให้เป็น 4.3v ก็ได้เพราะจะกลับมาใช้ power supply 5v

ส่วนบิท CKSEL[3:0], SUT[1:0] อยู่ตำแหน่งไหนใน fuse bits (fuse low byte) ก็ดูที่ตาราง fuse bits (ดูโพสต์นี้แถวที่ 13 ประกอบนะ) เราก็จะได้ค่า
           fuse low byte = 0xC0 = 0b1100 0000 ใช่ใหม



แล้วกด program ไป แล้วลอง read ดู จะขึ้น
Entering programming mode.. FAILED!
คราวนี้มันจะติดต่อกับ ET-AVR ISP mk-II ไม่ได้ เพราะสัญญานนาฬิกาเปลี่ยนเป็น External Clock แล้ว แต่เรายังไม่ได้ใส่สัญญานนาฬิกา External Clock เข้าที่ขา EXTCLK(XTAL1) ให้มัน

คราวนี้ก็ถอดไฟออก แล้วบัดกรีเอาสายต่อจากขา EXTCLK(XTAL1) ออกมา

เปลี่ยน programming mode and target setting จาก 6.478kHz เป็น 125kHz เหมือนเดิมด้วย

tha

คราวนี้เราจะเอาบอร์ดเจ้าสวิทช์ดำ(บอร์ด ATmega328p อีกบอร์ด)มาทำเป็นสัญญานนาฬิกาภายนอกให้กับบอร์ดเจ้าสวิทช์แดง
คราวนี้เราก็มาตั้งให้เป็น Full Swing Crystal Oscillator เลย รูปคลื่นสัญญานนาฬิกาจะได้ดีๆ
คราวนี้มากดถูกที่ CKDIV8 เพื่อให้หารสัญญานนาฬิกาลงมา 8 คือจาก 16MHz ลงเป็น 2MHz
คราวนี้มากดถูกที่ CKOUT  เพื่อให้มีสัญญานนาฬิกาออกมาที่ขา CLKO(PB0)
ส่วนบิท CKDIV8, CKOUT, CKSEL[3:0], SUT[1:0] อยู่ตำแหน่งไหนใน fuse bits (fuse low byte) ก็ดูที่ตาราง fuse bits (ดูโพสต์นี้แถวที่ 13 ประกอบนะ) เราก็จะได้ค่า
           fuse low byte = 0x37 = 0b0000 0111 ใช่ใหม



คราวนี้ก็กดโปรแกรมไป

tha

คราวนี้ลองเอา seleae logic analyzer มาวัดที่ขา CLKO(PB0) ดู ไม่ได้ใช้มานานออกจะลืมๆ ลองตั้ง sample rate 500Ks/s ดู วัดคลื่นได้ 203.7Hz เอง ไม่น่าจะถูกนะ



ลองตั้ง sample rate 16Ms/s ดู ขึ้นเป็นแบบนี้



งงไปตั้งนาน นึกว่าใช้ไม่ได้แล้ว พอลองเอาเม้าส์ไปจี้จอ แล้วหมุนเม้าส์ ปรากฎว่าได้รูปคลื่น 2MHz พอดี ตกลงว่าถูกนะ


tha

คราวนี้ก็เอาสายมาใส่ให้ขา CLKO(PB0) ของบอร์ดเจ้าสวิทช์ดำ มาใส่เข้าที่ขา EXTCLK(XTAL1) ของบอร์ดเจ้าสวิทช์แดง คราวนี้บอร์ดเจ้าสวิทช์แดงก็มี external clock 2MHz แล้ว คราวนี้เรามาแก้โปรแกรม

Quote
#define F_CPU 2000000UL    // set to 2000000Mhz because it effect to delay.h

ตรงนี้ให้เวลามันตรง คอมไพล์แล้วโปรแกรม hex ไฟล์เข้าไปใหม่ ก็สามารถทำงานไฟกระพริบได้ปกติครับ