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

📄 at45db041d.lst

📁 用ATMEGA16的硬件SPI驱动AT45DB041D
💻 LST
📖 第 1 页 / 共 5 页
字号:
__start:
__text_start:
      6A E5CF      LDI	R28,0x5F
      6B E0D4      LDI	R29,4
      6C BFCD      OUT	0x3D,R28
      6D BFDE      OUT	0x3E,R29
      6E 51CE      SUBI	R28,0x1E
      6F 40D0      SBCI	R29,0
      70 EA0A      LDI	R16,0xAA
      71 8308      STD	Y+0,R16
      72 2400      CLR	R0
      73 E6E0      LDI	R30,0x60
      74 E0F0      LDI	R31,0
      75 E010      LDI	R17,0
      76 36E0      CPI	R30,0x60
      77 07F1      CPC	R31,R17
      78 F011      BEQ	0x007B
      79 9201      ST	R0,Z+
      7A CFFB      RJMP	0x0076
      7B 8300      STD	Z+0,R16
      7C EDE4      LDI	R30,0xD4
      7D E0F0      LDI	R31,0
      7E E6A0      LDI	R26,0x60
      7F E0B0      LDI	R27,0
      80 E010      LDI	R17,0
      81 E000      LDI	R16,0
      82 BF0B      OUT	0x3B,R16
      83 3DE4      CPI	R30,0xD4
      84 07F1      CPC	R31,R17
      85 F021      BEQ	0x008A
      86 95C8      LPM
      87 9631      ADIW	R30,1
      88 920D      ST	R0,X+
      89 CFF9      RJMP	0x0083
      8A 940E 0544 CALL	_main
_exit:
      8C CFFF      RJMP	_exit
_DF_Delay:
  i                    --> R20
  j                    --> R22
  n                    --> R16
      8D 940E 0573 CALL	push_xgsetF000
FILE: E:\item\car\AT45DB041D\AT45DB041D.c
(0001) /************************************************************
(0002) *本驱动只用于AT45DB041D默认页大小为264的情况
(0003) *页改为256后可以有些不同
(0004) *页的大小只能改一次(从264改为256),不能改回
(0005) ************************************************************/
(0006) #include <iom16v.h>
(0007) #include <macros.h>
(0008) #include "AT45DB041D.h"
(0009) #include "eeprom.h"
(0010) 
(0011) /************************************************************
(0012) *SPI宏定义
(0013) ************************************************************/
(0014) #define  SPI_DDR    	 DDRB
(0015) #define  SPI_PORT   	 PORTB
(0016) 
(0017) #define  RESET           3
(0018) #define  SS              4
(0019) #define  MOSI            5
(0020) #define  MISO            6
(0021) #define  SCK             7
(0022) 
(0023) /************************************************************
(0024) *延时函数
(0025) ************************************************************/
(0026) void DF_Delay(unsigned int n)
(0027) {
(0028)   unsigned int i;
(0029)   unsigned int j;
(0030)   for(i=0;i<n;i++)
      8F 2744      CLR	R20
      90 2755      CLR	R21
      91 C00C      RJMP	0x009E
(0031)   {
(0032)     for(j=0;j<255;j++)
      92 2766      CLR	R22
      93 2777      CLR	R23
      94 C003      RJMP	0x0098
(0033) 	{
(0034) 	  asm("nop");
      95 0000      NOP
      96 5F6F      SUBI	R22,0xFF
      97 4F7F      SBCI	R23,0xFF
      98 3F6F      CPI	R22,0xFF
      99 E0E0      LDI	R30,0
      9A 077E      CPC	R23,R30
      9B F3C8      BCS	0x0095
      9C 5F4F      SUBI	R20,0xFF
      9D 4F5F      SBCI	R21,0xFF
      9E 1740      CP	R20,R16
      9F 0751      CPC	R21,R17
      A0 F388      BCS	0x0092
      A1 940C 0578 JMP	pop_xgsetF000
(0035) 	}
(0036)   }
(0037) }
(0038) /************************************************************
(0039) *Init SPI Port
(0040) ************************************************************/
(0041) void SPI_Port_Init(void)
(0042) {
(0043)   SPI_DDR  |= ((1<<SS)|(1<<SCK)|(1<<MOSI));//设为输出
_SPI_Port_Init:
      A3 B387      IN	R24,0x17
      A4 6B80      ORI	R24,0xB0
      A5 BB87      OUT	0x17,R24
(0044)   SPI_DDR  &=~ (1<<MISO);                  //设为输入
      A6 98BE      CBI	0x17,6
(0045)   SPI_PORT |= (1<<SS)|(1<<SCK)|(1<<MOSI);  //输出高电平
      A7 B388      IN	R24,0x18
      A8 6B80      ORI	R24,0xB0
      A9 BB88      OUT	0x18,R24
(0046)   SPI_PORT |= (1<<MOSI);				   //上拉
      AA 9AC5      SBI	0x18,5
(0047) 
(0048)   SPI_DDR|=(1<<RESET);                     //复位引脚设为输出
      AB 9ABB      SBI	0x17,3
      AC 9508      RET
(0049) }
(0050) /************************************************************
(0051) *初始化SPI
(0052) ************************************************************/
(0053) void SPI_Init(void)//最高能到fOSC/16
(0054) {
(0055)   SPI_Port_Init();
_SPI_Init:
      AD DFF5      RCALL	_SPI_Port_Init
(0056)   
(0057)   //SPI使能, master模式, MSB 前,  SPI 模式 3, SCK频率Fcl/4 平时SCK为高电平
(0058)   SPCR |= (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<CPOL);
      AE B18D      IN	R24,0x0D
      AF 658C      ORI	R24,0x5C
      B0 B98D      OUT	0x0D,R24
(0059)   //频率加倍
(0060)   SPSR |= (1<<SPI2X);
      B1 9A70      SBI	0x0E,0
      B2 9508      RET
(0061) }
(0062) /************************************************************
(0063) *使能SPI
(0064) ************************************************************/
(0065) void SPI_Start(void)
(0066) {
(0067)  	 SPCR |= (1<<SPE);
_SPI_Start:
      B3 9A6E      SBI	0x0D,6
      B4 9508      RET
(0068) }
(0069) /************************************************************
(0070) *禁止SPI
(0071) ************************************************************/
(0072) void SPI_Stop(void)
(0073) {
(0074)  	 SPCR &=~ (1<<SPE);
_SPI_Stop:
      B5 986E      CBI	0x0D,6
      B6 9508      RET
(0075) }
(0076) /************************************************************
(0077) *SPI send a Byte
(0078) ************************************************************/
(0079) void SPI_Write_Byte(unsigned char cData)
(0080) {
(0081)   SPDR = cData;                //write data
_SPI_Write_Byte:
  cData                --> R16
      B7 B90F      OUT	0x0F,R16
(0082)   while(!(SPSR & (1<<SPIF)));  //wait write ok
      B8 9B77      SBIS	0x0E,7
      B9 CFFE      RJMP	0x00B8
      BA 9508      RET
_SPI_Write_Bytes:
  i                    --> R20
  DataLen              --> R18
  cData                --> R16
      BB 934A      ST	R20,-Y
      BC 935A      ST	R21,-Y
(0083) }
(0084) /************************************************************
(0085) *SPI send  Bytes
(0086) ************************************************************/
(0087) void SPI_Write_Bytes(unsigned char *cData,unsigned int DataLen)
(0088) {
(0089)   unsigned int i;
(0090)   for(i=0;i<DataLen;i++)
      BD 2744      CLR	R20
      BE 2755      CLR	R21
      BF C009      RJMP	0x00C9
(0091)   {
(0092)     SPDR = *(cData+i);           //write data
      C0 01FA      MOVW	R30,R20
      C1 0FE0      ADD	R30,R16
      C2 1FF1      ADC	R31,R17
      C3 8020      LDD	R2,Z+0
      C4 B82F      OUT	0x0F,R2
(0093) 	while(!(SPSR & (1<<SPIF)));  //wait write ok
      C5 9B77      SBIS	0x0E,7
      C6 CFFE      RJMP	0x00C5
      C7 5F4F      SUBI	R20,0xFF
      C8 4F5F      SBCI	R21,0xFF
      C9 1742      CP	R20,R18
      CA 0753      CPC	R21,R19
      CB F3A0      BCS	0x00C0
      CC 9159      LD	R21,Y+
      CD 9149      LD	R20,Y+
      CE 9508      RET
(0094)   }
(0095) }
(0096) /************************************************************
(0097) *SPI Read char
(0098) ************************************************************/
(0099) unsigned char SPI_Read_Byte(unsigned char cData)
(0100) {
(0101)   SPDR = cData;                //write data
_SPI_Read_Byte:
  cData                --> R16
      CF B90F      OUT	0x0F,R16
(0102)   while(!(SPSR & (1<<SPIF)));  //wait receive ok
      D0 9B77      SBIS	0x0E,7
      D1 CFFE      RJMP	0x00D0
(0103)   return SPDR;                 //返回数据
      D2 B10F      IN	R16,0x0F
      D3 9508      RET
(0104) }
(0105) /************************************************************
(0106) *使能FLASH(低电平使能)
(0107) ************************************************************/
(0108) void Enable_DFLASH(void)
(0109) {
(0110)   unsigned char i=255;
_Enable_DFLASH:
  i                    --> R16
      D4 EF0F      LDI	R16,0xFF
(0111)   while(i--);			//延长上一次高电平时间
      D5 2E20      MOV	R2,R16
      D6 2433      CLR	R3
      D7 5001      SUBI	R16,1
      D8 2022      TST	R2
      D9 F7D9      BNE	0x00D5
(0112)   SPI_PORT&=~(1<<SS);
      DA 98C4      CBI	0x18,4
      DB 9508      RET
(0113) }
(0114) /************************************************************
(0115) *禁止FLASH(高电平禁止)
(0116) ************************************************************/
(0117) void Disable_DFLASH(void)
(0118) {
(0119)   unsigned char i=255;
_Disable_DFLASH:
  i                    --> R16
      DC EF0F      LDI	R16,0xFF
(0120)   SPI_PORT|=(1<<SS);	
      DD 9AC4      SBI	0x18,4
(0121)   while(i--);			//延长高电平时间
      DE 2E20      MOV	R2,R16
      DF 2433      CLR	R3
      E0 5001      SUBI	R16,1
      E1 2022      TST	R2
      E2 F7D9      BNE	0x00DE
      E3 9508      RET
_DF_Read_status_Register:
  rData                --> R10
      E4 92AA      ST	R10,-Y
(0122) }
(0123) /************************************************************
(0124) *读取FLASH内部状态寄存器
(0125) *Bit 7:Ready/busy status (1:no busy ; 0:busy)
(0126) *Bit 6:Compare (1: no matche ; 0:matche) 最近的一次比较结果
(0127) *Bit 0:PAGE SIZE (1:256 bytes ; 0:264 bytes)
(0128) ************************************************************/
(0129) unsigned char DF_Read_status_Register(void)
(0130) {
(0131)   unsigned char rData=0;
(0132)   Enable_DFLASH();
      E5 DFEE      RCALL	_Enable_DFLASH
(0133) 
(0134)   SPI_Write_Byte(Status_Register_Opcode);//write opcode
      E6 ED07      LDI	R16,0xD7
      E7 DFCF      RCALL	_SPI_Write_Byte
(0135) 
(0136)   rData = SPI_Read_Byte(0x00);//read device's status
      E8 2700      CLR	R16
      E9 DFE5      RCALL	_SPI_Read_Byte
      EA 2EA0      MOV	R10,R16
(0137) 
(0138)   Disable_DFLASH();
      EB DFF0      RCALL	_Disable_DFLASH
(0139) 
(0140)   return rData;
      EC 2D0A      MOV	R16,R10
      ED 90A9      LD	R10,Y+
      EE 9508      RET
_DF_Check_Page_Size:
  Page_Size            --> R10
      EF 92AA      ST	R10,-Y
(0141) }
(0142) /************************************************************
(0143) *读取FLASH的页大小
(0144) *返回1表示每一页的大小为264 bytes,否则为256 bytes
(0145) ************************************************************/
(0146) unsigned char DF_Check_Page_Size(void)
(0147) {
(0148)   unsigned char Page_Size;
(0149)   Page_Size=DF_Read_status_Register();
      F0 DFF3      RCALL	_DF_Read_status_Register
      F1 2EA0      MOV	R10,R16
(0150)   if(Page_Size&0x01) return 0;
      F2 FF00      SBRS	R16,0
      F3 C002      RJMP	0x00F6
      F4 2700      CLR	R16
      F5 C001      RJMP	0x00F7
(0151)   return 1;
      F6 E001      LDI	R16,1
      F7 90A9      LD	R10,Y+
      F8 9508      RET
_DF_Check_Busy_State:
  state                --> R10
  i                    --> R20
      F9 92AA      ST	R10,-Y
      FA 934A      ST	R20,-Y
(0152) }
(0153) /************************************************************
(0154) *读取FLASH忙标志位(最多判断255次,不行还是返回且返回0)
(0155) ************************************************************/
(0156) unsigned char DF_Check_Busy_State(void)
(0157) {
(0158)   unsigned char state;
(0159)   unsigned char i=255;
      FB EF4F      LDI	R20,0xFF
      FC C006      RJMP	0x0103
(0160)   while(i)
(0161)   {
(0162)      state=DF_Read_status_Register();
      FD DFE6      RCALL	_DF_Read_status_Register
      FE 2EA0      MOV	R10,R16
(0163) 	 if(state & 0x80) break;		//读取的最高位0时器件忙
      FF FF07      SBRS	R16,7
     100 C001      RJMP	0x0102
     101 C003      RJMP	0x0105
(0164) 	 --i;
     102 954A      DEC	R20
     103 2344      TST	R20
     104 F7C1      BNE	0x00FD
(0165)   }
(0166)   return i;
     105 2F04      MOV	R16,R20
     106 9149      LD	R20,Y+
     107 90A9      LD	R10,Y+
     108 9508      RET
_DF_Manufacturer_and_Device_ID:
  i                    --> R20
  ID                   --> R10
     109 940E 0569 CALL	push_xgset300C
     10B 0158      MOVW	R10,R16
(0167) }
(0168) /************************************************************
(0169) *读取FLASH的产家ID的芯片ID等内容;
(0170) *以下函数会返回四个值,第一个数对AT45DB041D来说为0x1F;
(0171) *第四个数为 0x00;
(0172) *用此函数可以判断芯片的好坏,是否正常;
(0173) ************************************************************/

⌨️ 快捷键说明

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