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

📄 at45db_for_msp430.c

📁 at45db_for_msp430.c,IAR2.31调试
💻 C
📖 第 1 页 / 共 2 页
字号:
        page = page_temp;
        addr = addr_temp;
        //return page2;
  //注意,只有1, 21+1,21*2+1,..., 21*11+1=232为起始地址
 //1-21; 22-42;43-63;64-84;85-105;106-126;127-147;148-168;169-189;190-210;211-231;232-252;
 }
 
 /*******************************************************************************
 * name: At45_read_Flash_module(unsigned char *w_data)
 * description: 模块内部自行维护flash的地址指针,能够实现自动时间数据的查询
                flash第0页已占用,本模块不得对第0页做写操作。
                数据包长度定义为全局变量 const uchar flash_data_len=21。
                需要定义全局变量:unsigned int page=1,addr=1;
 * input parameter: 时间值,6字节BCD。
                 方向,1=大于给定时间值,0=小于给定时间值。
 * output parameter: 标志+离给定时间值最近的一条记录
  其中标志=EB90表示数据有效,标志=0000表示无符合条件数据
 ********************************************************************************/
 void At45_read_Flash_module(unsigned char *give_time, unsigned char direction, unsigned char *data)
 {
       unsigned int i=0, j=0, count=0, num_addr=0, max_addr_flag=0, page45_flag=0;
       unsigned int beg_addr, second1, second2; //max_page=1023
       unsigned int min_page=1, max_page=1023, min_addr=1, max_addr=252,min_j,max_j;
       unsigned int page1 = 1, page2, page3 = 1023, page4=1, page5=1;
       unsigned char r_data[21], r_data4[21], r_data5[21];  //21*12=252; 264-252=12;
       unsigned char page_p[2];
       At45_read_Flash(0, 262, page_p, 2);
       page2=page_p[0]*256+page_p[1];
       if (page_rebegin_flag == 0)//在1023页没有写完的情况下,只写了一部分页
       {
          min_page = page1;
          max_page = page2;
          page = (min_page+max_page)/2;
          addr = 1;
          At45_read_Flash(page, addr, r_data, flash_data_len);//读取中间页的时间值
          for (i=0; i<=5; i++)  //年月日时分秒的比较:年--秒,先确定页
          {
            count = 0;
            
            while(*(give_time+i) != r_data[4+i]) //年--秒的比较
            {                       //第5个数据为年
//              WDTCTL = WDTPW + WDTCNTCL + 0x04;
              if (*(give_time+i) < r_data[4+i])
              {//如果给定的数据<读出的数据值,则页应该在前面较小页数的地方
                max_page = page;
                page = (min_page + page)/2;
              }
              else if (*(give_time+i) > r_data[4+i])
              {//如果给定的数据>读出的数据值,则页应该在后面较大页数的地方
                min_page = page;
                page = (max_page + page)/2;
              }
              At45_read_Flash(page, addr, r_data, flash_data_len);
              count = count+1;
              if (count > 12)  break;
            }
          }
       }
       else if (page_rebegin_flag == 1)//在1023页写完的情况下,重新从头开始写了一部分页
       {
          // 计算在page1和page2之间的最优值page4
          min_page = page1;
          max_page = page2;
          page = (min_page+max_page)/2;
          addr = 1;
          At45_read_Flash(page, addr, r_data, flash_data_len);//读取中间页的时间值
          for (i=0; i<=5; i++)  //年月日时分秒的比较:年--秒,先确定页
          {
            count = 0;
           
            while(*(give_time+i) != r_data[4+i]) //年--秒的比较
            {                       //第5个数据为年
//              WDTCTL = WDTPW + WDTCNTCL + 0x04;
              if (*(give_time+i) < r_data[4+i]) 
              {//如果给定的数据<读出的数据值,则页应该在前面较小页数的地方
                max_page = page;
                page = (min_page + page)/2;
              }
              else if (*(give_time+i) > r_data[4+i])
              {//如果给定的数据>读出的数据值,则页应该在后面较大页数的地方
                min_page = page;
                page = (max_page + page)/2;
              }
              At45_read_Flash(page, addr, r_data, flash_data_len);
              count = count+1;
              if (count > 12)  break;
            }
          }
          page4 = page; 
          
          // 计算在page2和page3之间的最优值page5
          min_page = page2;
          max_page = page3;
          page = (min_page+max_page)/2;
          addr = 1;
          At45_read_Flash(page, addr, r_data, flash_data_len);//读取中间页的时间值
          for (i=0; i<=5; i++)  //年月日时分秒的比较:年--秒,先确定页
          {
            count = 0;
            
            while(*(give_time+i) != r_data[4+i]) //年--秒的比较
            {                       //第5个数据为年
//              WDTCTL = WDTPW + WDTCNTCL + 0x04;
              if (*(give_time+i) < r_data[4+i]) 
              {//如果给定的数据<读出的数据值,则页应该在前面较小页数的地方
                max_page = page;
                page = (min_page + page)/2;
              }
              else if (*(give_time+i) > r_data[4+i])
              {//如果给定的数据>读出的数据值,则页应该在后面较大页数的地方
                min_page = page;
                page = (max_page + page)/2;
              }
              At45_read_Flash(page, addr, r_data, flash_data_len);
              count = count+1;
              if (count > 12)  break;
            }
          }
          page5 = page; 
          
          // 对page4和page5与给定的时间值作比较,得到最优值
          page45_flag=0;
          At45_read_Flash(page4, addr, r_data4, flash_data_len);//读取中间页的时间值
          At45_read_Flash(page5, addr, r_data5, flash_data_len);//读取中间页的时间值
          for (i=0; i<=5; i++)  //年月日时分秒的比较:年--秒,先确定页
          {
            if(abs(*(give_time+i) - r_data4[4+i])!=abs(*(give_time+i) - r_data5[4+i])&&page45_flag==0)
            {              
              if (abs(*(give_time+i) - r_data4[4+i])<abs(*(give_time+i) - r_data5[4+i]))
              {
                page = page4;
                page45_flag=1;
              }
              else if (abs(*(give_time+i) - r_data4[4+i])>abs(*(give_time+i) - r_data5[4+i]))
              {
                page = page5;
                page45_flag=1;
              }
              else //在绝对值相等的情况下,则需要进行下一步计算
              {
                page45_flag=0;
              }
            }
          }
       }
       
 //再确定页内地址:注意,只有1, 21*1+1,21*2+1,..., 21*11+1=232为起始地址
 //1-21; 22-42;43-63;64-84;85-105;106-126;127-147;148-168;169-189;190-210;211-231;232-252;
       num_addr = 264/flash_data_len; //=12
       beg_addr = (num_addr/2)*flash_data_len+1; //=127
       At45_read_Flash(page, beg_addr, r_data, flash_data_len);//读取页内中间起始地址的时间值
       min_j = 0;
       max_j = num_addr-1;
       count = 0;
       for (i=0; i<=5; i++)  //年月日时分秒的比较:年--秒,再确定页内地址
       {
          max_addr_flag = 0; //地址最大标志
          for (j=min_j; j<=max_j; j++)//每次都是在上一次时间数据基础上的范围内进行比较
          {
            beg_addr = j*flash_data_len+1; //得到页内的起始地址
            At45_read_Flash(page, beg_addr, r_data, flash_data_len);
            
            if (*(give_time+i) < r_data[4+i] && max_addr_flag ==0)
            {//如果给定的数据<读出的数据值,则地址应该在前面较小地址的地方
              max_j = j;// 得到最小的大于给定时间数据的位置P1,其它的大于P1的值就不能考虑,
              max_addr_flag = 1; //这样就找到了最小的大于给定时间数据的位置
            }
            else if (*(give_time+i) > r_data[4+i])
            {//如果给定的数据>读出的数据值,则地址应该在后面较大地址的地方
              min_j = j;//找到了最大的小于给定时间数据的位置
            }
          }
       }//得到了j的数据区间:min_j和max_j
       
       beg_addr = min_j*flash_data_len+1;//得到页内最小的的起始地址
       At45_read_Flash(page, beg_addr, r_data, flash_data_len);
       second1 = r_data[9];//得到最小的的起始地址上时间秒的数据
       beg_addr = max_j*flash_data_len+1;//得到页内最大的的起始地址
       At45_read_Flash(page, beg_addr, r_data, flash_data_len);
       second2 = r_data[9];//得到最大的的起始地址上时间秒的数据
       // 判断最后的时间数据是离min_j近还是离max_j近       
       /**/ if (abs(*(give_time+5)-second1) < abs(*(give_time+5)-second2))
       {
          j = min_j;
       }
       else if (abs(*(give_time+5)-second1) > abs(*(give_time+5)-second2))
       {
          j = max_j;
       }
       else
       {
          j = (min_j + max_j)/2;
       }
       min_j = j;
       max_j = j;
       if (direction==1)// 1为大于给定数据的最接近数据
       {
          if (*(give_time+5) > second2)
          {
              j = max_j;
          }
          else
          {
              if (j<num_addr-1)  //j<11
              {
                  j = max_j+1;
              }
              else   //j=11
              {
                  j = 0;
                  if (page<1023)
                  {
                      page=page+1;
                  }
                  else
                  {
                      page=1;
                  }
              }
          }
       }
       if (direction==0)// 0为小于给定数据的最接近数据
       {
          if (*(give_time+5) < second1)
          {
              j = min_j;
          }
          else
          {
              if (j>0)  //j>0
              {
                  j = min_j-1;
              }
              else   //j=0
              {
                  j = num_addr-1;
                  if (page>1)
                  {
                      page=page-1;
                  }
                  else
                  {
                      page=1023;
                  }
              }
          }
       }
       
       beg_addr = j*flash_data_len+1;
       At45_read_Flash(page, beg_addr, data, flash_data_len);      
       //读出来的r_data的内容即为与给定时间最为接近的数据值
       
       for (i=flash_data_len-1; i>0; i--)        //lhy
       {
         *(data+2+i)=*(data+i);
       }
       *(data)=0xeb;
       *(data+1)=0x90;
 }
 /*******************************************************************************
 * name: At45_write_Buffer()
 * description: 该函数向指定的地址连续写入指定个数的数据。
 * input parameter: page------目的页。有效范围:0~2047;
 *			 addr------页内地址。有效范围:0~263;
 *			 data------操作数据指针;
 *			 num-------数据个数。
 * output parameter: NULL
 ********************************************************************************/
 void At45_write_Buffer(unsigned int addr,unsigned char *data,unsigned int num)
 {
 	unsigned char cmd1;
 	unsigned int i;
 	
 	if (addr>263) return;	// 超出 at45 寻址范围,函数返回 
 	
 	CS_low();
 	
 	cmd1 = 0x84;// 写Buffer1,命令码为0x84
 	at45_hdr(cmd1,0x00,addr);
 	at45_write_hdr();	// 发送命令和地址

   	for(i=0;i<num;i++)			// 发送 num 个数据
 	{
 		SPIDataWrite(*(data+i));
 		//while(CheckStatus()==0);	// 等待数据发送完毕
 		//delay(10);
 	}
 	
 	CS_high();
 	
 }

 /*******************************************************************************
 * name: At45_read_Buffer()
 * description: 该函数从 at45db041b 的指定地址连续读出指定个数的数据
 * input parameter: page------目的页。有效范围:0~1023。
 *			 addr------页内地址。有效范围:0~263。
 *			 data------数据存放的首地址。
 *			 num-------数据个数。
 * output parameter: NULL
 ********************************************************************************/
 void At45_read_Buffer(unsigned int addr,unsigned char *data,unsigned int num)
 {
 	unsigned int i;
 	
 	if(addr>263) return;	// 超出 at45 的寻址范围,返回
 	CS_low();   // 选通 at45db041b
 	
 	
 	at45_hdr(0xD4,0x00,addr);	// 读缓存的命令码为0xD4
 	at45_write_hdr();	// 发送读命令和地址
 	SPIDataWrite(0xE8);  //8 don't care bits.
	
 	for(i=0;i<num;i++)
 	{ 	        
 		*(data+i) = SPIDataRead();
 		//while(CheckStatus()==0);
 		//delay(10);
 	}
 	
 	CS_high();
 	
 }
//*******************************************************************************

⌨️ 快捷键说明

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