การสร้างสัญญาณไซน์โดยใช้ PWM


16

เราไม่สามารถสร้างสัญญาณไซน์อย่างถูกต้องโดยใช้ไมโครคอนโทรลเลอร์MC68HC908GP32 คำอธิบาย PWM เริ่มต้นในหน้า 349 ความถี่สัญญาณนาฬิกา 2.4MHz ในขณะที่เราใช้ PWM 7 kHz โดยใช้ prescaler และตั้งค่าโมดูโลตัวจับเวลาเป็น 350 ดังนี้:

T1SC = 0x60;    // Prescaler: Div entre 64
//Counter modulo = 0x015E = 350
T1MODH = 0x01;   // High
T1MODL = 0x5E;   // Low

เอาต์พุต PWM เป็นตัวกรองโดยตัวกรอง RLC ต่อไปนี้จากนั้น DC จะถูกลบออกโดยใช้ซีรีส์ 1uF cap ความถี่คัตออฟอยู่ต่ำกว่า 7kHz ของ PWM

ป้อนคำอธิบายรูปภาพที่นี่

ก่อนอื่นเราลองใช้ LUT ซึ่งตัวอย่างถูกสร้างขึ้นโดยใช้ไซต์นี้ (100 ตัวอย่าง, แอมพลิจูด = 250) ประกอบด้วยช่วงเวลาเดียว

 int seno[100]={ 125, 133, 141, 148, 156, 164, 171, 178, 185, 192, 198, 205, 211, 216, 221, 226, 231, 235, 238, 241, 244, 246, 248, 249, 250, 250, 250, 249, 248, 246, 244, 241, 238, 235, 231, 226, 221, 216, 211, 205, 198, 192, 185, 178, 171, 164, 156, 148, 141, 133, 125, 117, 109, 102, 94, 86, 79, 72, 65, 58, 52, 45, 39, 34, 29, 24, 19, 15, 12, 9, 6, 4, 2, 1, 0, 0, 0, 1, 2, 4, 6, 9, 12, 15, 19, 24, 29, 34, 39, 45, 52, 58, 65, 72, 79, 86, 94, 102, 109, 117}; 

ความกว้างของพัลส์ต่อไปนี้ถูกคำนวณทุกรอบ PWM:

interrupt 4 void rsi_t1ch0 (void)
{
    //-- disable interruption flag
    T1SC0&=(~0x80);
    //-- pwm to '0' 
    PTB&=0xFD;

    //some sensor measures are done here.... 100 out of the 350 cycles are left for this                
}
/************************************************************/
/* TIM1 overflow rutine                                     */
/************************************************************/
interrupt 6 void rsi_ov1 (void)
{

    T1SC&=(~0x80);
    //-- set PWM to 1
    PTB|=0x02;
    T1CH0H = ((seno[fase])>>8);   // high bits
    T1CH0L = (seno[fase])&0xFF;   // low bits
    fase+=1;
    if (fase >= 99)
      fase=0;
}

void main(void)
{
float temp;
    int i;

    CONFIG1|=0x01;  
    DDRB=0xFF;      //-- Port B is set as output
    PTB=0x00;       
    //Timer setup
    T1SC = 0x60;    // Prescaler: Div by 64  
    T1MODH = 0x01;   //Counter modulo
    T1MODL = 0x5E;  
    T1SC0 = 0x50;  //Comparator setup
    //-- Initial width
    T1CH0H = 0x00;
    T1CH0L = 0x53;

    EnableInterrupts;
    T1SC&=~(0x20); //Run timer forever
    for(;;);   
}

เมื่อเสียบเข้าไปในขอบเขตเราจะได้รับสัญญาณต่อไปนี้ เราไม่สามารถหลีกเลี่ยงจุดสูงสุดแปลก ๆ ที่อยู่ใกล้ที่สุด

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อซูมรอบจุดสูงสุดนั้นเราจะเห็นได้ว่าในความเป็นจริงแล้วสัญญาณ PWM (ขึ้น) ไม่ถูกต้อง

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นหลังจากเลอะไประยะหนึ่งและไม่สามารถกำจัดมันได้เราได้ลองคำนวณสัญญาณไซน์ใน MCU แทนการเข้ารหัสค่าสำหรับแต่ละตัวอย่างอย่างหนัก เราได้เพิ่มรหัสต่อไปนี้ในฟังก์ชั่นหลักก่อนการตั้งค่าตัวนับทั้งหมด:

 for(i=0;i<99;i++) {
     temp=100*(sin(2*3.14159*i/100)+1);
     seno[i]=(int)temp;
 }

แต่ผลลัพธ์ไม่เหมือนไซน์อยด์:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากเวลาผ่านไปหลายชั่วโมงเราก็ไม่สามารถหาข้อผิดพลาดของเราได้ เราขอขอบคุณคำแนะนำ


คุณช่วยโพสต์รายการค่า PWM ทั้งหมดได้ไหม
pjc50

@ pjc50 นี่มันคือpastebin.com/sNyA0Hki ขอบคุณมาก.
Serge

ลองแทนที่ค่า "0" ทั้งหมดที่อยู่ตรงกลางด้วย "1" ฉันสงสัยว่า 0 ให้สัญญาณที่กว้างมากแทนที่จะเป็นสัญญาณต่ำที่คุณต้องการ
pjc50

@Serge - กรุณาอินไลน์ข้อมูล วางอาจหายไปและมันจะไม่ดีที่จะหลวมส่วนหนึ่งของคำถาม แต่โปรดฟอร์แมทมันเพื่อไม่ให้ใช้พื้นที่มากนัก ขอบคุณ
Trygve Laugstøl

เห็นได้ชัดว่าไม่ใช่ตัวกรอง - โชคดี - ดูตารางของคุณจะเสียหายหรือคุณสูญเสียตัวชี้ไป
แอนดี้อาคา

คำตอบ:


16

ที่ด้านล่างของหน้า 350 ของแผ่นข้อมูลไมโครคอนโทรลเลอร์มันระบุว่าการเขียนค่าเล็ก ๆ ลงในค่าตัวจับเวลาลงทะเบียนระหว่างการขัดจังหวะการโอเวอร์โฟลว์อาจทำให้การขัดจังหวะครั้งต่อไปถูกเรียกใช้ในการทำซ้ำ pwm ครั้งถัดไปเท่านั้น กำลังดำเนินการรูทีน interrupt

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

สิ่งนี้ได้รับการยืนยันจากความจริงที่ว่าค่า pwm นั้นมีค่าสูงตลอดช่วงเวลาหนึ่งนาฬิกา pwm + สิ่งที่ดูเหมือนความยาวของตัวจับเวลา (ขึ้นอยู่กับความยาวโดยรอบ) ค่าที่เขียนลงทะเบียนความยาวของตัวจับเวลาน่าจะใกล้เคียงกับ 0 ณ เวลาที่เกิดข้อผิดพลาดดังนั้นจึงค่อนข้างเป็นไปได้ที่ตัวนับได้ผ่านค่าที่น้อยกว่าระหว่างการขัดจังหวะและจะกระตุ้นเฉพาะรอบต่อไปนี้

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


1
ฉันไม่รู้ว่าจะข้ามไปได้อย่างไรเมื่ออ่านแผ่นข้อมูล ขอขอบคุณ!
Serge
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.