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

📄 at45db041d.s

📁 用ATMEGA16的硬件SPI驱动AT45DB041D
💻 S
📖 第 1 页 / 共 5 页
字号:
	.module AT45DB041D.c
	.area text(rom, con, rel)
	.dbfile E:\item\car\AT45DB041D\AT45DB041D.c
	.dbfunc e DF_Delay _DF_Delay fV
;              i -> R20,R21
;              j -> R22,R23
;              n -> R16,R17
	.even
_DF_Delay::
	xcall push_xgsetF000
	.dbline -1
	.dbline 27
; /************************************************************
; *本驱动只用于AT45DB041D默认页大小为264的情况
; *页改为256后可以有些不同
; *页的大小只能改一次(从264改为256),不能改回
; ************************************************************/
; #include <iom16v.h>
; #include <macros.h>
; #include "AT45DB041D.h"
; #include "eeprom.h"
; 
; /************************************************************
; *SPI宏定义
; ************************************************************/
; #define  SPI_DDR    	 DDRB
; #define  SPI_PORT   	 PORTB
; 
; #define  RESET           3
; #define  SS              4
; #define  MOSI            5
; #define  MISO            6
; #define  SCK             7
; 
; /************************************************************
; *延时函数
; ************************************************************/
; void DF_Delay(unsigned int n)
; {
	.dbline 30
;   unsigned int i;
;   unsigned int j;
;   for(i=0;i<n;i++)
	clr R20
	clr R21
	xjmp L5
L2:
	.dbline 31
;   {
	.dbline 32
;     for(j=0;j<255;j++)
	clr R22
	clr R23
	xjmp L9
L6:
	.dbline 33
; 	{
	.dbline 34
; 	  asm("nop");
	nop
	.dbline 35
; 	}
L7:
	.dbline 32
	subi R22,255  ; offset = 1
	sbci R23,255
L9:
	.dbline 32
	cpi R22,255
	ldi R30,0
	cpc R23,R30
	brlo L6
X0:
	.dbline 36
;   }
L3:
	.dbline 30
	subi R20,255  ; offset = 1
	sbci R21,255
L5:
	.dbline 30
	cp R20,R16
	cpc R21,R17
	brlo L2
X1:
	.dbline -2
L1:
	.dbline 0 ; func end
	xjmp pop_xgsetF000
	.dbsym r i 20 i
	.dbsym r j 22 i
	.dbsym r n 16 i
	.dbend
	.dbfunc e SPI_Port_Init _SPI_Port_Init fV
	.even
_SPI_Port_Init::
	.dbline -1
	.dbline 42
; }
; /************************************************************
; *Init SPI Port
; ************************************************************/
; void SPI_Port_Init(void)
; {
	.dbline 43
;   SPI_DDR  |= ((1<<SS)|(1<<SCK)|(1<<MOSI));//设为输出
	in R24,0x17
	ori R24,176
	out 0x17,R24
	.dbline 44
;   SPI_DDR  &=~ (1<<MISO);                  //设为输入
	cbi 0x17,6
	.dbline 45
;   SPI_PORT |= (1<<SS)|(1<<SCK)|(1<<MOSI);  //输出高电平
	in R24,0x18
	ori R24,176
	out 0x18,R24
	.dbline 46
;   SPI_PORT |= (1<<MOSI);				   //上拉
	sbi 0x18,5
	.dbline 48
; 
;   SPI_DDR|=(1<<RESET);                     //复位引脚设为输出
	sbi 0x17,3
	.dbline -2
L10:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e SPI_Init _SPI_Init fV
	.even
_SPI_Init::
	.dbline -1
	.dbline 54
; }
; /************************************************************
; *初始化SPI
; ************************************************************/
; void SPI_Init(void)//最高能到fOSC/16
; {
	.dbline 55
;   SPI_Port_Init();
	xcall _SPI_Port_Init
	.dbline 58
;   
;   //SPI使能, master模式, MSB 前,  SPI 模式 3, SCK频率Fcl/4 平时SCK为高电平
;   SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<CPOL);
	in R24,0xd
	ori R24,92
	out 0xd,R24
	.dbline 60
;   //频率加倍
;   SPSR |= (1<<SPI2X);
	sbi 0xe,0
	.dbline -2
L11:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e SPI_Start _SPI_Start fV
	.even
_SPI_Start::
	.dbline -1
	.dbline 66
; }
; /************************************************************
; *使能SPI
; ************************************************************/
; void SPI_Start(void)
; {
	.dbline 67
;  	 SPCR |= (1<<SPE);
	sbi 0xd,6
	.dbline -2
L12:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e SPI_Stop _SPI_Stop fV
	.even
_SPI_Stop::
	.dbline -1
	.dbline 73
; }
; /************************************************************
; *禁止SPI
; ************************************************************/
; void SPI_Stop(void)
; {
	.dbline 74
;  	 SPCR &=~ (1<<SPE);
	cbi 0xd,6
	.dbline -2
L13:
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e SPI_Write_Byte _SPI_Write_Byte fV
;          cData -> R16
	.even
_SPI_Write_Byte::
	.dbline -1
	.dbline 80
; }
; /************************************************************
; *SPI send a Byte
; ************************************************************/
; void SPI_Write_Byte(unsigned char cData)
; {
	.dbline 81
;   SPDR = cData;                //write data
	out 0xf,R16
L15:
	.dbline 82
;   while(!(SPSR & (1<<SPIF)));  //wait write ok
L16:
	.dbline 82
	sbis 0xe,7
	rjmp L15
X2:
	.dbline -2
L14:
	.dbline 0 ; func end
	ret
	.dbsym r cData 16 c
	.dbend
	.dbfunc e SPI_Write_Bytes _SPI_Write_Bytes fV
;              i -> R20,R21
;        DataLen -> R18,R19
;          cData -> R16,R17
	.even
_SPI_Write_Bytes::
	st -y,R20
	st -y,R21
	.dbline -1
	.dbline 88
; }
; /************************************************************
; *SPI send  Bytes
; ************************************************************/
; void SPI_Write_Bytes(unsigned char *cData,unsigned int DataLen)
; {
	.dbline 90
;   unsigned int i;
;   for(i=0;i<DataLen;i++)
	clr R20
	clr R21
	xjmp L22
L19:
	.dbline 91
;   {
	.dbline 92
;     SPDR = *(cData+i);           //write data
	movw R30,R20
	add R30,R16
	adc R31,R17
	ldd R2,z+0
	out 0xf,R2
L23:
	.dbline 93
; 	while(!(SPSR & (1<<SPIF)));  //wait write ok
L24:
	.dbline 93
	sbis 0xe,7
	rjmp L23
X3:
	.dbline 94
;   }
L20:
	.dbline 90
	subi R20,255  ; offset = 1
	sbci R21,255
L22:
	.dbline 90
	cp R20,R18
	cpc R21,R19
	brlo L19
X4:
	.dbline -2
L18:
	.dbline 0 ; func end
	ld R21,y+
	ld R20,y+
	ret
	.dbsym r i 20 i
	.dbsym r DataLen 18 i
	.dbsym r cData 16 pc
	.dbend
	.dbfunc e SPI_Read_Byte _SPI_Read_Byte fc
;          cData -> R16
	.even
_SPI_Read_Byte::
	.dbline -1
	.dbline 100
; }
; /************************************************************
; *SPI Read char
; ************************************************************/
; unsigned char SPI_Read_Byte(unsigned char cData)
; {
	.dbline 101
;   SPDR = cData;                //write data
	out 0xf,R16
L27:
	.dbline 102
;   while(!(SPSR & (1<<SPIF)));  //wait receive ok
L28:
	.dbline 102
	sbis 0xe,7
	rjmp L27
X5:
	.dbline 103
;   return SPDR;                 //返回数据
	in R16,0xf
	.dbline -2
L26:
	.dbline 0 ; func end
	ret
	.dbsym r cData 16 c
	.dbend
	.dbfunc e Enable_DFLASH _Enable_DFLASH fV
;              i -> R16
	.even
_Enable_DFLASH::
	.dbline -1
	.dbline 109
; }
; /************************************************************
; *使能FLASH(低电平使能)
; ************************************************************/
; void Enable_DFLASH(void)
; {
	.dbline 110
;   unsigned char i=255;
	ldi R16,255
L31:
	.dbline 111
;   while(i--);			//延长上一次高电平时间
L32:
	.dbline 111
	mov R2,R16
	clr R3
	subi R16,1
	tst R2
	brne L31
X6:
	.dbline 112
;   SPI_PORT&=~(1<<SS);
	cbi 0x18,4
	.dbline -2
L30:
	.dbline 0 ; func end
	ret
	.dbsym r i 16 c
	.dbend
	.dbfunc e Disable_DFLASH _Disable_DFLASH fV
;              i -> R16
	.even
_Disable_DFLASH::
	.dbline -1
	.dbline 118
; }
; /************************************************************
; *禁止FLASH(高电平禁止)
; ************************************************************/
; void Disable_DFLASH(void)
; {
	.dbline 119
;   unsigned char i=255;
	ldi R16,255
	.dbline 120
;   SPI_PORT|=(1<<SS);	
	sbi 0x18,4
L35:
	.dbline 121
;   while(i--);			//延长高电平时间
L36:
	.dbline 121
	mov R2,R16
	clr R3
	subi R16,1
	tst R2
	brne L35
X7:
	.dbline -2
L34:
	.dbline 0 ; func end
	ret
	.dbsym r i 16 c
	.dbend
	.dbfunc e DF_Read_status_Register _DF_Read_status_Register fc
;          rData -> R10
	.even
_DF_Read_status_Register::
	st -y,R10
	.dbline -1
	.dbline 130
; }
; /************************************************************
; *读取FLASH内部状态寄存器
; *Bit 7:Ready/busy status (1:no busy ; 0:busy)
; *Bit 6:Compare (1: no matche ; 0:matche) 最近的一次比较结果
; *Bit 0:PAGE SIZE (1:256 bytes ; 0:264 bytes)
; ************************************************************/
; unsigned char DF_Read_status_Register(void)
; {
	.dbline 131
;   unsigned char rData=0;
	.dbline 132
;   Enable_DFLASH();
	xcall _Enable_DFLASH
	.dbline 134
; 
;   SPI_Write_Byte(Status_Register_Opcode);//write opcode
	ldi R16,215
	xcall _SPI_Write_Byte
	.dbline 136
; 
;   rData = SPI_Read_Byte(0x00);//read device's status
	clr R16
	xcall _SPI_Read_Byte
	mov R10,R16
	.dbline 138
; 
;   Disable_DFLASH();
	xcall _Disable_DFLASH
	.dbline 140
; 
;   return rData;
	mov R16,R10
	.dbline -2
L38:
	.dbline 0 ; func end
	ld R10,y+
	ret
	.dbsym r rData 10 c
	.dbend
	.dbfunc e DF_Check_Page_Size _DF_Check_Page_Size fc
;      Page_Size -> R10
	.even
_DF_Check_Page_Size::
	st -y,R10
	.dbline -1
	.dbline 147
; }
; /************************************************************
; *读取FLASH的页大小
; *返回1表示每一页的大小为264 bytes,否则为256 bytes
; ************************************************************/
; unsigned char DF_Check_Page_Size(void)
; {
	.dbline 149
;   unsigned char Page_Size;
;   Page_Size=DF_Read_status_Register();
	xcall _DF_Read_status_Register
	mov R10,R16
	.dbline 150
;   if(Page_Size&0x01) return 0;
	sbrs R16,0
	rjmp L40
X8:
	.dbline 150
	clr R16
	xjmp L39
L40:
	.dbline 151
;   return 1;
	ldi R16,1
	.dbline -2
L39:
	.dbline 0 ; func end
	ld R10,y+
	ret
	.dbsym r Page_Size 10 c
	.dbend
	.dbfunc e DF_Check_Busy_State _DF_Check_Busy_State fc
;          state -> R10
;              i -> R20
	.even
_DF_Check_Busy_State::
	st -y,R10
	st -y,R20
	.dbline -1
	.dbline 157
; }
; /************************************************************
; *读取FLASH忙标志位(最多判断255次,不行还是返回且返回0)
; ************************************************************/
; unsigned char DF_Check_Busy_State(void)
; {
	.dbline 159
;   unsigned char state;
;   unsigned char i=255;
	ldi R20,255
	xjmp L44
L43:
	.dbline 161
;   while(i)
;   {
	.dbline 162
;      state=DF_Read_status_Register();
	xcall _DF_Read_status_Register
	mov R10,R16
	.dbline 163
; 	 if(state & 0x80) break;		//读取的最高位0时器件忙
	sbrs R16,7
	rjmp L46
X9:
	.dbline 163
	xjmp L45
L46:
	.dbline 164
; 	 --i;
	dec R20
	.dbline 165
;   }
L44:
	.dbline 160
	tst R20
	brne L43
X10:
L45:
	.dbline 166
;   return i;
	mov R16,R20
	.dbline -2
L42:
	.dbline 0 ; func end
	ld R20,y+
	ld R10,y+
	ret
	.dbsym r state 10 c
	.dbsym r i 20 c
	.dbend
	.dbfunc e DF_Manufacturer_and_Device_ID _DF_Manufacturer_and_Device_ID fV
;              i -> R20
;             ID -> R10,R11
	.even
_DF_Manufacturer_and_Device_ID::
	xcall push_xgset300C
	movw R10,R16
	.dbline -1
	.dbline 175
; }
; /************************************************************
; *读取FLASH的产家ID的芯片ID等内容;
; *以下函数会返回四个值,第一个数对AT45DB041D来说为0x1F;
; *第四个数为 0x00;
; *用此函数可以判断芯片的好坏,是否正常;
; ************************************************************/
; void DF_Manufacturer_and_Device_ID(unsigned char *ID)
; {
	.dbline 178
;   unsigned char i;
; 
;   DF_Check_Busy_State();
	xcall _DF_Check_Busy_State
	.dbline 180
; 
;   Enable_DFLASH();
	xcall _Enable_DFLASH
	.dbline 182
; 
;   SPI_Write_Byte(Device_ID_Opcode);
	ldi R16,159
	xcall _SPI_Write_Byte
	.dbline 184
; 
;   for(i=0;i<4;i++)
	clr R20
	xjmp L52
L49:
	.dbline 185
;   {
	.dbline 186
;     ID[i] = SPI_Read_Byte(0);
	clr R16
	xcall _SPI_Read_Byte
	mov R30,R20
	clr R31
	add R30,R10
	adc R31,R11
	std z+0,R16
	.dbline 187
;   }
L50:
	.dbline 184
	inc R20
L52:
	.dbline 184
	cpi R20,4
	brlo L49
X11:
	.dbline 189
; 
;   Disable_DFLASH();
	xcall _Disable_DFLASH
	.dbline -2
L48:
	.dbline 0 ; func end
	xjmp pop_xgset300C
	.dbsym r i 20 c
	.dbsym r ID 10 pc
	.dbend
	.dbfunc e Test_Manufacturer_ID _Test_Manufacturer_ID fc
;       Test_Buf -> y+0
	.even
_Test_Manufacturer_ID::
	sbiw R28,4
	.dbline -1
	.dbline 195
; }
; /************************************************************
; *测试FLASH产家ID,正常返回1,否则返回0
; ************************************************************/
; unsigned char Test_Manufacturer_ID(void)
; {
	.dbline 197
;   unsigned char Test_Buf[4];
;   DF_Manufacturer_and_Device_ID(Test_Buf);
	movw R16,R28
	xcall _DF_Manufacturer_and_Device_ID

⌨️ 快捷键说明

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