Atmega328P Datasheet 14. PM - Power Management and Sleep Modes

Started by tha, November 01, 2017, 11:51:44 AM

Previous topic - Next topic

tha

เซทเป็นบิทเอาก็จะได้เป็นแบบนี้ครับ ไม่รู้  timed sequence มันได้หรือเปล่า
http://www.mediafire.com/file/phmf8lrvhe79amd/slepp_bod2.rar
ลองเอามิเตอร์วัดกระแสไฟเลี้ยงดู เวลาเข้าสู่ sleep วัดได้ประมาณ 12.8 mA ทั้งที่มี BOD disable กับเอา BOD disable ออกเลย ทั้งสองแบบด้วย งง เราทำผิดหรือดาต้าชีทมันหลอกเราว่ะเนี้ย  :'(

tha

ส่วนค่า BOD เราสามารถเลือกโปรแกรมได้ที่ fuse bit



ถ้าใครมี power supply ที่ปรับค่าได้ ก็ลองปรับไฟเลี้ยงให้ต่ำกว่าค่า brown-out ดูว่าผลจะเป็นอย่างไร ครับ

tha

ลองเอา power supply ที่ปรับค่าได้มาลองทั้งสองโปรแกรมนี้ พอปรับ volt ลงให้ต่ำกว่า 4.3v แล้วปรับขึ้นมาพอผ่าน 4.3v ขึ้นมาแล้ว LED PD7 กระพริบขึ้นมา แสดงว่ามัน BOD reset ได้ มันไม่ได้ถูก disable อย่างที่เราโปรแกรม เป็นเพราะอะไรหนอ ท่านใดพอทราบ
พอลองตั้ง BOD disable ที่ fuse bit  พอปรับ volt ลงให้ต่ำกว่า 4.3v แล้วปรับขึ้นมาพอผ่าน 4.3v ขึ้นมาแล้ว LED PD7 ไม่กระพริบขึ้นมา แสดงว่าทำ BOD disable อย่างนี้ได้  :-\


tha

ทราบปัญหาแล้วครับ sleep mode IDLE ทำ BOD disable ไมได้ (ดูที่ตารางต้นบท) ทำ BOD disable ได้แต่ power down กับ standby ครับ ที่โปรแกรม sleep_bod1 ตั้งเป็น
Quoteset_sleep_mode(SLEEP_MODE_PWR_DOWN);
หรือ
Quoteset_sleep_mode(SLEEP_MODE_STANDBY);
ก็ใช้ได้แล้ว พอปรับ volt ลงให้ต่ำกว่า 4.3v แล้วปรับขึ้นมาพอผ่าน 4.3v ขึ้นมาแล้ว LED PD7 ไม่กระพริบขึ้นมา แสดงว่าทำ BOD disable อย่างนี้ได้

แต่ที่โปรแกรม slepp_bod2 ที่ตั้งเป็นบิท ทั้ง power down และ standby พอปรับ volt ลงให้ต่ำกว่า 4.3v แล้วปรับขึ้นมาพอผ่าน 4.3v ขึ้นมาแล้ว LED PD7 กระพริบขึ้นมา แสดงว่าทำ BOD disable ไม่ได้ คงจะเกิดจาก การเซทบิทอย่างนี้ time squence มันไม่ได้ เลย BOD disable ไม่ได้ ท่านใดมีความสามารถก็ทำการตรวจแก้ให้ด้วยนะครับ  ;)

tha

โปรแกรม sleep_bod1 ที่ตั้ง sleep mode power down วัดกระแสตอนที่เข้าสู่ sleep ได้ 3.35mA
พอเอา
Quotesleep_bod_disable();       // BOD disable
ออก วัดกระแสได้ 3.36mA
ก็ไม่หนีกันเท่าไหร่ระหว่าง bod disable กับไม่ bod disable
ต่างกันที่ ถ้าทำ bod disable แล้ว เวลาเข้าสู่ sleep แล้วไฟตกต่ำกว่า 4.3v(ตามที่เราตั้ง)แล้วกลับคืนมาเป็นปกติจะไม่เกิดการ reset เนื่องจาก BOD

tha

โปรแกรม slepp_bod2 ถ้ากำหนด register ตรงๆแบบนี้
Quotevoid sleep_mode_bod(void)
  {
    //if (some_condition)
    sleep_enable();            // set SE bit to enable sleep
    //sleep_bod_disable();       // BOD disable
    //MCUCR |= (1<<BODS)|(1<<BODSE);  // first set BODS and BODSE to 1
    //MCUCR |= (1<<BODS);             // then set BODS to 1
    //MCUCR &= ~(1<<BODSE);           // clear BODSE to 0
    MCUCR = 0x60;            // BOD sleep, datasheet page 48
    MCUCR = 0x40;               // then set BODS to 1, clear BODSE to 0
    sei();                     // set globol interrupt
    sleep_cpu();               // executed sleep instruction
    sleep_disable();           // clear SE bit to disable sleep

   //sleep = 0;
  }
 
สามารถทำงานได้ถูกต้อง code size ลดลงจาก 316 เหลือ 306 คงจะลดลงมาเนื่องจากโปรแกรมเราไม่ได้ shift , or ,and แล้ว time squence เลยได้ แต่การกำหนดตรงๆแบบนี้มันก็กระทบกระเทือนบิทอื่นด้วย ใน register เดียวกัน(เป็น 0 หมด)

เพลินดีมีอะไรทำ  :)

tha

Bit 4 – PUD: Pull-up Disable
เมื่อบิทนี้ถูกเขียนให้เป็น "1", the pull-ups ใน the I/O ports ถูก disabled ถึงแม้นว่า the DDxn and PORTxn Registers ถูกกำหนดเพื่อ enable the pull-ups ({DDxn, PORTxn} = 0b01).

Bit 1 – IVSEL: Interrupt Vector Select
เมื่อ the IVSEL bit ถูกเคลียร์ (0), the Interrupt Vectors ถูกบรรจุลงที่จุดเริ่มต้นของ the Flash memory. เมื่อบิทนี้ถูกเซท ("1"), the Interrupt Vectors ถูกย้ายไปที่จุดเริ่มต้นของ the Boot Loader section ของ the Flash. ตำแหน่งจริงๆของจุดเริ่มต้นของ the Boot Flash Section ถูกกำหนดโดย the BOOTSZ Fuses. เพื่อหลีกเลี่ยงการไม่ได้ตั้งใจเปลี่ยนของ Interrupt Vector tables, ขบวนการเขียนเป็นพิเศษที่ต้องปฏิบัติตามเพื่อเปลี่ยน the IVSEL bit:
     1. เขียน the Interrupt Vector Change Enable (IVCE) bit ให้เป็น "1".
     2. ภายใน 4 cycles, เขียนค่าที่ต้องการไปยัง IVSEL ขณะที่เขียน "0" ไปยัง IVCE.
Interrupts จะถูก disabled โดยอัตโนมัติขณะที่ขั้นตอนนี้ถูกปฏิบัติ. Interrupts ถูก disabled ในไซเกิลที่ IVCE ถูกเซท, และมันยังคง disabled จนกระทั่งหลังจากคำสั่งที่ตามหลังการเขียนถึง IVSEL. ถ้า IVSEL ไม่ได้ถูกเขียน, interrupts ยังคง disabled เป็นเวลา 4 cycles. The I-bit ใน the Status Register ไม่ได้รับกระทบโดย the automatic disabling นี้
หมายเหตุ : ถ้า Interrupt Vectors ถูกบรรจุลงใน the Boot Loader section และ Boot Lock bit BLB02 ถูกโปรแกรม, interrupts ถูก disabled ขณะที่กำลังปฏิบัติจาก the Application section. ถ้า Interrupt Vectors ถูกบรรจุลงใน the Application section และ Boot Lock bit BLB12 ถูกโปรแกรม interrupts ถูก disabled ขณะที่กำลังปฏิบัติจาก the Boot Loader section.

Bit 0 – IVCE: Interrupt Vector Change Enable
The IVCE bit ต้องถูกเขียนด้วยลอจิก "1" เพื่อ enable การเปลี่ยนของ the IVSEL bit. IVCE จะถูกเคลียร์โดยฮาร์ดแวร์ 4 cycles หลังจากที่มันถูกเขียนหรือเมื่อ IVSEL ถูกเขียน. การเซท the IVCE bit จะ disable interrupts, ตามที่อธิบายใน the IVSEL คำอธิบายด้านบน ดูตัวอย่างรโค็ดด้านล่าง



จะเอาไปใช้ในงานอย่างไรนี่ arduino หรือเปล่า? แต่เขาก็ทำสำเร็จรูปแล้วมั้ง ไม่ยกตัวอย่างหล่ะ  :o

tha

 :) สวัสดีปีใหม่ครับ ชาว electoday  :)
ขอให้มีความสุข สุขภาพแข็งแรง จิตใจแจ่มใสเบิกบานไปตลอดปีนะครับ  :)
ขอให้ประดิษฐ์คิดค้นอะไรใหม่ๆขึ้นมาได้ด้วย  :)
มาว่ากันต่อนะ  :)

14.12.3. Power Reduction Register



Bit 7 – PRTWI0: Power Reduction TWI0
เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the TWI0 โดยการหยุด the clock ที่ไปยัง the module นี้. เมื่อปลุกให้ the TWI ตื่นอีกครั้ง, the TWI ควรถูกเริ่มต้นซ้ำเพื่อให้แน่ใจว่าการทำงานได้อย่างเหมาะสม

Bit 6 – PRTIM2: Power Reduction Timer/Counter2
เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the Timer/Counter2 module ใน synchronous mode (AS2 เป็น 0). เมื่อ the Timer/Counter2 ถูก enabled, การทำงานจะดำเนินต่อไปเหมือนก่อนที่จะ the shutdown.

Bit 5 – PRTIM0: Power Reduction Timer/Counter0
เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the Timer/Counter0 module. เมื่อ the Timer/Counter0 ถูก enabled, การทำงานจะดำเนินต่อไปเหมือนก่อนที่จะ the shutdown.

Bit 3 – PRTIM1: Power Reduction Timer/Counter1
เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the Timer/Counter1 module. เมื่อ the Timer/Counter1 ถูก enabled, การทำงานจะดำเนินต่อไปเหมือนก่อนที่จะ the shutdown.

Bit 2 – PRSPI0: Power Reduction Serial Peripheral Interface 0
ถ้ามีการใช้ debugWIRE On-chip Debug System, บิทนี้ควรไม่ถูกเขียนให้เป็น "1". เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the Serial Peripheral Interface โดยการหยุด the clock ที่ไปยัง the module นี้..เมื่อปลุกให้ the SPI ตื่นอีกครั้ง, the SPI ควรถูกเริ่มต้นซ้ำเพื่อให้แน่ใจว่าการทำงานได้อย่างเหมาะสม

Bit 1 – PRUSART0: Power Reduction USART0
เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the USART โดยการหยุด the clock ที่ไปยัง the module นี้. เมื่อปลุกให้ the USART ตื่นอีกครั้ง, the USART ควรถูกเริ่มต้นซ้ำเพื่อให้แน่ใจว่าการทำงานได้อย่างเหมาะสม

Bit 0 – PRADC: Power Reduction ADC
เขียนลอจิก "1"ไปยังบิทนี้จะ shuts down the ADC. The ADC ต้องถูก disabled ก่อน shut down. The analog comparator ไม่สามารถใช้ the ADC input MUX เมื่อ the ADC ถูก shut down.

ถ้าจะหยุดตัวไหน ก็ทำอย่างนี้ตรงที่ต้องการหยุดได้เลย อย่างนี้หรือเปล่า
Quote
PRR |= (1<<PRTWI0);
เมื่อปลุกให้ the TWI ตื่นอีกครั้ง ก็ทำอย่างนี้
Quote
PRR &= ~(1<<PRTWI0);
แล้วก็ re initialized ตัวโมดูลนี้ซ้ำอีกครั้ง ถูกต้องใหมอย่างนี้ ตัวอย่างอาจมีภายหลัง เนื่องจากแปลยังไม่ถึงตัว Module ต่างๆเลย