กันยายน 02, 2014, 04:04:32 pm *
ยินดีต้อนรับคุณ, บุคคลทั่วไป กรุณา เข้าสู่ระบบ หรือ ลงทะเบียน
ส่งอีเมล์ยืนยันการใช้งาน?

เข้าสู่ระบบด้วยชื่อผู้ใช้ รหัสผ่าน และระยะเวลาในเซสชั่น
   หน้าแรก   ช่วยเหลือ เข้าสู่ระบบ สมัครสมาชิก  
หน้า: [1] 2   ลงล่าง
  พิมพ์  
ผู้เขียน หัวข้อ: PIC12F675 ตอนที่ 1 ไฟกระพริบ  (อ่าน 7249 ครั้ง)
0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« เมื่อ: เมษายน 30, 2010, 08:56:49 pm »

พูดถึง PIC หลายๆคนคงคิดไปถึง PIC16F628, PIC16F84, PIC16F877, dsPIC30x, dsPIC33x เพราะน่าจะคุ้นหูคุ้นตากันตามกระแสตลาดบ้านเรา
แต่ผมไม่อยากพูดถึงเบอร์เหล่านั้น เพราะขามันเยอะเกินจะมาทำอะไรเล่นๆ เพื่อเรียนรู้กันสนุกๆ ก็เลยหา PIC ที่มีแค่ 8 ขามาเสนอดีกว่า เบอร์ที่จะยกมาในที่นี้คือเบอร์...
PIC12F675



มี 8 ขาก็จริงครับ ต่อขาที่นำมาใช้งานได้มี 6 ขา ก็มากพอแล้วสำหรับนำมาทำอะไรเล่นๆ เช่นสร้างสัญญาณเสียง ไฟกระพริบ ควบคุมอะไรเล็กๆน้อยๆ


ถึงจะมีพอร์ตให้ใช้แค่ 6 ขา ก็ใช่ว่าจะทำอะไรที่ยากๆไม่ได้ซะเมื่อไร่


เสน่ห์ของมันอยู่ที่จะออกแบบวงจรและเขียนโปรแกรมอย่างไรให้ไมโครคอนโทรลเลอร์ตัวเล็กๆทำอะไรที่ยิ่งใหญ่ได้ นั่นคือสิ่งที่น่าสนใจ
เพราะจะนำพาให้เราคิดและพยายามแก้ปัญหา ได้รู้จักกับอุปกรณ์ที่ต้องนำมาต่อให้ทำงานร่วมกันกับไมโครคอนโทรลเลอร์

แน่นอน อาจจะขัดใจ ว่าทำไมต้องไปดิ้นรนออกแบบวงจรเพิ่มเข้ามา ยาก วุ่นวาย แพงกว่าด้วย ถ้าคิดแบบนั้น บทความนี้ได้จบลงแล้ว ณ บรรทัดนี้



ผมเดาถูกว่าคุณไม่ยอมจบที่บรรทัดก่อนหน้าหรอก มาถูกตรงนี้คุณติดกับดักผมแล้ว  ;)

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




บทความนี้และบทความต่อๆไป ผมจะใช้ MPLAB IDE จาก www.microchip.com เป็น Editor สำหรับการเขียนโปรแกรม
และใช้คอมไพเลอร์ HI-TECH C for the PIC10/12/16 MCU family จาก http://www.htsoft.com/ เป็น Compiler
ที่ใช้ตัวนี้เพราะ ผมไม่เคยใช้ นั่นเป็นเหตุผลเดียว

และเพื่อให้มั่นใจว่าทั้ง Hardware และ Software ทำงานได้ถูกต้อง จะใช้โปรแกรม Proteus จาก www.labcenter.co.uk/ เป็น Simulator สำหรับจำลองการทำงาน
เพราะผมมั่นใจว่าไม่มีโปรแกรมไหนทำหน้าที่จำลองการทำงานของไมโครคอนโทรลเลอร์ได้ดีกว่าโปรแกรมนี้


บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« ตอบ #1 เมื่อ: เมษายน 30, 2010, 10:31:23 pm »

ก่อนจะไปว่ากันถึงการเขียนโปรแกรม มาดูวงจรกันก่อน



