⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pwm.lst

📁 avr icc 平台开发的pwm模拟功能
💻 LST
📖 第 1 页 / 共 3 页
字号:
__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 + -