<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8364357518846111944</id><updated>2011-04-22T07:32:19.125+07:00</updated><category term='ATmega168'/><category term='disjoint set'/><category term='data structure'/><category term='avr'/><category term='pwm'/><title type='text'>Ram'z</title><subtitle type='html'>Blog ง่ายๆ ของคนขี้เกียจ =___=</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ramzpat.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ramzpat.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Im Arm</name><uri>http://www.blogger.com/profile/09454865819792095144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_XTk5CpPyThQ/Sf1Ix54JLZI/AAAAAAAAABY/Vxnd1OZCPCU/s1600-R/logo2_bigger.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8364357518846111944.post-3465288733648883519</id><published>2011-02-13T23:29:00.029+07:00</published><updated>2011-02-14T11:32:20.340+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='avr'/><title type='text'>AVR [C version]</title><content type='html'>ก็เห็นว่ามีคนงงๆ เกี่ยวกะ &lt;span style="font-weight: bold;"&gt;AVR &lt;/span&gt;อ่ะนะ เราก็ไม่ได้เก่งอะไรมาก&lt;br /&gt;แล้วก็ไม่รู้จะช่วยยังไงด้วย&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;เริ่มจาก &lt;span style="color: rgb(255, 0, 0);"&gt;ทำความเข้าใจกับเรื่องต่างๆก่อน&lt;/span&gt; นะ&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255); font-weight: bold; font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 51, 255); font-style: italic;"&gt;เขียน C ไม่เป็นทำไงดีวะ ?&lt;/span&gt; &lt;span style="color: rgb(153, 51, 0);"&gt;ก็เห็นหลายๆคนก็เขียน c ไม่เป็นอ่ะนะ &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;เลยจะมา &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(153, 51, 0);"&gt;เปรียบเทียบ C กะ Java&lt;/span&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;(ที่เคยเขียนกัน) ว่ามันเหมือน รึ ต่างกันยังไง &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;- main &lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[c version]&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;int main(void){&lt;span style="color: rgb(0, 153, 0);"&gt;  // ที่จริง int, void ที่ตั้งค่าของ main เราก็ไม่ค่อยรู้หรอก ก๊อปๆมาเฉบๆ =.=&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;   // do it&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;   return 0;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;[java version]&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(51, 102, 255);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;public class test{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    public static void main(String[] args){&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;        //do it&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;- switch case, if, while, for ใช้เหมือนกันเลย (รวมทั้งการประกาศตัวแปรด้วย)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;- การเขียน Method (หรือ function)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[c version]&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;[ตัวที่ return] [ชือ function]&lt;/span&gt; (&lt;span style="color: rgb(255, 0, 0);"&gt; [parameter]&lt;/span&gt; ){&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;   //.....&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;   return &lt;span style="color: rgb(255, 0, 0);"&gt;[ค่าที่คืน]&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;[java version]&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;public &lt;/span&gt;[ตัวที่ return] [ชือ function]&lt;/span&gt; (&lt;span style="color: rgb(255, 0, 0);"&gt; [parameter]&lt;/span&gt; ){&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;   //.....&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;   return &lt;span style="color: rgb(255, 0, 0);"&gt;[ค่าที่คืน]&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;จะเห็นว่า มันแทบไม่ต่างกันเลยนะ.... :D&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 51, 255); font-style: italic;"&gt;ประกาศตัวแปรใน AVR?&lt;/span&gt; &lt;span style="color: rgb(153, 51, 0);"&gt;บางคนอาจเห็น code ที่ว่า&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;int a, unsigned int b, char c, unsigned char d; &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ก็อาจงงว่า ทำไมต้องเป็นงี้, unsigned มันคือบ้าอะไร&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;ผมขอตอบตรงๆว่า "ผมก็ใช้มั่วครับ =_= "&lt;/span&gt;   แต่จะอธิบายคร่าวๆในแต่ละตัวแปรละกัน&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ใน AVR นี้ ขอแนะนำให้ใช้&lt;span style="font-weight: bold;"&gt; unsigned char &lt;/span&gt;นะ(ความรู้สึก) เพราะ char มั้นเป็นค่าแบบ 8 bit&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;และ unsigned หมายความว่าจะเป็นเฉพาะค่าบวก &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;เพราะฉะนั้น &lt;span style="font-weight: bold;"&gt;unsigned char จะเก็บค่าได้ตั้งแต่ 0-255 (เท่าที่เข้าใจนะ  - -a)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;&lt;span style="color: rgb(51, 51, 255); font-style: italic;"&gt;Include?&lt;/span&gt;&lt;span style="color: rgb(204, 102, 0);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;เหมือน import ใน java แหละ... ถ้าเราจะใช้อะไรก็ต้อง import เข้ามา&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;จริงๆ&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(204, 102, 0);"&gt; &lt;span style="font-style: italic;"&gt;เราก็ไม่เคยจำหรอก&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;ก๊อปๆ code เก่ามาอีกทีอ่ะ&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;- avr/io.h      &lt;span style="color: rgb(0, 153, 0);"&gt;  // จะมีตัวแปรต่างๆ ของ AVR อยู่,เอาไว้ตั้งค่าต่างๆ&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;- util/delay.h  &lt;span style="color: rgb(0, 153, 0);"&gt;// สามารถใช้ _delay_ms(int ms); ได้....&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;- avr/interrupt.h &lt;span style="color: rgb(0, 153, 0);"&gt;// ใช้พวก interrupt&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic; color: rgb(51, 51, 255);"&gt;Input&amp;amp;Output? &lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(204, 102, 0);"&gt;ขอสรุปง่ายๆ นะ&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;การตั้งค่า port ต่างๆของ avr นั้นจะตั้งค่าอยู่ที่ DDRx [x : B,C,D แล้วแต่เราจะใช้]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;โดย DDR แต่ละตัวจะมีจำนวน bit ต่างกันไป&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;  DDRB, DDRD จะมีจำนวน 8 บิท [7..0]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;  DDRC จะมี 7 บิท [6..0]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;แล้วก็ ถ้าสมมติเราจะ set ให้ PORTB5 เป็น Output สามารถตั้งค่าดังนี้&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(204, 102, 0);"&gt;&lt;span style="color: rgb(51, 102, 255);"&gt;DDRB |= (_BV(5));&lt;span style="color: rgb(51, 102, 255);"&gt;   &lt;span style="color: rgb(0, 153, 0);"&gt;// หมายถึง Shift left มา 5 บิท&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ถ้าจะตั้งเป็น input ก็ตั้งดังนี้ (ไปดูในส่วนของ &lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;Switch&lt;/span&gt; &lt;span style="color: rgb(153, 51, 0);"&gt;ด้วยนะ)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(51, 102, 255);"&gt;DDRB &amp;amp;= ~(&lt;span style="color: rgb(51, 102, 255);"&gt;_BV(5)&lt;/span&gt;);&lt;span style="color: rgb(0, 153, 0);"&gt; &lt;/span&gt;&lt;style="color: style="color: rgb(0, 153, 0);"&gt;// หมายถึง กลับบิท(Shift left มา 5 บิท)&lt;/style="color:&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(51, 51, 255);"&gt;Switch?&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 153);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(204, 102, 0);"&gt;&lt;span style="font-weight: bold;"&gt;ทำความเข้าใจ&lt;/span&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;กะ Switch ก่อนว่า ตอนต่อน่ะ มันจะเป็น Switch เปิด-ปิด&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ถ้าเกิดกด Switch มันจะให้ค่า 0 ออกมา(ต่อลง Ground) &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ฉะนั้น เราก็ต้อง Pull-up วงจร ซึ่ง AVR มัน Pull-up ให้อยู่แล้ว&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;(โดย set MCUCR ให้ bit ของ PUD ให้เป็น 0,   ดูได้จาก datasheet หน้า 86)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;แล้วก็ไปตั้งให้ PULL-UP เป็นค่า 1 ใน bit ที่ต้องการ &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;สมมติ จะ Pull-up PB0 ก็&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(51, 102, 255);"&gt;DDRB &amp;amp;= ~(&lt;span style="color: rgb(51, 102, 255);"&gt;_BV(PB0)&lt;/span&gt;);&lt;span style="color: rgb(0, 153, 0);"&gt;&lt;/span&gt;&lt;pb0);&gt;&lt;pb0);&gt;&lt;pb0); style="color: rgb(0, 153, 0);"&gt;      // input PB0&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;PORTB |= _BV(PB0)&lt;pb0);&gt;&lt;pb0); style="color: rgb(0, 153, 0);"&gt;   // Pull-up PB0&lt;/pb0);&gt;&lt;/pb0);&gt;&lt;/span&gt;&lt;/pb0);&gt;&lt;/pb0);&gt;&lt;/pb0);&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold; color: rgb(51, 204, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ส่วนการนำ Switch ไปใช้งานก็ทำได้ดังนี้&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(51, 102, 255);"&gt;if((PINB&amp;amp;0x01) == 0){          &lt;span style="color: rgb(0, 153, 0);"&gt;   // เช็คว่าเป็น 0 รึยัง ???&lt;/span&gt;&lt;br /&gt;_delay_ms(2);                    &lt;span style="color: rgb(51, 204, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt; // delay ระหว่างการกดให้มันรอซักหน่อย...&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;........ &lt;span style="color: rgb(51, 204, 0);"&gt;                                       &lt;span style="color: rgb(0, 153, 0);"&gt;// ทำอะไรก็ทำ... :P&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold; font-style: italic; color: rgb(51, 51, 255);"&gt;&lt;br /&gt;Timer&amp;amp;Clock? &lt;/span&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;มาเข้าใจก่อนว่า AVR ที่เรากำลังใช้อยู่นี้มันสามารถสร้าง Clock ที่ความถี่ 16MHz หรือใน 1 วิจะสร้าง clock ได้ 16 ล้านลูก...  โดยเราสามารถลดจำนวน clock ที่ผลิตออกมาได้โดยการ prescale&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;(ดูได้ที่ datasheet หน้า 104 ตาราง prescale)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ถ้าเราต้องการให้มัน prescale ที่ 1024 &lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(51, 102, 255);"&gt;TCCR0B |= _BV(CS02) | _BV(CS00)&lt;cs02)|(1&gt;&lt;cs00);&gt;&lt;cs00); style="color: rgb(0, 153, 0);"&gt;&lt;cs00);&gt;&lt;style="color:&gt;;  // 1024-prescaler &lt;/style="color:&gt;&lt;/cs00);&gt;&lt;/cs00);&gt;&lt;/cs00);&gt;&lt;/cs02)|(1&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;มันจะเปลี่ยนให้ AVR ปรับ Clock เป็นความถี่ 16MHz/1024 = 15625 Hz&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;แล้วก็ใน AVR จะมี Register ของ Timer อยู่คือ TCNT0( 8 bit )&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ซึ่งทุกๆ clock TCNT0 จะนับค่าเพิ่มขึ้น 1 ไปเรื่อยๆ จนถึงค่า 255 แล้วปรับเป็น 0 ใหม่&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic; color: rgb(51, 51, 255);"&gt;Interrupt?&lt;/span&gt; &lt;span style="color: rgb(153, 51, 0);"&gt;เอาแบบสรุปๆ รวดเร็วเลยนะ...&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;การตั้งค่า Interrupt มีหลากหลายแบบ &lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;เช่น Compare A, Compare B, Overflow&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; color: rgb(153, 51, 0);"&gt;แต่ที่ใช้กันในการทำแลปคือ Interrupt Overflow Flag&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ซึ่งตั้งค่าดังนี้ (ลองไปดู datasheet เกี่ยวกับ register timer เอาเด้อ... )&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(153, 51, 0);"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;TIMSK0 |= _BV(TOIE0)&lt;toie0); style="color: rgb(0, 102, 0);"&gt;// Timer Overflow Interrupt Enable&lt;/toie0);&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;sei();                                                 &lt;span style="color: rgb(0, 102, 0);"&gt;//Enable Interrupt&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ซึ่งการ Interrupt ทุกๆครั้งที่ TCNT0 นั้นเกิดการ Overflow(เกินค่า TOP ของ Counter)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;จะเกิด Overflow flag ขึ้นและไปทำงานที่ ISR(TIMER0_OVF_vect)&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="color: rgb(51, 51, 255);"&gt;ISR(TIMER0_OVF_vect) {&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;  // สมมติว่า AVR ให้ clock ที่ 15625 Hz และ Counter นี้จะ Interrupt ทุกๆ 256 clock&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;  // แสดงว่า Function นี้จะทำงาน 15625/256 ~ 61 Hz &lt;/span&gt;&lt;br /&gt;}&lt;/blockquote&gt;&lt;span style="color: rgb(51, 51, 255); font-weight: bold; font-style: italic;"&gt;&lt;br /&gt;PWM? &lt;/span&gt;&lt;span style="color: rgb(153, 51, 0);"&gt;ไปอ่านอันเก่าเอาเด้อ... =___=&lt;/span&gt;  &lt;a href="http://ramzpat.blogspot.com/2011/02/pwm-version.html"&gt;&lt;span style="font-weight: bold;"&gt; Click&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ปล. ถ้าว่าง(มาก) + ไม่เบื่อล่าแย้... จะมาอธิบาย แต่ละ Lab ให้ละกัน =..=&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ปล2. _BV(int bit) มันคือ shift left นะ....   ในBlog นี้ใช้ &lt; &lt; แล้วมันเจ๊ง = ="&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8364357518846111944-3465288733648883519?l=ramzpat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramzpat.blogspot.com/feeds/3465288733648883519/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://ramzpat.blogspot.com/2011/02/avr-c-version.html#comment-form' title='2 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default/3465288733648883519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default/3465288733648883519'/><link rel='alternate' type='text/html' href='http://ramzpat.blogspot.com/2011/02/avr-c-version.html' title='AVR [C version]'/><author><name>I'm Arm</name><uri>http://www.blogger.com/profile/17786183357862938531</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-n3EgJjQAof0/TVeOmgtfh-I/AAAAAAAAABo/SKHnyee-RW8/s220/logo2_bigger.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8364357518846111944.post-7222005391587827351</id><published>2011-02-10T00:42:00.000+07:00</published><updated>2011-02-10T00:42:46.411+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='disjoint set'/><category scheme='http://www.blogger.com/atom/ns#' term='data structure'/><title type='text'>Disjoint Set [data structure]</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_XTk5CpPyThQ/TVLJrzZ-4zI/AAAAAAAAADs/srj9qq7EC44/s1600/disjoint.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="220" src="http://2.bp.blogspot.com/_XTk5CpPyThQ/TVLJrzZ-4zI/AAAAAAAAADs/srj9qq7EC44/s320/disjoint.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;&lt;br /&gt;D&lt;/span&gt;&lt;span style="color: #073763;"&gt;isjoint Set&lt;/span&gt; ?&lt;/b&gt;&lt;/span&gt; &lt;span style="font-size: small;"&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp; ในการคำนวณที่มี set ของ element ให้มานั้น เราสามารถใช้ประโยชน์ในการแยกกลุ่มของ element ต่างๆออกได้เป็นกลุ่มๆ ที่ไม่มี element ที่เกี่ยวข้องกันเลย หรือเรียกว่า disjoint-set&amp;nbsp; ในระบบโครงสร้างแบบ Disjoint-set data structure นั้นจะแบ่ง element ต่างๆออกเป็นกลุ่มๆที่ไม่มีความเกี่ยวข้องกันเลย และจะมี Function หลักที่จัดการโครงสร้างข้อมูลดังนี้&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul style="color: #b45f06;"&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Find: สำหรับวิเคราะห์ว่า element ต่างๆที่เราหานั้น อยู่ใน set เดียวกันหรือไม่&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size: small;"&gt;Union: รวม set&amp;nbsp; สองอันให้เป็น set เดียวกัน&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #b45f06;"&gt;เนื่องจากการทำงานที่มีการทำงานทั้งสองแบบที่กล่าวมานั้น ทำให้โครงสร้างแบบ disjoint-set สามารถที่จะเรียกการใช้งาน union-find data structure หรือ merge-find set ได้&amp;nbsp; นอกจากนี้ยังมีการทำงานอย่างอื่นอีกคือ MakeSet จะเป็นการกำหนด set ให้ element (มี element คือตัวมันเองเพียง element เดียว)&amp;nbsp; ด้วยการทำงานทั้ง 3 อย่างนี้ เราสามารถที่จะใช้ในการแก้ปัญหา Partitioning problem ได้&lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ในบางครั้งเพื่อที่จะกำหนดฟังก์ชันการทำงานต่างๆเหล่านี้ เพื่อให้มีความแม่นยำมากขึ้น จำเป็นต้องแสดง set โดยละเอียด&lt;/span&gt;&lt;br style="color: #f6b26b;" /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;D&lt;/span&gt;&lt;span style="color: #134f5c;"&gt;isjoint-set: Linked-Lists&amp;nbsp; &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;a href="http://4.bp.blogspot.com/_XTk5CpPyThQ/TVLMYnNx5yI/AAAAAAAAADw/yZZw-h1-TP0/s1600/link-list.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp;&amp;nbsp; วิธีที่จะแสดงโครงสร้างข้อมูลแบบ disjoint-set อย่างง่ายๆคือการสร้าง &lt;a href="http://en.wikipedia.org/wiki/Minimum_spanning_tree"&gt;Linked list&lt;/a&gt; ในแต่ละ set โดย element ที่เป็น Head ของ list จะเป็นตัวแทนในการแสดง set ในกลุ่มนั้นๆ ซึ่งการกำหนด set เริ่มต้นในแต่ละ element ทำได้โดย MakeSet ขึ้นมาเพื่อสร้าง List ที่มี 1 element นอกจากนี้ก็จะมี Union จะทำการรวม element ใน แต่ละ set ให้เป็น set เดียวกัน ซึ่งในการ Union จะใช้เวลาเป็นค่าคงตัว แต่ในการ Find นั้นมีข้อเสียซึ่งใช้เวลาในการทำงาน Ω(n)  หรือ เป็นเชิงเส้น อย่างไรก็ตาม Union จะทำการปรับค่าของแต่ละ element  ใน set ให้มี head เป็นที่เดียวกันก็ต้องใช้เวลา Ω(n)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XTk5CpPyThQ/TVLMYnNx5yI/AAAAAAAAADw/yZZw-h1-TP0/s1600/link-list.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="199" src="http://4.bp.blogspot.com/_XTk5CpPyThQ/TVLMYnNx5yI/AAAAAAAAADw/yZZw-h1-TP0/s320/link-list.jpg" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-size: small;"&gt; &lt;br /&gt;&lt;b style="color: #38761d;"&gt;&lt;span style="color: red;"&gt;D&lt;/span&gt;isjoint-set: Forests(Tree structure)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp; Disjoint-set forests เป็นโครงสร้างของ disjoint-set ที่แสดงความสัมพันธ์ของ set ด้วย &lt;a href="http://en.wikipedia.org/wiki/Tree_data_structure"&gt;Tree data structure&lt;/a&gt; ซึ่งในแต่ละ node ของ tree นั้นจะถูกอ้างอิงไปยัง parent ของแต่ละ node โดยวิธีนี้ได้ถกอธิบายโดย Bernard A. Galler และ Michael J. Fischer ในปี ค.ศ. 1964 &lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp;&amp;nbsp; Disjoint-set forests จะแสดงแต่ละ set ของแต่ละกลุ่มด้วย root ของแต่ละ tree โดยเราสามารถหา( Find )ได้ว่า Element ที่เรากำลังพิจารณานั้นอยู่ใน set ใดโดยดู Parent ของแต่ละ tree นอกจากนี้ การUnion ก็สามารถทำได้โดยรวมเอา root ของแต่ละ set ให้รวมเป็น tree ต้นเดียวกัน ดังนั้นเราสามารถสร้าง Structure นี้ได้ดังนี้&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;function MakeSet(x)&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;     x.parent := x&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;b&gt;function Find(x)&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if x.parent == x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return Find(x.parent)&lt;/span&gt; &lt;/blockquote&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;b&gt;&amp;nbsp;function Union(x, y)&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xRoot := Find(x)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yRoot := Find(y)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xRoot.parent := yRoot&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp; ในรูปแบบที่กล่าวมานั้นยังเป็นการทำงานที่ไม่ดีพอ เนื่องจาก tree นั้นมีโอกาสสูงที่จะมีความสูงของต้นไม้มากเกินจำเป็นทำให้การค้นหา set นั้นใช้เวลานาน อย่างไรก็ตามเราสามารถเพิ่มประสิทธิภาพได้สองวิธี วิธีแรกจะใช้การ Union โดยใช้ Rank ซึ่งจะทำให้ tree นั้นมีความสูงน้อยลง(เตี้ยลง) และ เป็น tree ขนาดใหญ่ขึ้น(กว้างขึ้น) ซึ่งส่งผลต่อการประมวลผลจะทำให้เร็วขึ้นเนื่องจากความสูงของ tree นั้นมีผลต่อการประมวลผลต่างๆ ซึ่งการทำงานจะ Union tree มีมีความน้อย ไปต่อท้าย tree ที่มีความสูงมากกว่าซึ่งจะทำให้เวลาในการประมวลผลไม่เพิ่มขึ้น และ tree นั้นจะมีความสูงเพิ่มขึ้นก็ต่อเมื่อ tree สองต้นนั้นมีความสูงเท่ากัน ในวิธีนี้เราจะใช้ Rank แทนความสูงของต้นไม้ โดยจะกำหนดให้ ต้นไม้ที่มีเพียง 1 element จะมี Rank = 0 และความสูงของต้นไม้ที่มี rank = r เท่ากัน เมื่อถูก union จะมี rank = r+1 ซึ่งผลจากวิธีนี้จะทำให้เวลาในการทำงานของ MakeSet,Union,Find ใล้เวลาในการทำงานเป็น O(logn) จากที่กล่าวมาจะสามารถสร้าง Pseudocode ของ MakeSet และ Union ได้ดังนี้&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size: small;"&gt;&lt;span style="color: black;"&gt;&lt;b&gt;&amp;nbsp;function MakeSet(x)&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.parent := x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.rank&amp;nbsp;&amp;nbsp; := 0 &lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; function Union(x, y)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: small;"&gt;&amp;nbsp; xRoot := Find(x)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yRoot := Find(y)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if xRoot.rank &amp;gt; yRoot.rank&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yRoot.parent := xRoot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else if xRoot != yRoot // Unless x and y are already in same set, merge them&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; xRoot.parent := yRoot&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if xRoot.rank == yRoot.rank&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yRoot.rank := yRoot.rank + 1&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="color: #b45f06;"&gt;ส่วนวิธีที่สองที่จะปรับปรุงความสามารถให้ดีขึ้นนั้น จะเรียกว่า "path compression" หรืออธิบายคร่าวๆว่าจะเปลี่ยนเส้นทางการเชื่อมของ child ใน tree ของ set นั้นๆให้ชี้ Parent มาที่ root โดยตรงเลย ซึ่งจะทำให้ระยะทางที่ Find จะทำงานนั้นใช้เวลาที่สั้นลง โดยเราสามารถปรับปรุง Find ได้ดังนี้&lt;/span&gt; &lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: black;"&gt;&lt;b&gt;function Find(x)&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if x.parent == x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x.parent := Find(x.parent)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return x.parent&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="color: #b45f06;"&gt;&amp;nbsp;จากทั้งสองวิธีที่กล่าวมานั้นสามารถทำให้การทำงานมีประสิทธิภาพมากขึ้น โดยเวลาในการทำงานนั้นจะมีประสิทธิภาพเพิ่มมากขึ้น เมื่อมีการใช้งานที่มากขึ้น&amp;nbsp; ดังนั้นเวลาที่ใช้ดำเนินงานจะเข้าใกล้ค่าคงที่ขนาดเล็กมาก&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_XTk5CpPyThQ/TVLOH7tTMgI/AAAAAAAAAD0/LGz3siNyfTs/s1600/tree.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="216" src="http://4.bp.blogspot.com/_XTk5CpPyThQ/TVLOH7tTMgI/AAAAAAAAAD0/LGz3siNyfTs/s320/tree.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="color: #b45f06;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #b45f06;"&gt;&lt;b&gt;&lt;span style="color: red;"&gt;App&lt;/span&gt;&lt;span style="color: black;"&gt;lications &lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="color: #b45f06;"&gt;&amp;nbsp; โครงสร้างข้อมูลแบบ Disjoint-Set จะจำลองการแบ่งกลุ่มของงานออกเป็น set อย่างเช่นการตรวจสอบ Connected Component ของ undirected graph โดยในการจำลองปัญหานี้จะสามารถกำหนดได้ว่าจุดสองจุดใดๆจะเป็น component เดียวกัน หรือสามารถเช็คได้ว่า ถ้าหากเชื่อมจุดสองจุดนั้นจะทำให้เกิด cycle ขึ้น โดย Union-Find algorithm นี้ นอกจากนี้โครงสร้างนี้ได้ถูกใช้ใน &lt;a href="http://en.wikipedia.org/wiki/Kruskal%27s_algorithm"&gt;Kruskal's algorithm&lt;/a&gt; เพื่อใช้ในการหา &lt;a href="http://en.wikipedia.org/wiki/Minimum_spanning_tree"&gt;minimum spanning tree&lt;/a&gt; ของ graph&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_XTk5CpPyThQ/TVLPXN_ajnI/AAAAAAAAAD4/NTJ8ICTiOoE/s1600/kruskal.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XTk5CpPyThQ/TVLPXN_ajnI/AAAAAAAAAD4/NTJ8ICTiOoE/s1600/kruskal.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;R&lt;/span&gt;&lt;span style="color: blue;"&gt;eference&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;ul style="color: black;"&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/goog_1366568443"&gt;Wikipedia&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Disjoint-set_data_structure"&gt; - Disjoint-set&lt;/a&gt;&lt;/li&gt;&lt;li&gt;I&lt;a href="http://bt1.posterous.com/linked-list-representation-of-disjoint-sets"&gt;mplementation of Linked-list representation in C++&lt;/a&gt;, by Bo Tian&lt;/li&gt;&lt;li&gt;&lt;a class="external text" href="http://bt1.posterous.com/disjoint-set-forests" rel="nofollow"&gt;Implementation of Disjoint-set Forests in C++&lt;/a&gt;, by Bo Tian&lt;/li&gt;&lt;li&gt;&lt;a class="external text" href="http://www.boost.org/libs/disjoint_sets/disjoint_sets.html" rel="nofollow"&gt;C++ implementation&lt;/a&gt;, part of the &lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Boost_C%2B%2B_libraries" title="Boost C++ libraries"&gt;Boost C++ libraries&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a class="external text" href="http://www.cs.unm.edu/%7Erlpm/499/uf.html" rel="nofollow"&gt;Java applet: A Graphical Union-Find Implementation&lt;/a&gt;, by Rory L. P. McGuire&lt;/li&gt;&lt;li&gt;&lt;i&gt;&lt;a class="external text" href="http://citeseer.ist.psu.edu/anderson94waitfree.html" rel="nofollow"&gt;Wait-free Parallel Algorithms for the Union-Find Problem&lt;/a&gt;&lt;/i&gt;, a 1994 paper by Richard J. Anderson and Heather Woll describing a parallelized version of Union-Find that never needs to block&lt;/li&gt;&lt;li&gt;&lt;a class="external text" href="http://code.activestate.com/recipes/215912-union-find-data-structure/" rel="nofollow"&gt;Python implementation&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8364357518846111944-7222005391587827351?l=ramzpat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramzpat.blogspot.com/feeds/7222005391587827351/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://ramzpat.blogspot.com/2011/02/disjoint-set-data-structure.html#comment-form' title='0 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default/7222005391587827351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default/7222005391587827351'/><link rel='alternate' type='text/html' href='http://ramzpat.blogspot.com/2011/02/disjoint-set-data-structure.html' title='Disjoint Set [data structure]'/><author><name>Im Arm</name><uri>http://www.blogger.com/profile/09454865819792095144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_XTk5CpPyThQ/Sf1Ix54JLZI/AAAAAAAAABY/Vxnd1OZCPCU/s1600-R/logo2_bigger.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_XTk5CpPyThQ/TVLJrzZ-4zI/AAAAAAAAADs/srj9qq7EC44/s72-c/disjoint.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8364357518846111944.post-2735542145676889323</id><published>2011-02-09T21:58:00.000+07:00</published><updated>2011-02-09T21:58:07.229+07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pwm'/><category scheme='http://www.blogger.com/atom/ns#' term='avr'/><category scheme='http://www.blogger.com/atom/ns#' term='ATmega168'/><title type='text'>การใช้ PWM version มั่ว...</title><content type='html'>&lt;span style="color: #b45f06;"&gt;&amp;nbsp; เพื่อที่จะดูเป็น&lt;/span&gt;&lt;b style="color: #b45f06;"&gt;ทางการ&lt;/b&gt;&lt;span style="color: #b45f06;"&gt; กระผมขอเปิดบทความแรกด้วยการโพสอะไรที่มันดูมีสาระหน่อยละกันฮับ&amp;nbsp; เอาเป็นเรื่องการเขียน PWM ของบอร์ด AVR ที่กำลังเรียนอยู่ในวิชา Verilog ละกัน&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style="color: blue;"&gt;[PWM-ยกตัวอย่างแบบ fast pwm mode นะ]&lt;/b&gt;&lt;br /&gt;&lt;span style="color: #b45f06;"&gt;ขออธิบายเท่าที่เราเข้าใจนะ... เพราะไม่รู้จิง+จารย์ไม่ได้สอนในห้อง(เลยยยยย)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;?pwm&lt;span style="color: #134f5c;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="color: #b45f06;"&gt;คือ... อะไรไม่รู้ที่สามารถควบคุมการนับ &lt;b&gt;TCNT0&lt;/b&gt;(Counter ของ timer) ได้ [กำหนดค่าสูงสุดของการนับ ปกติเปน 255 แล้ว interrupt เป็น 0]&lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;และสามารถสร้าง square wave ได้จากไอ่ TCNT0 อ่ะแหละ... มันเป็นไง เด๋วบอกอีกที :P&lt;/span&gt;&lt;br style="color: #134f5c;" /&gt;&lt;br /&gt;&lt;b style="color: red;"&gt;fast pwm ?&lt;/b&gt;&lt;br /&gt;&lt;span style="color: #b45f06;"&gt;มันคือ mode ที่นับ Counter(TCNT0) ตั้งแต่ 0 ถึง TOP(ปกติ max:255) อ่ะ แล้วกลับมาที่ 0 ใหม่เพื่อนับไปเรื่อยๆ ในแต่ละ Clock &lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;ถ้าเราตั้งโหมดให้กำหนด TOP ได้ (กำหนดโดย OCR0A)&amp;nbsp; เราจะสามารถที่จะควบคุมปริมาณจำนวน square wave ที่เกิดขึ้นได้ในเวลาที่กำหนด&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;Square Wave &lt;/span&gt;มาจากไหน ?&lt;/b&gt;&lt;br /&gt;&lt;span style="color: #b45f06;"&gt;-ขอเริ่มจากการกำหนด ค่า &lt;b style="color: #e69138;"&gt;OCR0A&lt;/b&gt;&lt;span style="color: #e69138;"&gt; &lt;/span&gt;และ&lt;span style="color: #e69138;"&gt; &lt;/span&gt;&lt;b style="color: #e69138;"&gt;OCR0B&lt;/b&gt; ซึ่ง... OCR0A คือ TOP ของ TCNT0 ที่เป็น counter ที่จะนับ และ&lt;/span&gt;&lt;span style="color: #b45f06;"&gt; OCR0B เรียกง่ายๆ มันจะเป็นตัวกำหนด % Duty-Cycle ของ wave ที่เราต้องการ&amp;nbsp;&lt;span style="color: #f6b26b;"&gt; &lt;span style="color: #e69138;"&gt;[ในที่นี้ต้องการ 50% duty-cycle ดังนั้น OCR0B = OCR0A/2]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #b45f06;"&gt;-ส่วน &lt;/span&gt;&lt;b style="color: #b45f06;"&gt;Wave&lt;/b&gt;&lt;span style="color: #b45f06;"&gt; ที่แสดงออกมานั้นจะออกทาง&lt;i style="color: #e69138;"&gt; &lt;b&gt;OC0A(PD6)&lt;/b&gt;&lt;/i&gt; หรือไม่ก็ &lt;b&gt;&lt;i&gt;&lt;span style="color: #e69138;"&gt;OC0B(PD5) &lt;/span&gt;&lt;/i&gt;&lt;/b&gt;แล้วแต่เรากำหนด(เด๋วจะกำหนดให้ดู)&lt;/span&gt;&lt;span style="color: #b45f06;"&gt;&amp;nbsp; ซึ่งมันจะทำงานประมาณว่า พอ Counter นับไปถึง OCR0B แล้วมันจะสลับค่า Wave ไปอีกค่าหนึ่ง(ตามที่ตั้งค่าไว้)&lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;และจะสลับไปเป็นอีกค่าเมื่อ Counter นับถึง OCR0A หรือ TOP นั่นเอง แล้วกลับมานับ 0 ใหม่&lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;ซึ่งการทำงานตรงนี้จะให้ Square Wave มาให้เราได้&lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;ต้องการบรรเลง &lt;span style="color: red;"&gt;NOTE &lt;/span&gt;ต่างๆจะทำอย่างไร ?&lt;/b&gt;&lt;br /&gt;&lt;span style="color: #b45f06;"&gt;- เนื่องจากปกติ avr จะสร้าง clock ความถี่ 16MHz หรือ สร้าง คลื่นมา 16ล้าน ลูกถูกป่ะ,&amp;nbsp; แล้วหลังจากเรา prescale ด้วย 1024 แล้วมันจะให้ clock ทั้งหมด 15625 ลูกภายใน 1 วินาที(16MHz/1024 = 15625 Hz)&lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;คราวนี้(สมมติ)เราต้องการสร้าง wave จำนวน 261.63 Hz&amp;nbsp; ซึ่งหมายถึง ใน 1 วิต้องมี Wave ทั้งหมด ~ 261 ลูก&amp;nbsp; แสดงว่า Counter นั้นจะต้องวิ่งนับทั้งหมด 15625/261.63 clock ~&amp;nbsp; 59 clock&lt;/span&gt;&lt;br style="color: #b45f06;" /&gt;&lt;span style="color: #b45f06;"&gt;จะได้ว่าเราจะต้องกำหนด TOP(OCR0A) ให้เป็น 59 เพื่อจะทำให้ใน 1 วินั้นมี Wave ~ 261 ลูก&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;หมาวยเหตุ: &lt;/span&gt;&lt;/b&gt;&lt;span style="color: #b45f06;"&gt;ปกติ Interrupt นั้นจะต้องนับ Counter ถึง 255 มันถึงจะทำ ISR(TIMER0_OVF_vect)&amp;nbsp; แต่ในที่นี้ Counter พอนับถึง TOP มันก็ Interrupt เน้ออออ&lt;/span&gt;&lt;span style="color: #b45f06;"&gt;&lt;br /&gt;&lt;br /&gt;Example Code : &lt;/span&gt;&lt;a href="http://dl.dropbox.com/u/15478154/pwm_fast.c"&gt;&lt;b&gt;Click&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: #b45f06;"&gt;PWM Reference&lt;/span&gt; : &lt;a href="http://dl.dropbox.com/u/15478154/PWM%20in%20AVR%20v1.0.pdf"&gt;&lt;b&gt;Click&lt;/b&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8364357518846111944-2735542145676889323?l=ramzpat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ramzpat.blogspot.com/feeds/2735542145676889323/comments/default' title='ส่งความคิดเห็น'/><link rel='replies' type='text/html' href='http://ramzpat.blogspot.com/2011/02/pwm-version.html#comment-form' title='1 ความคิดเห็น'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default/2735542145676889323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8364357518846111944/posts/default/2735542145676889323'/><link rel='alternate' type='text/html' href='http://ramzpat.blogspot.com/2011/02/pwm-version.html' title='การใช้ PWM version มั่ว...'/><author><name>Im Arm</name><uri>http://www.blogger.com/profile/09454865819792095144</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_XTk5CpPyThQ/Sf1Ix54JLZI/AAAAAAAAABY/Vxnd1OZCPCU/s1600-R/logo2_bigger.jpg'/></author><thr:total>1</thr:total></entry></feed>