วงจรเป็นวงจรง่ายๆ คนที่มีความรู้วงจรอิเล็กทรอนิกส์อยู่แล้วคงไม่ต้องนั่งคิดว่ามันทำงานอย่างไร แต่ในเมื่อตั้งใจจะเขียนเป็นความรู้พื้นฐานแล้ว
ก็จะขออธิบายการทำงานของวงจรกันก่อน


  • ขา 7 ของ PIC12F675 ได้ต่อผ่านตัวต้านทาน R1 ค่า 330 โอห์ม เพื่อจำกัดกระแสที่ไหลผ่าน LED1
  • เมื่อขา 7 ของ PIC12F675 เป็นลอจิก '1' หรือมีแรงดันประมาณค่าแรงดันของแหล่งจ่าย (5 โวลท์) จะมีกระแสไฟฟ้าไหลผ่าน R1 ผ่าน LED1 ครบวงจรที่กราวด์)
  • เมื่อมีกระแสไฟฟ้าไหลผ่าน LED1 จะทำให้ LED1 สว่าง (ติด)

นั่นหมายความว่า การทำให้ LED1 ติด และ ดับ สามารถทำได้โดยการเปลี่ยนลอจิกที่ขา 7 ของ PIC12F675 เป็นลอจิก '1' และ '0' ตามลำดับ
ซึ่งสามารถทำได้โดยกระบวนการทางซอฟซ์แวร์ ที่จะพูดถึงต่อไป




การใช้งานพอร์ตของไมโครคอนโทรลเลอร์ สิ่งแรกที่ต้องทำคือการกำหนดการทำงานของพอร์ตให้ตรงกับความต้องการเสียก่อน
ในที่นี้เราต้องการใช้ขาพอร์ตไปควบคุมการติด ดับของ LED นั่นหมายความว่าจะต้องกำหนดขาพอร์ตให้เป็นพอร์ตแบบเอาต์พุตนั่นเอง
เมื่อกำหนดการทำงานของพอร์ตให้เป็นพอร์ตเอาต์พุตเสร็จแล้ว สามารถทำการส่งลอจิก '1' หรือ '0' ออกไปที่ขาพอร์ตได้ทันที มาดูโปรแกรมกันครับ


ภาษาซี:
Code: (c)

    TRISIO  = 0xFE;  // กำหนดให้ GP0 (ขา 7) เป็นพอร์ตแบบเอาต์พุต
    GPIO    = 0x01;  // ส่งลอจิก '1' ออกไปที่ GP0


TRISIO เป็นรีจิสเตอร์ที่ใช้สำหรับการกำหนดทิศทางของพอร์ต ให้เป็นพอร์ตอินพุตหรือเอาต์พุต ต้องการให้พอร์ตบิตไหนเป็นเอาต์พุต ให้ทำการเขียนลอจิก '0' ไปยังบิตนั้น
ในที่นี้ต้องการให้ GP0 (บิต 0) เป็นเอาต์พุต จึงได้ทำงานเขียนค่า 0xFE (1111 1110) ไปยังรีจิสเตอร์ TRISIO ซึ่งส่งผลให้ GP0 เป็นพอร์ตแบบเอาต์พุตนั่นเอง


GPIO เป็นรีจิสเตอร์ที่ใช้สำหรับกำหนดลอจิกที่พอร์ต (เมื่อพอร์ตกำหนดให้เป็นพอร์ตแบบเอาต์พุต) ในที่นี้ต้องการให้ LED1 ติด จึงทำการเขียนค่า 0x01 (0000 0001) ไปยัง GPIO

ผลที่ได้:


ตอนนี้เราได้ส่งลอจิก '1' ไปที่พอร์ตได้แล้วเรียบร้อย อย่างที่ได้กล่าวไปในตอนต้น เมื่อขาพอร์ตเป็น '1' จะมีกระแสไหลผ่านตัวทานตาน R1 ผ่าน LED1 ครบวงจรที่กราวด์ ทำให้ LED1 ติด

เพื่อให้เข้าใจถึงกระบวนการเชิงลึก กันอีกเล็กน้อย มาดูกันครับว่าโปรแกรมภาษาซีด้านบน เมื่อถูกแปลงมาเป็นโปรแกรมภาษาแอสแซมบลีจะเป็นอย่างไร

ภาษาแอสแซมบลี:
Code: (c)

    MOVLW 0xfe      // เขียนค่า 0xFE ไปยังรีจิสเตอร์ W
    BSF 0x3, 0x5   // เซตบิตที่ 5 ของหน่วยความจำตำแหน่งที่ 0x03 ซึ่งเป็นรีจอสเตอร์ STATUS เพื่อทำงานเลือกแบงค์ของรีจิสเตอร์เป็นแบงค์ 1
    MOVWF 0x5      // เขียนค่าจากรีจิสเตอร์ W ไปยังหน่วยความจำในตำแหน่ง 0x05 (ในแบงค์ 1 คือ 0x85) ซึ่งเป็นตำแหน่งของ TRISIO    

    MOVLW 0x1      // เขียนค่า 0x01 ไปยังรีจิสเตอร์ W
    BCF 0x3, 0x5   // เคลียร์บิตที่ 5 ของหน่วยความจำตำแหน่งที่ 0x03 ซึ่งเป็นรีจอสเตอร์ STATUS เพื่อทำงานเลือกแบงค์ของรีจิสเตอร์เป็นแบงค์ 0
    MOVWF 0x5      // เขียนค่าจากรีจิสเตอร์ W ไปยังหน่วยความจำในตำแหน่ง 0x05 (ในแบงค์ 0 คือ 0x05) ซึ่งเป็นตำแหน่งของ GPIO


BSF 0x3, 0x5 โดยทั่วไปจะเขียนเป็น BSF STATUS, 0x5 แต่ต้องทำการ include ไฟล์ของไมโครคอนโทลเลอร์เบอร์นั้นๆเข้ามาก่อน ปรกติไฟล์ดังกล่าวจะมีนามสกุลเป็น .inc

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


บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« ตอบ #2 เมื่อ: เมษายน 30, 2010, 10:32:06 pm »

ตอนนี้มาดูโปรแกรมกันอีกสักโปรแกรม ซึ่งเป็นโปรแกรมที่มีจุดประสงค์ทุกอย่างเหมือนโปรแกรมที่ได้กล่าวไปแล้วก่อนหน้า

ภาษาซี:
Code: (c)

    TRISIO  &= 0xFE;
    GPIO    |= 0x01;


TRISIO  &= 0xFE มีความหมายเหมือนกันกับ TRISIO  = TRISIO&0xFE คือนำค่าในรีจิสเตอร์ TRISIO มาทำการ AND กับ 0xFE ได้ค่าเท่าไร่นำไปใส่ไว้ที่ TRISIO (|= ก็มีการทำงานที่คล้ายกัน แต่เป็นการ OR)

มาดูในรูปแบบของโปรแกรมภาษาแอสแซมบลีกันบ้าง

ภาษาแอสแซมบลี:
Code: (c)

    BSF 0x3, 0x5
    BCF 0x5, 0

    BCF 0x3, 0x5
    BSF 0x5, 0


ลองเปรียบเทียบกับงโปรแกรมภาษาแอสแซมบลีด้านบนครับ ตอนนี้จะเห็นว่าคำสั่ง MOVLW ไม่มีแล้ว และเป็นผลทำให้โปรแกรมลดสั้นลงจาก 6 บรรทัดเหลือเพียง 4 บรรทัดเท่านั้น การที่โปรแกรมภาษาแอสแซมบลีสั้นลงเป็นตัวบ่งชี้ว่า โปรแกรมนี้ทำงานได้เร็วกว่า ใช้หน่วยความจำโปรแกรมน้อยกว่า และผู้เขียนโปรแกรมมีความรู้มากกว่า แน่นอนครับ โปรแกรมทำงานเร็ว ใช้หน่วยความจำน้อย และทำงานได้ถูกต้อง เป็นโปรแกรมที่ถือว่ายอดเยี่ยม สิ่งเหล่านี้จะได้มาเมื่อศึกษาการเขียนโปรแกรมภาษาซีควบคู่ไปกับการอ่านภาษาแอสแซมบลีและ datasheet ของไมโครคอนโรลเลอร์และคอมไพเลอร์ที่คุณให้อยู่



พูดมาซะยาวและนาน ไฟยังไม่กระพริบสักที เอาหละงั้นเริ่มกระพริบกันได้แล้ว
Code: (c)
#include <htc.h>

__CONFIG(INTIO & MCLRDIS & WDTDIS);

void delay_1ms(unsigned int ms)
{
   unsigned int k;
   while(ms--){
      for(k=0;k<83;k++); // 1mS @ CPU_CLK=4MHz
   }
}

void system_init(void)
{
   //--- Set all ports as Digital I/O
   CMCON  |= 0x07;   // Comparator Off
   ANSEL  &= 0xF0;   // Digital I/O
   TRISIO &= 0xFE; // GPIO1 as output
   GPIO   &= 0xFE; // Turn off LED   
}

void main(void)
{
   system_init();
   while(1)//for(;;)
   {
      GPIO |= 0x01;
      delay_1ms(100);
      
      GPIO &= 0xFE;   
      delay_1ms(100);
   }   
}


ผลที่ได้:


ดูจากโปรแกรมดูแล้วรับรู้ได้ทันทีว่า โปรแกรมนี้ยาวเกินไป น่าจะมีวิธีการเขียนโปรแกรมให้สั้นกว่านี้ได้
แน่นอนครับทำได้ แต่ผมจะปล่อยให้ไปคิดต่อเองครับ  :D

จบแล้ว


บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
EDENAS
บุคคลทั่วไป
| |
« ตอบ #3 เมื่อ: มิถุนายน 24, 2010, 09:43:21 am »

ขอบคุณครับสันติที่ให้ความรู้เกี่ยวกับ Editor และ Compiler ของ PIC เพื่อจะได้นำไปพัฒนาต่อไปครับ ผมกำลังอยากจะลอง Micro ตัวอื่นบ้างพอดี
ว่าแต่คำสั่งวนลูปในโปรแกรมที่ให้มายาวจัง อิอิ
บันทึกการเข้า
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« ตอบ #4 เมื่อ: สิงหาคม 10, 2010, 11:14:07 pm »

เพิ่งแวะมาเห็นครับ ว่ามีสิ่งแปลกปลอม อยู่ที่บรรทัดที่ 25 แก้ให้แล้วครับ
ตัว Syntax Highter มันตีความ for( ;; ) เป็นอย่างอื่นไป (เป็น HTML ตามที่ comment ไว้ในบรรทัดที่ 25) ตอนนี้แก้เป็น while( 1 ) แทนแล้วครับ
บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
m150
Newbie
*
ออฟไลน์ ออฟไลน์

กระทู้: 1


| |
« ตอบ #5 เมื่อ: กุมภาพันธ์ 11, 2011, 09:16:45 am »

ขอไฟล์ .DSN ของ Proteus หน่อยครับ
ผมอยากทดลองซิมดูผลการทดลองที่บ้านครับ
บันทึกการเข้า
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« ตอบ #6 เมื่อ: กุมภาพันธ์ 11, 2011, 09:30:57 am »

วงจรนี้มีอุปกรณ์เพียง 3 ตัวเท่านั้น
มีเหตุผลอะไรที่อยากได้ไฟล์ *.DSN ครับ?
ตอนนี้ไฟล์ไม่ได้อยู่ในเครื่องของผมบวกกับไม่ได้ลง Proteus ไว้ด้วย
และผมเชื่อว่าคุณสามารถเขียนวงจรนี้ขึ่นมาใหม่โดยใช้เวลาน้อยกว่า 3 นาที (หรือมากกว่าเล็กน้อย)
ถ้าทำไม่ได้ ด้วยเหตุผลอะไรก็ตาม บอกผมอีกที แล้วจะเขียนวงจรและส่ง *.DSN ไปให้ครับ
บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
MCPIC24
Newbie
*
ออฟไลน์ ออฟไลน์

กระทู้: 7


| |
« ตอบ #7 เมื่อ: กุมภาพันธ์ 28, 2011, 08:59:48 pm »

เชื่อม C กับ Assembly ได้ขนาดนี้เลย สุดยอดครับ
บันทึกการเข้า
the_hen
Newbie
*
ออฟไลน์ ออฟไลน์

กระทู้: 26


| |
« ตอบ #8 เมื่อ: สิงหาคม 04, 2011, 03:34:18 pm »

ขอดูวิธีลงโปรแกรมที่เขียนไมโครตัวนี้ได้ป่าวครับ
บันทึกการเข้า
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« ตอบ #9 เมื่อ: สิงหาคม 04, 2011, 05:03:44 pm »

อ้างถึง
ขอดูวิธีลงโปรแกรมที่เขียนไมโครตัวนี้ได้ป่าวครับ
โปรแกรมที่ใช้เขียน code มีสองตัวคือ
1. MPLAB IDE
2. HITECH PIC C
บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
the_hen
Newbie
*
ออฟไลน์ ออฟไลน์

กระทู้: 26


| |
« ตอบ #10 เมื่อ: สิงหาคม 08, 2011, 10:38:33 pm »

อยากรู้จังว่าจะมีหนุ่มๆที่คิดดีๆอย่างนี้ซั้กกี่คนทั้งฉลาดใฝ่หาความรู้ใจกว้างไม่รู้จะหาคำชมว่าไงแล้วล่ะ
บันทึกการเข้า
trose88
Newbie
*
ออฟไลน์ ออฟไลน์

กระทู้: 40


| |
« ตอบ #11 เมื่อ: กันยายน 02, 2011, 02:04:29 pm »

น่ารักดีแฮะ
บันทึกการเข้า
unvaliable
Global Moderator
Full Member
*****
ออฟไลน์ ออฟไลน์

กระทู้: 114


I  love  shadowwares.


| |
« ตอบ #12 เมื่อ: พฤษภาคม 06, 2012, 04:35:06 pm »

ถ้าทำไฟกระพิบ โดยใช้ timer  โดยใช้ ccs  compiler จะเขียน code  อย่างไรครับ huh
บันทึกการเข้า

Don't dream your life.Live your dream.
ShadowMan
Administrator
Hero Member
*****
ออฟไลน์ ออฟไลน์

เพศ: ชาย
กระทู้: 8020


ShadowWares


| |
« ตอบ #13 เมื่อ: พฤษภาคม 06, 2012, 05:44:25 pm »

เปิดดูโปรแกรมตัวอย่างของ CCS ในนั้นมีตัวอย่างการใช้งาน Timer อยู่
Code: (c)
///////////////////////////////////////////////////////////////////////
////                          EX_STWT.C                            ////
////                                                               ////
//// This program uses the RTCC (timer0) and interrupts to keep a  ////
//// real time seconds counter.  A simple stop watch function is   ////
//// then implemented.                                             ////
////                                                               ////
//// Configure the CCS prototype card as follows:                  ////
////     Insert jumpers from: 11 to 17 and 12 to 18.               ////
///////////////////////////////////////////////////////////////////////
#include<16f877a.h>
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

#define high_start 76
byte seconds, high_count;

#INT_RTCC                                    //Interrupt procedure
clock_isr() {                                //called every time RTCC
   high_count -= 1;                          //flips from 255 to 0

   if(high_count==0) {
      ++seconds;
      high_count=high_start;                 //Inc SECONDS counter every
   }                                         //76 times to keep time
}

void main() {                                //a simple stopwatch program
   byte start, time;

   high_count = high_start;
   setup_timer_0( RTCC_INTERNAL | RTCC_DIV_256 );
   set_timer0(0);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   do {
      printf("Press any key to begin.nr");
      getc();
      start = seconds;
      printf("Press any key to stop.rn");
      getc();
      time = seconds - start;
      printf("%U seconds.nr", time);
   } while (TRUE);
}
บันทึกการเข้า

By SDW: Do No Wrong Is Do Nothing
          If you want to increase your success rate, double your failure rate
unvaliable
Global Moderator
Full Member
*****
ออฟไลน์ ออฟไลน์

กระทู้: 114


I  love  shadowwares.


| |
« ตอบ #14 เมื่อ: พฤษภาคม 07, 2012, 01:06:13 am »

ผมรู้เเล้วครับ การที่จะเปลี่ยนเบอร์ Microcontroller ที่จะศึกษา คือ เราต้องรู้ถึง  Datasheet + Compiler for using + Ex.source  code  ใช่เปล่าครับผม evil
บันทึกการเข้า

Don't dream your life.Live your dream.
หน้า: [1] 2   ขึ้นบน
  พิมพ์  
 
กระโดดไป: