📄 power.lst
字号:
__start:
__text_start:
002A E5CF LDI R28,0x5F
002B E0D4 LDI R29,4
002C BFCD OUT 0x3D,R28
002D BFDE OUT 0x3E,R29
002E 51C0 SUBI R28,0x10
002F 40D0 SBCI R29,0
0030 EA0A LDI R16,0xAA
0031 8308 STD Y+0,R16
0032 2400 CLR R0
0033 E6E0 LDI R30,0x60
0034 E0F0 LDI R31,0
0035 E010 LDI R17,0
0036 36E0 CPI R30,0x60
0037 07F1 CPC R31,R17
0038 F011 BEQ 0x003B
0039 9201 ST R0,Z+
003A CFFB RJMP 0x0036
003B 8300 STD Z+0,R16
003C E5E4 LDI R30,0x54
003D E0F0 LDI R31,0
003E E6A0 LDI R26,0x60
003F E0B0 LDI R27,0
0040 E010 LDI R17,0
0041 35E4 CPI R30,0x54
0042 07F1 CPC R31,R17
0043 F021 BEQ 0x0048
0044 95C8 LPM
0045 9631 ADIW R30,1
0046 920D ST R0,X+
0047 CFF9 RJMP 0x0041
0048 940E0075 CALL _main
_exit:
004A CFFF RJMP _exit
FILE: D:\M16开发板实验教程\icc-avr\POWERM~1\delay.h
(0001) #include<iom16v.h>
(0002) #include <macros.h>
(0003)
(0004) /*-----------------------------------------------------------*/
(0005) /*-----------------------------------------------------------------------
(0006) 延时函数
(0007) 系统时钟:8M
(0008) -----------------------------------------------------------------------*/
(0009) void delay_1us(void) //1us延时函数
(0010) {
(0011) asm("nop");
_delay_1us:
004B 0000 NOP
004C 9508 RET
_delay_nus:
i --> R20
n --> R22
004D 940E00B2 CALL push_gset2
004F 01B8 MOVW R22,R16
(0012) }
(0013)
(0014) void delay_nus(unsigned int n) //N us延时函数
(0015) {
(0016) unsigned int i=0;
0050 2744 CLR R20
0051 2755 CLR R21
(0017) for (i=0;i<n;i++)
0052 C003 RJMP 0x0056
(0018) delay_1us();
0053 DFF7 RCALL _delay_1us
0054 5F4F SUBI R20,0xFF
0055 4F5F SBCI R21,0xFF
0056 1746 CP R20,R22
0057 0757 CPC R21,R23
0058 F3D0 BCS 0x0053
0059 940E00A9 CALL pop_gset2
005B 9508 RET
(0019) }
(0020)
(0021) void delay_1ms(void) //1ms延时函数
(0022) {
(0023) unsigned int i;
(0024) for (i=0;i<1140;i++);
_delay_1ms:
i --> R16
005C 2700 CLR R16
005D 2711 CLR R17
005E C002 RJMP 0x0061
005F 5F0F SUBI R16,0xFF
0060 4F1F SBCI R17,0xFF
0061 3704 CPI R16,0x74
0062 E0E4 LDI R30,4
0063 071E CPC R17,R30
0064 F3D0 BCS 0x005F
0065 9508 RET
_delay_nms:
i --> R20
n --> R22
0066 940E00B2 CALL push_gset2
0068 01B8 MOVW R22,R16
(0025) }
(0026)
(0027) void delay_nms(unsigned int n) //N ms延时函数
(0028) {
(0029) unsigned int i=0;
0069 2744 CLR R20
006A 2755 CLR R21
(0030) for (i=0;i<n;i++)
006B C003 RJMP 0x006F
(0031) delay_1ms();
006C DFEF RCALL _delay_1ms
006D 5F4F SUBI R20,0xFF
006E 4F5F SBCI R21,0xFF
006F 1746 CP R20,R22
0070 0757 CPC R21,R23
0071 F3D0 BCS 0x006C
0072 940E00A9 CALL pop_gset2
0074 9508 RET
FILE: D:\M16开发板实验教程\icc-avr\POWERM~1\power.c
(0001) /*
(0002) Title: icc-avr power management
(0003) Author: dushibiao
(0004) Date: 2007 10 22
(0005) Purpose: study how to magage power
(0006) Frequency: Ext 8M
(0007) Software: icc-avr to compile
(0008) Hardware: AVR mega16 BOARD
(0009) Connect: dushibiao@126.com
(0010) */
(0011) /*
(0012) 本程序简单的示范了如何令AVR ATMEGA16进入睡眠状态及唤醒
(0013) 电源管理及睡眠模式的介绍
(0014) 进入最低耗电的掉电模式
(0015) 关闭各种模块
(0016) 外部中断唤醒
(0017)
(0018) M16掉电模式的耗电情况(看门狗关闭),时钟为内部RC 1MHz
(0019) 0.9uA@Vcc=5.0V [手册的图表约为1.1uA]
(0020) 0.3uA@Vcc=3.3V [手册的图表约为0.4uA]
(0021) //测量的数字万用表是FLUKE 15B,分辨率0.1uA
(0022)
(0023) 这个程序需要MCU进入休眠状态,为实现最低功耗,JTAG接口会被关闭,只能通过LED的变化来观察程序的运行。
(0024) 这个实验里面,用STK500(AVRISP) ISP下载线来烧录更方便。
(0025)
(0026) 熔丝位设置
(0027) 1 关断BOD功能 BODEN=1
(0028) 2 如果用ISP方式烧录,就可以完全关闭JTAG口了 OCEEN=1,JTAGEN=1
(0029)
(0030) */
(0031)
(0032) #include<iom16v.h>
(0033) #include <macros.h>
(0034) #include "delay.h"
(0035)
(0036) //管脚定义
(0037) #define LED 0 //PA0 驱动LED,低电平有效
(0038) #define KEY_INT0 2 //PB2 按键, 低电平有效
(0039)
(0040) int main(void)
(0041) {
(0042) unsigned char i;
(0043) //上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻
(0044) PORTB=0xFF; //不用的管脚使能内部上拉电阻。
_main:
i --> R20
0075 EF8F LDI R24,0xFF
0076 BB88 OUT 0x18,R24
(0045) PORTC=0xFF;
0077 BB85 OUT 0x15,R24
(0046) PORTD=0xFF;
0078 BB82 OUT 0x12,R24
(0047)
(0048) PORTA=0xFF;
0079 BB8B OUT 0x1B,R24
(0049) DDRA =(1<<LED); //PB0设为输出高电平,灯灭
007A E081 LDI R24,1
007B BB8A OUT 0x1A,R24
(0050) /*
(0051) 端口引脚
(0052) 进入休眠模式时,所有的端口引脚都应该配置为只消耗最小的功耗。
(0053) 最重要的是避免驱动电阻性负载。
(0054) 在休眠模式下I/O 时钟clkI/O 和ADC 时钟clkADC 都被停止了,输入缓冲器也禁止了,从而保证输入电路不会消耗电流。
(0055) 在某些情况下输入逻辑是使能的,用来检测唤醒条件。用于此功能的具体引脚请参见“ 数字输入使能和休眠模式” 。
(0056) 如果输入缓冲器是使能的,此时输入不能悬空,信号电平也不应该接近VCC/2,否则输入缓冲器会消耗额外的电流。
(0057)
(0058) IO作输出(DDR=1)时,维持状态不变
(0059) */
(0060)
(0061) /*
(0062) 看门狗定时器(上电默认是关闭的)
(0063) 如果系统无需利用看门狗,这个模块也可以关闭。
(0064) 若使能,则在任何休眠模式下都持续工作,从而消耗电流。
(0065) 在深层次的睡眠模式下,这个电流将占总电流的很大比重。
(0066)
(0067) 假设看门狗定时器使能了,关闭程式如下
(0068) 1. 在同一个指令内对WDTOE 和WDE 写"1“,即使WDE 已经为"1“
(0069) 2. 在紧接的4 个时钟周期之内对WDE 写"0”
(0070) */
(0071) WDTCR=(1<<WDTOE)|(1<<WDE);
007C E188 LDI R24,0x18
007D BD81 OUT 0x21,R24
(0072) WDTCR=(0<<WDE);
007E 2422 CLR R2
007F BC21 OUT 0x21,R2
(0073) //或使用wdt.h里面的wdt_disable()函数
(0074)
(0075) /*
(0076) 模数转换器(上电默认是关闭的)
(0077) 使能时, ADC在睡眠模式下继续工作。
(0078) 为了降低功耗,在进入睡眠模式之前需要禁止ADC。
(0079) 重新启动后的第一次转换为扩展的转换。
(0080)
(0081) 假设模数转换器使能了,关闭程式如下
(0082) */
(0083) ADCSRA=(0<<ADEN);
0080 B826 OUT 0x06,R2
(0084) /*
(0085) 模拟比较器(上电默认是打开的,需要手工关闭)
(0086) 在空闲模式时,如果没有使用模拟比较器,可以将其关闭。在ADC 噪声抑制模式下也是如此。
(0087) 在其他睡眠模式模拟比较器是自动关闭的。
(0088) 如果模拟比较器使用了内部电压基准源,则不论在什么睡眠模式下都需要关闭它。否则内部电压基准源将一直使能。
(0089)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -