AVR ภาษาแอสเซมบลี โปรแกรมแรก

AVR ภาษาแอสเซมบลี โปรแกรมแรก เปิดไฟ LED

ไมโครคอนโทรลเลอร์ ATtiny13


ไมโครคอนโทรลเลอร์ ATtiny13 มี 8 ขา ซึ่งสามารถใช้เป็นขา GPIO (General Purpose Input / Output) ได้ 5 ขา ขาเหล่านี้มีชื่อว่า PB0 ถึง PB4 แต่ละ GPIO เหล่านั้นถูกควบคุมโดยสองบิตในที่เก็บข้อมูลภายในสองแห่ง สถานที่จัดเก็บเหล่านั้นมีชื่อว่า DDRB (data direction register port B) และ PORTB (data output register port B) สถานะลอจิคัลของพินพอร์ตสามารถอ่านได้ผ่าน PINB (อินพุตรีจิสเตอร์ B) เหตุใดชื่อพอร์ตจึงขึ้นต้นด้วย B ไม่ใช่ A จึงเป็นความลับของ ATMEL เหตุใดพวกเขาจึงตั้งชื่อที่เก็บข้อมูลเหล่านั้นว่า “รีจิสเตอร์” คือการทำให้คุณสับสนเล็กน้อยกับการลงทะเบียนภายในอื่น ๆ

ไมโครคอนโทรลเลอร์ ATtiny13
รีจิสเตอร์ ไมโครคอนโทรลเลอร์ ATtiny13


แต่ละ GPIO สามารถเปลี่ยนเป็น 4 สถานะ (ต่อไปนี้สำหรับขา PB0):

  1. ให้เอาต์พุตเป็นแบบปิด (DDB0 = 0) , ปิดตัวต้านทานแบบ Pull-up (PORTB0 = 0)
    โดยในโหมดนี้สามารถใช้ GPIO เป็นขาอินพุตที่มีความต้านทานสูงได้ สถานะลอจิคัลของขาสามารถอ่านได้ใน PINB0

  2. ให้เอาต์พุตเป็นแบบปิด (DDB0 = 0) , เปิดตัวต้านทานแบบ Pull-up (PORTB0 = 1)
    โดยในโหมดนี้ตัวต้านทานประมาณ 50 k จะเชื่อมโยงแรงดันไฟฟ้าที่ขาอินพุตแบบเปิดกับแรงดันไฟฟ้าของคอนโทรลเลอร์ สวิตช์หรือปุ่มกดภายนอกสามารถเขียนทับสิ่งนี้และดึงแรงดันไฟฟ้าอินพุตลงไปที่ศูนย์โวลต์ (Ground, GND) สามารถอ่านได้ใน PINB0

  3. ให้เอาต์พุตเป็นแบบเปิด (DDB0 = 1) , ให้เอาต์พุตบิตเป็น 0 (PORTB0 = 0)
    โดยตอนนี้ขา PB0 อยู่บนแรงดันไฟฟ้าต่ำมากใกล้กับแรงดันไฟฟ้าเชิงลบ ขา PB0 สามารถดึงกระแสได้ถึง 50 mA โดยที่แรงดันขา PB0 จะเพิ่มขึ้นเล็กน้อยตามกระแส

  4. ให้เอาต์พุตเป็นแบบเปิด (DDB0 = 1) , ให้เอาต์พุตบิตเป็น 1 (PORTB0 = 1)
    ขา PB0 อยู่บนแรงดันไฟฟ้าสูงต่ำกว่าแรงดันไฟฟ้าที่ใช้งานเล็กน้อย ขา PB0 สามารถขับได้สูงสุดประมาณ 30 mA โดยมีแรงดันไฟฟ้าของขาลดลงเล็กน้อย

โปรแกรมแรก ภาษาแอสเซมบลี เปิดไฟ LED

 รายการอุปกรณ์


ขั้นตอนการทํางาน


1 : ลงโปรแกรม และ ต่อวงจร ATtiny13



ก่อนเขียนโปรแกรมแรก ต้องลงโปรแกรม และ ต่อวงจร ATtiny13 โดยทำตามขั้นตอนลิงค์บทความด้านล่าง


2 : สร้างโปรเจคสำหรับเขียนโค้ดภาษา Assembly


เมื่อเปิดโปรแกรม Atmel Studio 7.0 ขึ้นมา ให้คลิกที่เมนู File -> Project..



เลือกเป็น Assembler -> AVR Assembler Project – ตั้งชื่อโปรเจค เป็น attiny13-led -> OK


เลือกเป็น ATtiny -> ATtiny13A (เพราะในบทความใช่รุ่น ATtiny13A) -> OK


Atmel Studio จะสร้าง ไฟล์โค้ด main.asm ให้โดยอัตโนมัติ


เขียนโค้ด ดังนี้

sbi DDRB,DDB0
sbi PORTB,PORTB0



คอมไพล์โค้ด โดย คลิก Build -> Build Solution

รอจนขึ้นข้อความ Build Success แสดงว่า โค้ดไม่มีปัญหาอะไร


3 : ปรับแต่ง Atmel Studio 7 เพื่ออัพโหลดโค้ด ด้วย USBasp


ดาวน์โหลด AVRDUDE.

https://mirror.freedif.org/GNU-Sa/avrdude/avrdude-6.3-mingw32.zip


คลายซิป


เข้าไปในโฟลเดอร์ avrdude-6.3-mingw32 จะพบ 2 ไฟล์ ให้ copy 2 ไฟล์นี้ ไปยัง


C:\Program Files (x86)\Atmel\Studio

ไปที่ Tools -> External Tools…


ที่ Title: ในตัวอย่างตั้งชื่อเป็น ATtiny13-Upload

ที่ Command:

C:\Program Files (x86)\Atmel\Studio\avrdude.exe


ที่ Arguments:

-c usbasp -p t13 -Uflash:w:"$(ProjectDir)Debug\$(TargetName).hex":i


ติ๊กเลือก Use Output window -> OK

AVR ภาษาแอสเซมบลี โปรแกรมแรก เปิดไฟ LED



4 : อัพโหลดโค้ด


เมื่อต้องการอัพโหลด ไปที่ Tools -> ATtiny13-Upload (ที่ตั้งชื่อไว้)

AVR ภาษาแอสเซมบลี โปรแกรมแรก เปิดไฟ LED


ที่ Output ด้านล่างซ้ายมือ แสดง avrdude.exe done. Thank you. แสดงว่าการอัพโหลดสำเร็จแล้ว

AVR ภาษาแอสเซมบลี โปรแกรมแรก เปิดไฟ LED


ไฟ LED ที่เชื่อมต่อที่ขา PB0 ของ ATtiny13 จาก “ดับ” เปลี่ยนเป็น “ติด” แสดงว่า การทดสอบการทำงานอัพโหลดโค้ด เข้าบอร์ด ATtiny13 สําเร็จแล้ว

AVR ภาษาแอสเซมบลี โปรแกรมแรก เปิดไฟ LED



5 : Simulator ด้วย Atmel Studio



ไปที่ Debug -> Step Info


คลิก Continue

ที่ Tool เลือกเป็น Simulator


คอมไพล์โค้ด อีกครั้ง โดย ไปที่ Build -> Build Solution


ไปที่ Debug -> Step Info อีกครั้ง


เครื่องจำลองจะเริ่มขึ้น มันแสดง ลูกศรสีเหลืองชี้ไปที่คำสั่งปฏิบัติการแรก และ ที่ วินโดว์ ด้านล่าง ขวามือ จะแสดง Memory


หากคุณคลิกที่ “พอร์ต B” ใน “มุมมอง I / O”



คลิกที่ I/O Port (PORTB) ตำแหน่งและเนื้อหาของรีจิสเตอร์พอร์ตทั้งสามพอร์ตของพอร์ต B จะปรากฏขึ้น (ซึ่งทั้งหมดจะถูกลบโดยการรีเซ็ต)


ไปที่ Debug -> Step Info อีกครั้ง


เคอร์เซอร์ได้ย้ายหนึ่งคำสั่ง และแสดงตั้งค่าบิต 0 ของพอร์ตรีจิสเตอร์ DDRB แล้ว ตอนนี้เอาต์พุตของพิน PB0 เป็นไปตามสถานะของพอร์ต PORTB0 รีจิสเตอร์ PORTB


ไปที่ Debug -> Step Info


ปิดหน้าต่าง “มุมมอง I / O” แล้วทดสอบ ไปที่ Processor Status



แสดงการทำงานของไมโครคอนโทรลเลอร์ ATtiny13 ที่ใช้ความถี่ 1Mhz เป็นแหล่งสัญญาณนาฬิกา เป็นต้น


ด้วยเครื่องมือนี้เราสามารถดำเนินการผ่านโปรแกรมแอสเซมบลี และเราสามารถดูฮาร์ดแวร์คอนโทรลเลอร์ภายในโดยละเอียดและดูว่าคำแนะนำเปลี่ยนแปลงอย่างไร การจำลองจึงเป็นเครื่องมือที่มีประสิทธิภาพในการตรวจสอบการทำงานภายในของ โปรแกรมแอสเซมบลี 


6 : อธิบายโค้ด


ใช้โปรแกรม Notepad เปิดไฟล์ attiny13-led.hex ที่ได้จาก การคอมไพล์ และ เป็นไฟล์ ที่โปรแกรม Atmel Studio 7.0 อัพโหลดโค้ดเข้าไปที่ ATtiny13



.hex คือไฟล์รหัสภาษาเครื่อง (machine code)  เป็นไฟล์ต้นฉบับเลขฐานสิบหกที่มักใช้โดยอุปกรณ์ลอจิกที่โปรแกรมได้เช่นไมโครคอนโทรลเลอร์ มันมีการตั้งค่าข้อมูลการกำหนดค่าหรือข้อมูลอื่น ๆ ที่บันทึกในรูปแบบเลขฐานสิบหก

นี่คือข้อมูลที่อยู่ในไฟล์ attiny13-led.hex


โดยจะแสดงรหัสภาษาเครื่อง (machine code) เช่น B89A และ C09A ซึ่งไม่ใช่เรื่องง่ายที่จะจดจำ ฉะนั้นการที่จะทำให้เข้าใจได้จึงถูกกำหนดให้จำได้ง่ายขึ้น โดยในภาษาแอสเซมบลี (Assembly) จะเขียนเพียง 2 บรรทัด คือ

sbi DDRB,DDB0 
sbi PORTB,PORTB0


ในการทำให้ ATtiny13 ทำงานได้ จะต้องมีการตั้งโปรแกรม ในกรณีนี้มีคำเลขฐานสิบหกสองคำคือ B89A และ C09A ในภาษาเครื่อง (machine code) สองคำอยู่ที่จุดเริ่มต้นของพื้นที่จัดเก็บโปรแกรม (แฟลช) ที่อยู่ 0000 และ 0001 หากคุณซื้ออุปกรณ์ใหม่ (หรือหากคุณลบพื้นที่แฟลช) จะไม่มีอะไรเลย แต่จะไม่มีประโยชน์ใดๆ เนื่องจากที่เก็บข้อมูลต้องไม่ว่างเปล่า จึงเต็มไปด้วย FFFF เลขฐานสิบหกในเซลล์เหล่านั้นทั้งหมด ในความเป็นจริงคอนโทรลเลอร์อ่าน FFFFs ถอดรหัสและเรียกใช้งาน การดำเนินการนี้เรียกว่า “NOP” หรือ “No operation” NOP เป็นตัวแทนช่วยในการจำสำหรับไบนารี 0000.0000.0000.0000 หรือเลขฐานสิบหก 0000 ซึ่งจะมีตัวช่วยในการจำดังที่เราจะเห็นในภายหลัง



ที่เก็บโปรแกรมหรือหน่วยความจำแฟลชของ ATtiny13 มี 1024 ไบต์ซึ่งพอดีกับคำสั่ง 512 คำ ซึ่งดูไม่ใหญ่มาก แต่ในแอสเซมเบลอร์นี่เป็นก้อนขนาดใหญ่

พอร์ต ของ ATtiny13 จะมีพอร์ตเดียว คือ พอร์ต B ถ้าเทียบกับ ไมโครคอนโทรลเลอร์ Atmega328P ที่ใช้ในบอร์ด Arduino UNO จะมีทั้ง พอร์ต B , พอร์ต C และ พอร์ต D


DDRB คือ รับการกำหนดพอร์ต B ให้เป็น อินพุท/เอาท์พุท (ถ้า = 0 เป็น อินพุท หรือ = 1 เป็น เอาท์พุท)

DDB0 คือ พอร์ต B บิตที่ 0 หรือ ขา PB0 ของ ATtiny13

ด้านหน้าสุด cbi จะให้สถานะเป็น 0 หรือ sbi จะให้สถานะเป็น 1

ดังนั้น โค้ดด้านล่าง คือคำสั่ง ให้พอร์ต B ขา PB0 ขาเดียว เป็นขาที่ทำงานแบบ เอาท์พุท

sbi DDRB,DDB0



PORTB คือ รับการกำหนดพอร์ต B ให้เอาต์พุตเป็น LOW/HIGH (ถ้า = 0 เป็น LOW หรือ = 1 เป็น HIGH)

PORTB0 คือ พอร์ต B บิตที่ 0 หรือ ขา PB0 ของ ATtiny13

ด้านหน้าสุด cbi จะให้สถานะเป็น 0 หรือ sbi จะให้สถานะเป็น 1

ดังนั้น โค้ดด้านล่าง คือคำสั่ง ให้พอร์ต B ขา PB0 ขาเดียว เป็นขาที่ให้เอาต์พุตเป็น 1 หรือเป็น HIGH ไฟ LED จึงติด

sbi PORTB,PORTB0



ในบรรทัดรหัส “sbi DDRB, DDB0” ประเภทของ “sbi” หมายถึงคำสั่งในขณะที่ “DDRB” และ “DDB0” เป็นพารามิเตอร์สำหรับคำสั่งนี้ พารามิเตอร์ตัวแรกคือพอร์ตทิศทางข้อมูลของพอร์ต B ส่วนที่สองคือตำแหน่งบิตในพอร์ตนั้นที่จะกำหนดเป็นหนึ่ง คู่มือข้อมูลอุปกรณ์สำหรับ ATtiny13 กล่าวเกี่ยวกับเรื่องนี้:


ดังนั้น DDRB จึงแปลเป็นพอร์ตหมายเลข 17 (เลขฐานสิบหกนั่นคือ 23 ทศนิยม) DDB0 แปลเป็นเลขฐานสิบหก 0 หรือบิต 0 พารามิเตอร์ทั้งสองหมายถึงตัวเลข เราไม่จำเป็นต้องจำตัวเลขเหล่านั้นหากเราใช้สัญลักษณ์ชื่อ DDRB และ DDB0 แทน หลีกเลี่ยงการเรียนรู้และใช้ตัวเลขเนื่องจากในอุปกรณ์อื่นตัวเลขเหล่านี้อาจแตกต่างจากใน ATtiny13 ในอุปกรณ์อื่น

พอร์ต DDRB และ PORTB แสดงรายการในฐานข้อมูลอุปกรณ์ดังนี้:


R / W หมายความว่าบิตเหล่านั้นสามารถอ่าน (R) และเขียน (W) ได้ “ค่าเริ่มต้น” หมายความว่าบิตนี้จะถูกล้าง (0) หรือตั้งค่า (1) ระหว่างลำดับการรีเซ็ตของคอนโทรลเลอร์

credit : http://www.avr-asm-tutorial.net/avr_en/micro_beginner/2_Led_On/2_Led_On.html


<<< #1 ลงโปรแกรม และ ต่อวงจร ATtiny13 บทความก่อนหน้า | บทความต่อไป #3 Blink ไฟกระพริบ LED >>>