- PWM (การมอดูเลตความกว้างพัลส์)
- PWM Pins ใน ARM7-LPC2148
- PWM รีจิสเตอร์ใน ARM7-LPC2148
- ส่วนประกอบที่จำเป็น
- แผนภาพวงจรและการเชื่อมต่อ
- การเขียนโปรแกรม ARM7-LPC2148 สำหรับ PWM
- ขั้นตอนที่เกี่ยวข้องในการเขียนโปรแกรม LPC2148 สำหรับ PWM & ADC
อย่างที่เราทราบกันดีว่าไมโครคอนโทรลเลอร์ใช้อินพุตแบบอนาล็อกจากเซ็นเซอร์อนาล็อกและใช้ ADC (ตัวแปลงอนาล็อกเป็นดิจิตอล) เพื่อประมวลผลสัญญาณเหล่านั้น แต่ถ้าไมโครคอนโทรลเลอร์ต้องการสร้างสัญญาณแอนะล็อกเพื่อควบคุมอุปกรณ์ที่ทำงานแบบอะนาล็อกเช่นเซอร์โวมอเตอร์มอเตอร์กระแสตรงเป็นต้น ไมโครคอนโทรลเลอร์ไม่สร้างแรงดันเอาต์พุตเช่น 1V, 5V แทนที่จะใช้เทคนิคที่เรียกว่า PWM สำหรับการใช้งานอุปกรณ์อนาล็อก ตัวอย่างของ PWM คือพัดลมระบายความร้อน (มอเตอร์ DC) ของแล็ปท็อปของเราซึ่งจะต้องมีการควบคุมความเร็วตามอุณหภูมิและใช้เทคนิคการมอดูเลตความกว้างพัลส์ (PWM)ในเมนบอร์ด
ในการกวดวิชานี้เราจะควบคุมความสว่างของไฟ LED ที่ใช้ PWM ใน ARM7-LPC2148 ไมโครคอนโทรลเลอร์
PWM (การมอดูเลตความกว้างพัลส์)
PWM เป็นวิธีที่ดีในการควบคุมอุปกรณ์อนาล็อกโดยใช้ค่าดิจิทัลเช่นการควบคุมความเร็วของมอเตอร์ความสว่างของไฟ LED เป็นต้นแม้ว่า PWM จะไม่ได้ให้เอาต์พุตแบบอะนาล็อกที่บริสุทธิ์ แต่ก็สร้างพัลส์อนาล็อกที่เหมาะสมเพื่อควบคุมอุปกรณ์อนาล็อก จริงๆแล้ว PWM จะปรับความกว้างของคลื่นพัลส์สี่เหลี่ยมเพื่อให้ได้ค่าเฉลี่ยของคลื่นผลลัพธ์ที่เปลี่ยนแปลงไป
รอบการทำงานของ PWM
เปอร์เซ็นต์ของเวลาที่สัญญาณ PWM ยังคงสูง (ตรงเวลา) เรียกว่าเป็นรอบการทำงาน หากสัญญาณเปิดอยู่เสมอสัญญาณจะอยู่ในรอบการทำงาน 100% และหากปิดอยู่เสมอจะเป็นรอบการทำงาน 0%
Duty Cycle = เปิดเวลา / (เปิดเวลา + ปิดเวลา)
PWM Pins ใน ARM7-LPC2148
ภาพด้านล่างแสดงพินเอาต์พุต PWM ของ ARM7-LPC2148มีทั้งหมดหกพินสำหรับ PWM
PWM ช่อง |
LPC2148 พินพอร์ต |
PWM1 |
P0.0 |
PWM2 |
P0.7 |
PWM3 |
P0.1 |
PWM4 |
P0.8 |
PWM5 |
P0.21 |
PWM6 |
P0.9 |
PWM รีจิสเตอร์ใน ARM7-LPC2148
ก่อนที่จะเข้าสู่โครงการของเราเราจำเป็นต้องรู้เกี่ยวกับการลงทะเบียน PWM ใน LPC2148
นี่คือรายการรีจิสเตอร์ที่ใช้ใน LPC2148 สำหรับ PWM
1. PWMPR: PWM Prescale Register
ใช้: เป็นรีจิสเตอร์ 32 บิต ประกอบด้วยจำนวนครั้ง (ลบ 1) PCLK ต้องวนรอบก่อนที่จะเพิ่มตัวนับตัวจับเวลา PWM (จริง ๆ แล้วจะมีค่าสูงสุดของตัวนับจำนวนล่วงหน้า)
2. PWMPC: PWM Prescaler Counter
ใช้: มันลงทะเบียน มันมีค่าตัวนับที่เพิ่มขึ้น เมื่อค่านี้เท่ากับค่า PR บวก 1 PWM Timer Counter (TC) จะเพิ่มขึ้น
3. PWMTCR: PWM Timer Control Register
ใช้: ประกอบด้วย Counter Enable, Counter Reset และ PWM Enable control bits มันคือการลงทะเบียน 8 บิต
7: 4 |
3 |
2 |
1 |
0 |
ที่สงวนไว้ |
PWM เปิดใช้งาน |
ที่สงวนไว้ |
รีเซ็ตเคาน์เตอร์ |
เปิดใช้งานเคาน์เตอร์ |
- PWM เปิดใช้งาน: (Bit-3)
0- PWM Disabled
1- เปิดใช้งาน PWM
- เปิดใช้งานตัวนับ: (Bit-0)
0- ปิดการใช้งานตัวนับ
1- เปิดใช้งานตัวนับ
- รีเซ็ตตัวนับ: (Bit-1)
0- ไม่ต้องทำอะไรเลย
1- รีเซ็ต PWMTC & PWMPC บนขอบบวกของ PCLK
4. PWMTC: PWM Timer Counter
ใช้: เป็นรีจิสเตอร์ 32 บิต ประกอบด้วยค่าปัจจุบันของตัวจับเวลา PWM ที่เพิ่มขึ้น เมื่อ Prescaler Counter (PC) ถึงค่า Prescaler Register (PR) บวก 1 ตัวนับนี้จะเพิ่มขึ้น
5. PWMIR: PWM Interrupt Register
ใช้: เป็นการลงทะเบียน 16 บิต มีแฟล็กขัดจังหวะสำหรับ PWM Match Channels 0-6 ค่าสถานะอินเตอร์รัปต์ถูกตั้งค่าเมื่อเกิดการขัดจังหวะสำหรับช่องสัญญาณนั้น (MRx Interrupt) โดยที่ X คือหมายเลขช่องสัญญาณ (0 ถึง 6)
6. PWMMR0-PWMMR6: PWM Match Register
ใช้: มันเป็นทะเบียน จริงๆแล้วกลุ่ม Match Channel อนุญาตให้ตั้งค่าเอาต์พุต PWM แบบควบคุมขอบเดียว 6 แบบหรือ 3 เอาต์พุต PWM แบบควบคุมสองขอบ คุณสามารถปรับเปลี่ยน Match Channels ทั้งเจ็ดเพื่อกำหนดค่าเอาต์พุต PWM เหล่านี้ให้เหมาะกับความต้องการของคุณใน PWMPCR
7. PWMMCR: PWM Match Control Register
ใช้: เป็นรีจิสเตอร์ 32 บิต ประกอบด้วยบิตขัดจังหวะรีเซ็ตและหยุดที่ควบคุม Match Channel ที่เลือก การจับคู่เกิดขึ้นระหว่างการลงทะเบียนการจับคู่ PWM และตัวนับตัวจับเวลา PWM
31:21 น |
20 |
19 |
18 |
.. |
5 |
4 |
3 |
2 |
1 |
0 |
ที่สงวนไว้ |
PWMMR6S |
PWMMR6R |
PWMMR6I |
.. |
PWMMR1S |
PWMMR1R |
PWMMR11 |
PWMMR0S |
PWMMR0R |
PWMMR01 |
นี่ x คือ 0 ถึง 6
- PWMMRxI (บิต -0)
เปิดใช้งานหรือปิดใช้งานการขัดจังหวะ PWM
0- ปิดใช้งานการขัดจังหวะการจับคู่ PWM
1- เปิดใช้งานการขัดจังหวะการจับคู่ PWM
- PWMMRxR: (บิต -1)
รีเซ็ต PWMTC -ค่าตัวนับตัวจับเวลาเมื่อใดก็ตามที่ตรงกับ PWMRx
0- ไม่ทำอะไรเลย
1- รีเซ็ต PWMTC
- PWMMRxS: (บิต 2)
หยุด PWMTC & PWMPC เมื่อ PWMTC ถึงค่า Match register
0- ปิดใช้งานคุณสมบัติหยุด PWM
1- เปิดใช้งานคุณสมบัติ PWM Stop
8. PWMPCR: ลงทะเบียนควบคุม PWM
ใช้: เป็นการลงทะเบียน 16 บิต ประกอบด้วยบิตที่เปิดใช้งานเอาต์พุต PWM 0-6 และเลือกการควบคุมขอบเดียวหรือสองขอบสำหรับแต่ละเอาต์พุต
31:15 น |
14: 9 |
8: 7 |
6: 2 |
1: 0 |
ไม่ได้ใช้ |
PWMENA6-PWMENA1 |
ไม่ได้ใช้ |
PWMSEL6-PWMSEL2 |
ไม่ได้ใช้ |
- PWMSELx (x: 2 ถึง 6)
- โหมด Single Edge สำหรับ PWMx
- 1- โหมด Double Edge สำหรับ PWMx
- PWMENAx (x: 1 ถึง 6)
- PWMx ปิดใช้งาน
- 1- เปิดใช้งาน PWMx
9. PWMLER: PWM Latch เปิดใช้งานการลงทะเบียน
ใช้: เป็นการลงทะเบียน 8 บิต ประกอบด้วยบิต Match x Latch สำหรับแต่ละ Match Channel
31: 7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ไม่ได้ใช้ |
LEN6 |
LEN5 |
เลน 4 |
LEN3 |
LEN2 |
LEN1 |
LEN0 |
LENx (x: 0 ถึง 6):
0- ปิดการโหลดค่า Match ใหม่
1- โหลดค่า Match ใหม่จาก (PWMMRx) PWMMatch Register เมื่อรีเซ็ตตัวจับเวลา
ตอนนี้ให้เริ่มสร้างการตั้งค่าฮาร์ดแวร์เพื่อสาธิตการมอดูเลตความกว้างพัลส์ในไมโครคอนโทรลเลอร์ ARM
ส่วนประกอบที่จำเป็น
ฮาร์ดแวร์
- ไมโครคอนโทรลเลอร์ ARM7-LPC2148
- IC ควบคุมแรงดันไฟฟ้า 3.3V
- โพเทนชิออมิเตอร์ 10k
- LED (สีใดก็ได้)
- โมดูลการแสดงผล LCD (16x2)
- เขียงหั่นขนม
- การเชื่อมต่อสายไฟ
ซอฟต์แวร์
- Keil uVision 5
- Flash Magic Tool
แผนภาพวงจรและการเชื่อมต่อ
การเชื่อมต่อระหว่าง LCD และ ARM7-LPC2148
ARM7-LPC2148 |
จอแอลซีดี (16x2) |
P0.4 |
RS (ลงทะเบียนเลือก) |
P0.6 |
E (เปิดใช้งาน) |
P0.12 |
D4 (พินข้อมูล 4) |
P0.13 |
D5 (พินข้อมูล 5) |
P0.14 |
D6 (พินข้อมูล 6) |
P0.15 |
D7 (พินข้อมูล 7) |
GND |
VSS, R / W, K |
+ 5V |
VDD, อ |
การเชื่อมต่อระหว่าง LED และ ARM7-LPC2148
ANODE ของ LED เชื่อมต่อกับเอาต์พุต PWM (P0.0) ของ LPC2148 ในขณะที่ขา CATHODE ของ LED เชื่อมต่อกับพิน GND ของ LPC2148
การเชื่อมต่อระหว่าง ARM7-LPC2148 และโพเทนชิออมิเตอร์พร้อมตัวควบคุมแรงดันไฟฟ้า 3.3V
IC ควบคุมแรงดันไฟฟ้า 3.3V |
ฟังก์ชัน Pin |
ARM-7 LPC2148 พิน |
1. ขาซ้าย |
- จาก GND |
พิน GND |
2. หมุดกลาง |
เอาต์พุตควบคุม + 3.3V |
ไปยังอินพุตโพเทนชิออมิเตอร์และเอาต์พุตของโพเทนชิออมิเตอร์เป็นP0.28 ของ LPC2148 |
3. หมุดขวา |
+ จาก 5V อินพุต |
+ 5V |
จุดที่ควรสังเกต
1. ที่นี่ใช้ตัวควบคุมแรงดันไฟฟ้า 3.3V เพื่อระบุค่าอินพุตแบบอะนาล็อกให้กับขา ADC (P0.28) ของ LPC2148 และเนื่องจากเราใช้ไฟ 5V เราจึงต้องควบคุมแรงดันไฟฟ้าด้วยตัวควบคุมแรงดันไฟฟ้า 3.3V
2. โพเทนชิออมิเตอร์ใช้เพื่อเปลี่ยนแรงดันไฟฟ้าระหว่าง (0V ถึง 3.3V) เพื่อให้อินพุตอะนาล็อก (ADC) ไปยัง LPC2148 พิน P0.28
การเขียนโปรแกรม ARM7-LPC2148 สำหรับ PWM
ในการเขียนโปรแกรม ARM7-LPC2148 เราต้องใช้เครื่องมือ keil uVision & Flash Magic เราใช้สาย USB เพื่อตั้งโปรแกรม ARM7 Stick ผ่านพอร์ต micro USB เราเขียนโค้ดโดยใช้ Keil และสร้างไฟล์ hex จากนั้นไฟล์ HEX จะถูกแฟลชไปที่แท่ง ARM7 โดยใช้ Flash Magic หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับการติดตั้ง keil uVision และ Flash Magic และวิธีการใช้งานให้ไปที่ลิงค์เริ่มต้นใช้งานไมโครคอนโทรลเลอร์ ARM7 LPC2148 และตั้งโปรแกรมโดยใช้ Keil uVision
ในบทช่วยสอนนี้เราจะใช้เทคนิค ADC และ PWM เพื่อควบคุมความสว่างของ LED ที่นี่ LPC2148 ได้รับอินพุตอะนาล็อก (0 ถึง 3.3V) ผ่านขาอินพุต ADC P0.28 จากนั้นอินพุตอะนาล็อกนี้จะถูกแปลงเป็นค่าดิจิทัล (0 ถึง 1023) จากนั้นค่านี้จะถูกแปลงเป็นค่าดิจิทัลอีกครั้ง (0-255) เนื่องจากเอาต์พุต PWM ของ LPC2148 มีความละเอียด 8 บิตเท่านั้น (2 8) LED เชื่อมต่อกับพิน PWM P0.0 และสามารถควบคุมความสว่างของ LED ได้โดยใช้โพเทนชิออมิเตอร์ หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับ ADC ใน ARM7-LPC2148 ตามลิงค์
ขั้นตอนที่เกี่ยวข้องในการเขียนโปรแกรม LPC2148 สำหรับ PWM & ADC
ขั้นตอนที่ 1: -สิ่งแรกคือการกำหนดค่า PLLสำหรับการสร้างนาฬิกาเนื่องจากตั้งค่านาฬิการะบบและนาฬิกาอุปกรณ์ต่อพ่วงของ LPC2148 ตามที่โปรแกรมเมอร์ต้องการ ความถี่สัญญาณนาฬิกาสูงสุดสำหรับ LPC2148 คือ 60Mhz บรรทัดต่อไปนี้ใช้เพื่อกำหนดค่าการสร้างนาฬิกา PLL
เป็นโมฆะเริ่มต้น PLL (โมฆะ) // ฟังก์ชันใช้ PLL สำหรับการสร้างนาฬิกา { PLL0CON = 0x01; PLL0CFG = 0x24; PLL0FEED = 0xAA; PLL0FEED = 0x55; ในขณะที่ (! (PLL0STAT & 0x00000400)); PLL0CON = 0x03; PLL0FEED = 0xAA; PLL0FEED = 0x55; VPBDIV = 0x01; }
ขั้นตอนที่ 2: -สิ่งต่อไปคือการเลือกพิน PWM และฟังก์ชัน PWM ของ LPC2148 โดยใช้ PINSEL register เราใช้ PINSEL0 เมื่อเราใช้ P0.0 สำหรับเอาต์พุต PWM ของ LPC2148
PINSEL0 = 0x00000002; // การตั้งค่าพิน P0.0 สำหรับเอาต์พุต PWM
ขั้นตอนที่ 3: -ต่อไปเราต้องรีเซ็ตตัวจับเวลาโดยใช้ PWMTCR (Timer Control Register)
PWMTCR = (1 << 1); // การตั้งค่า PWM Timer Control Register เป็นการรีเซ็ตตัวนับ
จากนั้นตั้งค่า prescale ซึ่งจะตัดสินความละเอียดของ PWM ฉันตั้งค่าเป็นศูนย์
PWMPR = 0X00; // การตั้งค่า PWM prescale
ขั้นตอนที่ 4: -ต่อไปเราต้องตั้งค่า PWMMCR (ทะเบียนควบคุมการจับคู่ PWM) เนื่องจากตั้งค่าการทำงานเช่นรีเซ็ตขัดจังหวะสำหรับ PWMMR0
PWMMCR = (1 << 0) - (1 << 1); // การตั้งค่า PWM Match Control Register
ขั้นตอนที่ 5: -ระยะเวลาสูงสุดของช่องสัญญาณ PWM ถูกตั้งค่าโดยใช้ PWMMR
PWMMR0 = ค่า PWM; // ให้ค่า PWM ค่าสูงสุด
ในกรณีของเราค่าสูงสุดคือ 255 (สำหรับความสว่างสูงสุด)
ขั้นตอนที่ 6: -ต่อไปเราต้องตั้งค่า Latch Enable ให้กับการลงทะเบียนการแข่งขันที่เกี่ยวข้องโดยใช้ PWMLER
PWMLER = (1 << 0); // สลัก PWM ของ Enalbe
(เราใช้ PWMMR0) ดังนั้นเปิดใช้งานบิตที่เกี่ยวข้องโดยการตั้งค่า 1 ใน PWMLER
ขั้นตอนที่ 7: -ในการเปิดใช้งานเอาต์พุต PWM ไปยังพินเราจำเป็นต้องใช้ PWMTCR เพื่อเปิดใช้งานตัวนับตัวจับเวลา PWM และโหมด PWM
PWMTCR = (1 << 0) - (1 << 3); // เปิดใช้งานตัวนับ PWM และ PWM
ขั้นตอนที่ 8: -ตอนนี้เราต้องได้รับค่าโพเทนชิออมิเตอร์สำหรับการตั้งค่ารอบการทำงานของ PWM จากพิน ADC P0.28 ดังนั้นเราจึงใช้โมดูล ADC ใน LPC2148 สำหรับการแปลงอินพุตอะนาล็อกโพเทนชิโอมิเตอร์ (0 ถึง 3.3V) เป็นค่า ADC (0 ถึง 1023)
ที่นี่เราจะแปลงค่า 0-1023 เพื่อ 0-255 โดยการหารด้วย 4 PWM ของ LPC2148 มีความละเอียด 8 บิต (2 8)
ขั้นตอนที่ 9: -สำหรับการเลือกพิน ADC P0.28 ใน LPC2148เราใช้
PINSEL1 = 0x01000000; // การตั้งค่า P0.28 เป็น ADC INPUT AD0CR = (((14) << 8) - (1 << 21)); // การตั้งค่านาฬิกาและ PDN สำหรับการแปลง A / D
บรรทัดต่อไปนี้จับอินพุตอนาล็อก (0 ถึง 3.3V)และแปลงเป็นค่าดิจิตอล (0 ถึง 1023) จากนั้นค่าดิจิทัลนี้จะหารด้วย 4 เพื่อแปลงเป็น(0 ถึง 255)และสุดท้ายป้อนเป็นเอาต์พุต PWM ในพิน P0.0ของ LPC2148 ที่ LED เชื่อมต่ออยู่
AD0CR - = (1 << 1); // เลือกช่อง AD0.1 ใน ADC register delaytime (10); AD0CR - = (1 << 24); // เริ่มการแปลง A / D ในขณะที่ ((AD0DR1 & (1 << 31)) == 0); // ตรวจสอบบิต DONE ใน ADC Data register adcvalue = (AD0DR1 >> 6) & 0x3ff; // รับผลลัพธ์จากการลงทะเบียนข้อมูล ADC dutycycle = adcvalue / 4; // สูตรรับค่า dutycycle จาก (0 ถึง 255) PWMMR1 = dutycycle; // ตั้งค่า dutycycle เป็น PWM match register PWMLER - = (1 << 1); // เปิดใช้งานเอาต์พุต PWM ด้วยค่า dutycycle
ขั้นตอนที่ 10: -ต่อไปเราจะแสดงค่าเหล่านั้นในโมดูลการแสดงผล LCD (16X2) ดังนั้นเราจึงเพิ่มบรรทัดต่อไปนี้เพื่อเริ่มต้นโมดูลจอแสดงผล LCD
Void LCD_INITILIZE (โมฆะ) // ฟังก์ชั่นเพื่อเตรียม LCD { IO0DIR = 0x0000FFF0; // ตั้งค่าพิน P0.12, P0.13, P0.14, P0.15, P0.4, P0.6 เป็น เวลาหน่วงเอาท์ พุท (20); LCD_SEND (0x02); // เริ่มต้น LCD ในโหมดการทำงาน 4 บิต LCD_SEND (0x28); // 2 บรรทัด (16X2) LCD_SEND (0x0C); // แสดงเคอร์เซอร์ปิด LCD_SEND (0x06); // เคอร์เซอร์เพิ่มอัตโนมัติ LCD_SEND (0x01); // แสดง LCD_SEND ที่ ชัดเจน(0x80); // บรรทัดแรกตำแหน่งแรก}
ในขณะที่เราเชื่อมต่อLCD ในโหมด 4 บิตกับ LPC2148เราจำเป็นต้องส่งค่าที่จะแสดงเป็นการแทะโดยการแทะ (Upper Nibble & Lower Nibble) ดังนั้นจึงใช้บรรทัดต่อไปนี้
โมฆะ LCD_DISPLAY (ถ่าน * msg) // ฟังก์ชันพิมพ์อักขระที่ส่งทีละตัว { uint8_t i = 0; ในขณะที่ (msg! = 0) { IO0PIN = ((IO0PIN & 0xFFFF00FF) - ((msg & 0xF0) << 8)); // ส่ง IO0SET บนแทะ= 0x00000050; // RS HIGH & ENABLE HIGH เพื่อพิมพ์ข้อมูลIO0CLR = 0x00000020; // RW LOW โหมดการเขียน ล่าช้า (2); IO0CLR = 0x00000040; // EN = 0, RS และ RW ไม่เปลี่ยนแปลง (เช่น RS = 1, RW = 0) delaytime (5); IO0PIN = ((IO0PIN & 0xFFFF00FF) - ((ข้อความ & 0x0F) << 12)); // ส่ง IO0SET ล่างแทะ= 0x00000050; // RS & EN สูงIO0CLR = 0x00000020; เวลาล่าช้า (2); IO0CLR = 0x00000040; เวลาล่าช้า (5); ผม ++; } }
ในการแสดงเหล่านั้น ADC & PWM ค่าที่เราใช้บรรทัดต่อไปนี้ใน หลัก int () ฟังก์ชั่น
LCD_SEND (0x80); sprintf (displayadc, "adcvalue =% f", adcvalue); LCD_DISPLAY (displayadc); // แสดงค่า ADC (0 ถึง 1023) LCD_SEND (0xC0); sprintf (ledoutput, "PWM OP =%. 2f", ความสว่าง); LCD_DISPLAY (ledoutput); // แสดงค่า dutycycle ตั้งแต่ (0 ถึง 255)
คำอธิบายโค้ดและวิดีโอที่สมบูรณ์ของบทช่วยสอนมีอยู่ด้านล่าง