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

📄 max5478.s

📁 Max5479 数字电位器的驱动源程序 用M16来实现C语言的编程!
💻 S
字号:
	.module MAX5478.C
	.area text(rom, con, rel)
	.dbfile E:\程序与资料\dpj\AVR\自己写的AVR\MAX5478\MAX5478.C
	.dbfunc e Delayms _Delayms fV
;              i -> R10,R11
;              j -> R12,R13
;             MS -> R16,R17
	.even
_Delayms::
	xcall push_xgset003C
	.dbline -1
	.dbline 23
; /***************MAX5478数字电位器-I2C**********************/
; #include <iom16v.h>			//包含型号头文件
; #include <macros.h>			//包含"位"操作头文件
; #include <stdio.h>			//标准输入输出头文件
; /******************数据类型宏定义******************/
; #define TRUE  1
; #define FALSE 0
; #define uchar unsigned char
; #define uint unsigned int
; //******************按键常量******************/
; #define KEY_DDR DDRD			//按键方向定义
; #define KEY_PORTO PORTD			//按键端口输出定义
; #define KEY_PORTI PIND			//按键端口输入定义
; #define OUT 0xFF			//输出常量
; #define IN  0xF0			//输入常量
; /*******************************************
; 函数名称: Delayms
; 功    能: 延时指定毫秒(12M晶振)
; 参    数: MS--延时的毫秒数
; 返回值  : 无
; /********************************************/
; void Delayms(uint MS)		  
; {
	.dbline 25
;  uint i,j;
;  for( i=0;i<MS;i++)
	clr R10
	clr R11
	xjmp L5
L2:
	.dbline 26
;  for(j=0;j<1141;j++);	//1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
	clr R12
	clr R13
	xjmp L9
L6:
	.dbline 26
L7:
	.dbline 26
	movw R24,R12
	adiw R24,1
	movw R12,R24
L9:
	.dbline 26
	movw R24,R12
	cpi R24,117
	ldi R30,4
	cpc R25,R30
	brlo L6
X0:
L3:
	.dbline 25
	movw R24,R10
	adiw R24,1
	movw R10,R24
L5:
	.dbline 25
	cp R10,R16
	cpc R11,R17
	brlo L2
X1:
	.dbline -2
L1:
	.dbline 0 ; func end
	xjmp pop_xgset003C
	.dbsym r i 10 i
	.dbsym r j 12 i
	.dbsym r MS 16 i
	.dbend
	.dbfile E:\程序与资料\dpj\AVR\自己写的AVR\MAX5478\Skey.C
	.dbfunc e Skey_press _Skey_press fc
;        pressed -> R16
	.even
_Skey_press::
	.dbline -1
	.dbline 10
; 
; 
; /*******************************************
; 函数名称: Skey_press
; 功    能: 检测是否有键按下
; 参    数: 无
; 返回值  : pressed--有键按下时为TRUE,否则为FALSE
; /********************************************/
; uchar Skey_press(void)
; {
	.dbline 12
;  uchar pressed;		 		
;  KEY_DDR=OUT;			//定义数据端口为输出
	ldi R24,255
	out 0x11,R24
	.dbline 13
;  KEY_PORTO|=0x0F;		//输出数据(输出检测码)
	in R24,0x12
	ori R24,15
	out 0x12,R24
	.dbline 14
;  KEY_DDR=IN;				//定义数据端口为输入
	ldi R24,240
	out 0x11,R24
	.dbline 15
;  if((KEY_PORTI&0x0F)!=0x0F)	//检测是否有键按下
	in R24,0x10
	andi R24,15
	cpi R24,15
	breq L11
X2:
	.dbline 16
;  	pressed=TRUE;			//有键按下则返回TRUE
	ldi R16,1
	xjmp L12
L11:
	.dbline 18
;  else
;  	pressed=FALSE;			//无键按下则返回FALSE
	clr R16
L12:
	.dbline 19
;  KEY_DDR=OUT;				//数据端口还原为输出
	ldi R24,255
	out 0x11,R24
	.dbline 20
;  return pressed;
	.dbline -2
L10:
	.dbline 0 ; func end
	ret
	.dbsym r pressed 16 c
	.dbend
	.dbfunc e Skey_scan _Skey_scan fc
;        keycode -> R10
	.even
_Skey_scan::
	xcall push_xgset003C
	.dbline -1
	.dbline 29
; }
; /*******************************************
; 函数名称: Skey_scan
; 功    能: 扫描所按的键并返回键值
; 参    数: 无
; 返回值  : keycode--被按下键值
; /********************************************/
; uchar Skey_scan(void)
; {
	.dbline 30
;  uchar keycode=0xFF;
	ldi R24,255
	mov R10,R24
	.dbline 31
;  Delayms(15);		 		//延时消抖
	ldi R16,15
	ldi R17,0
	xcall _Delayms
	.dbline 32
;  if(Skey_press()==TRUE)		//如果有键按下
	xcall _Skey_press
	cpi R16,1
	brne L14
X3:
	.dbline 33
;  {
	.dbline 34
;     KEY_DDR=IN;				//定义数据端口为输入
	ldi R24,240
	out 0x11,R24
	.dbline 35
; 	keycode=KEY_PORTI;		//读入原始键码
	in R10,0x10
	.dbline 36
; 	keycode&=0x0F;			//屏蔽高4位
	mov R24,R10
	andi R24,15
	mov R10,R24
	.dbline 37
; 	switch(keycode)			//翻译原始键码为0~3
	mov R12,R24
	clr R13
	movw R24,R12
	cpi R24,7
	ldi R30,0
	cpc R25,R30
	breq L22
X4:
	cpi R24,11
	ldi R30,0
	cpc R25,R30
	breq L21
X5:
	cpi R24,13
	ldi R30,0
	cpc R25,R30
	breq L20
X6:
	cpi R24,14
	ldi R30,0
	cpc R25,R30
	breq L19
X7:
	xjmp L16
L19:
	.dbline 40
; 	{
; 	   case 0x0E:
; 	   		keycode=0;
	clr R10
	.dbline 41
; 			break;
	xjmp L17
L20:
	.dbline 43
; 	   case 0x0D:
; 	   		keycode=1;
	clr R10
	inc R10
	.dbline 44
; 			break;
	xjmp L17
L21:
	.dbline 46
; 	   case 0x0B:
; 	   		keycode=2;
	ldi R24,2
	mov R10,R24
	.dbline 47
; 			break;
	xjmp L17
L22:
	.dbline 49
; 	   case 0x07:
; 	   		keycode=3;
	ldi R24,3
	mov R10,R24
	.dbline 50
; 			break;
	xjmp L17
L16:
	.dbline 52
; 	   default:
; 	        keycode=0x00;
	clr R10
	.dbline 53
; 	}
L17:
L23:
	.dbline 55
; 	do
; 	{
	.dbline 56
; 	}while(Skey_press()==TRUE);	//等待按键释放(为了防止按一次,执行多次的现象)
L24:
	.dbline 56
	xcall _Skey_press
	cpi R16,1
	breq L23
X8:
	.dbline 57
;  }
L14:
	.dbline 58
;  return keycode;
	mov R16,R10
	.dbline -2
L13:
	.dbline 0 ; func end
	xjmp pop_xgset003C
	.dbsym r keycode 10 c
	.dbend
	.dbfile E:\程序与资料\dpj\AVR\自己写的AVR\MAX5478\MAX5478.C
	.dbfunc e Twi_init _Twi_init fV
	.even
_Twi_init::
	.dbline -1
	.dbline 45
; }
; //************************************************
; #include "Skey.C"			//包含键盘扫描函数
; /******************TWI(IIC)常量******************/
; #define START 0x08			//START信号发送完毕状态
; #define MT_SLA_ACK 0x18		//从器件地址发送,返回ACK
; #define MT_SLA_NOACK 0x20	//从器件地址发送,但是返回NOACK
; #define MT_DATA_ACK  0x28	//数据已发送,返回ACK
; #define MT_DATA_NOACK 0x30	//数据已发送,返回NOACK
; 
; #define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))	//产生START信号
; #define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))	//产生STOP信号
; #define Wait() while(!(TWCR&(1<<TWINT)))		//等待当前操作完成
; #define TestACK() (TWSR&0xF8)				//取出状态码
; #define SetACK() (TWCR|=(1<<TWEA))			//产生ACK
; #define Writebyte(twi_d) {TWDR=(twi_d);TWCR=(1<<TWINT)|(1<<TWEN);}	//发送一个字节(twi_d为写入的数据)
; //************************************************************************************************************
; void Twi_init(void)
; {
	.dbline 46
;  TWBR= 0x20; //设置波特率
	ldi R24,32
	out 0x0,R24
	.dbline 47
;  TWSR= 0x00; //设置预分频比
	clr R2
	out 0x1,R2
	.dbline 48
;  TWCR= 0x44; //使能应答,使能TWI
	ldi R24,68
	out 0x36,R24
	.dbline -2
L26:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e MAX5478_writeB _MAX5478_writeB fc
;        success -> R10
;          rdata -> y+6
;            cmd -> R12
;         devadd -> R14
	.even
_MAX5478_writeB::
	xcall push_xgset00FC
	mov R12,R18
	mov R14,R16
	.dbline -1
	.dbline 60
; }
; 
; /*******************************************
; 函数名称: MAX5478_writeB
; 功    能: 向MAX5478写入电阻值数据
; 参    数: devadd--器件地址
; 	  	  cmd--控制命令
; 		  rdata--电阻数据
; 返回值  : success--数据成功标志(为TRUE时写入成功,为FALSE时失败)
; /********************************************/
; uchar MAX5478_writeB(uchar devadd,uchar cmd,uchar rdata)
; {
	.dbline 61
;  uchar success=FALSE;	  //默认返回是写入失败
	clr R10
	.dbline 62
;  Start();				  //产生START信号
	ldi R24,164
	out 0x36,R24
L28:
	.dbline 63
;  Wait();				  //等待START信号发送完毕
L29:
	.dbline 63
	in R2,0x36
	sbrs R2,7
	rjmp L28
X9:
	.dbline 64
;  if(TestACK()!=START)	  //检查是否是START信号发送完毕状态
	in R24,0x1
	andi R24,248
	cpi R24,8
	breq L31
X10:
	.dbline 65
;  {
	.dbline 66
;   success=FALSE;  		  //如果不是,则返回写入失败
	clr R10
	.dbline 67
;   return success;
	mov R16,R10
	xjmp L27
L31:
	.dbline 69
;  }
;  Writebyte(devadd);		  //发送从器件地址
	.dbline 69
	out 0x3,R14
	.dbline 69
	ldi R24,132
	out 0x36,R24
	.dbline 69
	.dbline 69
L33:
	.dbline 70
;  Wait();				  //等待发送完毕
L34:
	.dbline 70
	in R2,0x36
	sbrs R2,7
	rjmp L33
X11:
	.dbline 71
;  if(TestACK()!=MT_SLA_ACK)//检查是否是从器件地址发送完毕状态
	in R24,0x1
	andi R24,248
	cpi R24,24
	breq L36
X12:
	.dbline 72
;  {
	.dbline 73
;   success=FALSE;		  //如果不是,则返回写入失败
	clr R10
	.dbline 74
;   return success;
	mov R16,R10
	xjmp L27
L36:
	.dbline 76
;  }
;  Writebyte(cmd); 		  //发送MAX5478的命令字节(具体含义请参看MAX5478的数据手册)
	.dbline 76
	out 0x3,R12
	.dbline 76
	ldi R24,132
	out 0x36,R24
	.dbline 76
	.dbline 76
L38:
	.dbline 77
;  Wait();				  //等待发送完毕
L39:
	.dbline 77
	in R2,0x36
	sbrs R2,7
	rjmp L38
X13:
	.dbline 78
;  if(TestACK()!=MT_DATA_ACK)//检查是否是数据发送完毕
	in R24,0x1
	andi R24,248
	cpi R24,40
	breq L41
X14:
	.dbline 79
;  {
	.dbline 80
;   success=FALSE;		  //如果不是,则返回写入失败
	clr R10
	.dbline 81
;   return success;
	mov R16,R10
	xjmp L27
L41:
	.dbline 83
;  }
;  Writebyte(rdata);		  //发送电阻值数据
	.dbline 83
	ldd R0,y+6
	out 0x3,R0
	.dbline 83
	ldi R24,132
	out 0x36,R24
	.dbline 83
	.dbline 83
L43:
	.dbline 84
;  Wait();				  //等待发送完毕
L44:
	.dbline 84
	in R2,0x36
	sbrs R2,7
	rjmp L43
X15:
	.dbline 85
;  if(TestACK()!=MT_DATA_ACK)//检查是否是数据发送完毕
	in R24,0x1
	andi R24,248
	cpi R24,40
	breq L46
X16:
	.dbline 86
;  {
	.dbline 87
;   success=FALSE;		  //如果不是,则返回写入失败
	clr R10
	.dbline 88
;   return success;
	mov R16,R10
	xjmp L27
L46:
	.dbline 90
;  }
;  Stop(); 		 		  //对MAX5478的一次操作完毕,发送STOP信号
	ldi R24,148
	out 0x36,R24
	.dbline 91
;  Delayms(10);			  //等待发送完毕
	ldi R16,10
	ldi R17,0
	xcall _Delayms
	.dbline 92
;  success=TRUE;			  //本次写入成功
	clr R10
	inc R10
	.dbline 93
;  return success;		  //返回写入成功状态
	mov R16,R10
	.dbline -2
L27:
	.dbline 0 ; func end
	xjmp pop_xgset00FC
	.dbsym r success 10 c
	.dbsym l rdata 6 c
	.dbsym r cmd 12 c
	.dbsym r devadd 14 c
	.dbend
	.dbfunc e main _main fV
;           data -> R10
;              i -> R12
	.even
_main::
	sbiw R28,1
	.dbline -1
	.dbline 102
; }
; /*******************************************
; 函数名称: main
; 功    能: 按键更新数字电位器的阻值(电阻是A和W端的阻值,默认B端是开路的)
; 参    数: 无
; 返回值  : 无
; /********************************************/
; void main(void)
; {
	.dbline 103
;  uchar i,data=255;  //初始电阻是满量程
	ldi R24,255
	mov R10,R24
	.dbline 105
;  
;  Twi_init( );	  //初始化TWI 
	xcall _Twi_init
	.dbline 106
;  MAX5478_writeB(0x50,0x13,data);	//设置初始电阻
	std y+0,R10
	ldi R18,19
	ldi R16,80
	xcall _MAX5478_writeB
	xjmp L50
L49:
	.dbline 108
;  while(1)
;  {
	.dbline 109
;   if(Skey_press())	  		//是否有按键按下
	xcall _Skey_press
	tst R16
	breq L52
X17:
	.dbline 110
;   {
	.dbline 111
;    i=Skey_scan();	  		//扫描并反回翻译后的键码
	xcall _Skey_scan
	mov R12,R16
	.dbline 112
;    switch(i)
	clr R13
	tst R12
	brne X18
	tst R13
	breq L57
X18:
	movw R24,R12
	cpi R24,1
	ldi R30,0
	cpc R25,R30
	breq L58
X19:
	cpi R24,2
	ldi R30,0
	cpc R25,R30
	breq L59
X20:
	cpi R24,3
	ldi R30,0
	cpc R25,R30
	breq L60
X21:
	xjmp L54
L57:
	.dbline 115
;    {
;    	case 0:					//S1键按下,减少电阻的数字量(MAX5478的特性是减少电阻的数字量,阻值增加)
; 		 data-=5;
	mov R24,R10
	subi R24,5
	mov R10,R24
	.dbline 116
; 		 break;
	xjmp L55
L58:
	.dbline 118
; 	case 1:	   	  			//S2键按下,增加电阻的数字量
; 		 data+=5;
	mov R24,R10
	subi R24,251    ; addi 5
	mov R10,R24
	.dbline 119
; 		 break;
	xjmp L55
L59:
	.dbline 121
; 	case 2:	   	  			//S3键按下,使电阻的数字量为零(阻值满量程)
; 		 data=0;
	clr R10
	.dbline 122
; 		 break;
	xjmp L55
L60:
	.dbline 124
; 	case 3:	   				//S3键按下,使电阻的数字量为满(阻值清零,只剩下接触电阻)
; 		 data=255;
	ldi R24,255
	mov R10,R24
	.dbline 125
; 		 break;
L54:
L55:
	.dbline 127
;    }
;    MAX5478_writeB(0x50,0x13,data);  //更新电阻
	std y+0,R10
	ldi R18,19
	ldi R16,80
	xcall _MAX5478_writeB
	.dbline 128
;    Delayms(5);	
	ldi R16,5
	ldi R17,0
	xcall _Delayms
	.dbline 129
;   }
L52:
	.dbline 130
;  }
L50:
	.dbline 107
	xjmp L49
X22:
	.dbline -2
L48:
	.dbline 0 ; func end
	adiw R28,1
	ret
	.dbsym r data 10 c
	.dbsym r i 12 c
	.dbend
; }	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -