?? pwm.lst
字號:
__text_start:
__start:
004E E5CF LDI R28,0x5F
004F E0D4 LDI R29,4
0050 BFCD OUT 0x3D,R28
0051 BFDE OUT 0x3E,R29
0052 51C0 SUBI R28,0x10
0053 40D0 SBCI R29,0
0054 EA0A LDI R16,0xAA
0055 8308 STD Y+0,R16
0056 2400 CLR R0
0057 EAE7 LDI R30,0xA7
0058 E0F0 LDI R31,0
0059 E010 LDI R17,0
005A 3AEA CPI R30,0xAA
005B 07F1 CPC R31,R17
005C F011 BEQ 0x005F
005D 9201 ST R0,Z+
005E CFFB RJMP 0x005A
005F 8300 STD Z+0,R16
0060 E5E4 LDI R30,0x54
0061 E0F0 LDI R31,0
0062 E6A0 LDI R26,0x60
0063 E0B0 LDI R27,0
0064 E010 LDI R17,0
0065 39EB CPI R30,0x9B
0066 07F1 CPC R31,R17
0067 F021 BEQ 0x006C
0068 95C8 LPM
0069 9631 ADIW R30,1
006A 920D ST R0,X+
006B CFF9 RJMP 0x0065
006C D05B RCALL _main
_exit:
006D CFFF RJMP _exit
FILE: D:\NEW\AVR_PWM\main.c
(0001) #define MAIN_C
(0002) #include "includes.h"
(0003) /***************************/
(0004) /*PWM*/
(0005) /*晶振為4MHz*/
(0006) /*利用Timer1的OC1A腳輸出占空比可調的信號*/
(0007) /*通過按鍵控制OCR1A的值*/
(0008) /***************************/
(0009)
(0010) #define PwmOut PD5 //A通道的PWM輸出
(0011) #define OCR OCR1A
(0012) #define KeyUp PA0 //增大PWM值的按鍵
(0013) #define KeyDown PA1 //減小PWM值的按鍵
(0014) #define Above PA2 //設置位值過高指示
(0015) #define Below PA3 //設置位值過低指示
(0016) #define STEP 64 //定義按鍵時的步進值
(0017) int OcrReg = 1024; //OCR1A初始值
(0018) int Icr1Reg = 0x7ff; //PWM的計數頂部值 Icr1Reg = 2047
(0019) //unsigned char *show = "0000";
(0020) unsigned char temp;
(0021)
(0022) void init(void) //初始化函數
(0023) {
(0024) //比較匹配時清零,計數到最大時置位OC1A
(0025) TCCR1A |= (1<<COM1A1)|(1<<PWM11);/*PWM11=WGM11 name changed*/
_init:
006E B58F IN R24,0x2F
006F 6882 ORI R24,0x82
0070 BD8F OUT 0x2F,R24
(0026) //11位分辨率,快速PWM模式,使用系統時鐘作為計數時鐘
(0027) TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
0071 B58E IN R24,0x2E
0072 6189 ORI R24,0x19
0073 BD8E OUT 0x2E,R24
(0028) ICR1 = Icr1Reg;
0074 90200067 LDS R2,0x67
0076 90300068 LDS R3,0x68
0078 BC37 OUT 0x27,R3
0079 BC26 OUT 0x26,R2
(0029) OCR = 0 ;
007A 2422 CLR R2
007B 2433 CLR R3
007C BC3B OUT 0x2B,R3
007D BC2A OUT 0x2A,R2
(0030) DDRD |= (1<<PwmOut); //置PWM為輸出
007E 9A8D SBI 0x11,5
(0031) DDRA |= (1<<Above)|(1<<Below); //指示燈定義為輸出
007F B38A IN R24,0x1A
0080 608C ORI R24,0xC
0081 BB8A OUT 0x1A,R24
(0032) DDRA &= ~((1<<KeyUp)|(1<<KeyDown)); //按鍵定義為輸入
0082 B38A IN R24,0x1A
0083 7F8C ANDI R24,0xFC
0084 BB8A OUT 0x1A,R24
(0033) PORTA |= (1<<KeyUp)|(1<<KeyDown); //按鍵開啟上拉
0085 B38B IN R24,0x1B
0086 6083 ORI R24,3
0087 BB8B OUT 0x1B,R24
(0034) PORTA |= (1<<Above)|(1<<Below); //關閉兩個指示燈
0088 B38B IN R24,0x1B
0089 608C ORI R24,0xC
008A BB8B OUT 0x1B,R24
(0035) //TIMSK |= (1<<OCIE1A); //允許計數器比較匹配中斷
(0036) //SREG |= (1<<7); //開全局中斷
(0037) }
008B 9508 RET
_ShowValue:
temp --> R20
value --> R22
008C D1EF RCALL push_gset2
008D 01B8 MOVW R22,R16
008E 9722 SBIW R28,2
(0038)
(0039) void ShowValue(int value)
(0040) {
(0041) unsigned char *temp = "0000";
008F E941 LDI R20,0x91
0090 E050 LDI R21,0
(0042) temp[0] = value/1000 + 0x30;
0091 EE28 LDI R18,0xE8
0092 E033 LDI R19,3
0093 018B MOVW R16,R22
0094 D19B RCALL div16s
0095 01C8 MOVW R24,R16
0096 96C0 ADIW R24,0x30
0097 01FA MOVW R30,R20
0098 8380 STD Z+0,R24
(0043) value = value%1000;
0099 EE28 LDI R18,0xE8
009A E033 LDI R19,3
009B 018B MOVW R16,R22
009C D18F RCALL mod16s
009D 01B8 MOVW R22,R16
(0044) temp[1] = value/100 +0x30;
009E E624 LDI R18,0x64
009F E030 LDI R19,0
00A0 D18F RCALL div16s
00A1 01C8 MOVW R24,R16
00A2 96C0 ADIW R24,0x30
00A3 01FA MOVW R30,R20
00A4 8381 STD Z+1,R24
(0045) value = value%100;
00A5 E624 LDI R18,0x64
00A6 E030 LDI R19,0
00A7 018B MOVW R16,R22
00A8 D183 RCALL mod16s
00A9 01B8 MOVW R22,R16
(0046) temp[2] = value/10 + 0x30;
00AA E02A LDI R18,0xA
00AB E030 LDI R19,0
00AC D183 RCALL div16s
00AD 01C8 MOVW R24,R16
00AE 96C0 ADIW R24,0x30
00AF 01FA MOVW R30,R20
00B0 8382 STD Z+2,R24
(0047) value = value%10;
00B1 E02A LDI R18,0xA
00B2 E030 LDI R19,0
00B3 018B MOVW R16,R22
00B4 D177 RCALL mod16s
00B5 01B8 MOVW R22,R16
(0048) temp[3] = value + 0x30;
00B6 01CB MOVW R24,R22
00B7 96C0 ADIW R24,0x30
00B8 01FA MOVW R30,R20
00B9 8383 STD Z+3,R24
(0049) ClearLine(2);
00BA E002 LDI R16,2
00BB D163 RCALL _ClearLine
(0050) LCD_DisplayString(2,1,"OCR1A = ");
00BC E888 LDI R24,0x88
00BD 940E0287 CALL 0x287
00BF D11E RCALL _LCD_DisplayString
(0051) LCD_DisplayString(2,9,temp);
00C0 8359 STD Y+1,R21
00C1 8348 STD Y+0,R20
00C2 E029 LDI R18,0x9
00C3 E002 LDI R16,2
00C4 D119 RCALL _LCD_DisplayString
(0052) }
00C5 9622 ADIW R28,2
00C6 D19A RCALL pop_gset2
00C7 9508 RET
_main:
i --> R20
00C8 9722 SBIW R28,2
(0053)
(0054) void main(void)
(0055) {
(0056) unsigned char i;
(0057) init();
00C9 DFA4 RCALL _init
(0058) Init_LCD();
00CA D0EB RCALL _Init_LCD
00CB 940E02B3 CALL 0x2B3
(0059) OCR = OcrReg;
00CD BC3B OUT 0x2B,R3
00CE BC2A OUT 0x2A,R2
(0060) LCD_DisplayString(1,1,"PWM test");
00CF E78F LDI R24,0x7F
00D0 E090 LDI R25,0
00D1 8399 STD Y+1,R25
00D2 8388 STD Y+0,R24
00D3 E021 LDI R18,1
00D4 E001 LDI R16,1
00D5 D108 RCALL _LCD_DisplayString
(0061) LCD_DisplayString(2,1,"OCR1A = ");
00D6 E888 LDI R24,0x88
00D7 940E0287 CALL 0x287
00D9 D104 RCALL _LCD_DisplayString
(0062) ShowValue(OcrReg);
00DA 91000065 LDS R16,0x65
00DC 91100066 LDS R17,0x66
00DE DFAD RCALL _ShowValue
00DF C055 RJMP 0x0135
(0063) while(1)
(0064) {
(0065) if(!(PINA&(1<<KeyUp)))
00E0 99C8 SBIC 0x19,0
00E1 C029 RJMP 0x010B
(0066) {
(0067) delay_nms(10); //按鍵消抖
00E2 E00A LDI R16,0xA
00E3 E010 LDI R17,0
00E4 D06C RCALL _delay_nms
(0068) if(!(PINA&(1<<KeyUp)))
00E5 99C8 SBIC 0x19,0
00E6 C024 RJMP 0x010B
(0069) {
(0070) while(!(PINA&(1<<KeyUp))); //等待按鍵釋放
00E7 9BC8 SBIS 0x19,0
00E8 CFFE RJMP 0x00E7
(0071) if(OcrReg >= (Icr1Reg+1))
00E9 91800067 LDS R24,0x67
00EB 91900068 LDS R25,0x68
00ED 9601 ADIW R24,1
00EE 940E02B3 CALL 0x2B3
00F0 1628 CP R2,R24
00F1 0639 CPC R3,R25
00F2 F084 BLT 0x0103
(0072) {
(0073) for(i=0;i<5;i++)
00F3 2744 CLR R20
00F4 C005 RJMP 0x00FA
(0074) {
(0075) PORTA ^= (1<<Above);
00F5 E084 LDI R24,4
00F6 940E02AD CALL 0x2AD
(0076) delay_nms(200);
00F8 D058 RCALL _delay_nms
00F9 9543 INC R20
00FA 3045 CPI R20,5
00FB F3C8 BCS 0x00F5
(0077) }
(0078) ClearLine(2);
00FC E002 LDI R16,2
00FD D121 RCALL _ClearLine
(0079) LCD_DisplayString(2,1,"Value MAX!");
00FE E784 LDI R24,0x74
00FF 940E0287 CALL 0x287
0101 D0DC RCALL _LCD_DisplayString
(0080) }
0102 C008 RJMP 0x010B
(0081) else
(0082) {
(0083) PORTA |= (1<<Above);
0103 9ADA SBI 0x1B,2
0104 940E02BD CALL 0x2BD
(0084) OcrReg += STEP;
0106 5C80 SUBI R24,0xC0
0107 4F9F SBCI R25,0xFF
0108 940E0297 CALL 0x297
(0085) OCR = OcrReg;
(0086) ShowValue(OcrReg);
010A DF81 RCALL _ShowValue
(0087) }
(0088) }
(0089) }
(0090) if(!(PINA&(1<<KeyDown)))
010B 99C9 SBIC 0x19,1
010C C028 RJMP 0x0135
(0091) {
(0092) delay_nms(10); //按鍵消抖
010D E00A LDI R16,0xA
010E E010 LDI R17,0
010F D041 RCALL _delay_nms
(0093) if(!(PINA&(1<<KeyDown)))
0110 99C9 SBIC 0x19,1
0111 C023 RJMP 0x0135
(0094) {
(0095) while(!(PINA&(1<<KeyDown))); //等待按鍵釋放
0112 9BC9 SBIS 0x19,1
0113 CFFE RJMP 0x0112
(0096) if(OcrReg <= 0)
0114 2422 CLR R2
0115 2433 CLR R3
0116 90400065 LDS R4,0x65
0118 90500066 LDS R5,0x66
011A 1424 CP R2,R4
011B 0435 CPC R3,R5
011C F084 BLT 0x012D
(0097) {
(0098) for(i=0;i<5;i++)
011D 2744 CLR R20
011E C005 RJMP 0x0124
(0099) {
(0100) PORTA ^= (1<<Below);
011F E088 LDI R24,0x8
0120 940E02AD CALL 0x2AD
(0101) delay_nms(200);
0122 D02E RCALL _delay_nms
0123 9543 INC R20
0124 3045 CPI R20,5
0125 F3C8 BCS 0x011F
(0102) }
(0103) ClearLine(2);
0126 E002 LDI R16,2
0127 D0F7 RCALL _ClearLine
(0104) LCD_DisplayString(2,1,"Value MIN!");
0128 E689 LDI R24,0x69
0129 940E0287 CALL 0x287
012B D0B2 RCALL _LCD_DisplayString
(0105) }
012C C008 RJMP 0x0135
(0106) else
(0107) {
(0108) PORTA |= (1<<Below);
012D 9ADB SBI 0x1B,3
012E 940E02BD CALL 0x2BD
(0109) OcrReg -= STEP;
0130 5480 SUBI R24,0x40
0131 4090 SBCI R25,0
0132 940E0297 CALL 0x297
(0110) OCR = OcrReg;
(0111) ShowValue(OcrReg);
0134 DF57 RCALL _ShowValue
0135 CFAA RJMP 0x00E0
(0112) }
(0113) }
(0114) }
(0115) }
(0116) }
0136 9622 ADIW R28,2
0137 9508 RET
FILE: D:\NEW\AVR_PWM\delay.c
(0001) #define DELAY_C
(0002) #include "includes.h"
(0003) #define XTAL 4 //晶振頻率,單位MHz
(0004) void delay_1us(void) //1us延時函數
(0005) {
(0006) asm("nop");
_delay_1us:
0138 0000 NOP
(0007) }
0139 9508 RET
_delay_nus:
i --> R20
n --> R22
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -