📄 ad5161.s
字号:
.module AD5161.c
.area text(rom, con, rel)
.dbfile C:/icc/include/AVR_PQ1A.h
.dbfunc e Delayus _Delayus fV
; i -> R20,R21
; US -> R22,R23
.even
_Delayus::
xcall push_gset2
movw R22,R16
.dbline -1
.dbline 28
; /*******************************************
; 文件:AD5161.C
; 环境:编译为ICC AVR6.25A,仿真为AVR Studio4.10
; 硬件:ATMEGA16芯片
; 日期:2006年12月10日
; 功能:驱动开发板上的数字电位器(AD5161采用IIC接口)
; 备注:参考《AVR系列单片机C语言编程与应用实例》(清华大学出版社)
; /******************************************/
; #include <iom16v.h> //包含型号头文件
; #include <macros.h> //包含"位"操作头文件
; #include <stdio.h> //标准输入输出头文件
; #include <AVR_PQ1A.h> //包含自定义常量头文件
; #include "Skey.C" //包含数码管显示函数
;
; /*******************************************
; 函数名称: Twi_init
; 功 能: 初始化TWI
; 参 数: MS--延时的毫秒数
; 返回值 : 无
; /********************************************/
; void Twi_init(void)
; {
; TWBR= 0x20; //设置波特率
; TWSR= 0x00; //设置预分频比
; TWCR= 0x44; //使能应答,使能TWI
; }
; /*******************************************
; 函数名称: AD5161_writeB
.dbline 30
; 功 能: 向AD5161写入电阻值数据
; 参 数: devadd--器件地址
ldi R16,5
ldi R17,0
movw R18,R22
xcall empy16s
movw R22,R16
lsr R23
ror R22
lsr R23
ror R22
.dbline 31
clr R20
clr R21
xjmp L5
L2:
.dbline 31
L3:
.dbline 31
subi R20,255 ; offset = 1
sbci R21,255
L5:
.dbline 31
; cmd--控制命令
cp R20,R22
cpc R21,R23
brlo L2
.dbline -2
.dbline 32
; rdata--电阻数据
L1:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r US 22 i
.dbend
.dbfunc e Delayms _Delayms fV
; i -> R20,R21
; j -> R22,R23
; MS -> R16,R17
.even
_Delayms::
xcall push_gset2
.dbline -1
.dbline 40
; 返回值 : success--数据成功标志(为TRUE时写入成功,为FALSE时失败)
; /********************************************/
; uchar AD5161_writeB(uchar devadd,uchar cmd,uchar rdata)
; {
; uchar success=FALSE; //默认返回是写入失败
; Start(); //产生START信号
; Wait(); //等待START信号发送完毕
; if(TestACK()!=START) //检查是否是START信号发送完毕状态
.dbline 42
; {
; success=FALSE; //如果不是,则返回写入失败
clr R20
clr R21
xjmp L10
L7:
.dbline 43
clr R22
clr R23
xjmp L14
L11:
.dbline 43
L12:
.dbline 43
subi R22,255 ; offset = 1
sbci R23,255
L14:
.dbline 43
cpi R22,117
ldi R30,4
cpc R23,R30
brlo L11
L8:
.dbline 42
subi R20,255 ; offset = 1
sbci R21,255
L10:
.dbline 42
cp R20,R16
cpc R21,R17
brlo L7
.dbline -2
.dbline 44
; return success;
; }
L6:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r i 20 i
.dbsym r j 22 i
.dbsym r MS 16 i
.dbend
.dbfunc e Board_init _Board_init fV
.even
_Board_init::
.dbline -1
.dbline 52
; Writebyte(devadd); //发送从器件地址
; Wait(); //等待发送完毕
; if(TestACK()!=MT_SLA_ACK)//检查是否是从器件地址发送完毕状态
; {
; success=FALSE; //如果不是,则返回写入失败
; return success;
; }
; Writebyte(cmd); //发送AD5161的命令字节(具体含义请参看AD5161的数据手册)
.dbline 53
; Wait(); //等待发送完毕
ldi R24,255
out 0x1a,R24
.dbline 54
; if(TestACK()!=MT_DATA_ACK)//检查是否是数据发送完毕
out 0x17,R24
.dbline 55
; {
out 0x14,R24
.dbline 56
; success=FALSE; //如果不是,则返回写入失败
out 0x11,R24
.dbline 58
; return success;
; }
clr R2
out 0xd,R2
.dbline 60
; Writebyte(rdata); //发送电阻值数据
; Wait(); //等待发送完毕
sbi 0x1b,6
.dbline 61
; if(TestACK()!=MT_DATA_ACK)//检查是否是数据发送完毕
cbi 0x15,6
.dbline 62
; {
cbi 0x1b,1
.dbline 63
; success=FALSE; //如果不是,则返回写入失败
out 0x18,R24
.dbline 64
; return success;
sbi 0x1b,2
.dbline 65
; }
ldi R16,5
ldi R17,0
xcall _Delayus
.dbline 66
; Stop(); //对AD5161的一次操作完毕,发送STOP信号
cbi 0x1b,2
.dbline 68
; Delayms(10); //等待发送完毕
; success=TRUE; //本次写入成功
clr R2
out 0x18,R2
.dbline 69
; return success; //返回写入成功状态
sbi 0x1b,3
.dbline 70
; }
ldi R16,50
ldi R17,0
xcall _Delayus
.dbline 71
; /*******************************************
cbi 0x1b,3
.dbline 73
; 函数名称: main
; 功 能: 按键更新数字电位器的阻值(电阻是A和W端的阻值,默认B端是开路的)
ldi R24,255
out 0x18,R24
.dbline 74
; 参 数: 无
sbi 0x1b,4
.dbline 75
; 返回值 : 无
ldi R16,50
ldi R17,0
xcall _Delayus
.dbline 76
; /********************************************/
cbi 0x1b,4
.dbline 78
; void main(void)
; {
ldi R24,255
out 0x12,R24
.dbline 79
; uchar i,data=0; //初始电阻是满量程
sbi 0x1b,7
.dbline 80
; Board_init( ); //初始化开发板
ldi R16,50
ldi R17,0
xcall _Delayus
.dbline 81
; Twi_init( ); //初始化TWI
cbi 0x1b,7
.dbline -2
.dbline 84
; AD5161_writeB(0x58,0x00,data); //设置初始电阻
; while(1)
; {
L15:
.dbline 0 ; func end
ret
.dbend
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\12_TWI(IIC)/Skey.C
.dbfunc e Skey_press _Skey_press fc
; pressed -> R16
.even
_Skey_press::
.dbline -1
.dbline 20
.dbline 22
ldi R24,255
out 0x11,R24
.dbline 23
in R24,0x12
ori R24,15
out 0x12,R24
.dbline 24
ldi R24,240
out 0x11,R24
.dbline 25
in R24,0x10
andi R24,15
cpi R24,15
breq L17
.dbline 26
ldi R16,1
xjmp L18
L17:
.dbline 28
clr R16
L18:
.dbline 29
ldi R24,255
out 0x11,R24
.dbline 30
.dbline -2
L16:
.dbline 0 ; func end
ret
.dbsym r pressed 16 c
.dbend
.dbfunc e Skey_scan _Skey_scan fc
; keycode -> R20
.even
_Skey_scan::
xcall push_gset2
.dbline -1
.dbline 39
.dbline 40
ldi R20,255
.dbline 41
ldi R16,15
ldi R17,0
xcall _Delayms
.dbline 42
xcall _Skey_press
cpi R16,1
brne L20
.dbline 43
.dbline 44
ldi R24,240
out 0x11,R24
.dbline 45
in R20,0x10
.dbline 46
andi R20,15
.dbline 47
mov R22,R20
clr R23
cpi R22,7
ldi R30,0
cpc R23,R30
breq L28
cpi R22,11
ldi R30,0
cpc R23,R30
breq L27
cpi R22,13
ldi R30,0
cpc R23,R30
breq L26
cpi R22,14
ldi R30,0
cpc R23,R30
breq L25
xjmp L22
X0:
.dbline 48
L25:
.dbline 50
clr R20
.dbline 51
xjmp L23
L26:
.dbline 53
ldi R20,1
.dbline 54
xjmp L23
L27:
.dbline 56
ldi R20,2
.dbline 57
xjmp L23
L28:
.dbline 59
ldi R20,3
.dbline 60
xjmp L23
L22:
.dbline 62
clr R20
.dbline 63
L23:
L29:
.dbline 65
.dbline 66
L30:
.dbline 66
xcall _Skey_press
cpi R16,1
breq L29
.dbline 67
L20:
.dbline 68
mov R16,R20
.dbline -2
L19:
xcall pop_gset2
.dbline 0 ; func end
ret
.dbsym r keycode 20 c
.dbend
.dbfile C:\icc\examples.avr\AVR_PQ1A_DEMO\12_TWI(IIC)\AD5161.c
.dbfunc e Twi_init _Twi_init fV
.even
_Twi_init::
.dbline -1
.dbline 22
.dbline 23
ldi R24,32
out 0x0,R24
.dbline 24
clr R2
out 0x1,R2
.dbline 25
ldi R24,68
out 0x36,R24
.dbline -2
.dbline 26
L32:
.dbline 0 ; func end
ret
.dbend
.dbfunc e AD5161_writeB _AD5161_writeB fc
; success -> R20
; rdata -> y+6
; cmd -> R22
; devadd -> R10
.even
_AD5161_writeB::
xcall push_gset3
mov R22,R18
mov R10,R16
.dbline -1
.dbline 36
.dbline 37
clr R20
.dbline 38
ldi R24,164
out 0x36,R24
L34:
.dbline 39
L35:
.dbline 39
in R2,0x36
sbrs R2,7
rjmp L34
.dbline 40
in R24,0x1
andi R24,248
cpi R24,8
breq L37
.dbline 41
.dbline 42
clr R20
.dbline 43
mov R16,R20
xjmp L33
L37:
.dbline 45
.dbline 45
out 0x3,R10
.dbline 45
ldi R24,132
out 0x36,R24
.dbline 45
.dbline 45
L39:
.dbline 46
L40:
.dbline 46
in R2,0x36
sbrs R2,7
rjmp L39
.dbline 47
in R24,0x1
andi R24,248
cpi R24,24
breq L42
.dbline 48
.dbline 49
clr R20
.dbline 50
mov R16,R20
xjmp L33
L42:
.dbline 52
.dbline 52
out 0x3,R22
.dbline 52
ldi R24,132
out 0x36,R24
.dbline 52
.dbline 52
L44:
.dbline 53
L45:
.dbline 53
in R2,0x36
sbrs R2,7
rjmp L44
.dbline 54
in R24,0x1
andi R24,248
cpi R24,40
breq L47
.dbline 55
.dbline 56
clr R20
.dbline 57
mov R16,R20
xjmp L33
L47:
.dbline 59
.dbline 59
ldd R0,y+6
out 0x3,R0
.dbline 59
ldi R24,132
out 0x36,R24
.dbline 59
.dbline 59
L49:
.dbline 60
L50:
.dbline 60
in R2,0x36
sbrs R2,7
rjmp L49
.dbline 61
in R24,0x1
andi R24,248
cpi R24,40
breq L52
.dbline 62
.dbline 63
clr R20
.dbline 64
mov R16,R20
xjmp L33
L52:
.dbline 66
ldi R24,148
out 0x36,R24
.dbline 67
ldi R16,10
ldi R17,0
xcall _Delayms
.dbline 68
ldi R20,1
.dbline 69
mov R16,R20
.dbline -2
L33:
xcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r success 20 c
.dbsym l rdata 6 c
.dbsym r cmd 22 c
.dbsym r devadd 10 c
.dbend
.dbfunc e main _main fV
; data -> R20
; i -> R10
.even
_main::
sbiw R28,1
.dbline -1
.dbline 78
.dbline 79
clr R20
.dbline 80
xcall _Board_init
.dbline 81
xcall _Twi_init
.dbline 82
std y+0,R20
clr R18
ldi R16,88
xcall _AD5161_writeB
xjmp L56
L55:
.dbline 84
.dbline 85
; if(Skey_press()) //是否有按键按下
xcall _Skey_press
tst R16
breq L58
.dbline 86
; {
.dbline 87
; i=Skey_scan(); //扫描并反回翻译后的键码
xcall _Skey_scan
mov R10,R16
.dbline 88
; switch(i)
mov R22,R10
clr R23
cpi R22,0
cpc R22,R23
breq L63
X1:
cpi R22,1
ldi R30,0
cpc R23,R30
breq L64
cpi R22,2
ldi R30,0
cpc R23,R30
breq L65
cpi R22,3
ldi R30,0
cpc R23,R30
breq L66
xjmp L60
X2:
.dbline 89
; {
L63:
.dbline 91
; case 0: //S1键按下,减少电阻的数字量(AD5161的特性是减少电阻的数字量,阻值增加)
; data-=16;
subi R20,16
.dbline 92
; break;
xjmp L61
L64:
.dbline 94
; case 1: //S2键按下,增加电阻的数字量
; data+=16;
subi R20,240 ; addi 16
.dbline 95
; break;
xjmp L61
L65:
.dbline 97
; case 2: //S3键按下,使电阻的数字量为零(阻值满量程)
; data=0;
clr R20
.dbline 98
; break;
xjmp L61
L66:
.dbline 100
; case 3: //S3键按下,使电阻的数字量为满(阻值清零,只剩下接触电阻)
; data=255;
ldi R20,255
.dbline 101
; break;
L60:
L61:
.dbline 103
; }
; AD5161_writeB(0x58,0x00,data); //更新电阻
std y+0,R20
clr R18
ldi R16,88
xcall _AD5161_writeB
.dbline 104
; }
L58:
.dbline 105
L56:
.dbline 83
xjmp L55
X3:
.dbline -2
.dbline 106
; }
; }
L54:
adiw R28,1
.dbline 0 ; func end
ret
.dbsym r data 20 c
.dbsym r i 10 c
.dbend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -