📄 max5478.lst
字号:
__start:
__text_start:
0030 E5CF LDI R28,0x5F
0031 E0D4 LDI R29,4
0032 BFCD OUT P3D,R28
0033 BFDE OUT P3E,R29
0034 51C0 SUBI R28,0x10
0035 40D0 SBCI R29,0
0036 EA0A LDI R16,0xAA
0037 8308 STD R16,0+Y
0038 2400 CLR R0
0039 E6E0 LDI R30,0x60
003A E0F0 LDI R31,0
003B E010 LDI R17,0
003C 36E0 CPI R30,0x60
003D 07F1 CPC R31,R17
003E F011 BEQ 0x0041
003F 9201 ST R0,Z+
0040 CFFB RJMP 0x003C
0041 8300 STD R16,0+Z
0042 E6E0 LDI R30,0x60
0043 E0F0 LDI R31,0
0044 E6A0 LDI R26,0x60
0045 E0B0 LDI R27,0
0046 E010 LDI R17,0
0047 36E0 CPI R30,0x60
0048 07F1 CPC R31,R17
0049 F021 BEQ 0x004E
004A 95C8 LPM
004B 9631 ADIW R30,1
004C 920D ST R0,X+
004D CFF9 RJMP 0x0047
004E 940E00F2 CALL _main
_exit:
0050 CFFF RJMP _exit
_Delayms:
i --> R20
j --> R22
MS --> R16
0051 940E0139 CALL push_gset2
FILE: E:\程序与资料\dpj\AVR\自己写的AVR\MAX5478\MAX5478.C
(0001) /***************MAX5478数字电位器-I2C**********************/
(0002) #include <iom16v.h> //包含型号头文件
(0003) #include <macros.h> //包含"位"操作头文件
(0004) #include <stdio.h> //标准输入输出头文件
(0005) /******************数据类型宏定义******************/
(0006) #define TRUE 1
(0007) #define FALSE 0
(0008) #define uchar unsigned char
(0009) #define uint unsigned int
(0010) //******************按键常量******************/
(0011) #define KEY_DDR DDRD //按键方向定义
(0012) #define KEY_PORTO PORTD //按键端口输出定义
(0013) #define KEY_PORTI PIND //按键端口输入定义
(0014) #define OUT 0xFF //输出常量
(0015) #define IN 0xF0 //输入常量
(0016) /*******************************************
(0017) 函数名称: Delayms
(0018) 功 能: 延时指定毫秒(12M晶振)
(0019) 参 数: MS--延时的毫秒数
(0020) 返回值 : 无
(0021) /********************************************/
(0022) void Delayms(uint MS)
(0023) {
(0024) uint i,j;
(0025) for( i=0;i<MS;i++)
0053 2744 CLR R20
0054 2755 CLR R21
0055 C00B RJMP 0x0061
(0026) for(j=0;j<1141;j++); //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
0056 2766 CLR R22
0057 2777 CLR R23
0058 C002 RJMP 0x005B
0059 5F6F SUBI R22,0xFF
005A 4F7F SBCI R23,0xFF
005B 3765 CPI R22,0x75
005C E0E4 LDI R30,4
005D 077E CPC R23,R30
005E F3D0 BCS 0x0059
005F 5F4F SUBI R20,0xFF
0060 4F5F SBCI R21,0xFF
0061 1740 CP R20,R16
0062 0751 CPC R21,R17
0063 F390 BCS 0x0056
(0027) }
0064 940E0141 CALL pop_gset2
0066 9508 RET
_Skey_press:
pressed --> R16
0067 EF8F LDI R24,0xFF
0068 BB81 OUT P11,R24
0069 B382 IN R24,P12
006A 608F ORI R24,0xF
006B BB82 OUT P12,R24
006C EF80 LDI R24,0xF0
006D BB81 OUT P11,R24
006E B380 IN R24,P10
006F 708F ANDI R24,0xF
0070 308F CPI R24,0xF
0071 F011 BEQ 0x0074
0072 E001 LDI R16,1
0073 C001 RJMP 0x0075
0074 2700 CLR R16
0075 EF8F LDI R24,0xFF
0076 BB81 OUT P11,R24
0077 9508 RET
_Skey_scan:
keycode --> R20
0078 940E0139 CALL push_gset2
007A EF4F LDI R20,0xFF
007B E00F LDI R16,0xF
007C E010 LDI R17,0
007D DFD3 RCALL _Delayms
007E DFE8 RCALL _Skey_press
007F 3001 CPI R16,1
0080 F519 BNE 0x00A4
0081 EF80 LDI R24,0xF0
0082 BB81 OUT P11,R24
0083 B340 IN R20,P10
0084 704F ANDI R20,0xF
0085 2F64 MOV R22,R20
0086 2777 CLR R23
0087 3067 CPI R22,7
0088 E0E0 LDI R30,0
0089 077E CPC R23,R30
008A F099 BEQ 0x009E
008B 306B CPI R22,0xB
008C E0E0 LDI R30,0
008D 077E CPC R23,R30
008E F069 BEQ 0x009C
008F 306D CPI R22,0xD
0090 E0E0 LDI R30,0
0091 077E CPC R23,R30
0092 F039 BEQ 0x009A
0093 306E CPI R22,0xE
0094 E0E0 LDI R30,0
0095 077E CPC R23,R30
0096 F009 BEQ 0x0098
0097 C008 RJMP 0x00A0
0098 2744 CLR R20
0099 C007 RJMP 0x00A1
009A E041 LDI R20,1
009B C005 RJMP 0x00A1
009C E042 LDI R20,2
009D C003 RJMP 0x00A1
009E E043 LDI R20,3
009F C001 RJMP 0x00A1
00A0 2744 CLR R20
00A1 DFC5 RCALL _Skey_press
00A2 3001 CPI R16,1
00A3 F3E9 BEQ 0x00A1
00A4 2F04 MOV R16,R20
00A5 940E0141 CALL pop_gset2
00A7 9508 RET
(0028) //************************************************
(0029) #include "Skey.C" //包含键盘扫描函数
(0030) /******************TWI(IIC)常量******************/
(0031) #define START 0x08 //START信号发送完毕状态
(0032) #define MT_SLA_ACK 0x18 //从器件地址发送,返回ACK
(0033) #define MT_SLA_NOACK 0x20 //从器件地址发送,但是返回NOACK
(0034) #define MT_DATA_ACK 0x28 //数据已发送,返回ACK
(0035) #define MT_DATA_NOACK 0x30 //数据已发送,返回NOACK
(0036)
(0037) #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) //产生START信号
(0038) #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) //产生STOP信号
(0039) #define Wait() while(!(TWCR&(1<<TWINT))) //等待当前操作完成
(0040) #define TestACK() (TWSR&0xF8) //取出状态码
(0041) #define SetACK() (TWCR|=(1<<TWEA)) //产生ACK
(0042) #define Writebyte(twi_d) {TWDR=(twi_d);TWCR=(1<<TWINT)|(1<<TWEN);} //发送一个字节(twi_d为写入的数据)
(0043) //************************************************************************************************************
(0044) void Twi_init(void)
(0045) {
(0046) TWBR= 0x20; //设置波特率
_Twi_init:
00A8 E280 LDI R24,0x20
00A9 B980 OUT P00,R24
(0047) TWSR= 0x00; //设置预分频比
00AA 2422 CLR R2
00AB B821 OUT P01,R2
(0048) TWCR= 0x44; //使能应答,使能TWI
00AC E484 LDI R24,0x44
00AD BF86 OUT P36,R24
(0049) }
00AE 9508 RET
_MAX5478_writeB:
success --> R20
rdata --> Y+6
cmd --> R22
devadd --> R10
00AF 940E013D CALL push_gset3
00B1 2F62 MOV R22,R18
00B2 2EA0 MOV R10,R16
(0050)
(0051) /*******************************************
(0052) 函数名称: MAX5478_writeB
(0053) 功 能: 向MAX5478写入电阻值数据
(0054) 参 数: devadd--器件地址
(0055) cmd--控制命令
(0056) rdata--电阻数据
(0057) 返回值 : success--数据成功标志(为TRUE时写入成功,为FALSE时失败)
(0058) /********************************************/
(0059) uchar MAX5478_writeB(uchar devadd,uchar cmd,uchar rdata)
(0060) {
(0061) uchar success=FALSE; //默认返回是写入失败
00B3 2744 CLR R20
(0062) Start(); //产生START信号
00B4 EA84 LDI R24,0xA4
00B5 BF86 OUT P36,R24
(0063) Wait(); //等待START信号发送完毕
00B6 B626 IN R2,P36
00B7 FE27 SBRS R2,7
00B8 CFFD RJMP 0x00B6
(0064) if(TestACK()!=START) //检查是否是START信号发送完毕状态
00B9 B181 IN R24,P01
00BA 7F88 ANDI R24,0xF8
00BB 3088 CPI R24,0x8
00BC F019 BEQ 0x00C0
(0065) {
(0066) success=FALSE; //如果不是,则返回写入失败
00BD 2744 CLR R20
(0067) return success;
00BE 2F04 MOV R16,R20
00BF C02F RJMP 0x00EF
(0068) }
(0069) Writebyte(devadd); //发送从器件地址
00C0 B8A3 OUT P03,R10
00C1 E884 LDI R24,0x84
00C2 BF86 OUT P36,R24
(0070) Wait(); //等待发送完毕
00C3 B626 IN R2,P36
00C4 FE27 SBRS R2,7
00C5 CFFD RJMP 0x00C3
(0071) if(TestACK()!=MT_SLA_ACK)//检查是否是从器件地址发送完毕状态
00C6 B181 IN R24,P01
00C7 7F88 ANDI R24,0xF8
00C8 3188 CPI R24,0x18
00C9 F019 BEQ 0x00CD
(0072) {
(0073) success=FALSE; //如果不是,则返回写入失败
00CA 2744 CLR R20
(0074) return success;
00CB 2F04 MOV R16,R20
00CC C022 RJMP 0x00EF
(0075) }
(0076) Writebyte(cmd); //发送MAX5478的命令字节(具体含义请参看MAX5478的数据手册)
00CD B963 OUT P03,R22
00CE E884 LDI R24,0x84
00CF BF86 OUT P36,R24
(0077) Wait(); //等待发送完毕
00D0 B626 IN R2,P36
00D1 FE27 SBRS R2,7
00D2 CFFD RJMP 0x00D0
(0078) if(TestACK()!=MT_DATA_ACK)//检查是否是数据发送完毕
00D3 B181 IN R24,P01
00D4 7F88 ANDI R24,0xF8
00D5 3288 CPI R24,0x28
00D6 F019 BEQ 0x00DA
(0079) {
(0080) success=FALSE; //如果不是,则返回写入失败
00D7 2744 CLR R20
(0081) return success;
00D8 2F04 MOV R16,R20
00D9 C015 RJMP 0x00EF
(0082) }
(0083) Writebyte(rdata); //发送电阻值数据
00DA 800E LDD R0,6+Y
00DB B803 OUT P03,R0
00DC E884 LDI R24,0x84
00DD BF86 OUT P36,R24
(0084) Wait(); //等待发送完毕
00DE B626 IN R2,P36
00DF FE27 SBRS R2,7
00E0 CFFD RJMP 0x00DE
(0085) if(TestACK()!=MT_DATA_ACK)//检查是否是数据发送完毕
00E1 B181 IN R24,P01
00E2 7F88 ANDI R24,0xF8
00E3 3288 CPI R24,0x28
00E4 F019 BEQ 0x00E8
(0086) {
(0087) success=FALSE; //如果不是,则返回写入失败
00E5 2744 CLR R20
(0088) return success;
00E6 2F04 MOV R16,R20
00E7 C007 RJMP 0x00EF
(0089) }
(0090) Stop(); //对MAX5478的一次操作完毕,发送STOP信号
00E8 E984 LDI R24,0x94
00E9 BF86 OUT P36,R24
(0091) Delayms(10); //等待发送完毕
00EA E00A LDI R16,0xA
00EB E010 LDI R17,0
00EC DF64 RCALL _Delayms
(0092) success=TRUE; //本次写入成功
00ED E041 LDI R20,1
(0093) return success; //返回写入成功状态
00EE 2F04 MOV R16,R20
00EF 940E0144 CALL pop_gset3
00F1 9508 RET
_main:
data --> R20
i --> R10
00F2 9721 SBIW R28,1
(0094) }
(0095) /*******************************************
(0096) 函数名称: main
(0097) 功 能: 按键更新数字电位器的阻值(电阻是A和W端的阻值,默认B端是开路的)
(0098) 参 数: 无
(0099) 返回值 : 无
(0100) /********************************************/
(0101) void main(void)
(0102) {
(0103) uchar i,data=255; //初始电阻是满量程
00F3 EF4F LDI R20,0xFF
(0104)
(0105) Twi_init( ); //初始化TWI
00F4 DFB3 RCALL _Twi_init
(0106) MAX5478_writeB(0x50,0x13,data); //设置初始电阻
00F5 8348 STD R20,0+Y
00F6 E123 LDI R18,0x13
00F7 E500 LDI R16,0x50
00F8 DFB6 RCALL _MAX5478_writeB
00F9 C025 RJMP 0x011F
(0107) while(1)
(0108) {
(0109) if(Skey_press()) //是否有按键按下
00FA DF6C RCALL _Skey_press
00FB 2300 TST R16
00FC F111 BEQ 0x011F
(0110) {
(0111) i=Skey_scan(); //扫描并反回翻译后的键码
00FD DF7A RCALL _Skey_scan
00FE 2EA0 MOV R10,R16
(0112) switch(i)
00FF 2D6A MOV R22,R10
0100 2777 CLR R23
0101 3060 CPI R22,0
0102 0767 CPC R22,R23
0103 F069 BEQ 0x0111
0104 3061 CPI R22,1
0105 E0E0 LDI R30,0
0106 077E CPC R23,R30
0107 F059 BEQ 0x0113
0108 3062 CPI R22,2
0109 E0E0 LDI R30,0
010A 077E CPC R23,R30
010B F049 BEQ 0x0115
010C 3063 CPI R22,3
010D E0E0 LDI R30,0
010E 077E CPC R23,R30
010F F039 BEQ 0x0117
0110 C007 RJMP 0x0118
(0113) {
(0114) case 0: //S1键按下,减少电阻的数字量(MAX5478的特性是减少电阻的数字量,阻值增加)
(0115) data-=5;
0111 5045 SUBI R20,5
(0116) break;
0112 C005 RJMP 0x0118
(0117) case 1: //S2键按下,增加电阻的数字量
(0118) data+=5;
0113 5F4B SUBI R20,0xFB
(0119) break;
0114 C003 RJMP 0x0118
(0120) case 2: //S3键按下,使电阻的数字量为零(阻值满量程)
(0121) data=0;
0115 2744 CLR R20
(0122) break;
0116 C001 RJMP 0x0118
(0123) case 3: //S3键按下,使电阻的数字量为满(阻值清零,只剩下接触电阻)
(0124) data=255;
0117 EF4F LDI R20,0xFF
(0125) break;
(0126) }
(0127) MAX5478_writeB(0x50,0x13,data); //更新电阻
0118 8348 STD R20,0+Y
0119 E123 LDI R18,0x13
011A E500 LDI R16,0x50
011B DF93 RCALL _MAX5478_writeB
(0128) Delayms(5);
011C E005 LDI R16,5
011D E010 LDI R17,0
011E DF32 RCALL _Delayms
011F CFDA RJMP 0x00FA
(0129) }
(0130) }
(0131) } FILE: <library>
0120 9621 ADIW R28,1
0121 9508 RET
push_gset1:
0122 935A ST R21,-Y
0123 934A ST R20,-Y
0124 9508 RET
pop_gset1:
0125 E0E1 LDI R30,1
pop:
0126 9149 LD R20,Y+
0127 9159 LD R21,Y+
0128 FDE0 SBRC R30,0
0129 9508 RET
012A 9169 LD R22,Y+
012B 9179 LD R23,Y+
012C FDE1 SBRC R30,1
012D 9508 RET
012E 90A9 LD R10,Y+
012F 90B9 LD R11,Y+
0130 FDE2 SBRC R30,2
0131 9508 RET
0132 90C9 LD R12,Y+
0133 90D9 LD R13,Y+
0134 FDE3 SBRC R30,3
0135 9508 RET
0136 90E9 LD R14,Y+
0137 90F9 LD R15,Y+
0138 9508 RET
push_gset2:
0139 937A ST R23,-Y
013A 936A ST R22,-Y
013B 940C0122 JMP push_gset1
push_gset3:
013D 92BA ST R11,-Y
013E 92AA ST R10,-Y
013F 940C0139 JMP push_gset2
pop_gset2:
0141 E0E2 LDI R30,2
0142 940C0126 JMP pop
pop_gset3:
0144 E0E4 LDI R30,4
0145 940C0126 JMP pop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -