打印
[DemoCode下载]

SmartMini例程-实验-TFT【中断唤醒-睡眠模式】

[复制链接]
1393|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
haolaishi|  楼主 | 2014-10-23 21:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
饮水思源,Smart板子的官网如下 http://www.smartmcu.com/

沙发
haolaishi|  楼主 | 2014-10-23 21:07 | 只看该作者
实验-TFT【中断唤醒-睡眠模式】.zip (96.91 KB)

使用特权

评论回复
板凳
cornrn| | 2015-11-17 13:42 | 只看该作者
无用代码别乱发

使用特权

评论回复
地板
wahahaheihei| | 2015-11-17 15:18 | 只看该作者
/************************* Copyright (c) 2014 SmartMcu Team *****************************
*项目名称:ARM Cortex-M0 显示FLASH图片
*描    述:显示FLASH存储中的位图
*设    计:SmartMcu Team
*修改日期:2014/3/5
*官    网:www.smartmcu.com
*淘    宝:http://smartmcu.taobao.com/
*说    明:代码注释与讲解详见《ARM Cortex-M0微控制器深度实战》温子祺等著,
           北京航空航天大学出版社
*******************************************************************************************/

#include "SmartM_M0.h"

/****************************************
*函数名称:KeyIntInit
*输    入:无
*输    出:无
*功    能:按键中断初始化
******************************************/
VOID KeyIntInit(VOID)
{
        P3_MFP = (P3_MFP & (~P32_EINT0_MCLK)) | EINT0;  //P3.2引脚设置为外部中断
               
        P3_IMD &= IMD2_EDG;                               
        P3_IEN |= IF_EN2;                                                                                                                           //设置外部中断0为下降沿触发
        NVIC_ISER |= EXT_INT0;

}

/****************************************
*函数名称:McuIdle
*输    入:无
*输    出:无
*功    能:MCU进入空闲
******************************************/
VOID McuIdle(VOID)
{
          LcdCleanScreen(BLACK);       
    LcdShowString(30,10,"中断唤醒(空闲模式)实验",WHITE,BLACK);
    LcdShowString(40,120,"MCU状态:空闲模式",YELLOW,BLACK);
    LcdShowString(30,180,"【唤醒】-请按下KEY1",RED,BLACK);       
       
    PROTECT_REG
          (
                   PWRCON &= ~PD_WAIT_CPU;
                   PWRCON &= ~PWR_DOWN_EN;               
          )
          __WFI();

          Delayms(20);
}
/****************************************
*函数名称:main
*输    入:无
*输    出:无
*功    能:函数主体
******************************************/
INT32 main(VOID)
{

         
         /*   Mcu初始化 */
   McuInit(MCU_FREQUENCY);
       

         /*   Led 初始化 */
         LedInit();            

         /*   LCD 初始化 */
         LcdInit(LCD_FONT_IN_FLASH,LCD_DIRECTION_180);                             

         /*   SPI FLash 初始化 */
         SpiFlashInit();                 

         while(SpiFlashReadID()!=W25Q16)                                                       
         {
            Led1(1);Delayms(100);
            Led1(0);Delayms(100);       
   }
         
         /*   按键中断 初始化 */
   KeyIntInit();

         
         while(1)
         {          
                      /* MCU工作模式 */
                      LcdCleanScreen(WHITE);       
                      LcdShowString(30,10,"中断唤醒(空闲模式)实验",BLUE,WHITE);
                      LcdShowString(40,120,"MCU状态:工作模式",RED,WHITE);
          Delayms(1000);Delayms(1000);
                 
                      /* MCU进入空闲模式 */
          McuIdle();
         }
}
/****************************************
*函数名称:EINT1_IRQHandler
*输    入:无
*输    出:无
*功    能:外部中断1服务函数
******************************************/
VOID EINT0_IRQHandler(VOID)
{                  

         P3_ISRC = P3_ISRC;                //写1清空
}

使用特权

评论回复
5
wahahaheihei| | 2015-11-17 15:19 | 只看该作者
#include "SmartM_M0.h"

STATIC UINT32 g_unFontPos     =LCD_FONT_IN_SD ;
STATIC UINT32 g_unLcdDirection=LCD_DIRECTION_180;

/****************************************
*函数名称:LcdWriteBus
*输    入:VH -高8位数据
          VL -低8位数据
*输    出:无
*功    能:Lcd并行数据传输
******************************************/                                            
VOID LcdWriteBus(UINT8 VH,UINT8 VL)   //并行数据写入函数
{       

        LCD_DATAPORT_L=VL;
  LCD_DATAPORT_H=VH;
        LCD_WR(0);
        NOP();NOP();NOP();NOP();
        LCD_WR(1);       

}
/****************************************
*函数名称:LcdWriteCmd
*输    入:VH -高8位数据
          VL -低8位数据
*输    出:无
*功    能:Lcd写命令
******************************************/               
VOID LcdWriteCmd(UINT8 VH,UINT8 VL)         //发送命令-8位参数
{       
    LCD_RS(0);
          NOP();NOP();NOP();NOP();
          LcdWriteBus(VH,VL);
          
}
/****************************************
*函数名称:LcdWriteCmd
*输    入:VH -高8位数据
          VL -低8位数据
*输    出:无
*功    能:Lcd写数据
******************************************/       
VOID LcdWriteData(UINT8 VH,UINT8 VL) //发送数据-8位参数
{
    LCD_RS(1);
          NOP();NOP();NOP();NOP();
          LcdWriteBus(VH,VL);
}
/****************************************
*函数名称:LcdWriteCmdData
*输    入:VH -高8位数据
          VL -低8位数据
*输    出:无
*功    能:Lcd写数据
******************************************/       
VOID LcdWriteCmdData(UINT32 cmd,UINT32 val)                   //发送数据命令
{
          LcdWriteCmd(cmd>>8,cmd);
    LcdWriteData(val>>8,val);
}
/****************************************
*函数名称:LcdAddressSet
*输    入:x1 -横坐标1
          y1 -纵坐标1
          x2 -横坐标2
          y2 -纵坐标2
*输    出:无
*功    能:Lcd显示地址
******************************************/       
VOID LcdAddressSet(UINT32 x1,UINT32 y1,UINT32 x2,UINT32 y2)
{
          UINT16 Lcd_x1=x1,Lcd_y1=y1,Lcd_x2=x2,Lcd_y2=y2;
       
           /*   检测屏幕是否翻转180度 */
          if(g_unLcdDirection == LCD_DIRECTION_180)
          {
             Lcd_x1=LCD_WIDTH-x2;
                   Lcd_x2=LCD_WIDTH-x1;
                   Lcd_y1=LCD_HEIGHT-y2;
                   Lcd_y2=LCD_HEIGHT-y1;
          }
               
                LcdWriteCmd(0x00,0x20);LcdWriteData(Lcd_x1>>8,Lcd_x1);//设置X坐标位置          
                LcdWriteCmd(0x00,0x21);LcdWriteData(Lcd_y1>>8,Lcd_y1);//设置Y坐标位置

                LcdWriteCmd(0x00,0x50);LcdWriteData(Lcd_x1>>8,Lcd_x1);//开始X


                LcdWriteCmd(0x00,0x52);LcdWriteData(Lcd_y1>>8,Lcd_y1);//开始Y          
                LcdWriteCmd(0x00,0x51);LcdWriteData(Lcd_x2>>8,Lcd_x2);//结束X
                LcdWriteCmd(0x00,0x53);LcdWriteData(Lcd_y2>>8,Lcd_y2);//结束Y
       
                LcdWriteCmd(0x00,0x22);                                                       
}
/****************************************
*函数名称:LcdCleanScreen
*输    入:usColor -颜色
*输    出:无
*功    能:Lcd清屏
******************************************/       
VOID LcdCleanScreen(UINT16 usColor)
{
         UINT32 i,j;

         LcdAddressSet(0,0,239,319);

   for(i=0;i<320;i++)
         {
            for (j=0;j<240;j++)
                   {
                 LcdWriteData(usColor>>8,usColor);
            }
         }
}
/****************************************
*函数名称:LcdInit
*输    入:unFontPos       -字符存储位置
          unLcdDirection  -显示方向
*输    出:无
*功    能:Lcd初始化
******************************************/       
VOID LcdInit(UINT32 unFontPos,UINT32 unLcdDirection)
{
         g_unLcdDirection = unLcdDirection;
       
         g_unFontPos = unFontPos;
       

         P0_PMD = 0x5555;
         P2_PMD = 0x5555;       
       
         /*
            P4.4-Lcd cs pin
            P4.5-Lcd rs pin
         */
         P4_PMD &=~((3<<8)|(3<<10));
         P4_PMD |=  (1<<8)|(1<<10);       

         LCD_RS(1);
         
         LCD_CS(0);

         /* P3.6-Lcd wr
            P3.7-Lcd rd
         */       
         P3_PMD &=~((3<<12)|(3<<14));
         P3_PMD |=  (1<<12)|(1<<14);       
         
         LCD_WR(1);
         LCD_RD(1);
         

   /* P4.3-Lcd led pin */
   P4_PMD &=~(3<<6);
         P4_PMD |= (1<<6);
         LCD_BL(0);       

       
   Delayms(100);
         
         
         LcdWriteCmdData(0x0001,0x0100); Delayms(1);
         LcdWriteCmdData(0x0002,0x0700); Delayms(1);
         LcdWriteCmdData(0x0003,0x1030); Delayms(1);
         LcdWriteCmdData(0x0004,0x0000); Delayms(1);
         LcdWriteCmdData(0x0008,0x0207); Delayms(1);
         LcdWriteCmdData(0x0009,0x0000); Delayms(1);
         LcdWriteCmdData(0x000A,0x0000); Delayms(1);
         LcdWriteCmdData(0x000C,0x0000); Delayms(1);
         LcdWriteCmdData(0x000D,0x0000); Delayms(1);
         LcdWriteCmdData(0x000F,0x0000); Delayms(1);
         LcdWriteCmdData(0x0010,0x0000); Delayms(1);  
         LcdWriteCmdData(0x0011,0x0007); Delayms(1);
         LcdWriteCmdData(0x0012,0x0000); Delayms(1);
         LcdWriteCmdData(0x0013,0x0000); Delayms(1);
         LcdWriteCmdData(0x0010,0x1290); Delayms(1);  
         LcdWriteCmdData(0x0011,0x0227); Delayms(1);
         LcdWriteCmdData(0x0012,0x001d); Delayms(1);
         LcdWriteCmdData(0x0013,0x1500); Delayms(1);
         LcdWriteCmdData(0x0029,0x0018); Delayms(1);
         LcdWriteCmdData(0x002B,0x000D); Delayms(1);
         LcdWriteCmdData(0x0030,0x0004); Delayms(1);
         LcdWriteCmdData(0x0031,0x0307); Delayms(1);
         LcdWriteCmdData(0x0032,0x0002); Delayms(1);
         LcdWriteCmdData(0x0035,0x0206); Delayms(1);
         LcdWriteCmdData(0x0036,0x0408); Delayms(1);
         LcdWriteCmdData(0x0037,0x0507); Delayms(1);
         LcdWriteCmdData(0x0038,0x0204); Delayms(1);
         LcdWriteCmdData(0x0039,0x0707); Delayms(1);
         LcdWriteCmdData(0x003C,0x0405); Delayms(1);
         LcdWriteCmdData(0x003D,0x0F02); Delayms(1);
         LcdWriteCmdData(0x0050,0x0000); Delayms(1);
         LcdWriteCmdData(0x0051,0x00EF); Delayms(1);
         LcdWriteCmdData(0x0052,0x0000); Delayms(1);
         LcdWriteCmdData(0x0053,0x013F); Delayms(1);
         LcdWriteCmdData(0x0060,0xA700); Delayms(1);
         LcdWriteCmdData(0x0061,0x0001); Delayms(1);
         LcdWriteCmdData(0x006A,0x0000); Delayms(1);
         LcdWriteCmdData(0x0080,0x0000); Delayms(1);
         LcdWriteCmdData(0x0081,0x0000); Delayms(1);
         LcdWriteCmdData(0x0082,0x0000); Delayms(1);
         LcdWriteCmdData(0x0083,0x0000); Delayms(1);
         LcdWriteCmdData(0x0084,0x0000); Delayms(1);
         LcdWriteCmdData(0x0085,0x0000); Delayms(1);
         LcdWriteCmdData(0x0090,0x0010); Delayms(1);
         LcdWriteCmdData(0x0092,0x0600); Delayms(1);
         LcdWriteCmdData(0x0093,0x0003); Delayms(1);
         LcdWriteCmdData(0x0095,0x0110); Delayms(1);
         LcdWriteCmdData(0x0097,0x0000); Delayms(1);
         LcdWriteCmdData(0x0098,0x0000); Delayms(1);
         LcdWriteCmdData(0x0007,0x0133); Delayms(1);
}         
/****************************************
*函数名称:LcdDrawPoint
*输    入:unFontPos       -字符存储位置
          unLcdDirection  -显示方向
*输    出:无
*功    能:Lcd初始化
******************************************/
VOID LcdDrawPoint(UINT32 x,UINT32 y,UINT32 color)
{
        LcdAddressSet(x,y,x,y);//设置光标位置
        LcdWriteData(color>>8,color);         
}
/****************************************
*函数名称:LcdFill
*输    入:x_s    -横坐标起始地址
          y_s    -纵坐标起始地址
          x_e    -横坐标结束地址
          y_e    -纵坐标结束地址
          color  -颜色
*输    出:无
*功    能:Lcd颜色填充
******************************************/
VOID LcdFill(UINT32 x_s,UINT32 y_s,UINT32 x_e,UINT32 y_e,UINT32 color)
{         
        UINT32 i,j;

        LcdAddressSet(x_s,y_s,x_e,y_e);      //设置光标位置

        for(i=y_s;i<=y_e;i++)
        {                                                                                                                           
                for(j=x_s;j<=x_e;j++)LcdWriteData(color>>8,color);//设置光标位置             
        }                                                       
}
/****************************************
*函数名称:LcdSetDirection
*输    入:unDirection 显示方向
*输    出:无
*功    能:Lcd显示方向设置
******************************************/
VOID LcdSetDirection(UINT32 unDirection)
{
           g_unLcdDirection = unDirection;
}
/****************************************
*函数名称:LcdGetDirection
*输    入:无
*输    出:无
*功    能:Lcd显示方向获取
******************************************/
UINT32 LcdGetDirection(VOID)
{

           return g_unLcdDirection;
}
/****************************************
*函数名称:LcdRemakeFont
*输    入:pucCode       -字符缓冲区
          unDirection   -字体方向
          unFontType    -字体
*输    出:无
*功    能:重置字体
******************************************/
STATIC VOID LcdRemakeFont(UINT8 *pucCode,UINT32 unDirection,UINT32 unFontType)
{
   UINT8   i=0,j=0,m=0,n=0,size=0;
   UINT8   TempBuf[32]={0};

   if(unFontType ==FONT_IS_ASC16)
   {
             size=16;
   }
   
   if(unFontType ==FONT_IS_GBK16)
   {
             size=32;
   }

   for(i=0;i<size;i++)
   {
              TempBuf[size-1-i]=pucCode[i];
             TempBuf[i]=pucCode[size-1-i];
   }

   for(i=0;i<size;i+=2)
   {
      m=0;n=0;

      for(j=0; j<8; j++)
            {
                    if(TempBuf[i]  &1<<j)m|=1<<(7-j);
                    if(TempBuf[i+1]&1<<j)n|=1<<(7-j);
            }

            pucCode[i]  =m;
             pucCode[i+1]=n;
   }
}
/****************************************
*函数名称:LcdDrawBigPoint
*输    入:x          -横坐标
          y          -纵坐标
                                        color      -描点颜色
*输    出:无
*功    能:Lcd描粗点
******************************************/
VOID LcdDrawBigPoint(UINT32 x,UINT32 y,UINT32 color)
{
           LcdFill(x,y,x+10,y+10,color);
}

/****************************************
*函数名称:LcdShowFlashFont
*输    入:x          -横坐标
          y          -纵坐标
          pucCode    -字符缓冲区
                                        color      -字体颜色
                                        bgcolor    -字体背景色
*输    出:无
*功    能:Lcd显示时采用存储在Flash中的字体
******************************************/
STATIC VOID LcdShowFlashFont(UINT32 x,UINT32 y,UINT8 *pucCode,UINT32 color,UINT32 bgcolor)
{                                  
   UINT32  FontOffset;
   UINT8   i=0,j=0;
   UINT8   buf[32]={0};

   if(pucCode[0]&0x80)  //汉字
   {
           FontOffset =FLASH_HZK16_ADDRESS;

           FontOffset+=(94 *((UINT8) pucCode[0] - 0xA1 ) + ( (UINT8)pucCode[1] - 0xA1 ) ) << 5;

           SpiFlashRead(buf,FontOffset,32);

     if(LcdGetDirection()!=LCD_DIRECTION_0)
           {
                     LcdRemakeFont(buf,LcdGetDirection(),FONT_IS_GBK16);
           }

           LcdAddressSet(x,y,x+15,y+15); //设置区域   
               
           for(j=0;j<32;j++)
           {
                                for(i=0;i<8;i++)
                                {                      
                                                if((buf[j]&(1<<(7-i)))!=0)
                                                {
                                                        LcdWriteData(color>>8,color);
                                                }
                                                else
                                                {
                                                        LcdWriteData(bgcolor>>8,bgcolor);
                                                }   
                                }
           }
            
   }//ASC
   else
   {
       FontOffset  =FLASH_ASC16_ADDRESS;

       FontOffset += pucCode[0] << 4;

             SpiFlashRead(buf,FontOffset,16);

       if(LcdGetDirection()!=LCD_DIRECTION_0)
             {
                       LcdRemakeFont(buf,LcdGetDirection(),FONT_IS_ASC16);
             }
       
             LcdAddressSet(x,y,x+7,y+15); //设置区域  
               
                         for(j=0;j<16;j++)
                         {
                                        for(i=0;i<8;i++)
                                        {                      
                                                if((buf[j]&(1<<(7-i)))!=0)
                                                {
                                                        LcdWriteData(color>>8,color);
                                                }
                                                else
                                                {
                                                        LcdWriteData(bgcolor>>8,bgcolor);
                                                }   
                                        }
                         }
   }

}

/****************************************
*函数名称:LcdShowFont
*输    入:x          -横坐标
          y          -纵坐标
          pucCode    -字符缓冲区
                                        color      -字体颜色
                                        bgcolor    -字体背景色
*输    出:无
*功    能:Lcd显示单个文字
******************************************/
VOID LcdShowFont(UINT32 x,UINT32 y,UINT8 *pucCode,UINT32 color,UINT32 bgcolor)
{
         switch(g_unFontPos)
         {
                        case LCD_FONT_IN_SD:
                        {
                                  
                        }break;

                        case LCD_FONT_IN_FLASH:
                        {
                                 LcdShowFlashFont(x,y,pucCode,color,bgcolor);
                        }break;

                  default:break;
         }

}
/****************************************
*函数名称:LcdShowString
*输    入:x          -横坐标
          y          -纵坐标
          pucCode    -字符缓冲区
                                        color      -字体颜色
                                        bgcolor    -字体背景色
*输    出:无
*功    能:Lcd显示字符串
******************************************/
VOID LcdShowString(UINT32 x,UINT32 y,UINT8 *pucCode,UINT32 color,UINT32 bgcolor)
{
   UINT32 x_bak=x;

   while(pucCode && *pucCode)
         {
                         LcdShowFont(x,y,pucCode,color,bgcolor);

                         if(*pucCode & 0x80)
                         {
                                   pucCode+=2;

                                   x+=16;
                         }
                         else
                         {
                                   pucCode++;

                                   x+=16;
                         }

                         if(x>=240)                //换行
                         {
                                  x = x_bak;

                                  y+=20;       
                         }          
         }

}






使用特权

评论回复
6
wahahaheihei| | 2015-11-17 15:20 | 只看该作者
#include "SmartM_M0.h"



/****************************************
*函数名称:SpiFlashInit
*输    入:无
*输    出:无
*功    能:初始化SPI FLASH的IO口
******************************************/
VOID SpiFlashInit(VOID)
{
        //初始化P1.3作为FLASH的片选引脚
        P1_PMD &=~(3UL<<6);
        P1_PMD |=  1UL<<6 ;

  Spi0MasterInit();
}  
/****************************************
*函数名称:SpiFlashReadSR
*输    入:无
*输    出:忙标记位(1,忙;0,空闲)
*功    能:读取SPI_FLASH的状态寄存器
BIT7  6   5   4   3   2   1   0
SPR   RV  TB BP2 BP1 BP0 WEL BUSY
SPR:默认0,状态寄存器保护位,配合WP使用
TB,BP2,BP1,BP0:FLASH区域写保护设置
WEL:写使能锁定
BUSY:忙标记位(1,忙;0,空闲)
默认:0x00
******************************************/
UINT8 SpiFlashReadSR(VOID)   
{  
        UINT8 rt=0;   
        SPI_FLASH_CS(0);                      //使能器件   
        Spi0WriteRead(W25X_ReadStatusReg);    //发送读取状态寄存器命令   
        rt=Spi0WriteRead(0Xff);               //读取一个字节  
        SPI_FLASH_CS(1);                      //取消片选     
        return rt;   
}
/****************************************
*函数名称:SpiFlashWriteSR
*输    入:设置状态值
*输    出:无
*功    能:写SPI_FLASH的状态寄存器
只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写
******************************************/
VOID SpiFlashWriteSR(UINT8 sr)   
{   
        SPI_FLASH_CS(0);                      //使能器件   
        Spi0WriteRead(W25X_WriteStatusReg);   //发送写取状态寄存器命令   
        Spi0WriteRead(sr);                    //写入一个字节  
        SPI_FLASH_CS(1);                      //取消片选                  
}   
/****************************************
*函数名称:SpiFlashWriteEnable
*输    入:无
*输    出:无
*功    能:SPI_FLASH写使能,WEL置位
******************************************/
VOID SpiFlashWriteEnable(VOID)   
{
        SPI_FLASH_CS(0);                      //使能器件   
  Spi0WriteRead(W25X_WriteEnable);      //发送写使能  
        SPI_FLASH_CS(1);                      //取消片选                  
}
/****************************************
*函数名称:SpiFlashWriteDisable
*输    入:无
*输    出:无
*功    能:SPI_FLASH写禁止,将WEL清零         
******************************************/
VOID SpiFlashWriteDisable(VOID)   
{  
        SPI_FLASH_CS(0);                       //使能器件   
  Spi0WriteRead(W25X_WriteDisable);      //发送写禁止指令   
        SPI_FLASH_CS(1);                       //取消片选                  
}                   
/****************************************
*函数名称:SpiFlashReadID
*输    入:无
*输    出:                          
                                        0XEF13,表示芯片型号为W25Q80  
                                        0XEF14,表示芯片型号为W25Q16   
                                        0XEF15,表示芯片型号为W25Q32  
                                        0XEF16,表示芯片型号为W25Q64
*功    能:读取芯片ID
******************************************/
UINT16 SpiFlashReadID(VOID)
{
        UINT16 Temp = 0;          
        SPI_FLASH_CS(0);                                    
        Spi0WriteRead(0x90);             //发送读取ID命令            
        Spi0WriteRead(0x00);             
        Spi0WriteRead(0x00);             
        Spi0WriteRead(0x00);                                    
        Temp|=Spi0WriteRead(0xFF)<<8;  
        Temp|=Spi0WriteRead(0xFF);         
        SPI_FLASH_CS(1);                                    
        return Temp;
}                       
/****************************************
*函数名称:SpiFlashRead
*输    入:pBuffer        -数据存储区
          ReadAddr       -开始读取的地址(24bit)
          NumByteToRead  -要读取的字节数(最大65535)
*输    出:无
*功    能:读取SPI FLASH  
******************************************/
VOID SpiFlashRead(UINT8* pBuffer,UINT32 ReadAddr,UINT16 NumByteToRead)   
{
        UINT16 i;                                                                                       
        SPI_FLASH_CS(0);                         //使能器件   
  Spi0WriteRead(W25X_ReadData);            //发送读取命令   
  Spi0WriteRead((UINT8)((ReadAddr)>>16));  //发送24bit地址   
  Spi0WriteRead((UINT8)((ReadAddr)>>8));   
  Spi0WriteRead((UINT8)ReadAddr);   
       
  for(i=0;i<NumByteToRead;i++)
        {
      pBuffer[i]=Spi0WriteRead(0XFF);      //循环读数  
  }
       
        SPI_FLASH_CS(1);                                                   
}  
/****************************************
*函数名称:SpiFlashWritePage
*输    入:pBuffer        -数据存储区
          WriteAddr      -开始写入的地址(24bit)
          NumByteToWrite -要写入的字节数(最大256),该数不应该超过该页的剩余字节数
*输    出:无
*功    能:SPI在一页(0~65535)内写入少于256个字节的数据
******************************************/
VOID SpiFlashWritePage(UINT8* pBuffer,UINT32 WriteAddr,UINT16 NumByteToWrite)
{
        UINT16 i;
       
  SpiFlashWriteEnable();                  //SET WEL
        SPI_FLASH_CS(0);                           //使能器件
       
  Spi0WriteRead(W25X_PageProgram);           //发送写页命令   
  Spi0WriteRead((UINT8)((WriteAddr)>>16));   //发送24bit地址   
  Spi0WriteRead((UINT8)((WriteAddr)>>8));   
  Spi0WriteRead((UINT8)WriteAddr);
       
  for(i=0;i<NumByteToWrite;i++)Spi0WriteRead(pBuffer[i]);//循环写数  
       
        SPI_FLASH_CS(1);                            //取消片选
        SpiFlashWaitBusy();                                                    //等待写入结束
}
/****************************************
*函数名称:SpiFlashWriteNoCheck
*输    入:pBuffer        -数据存储区
          WriteAddr      -开始写入的地址(24bit)
          NumByteToWrite -要写入的字节数(最大65535)
*输    出:无
*功    能:无检验写SPI FLASH
必须确保所写的地址范围内的数据全部为0XFF,
否则在非0XFF处写入的数据将失败!
具有自动换页功能
在指定地址开始写入指定长度的数据,但是要确保地址不越界!
******************************************/
VOID SpiFlashWriteNoCheck(UINT8* pBuffer,UINT32 WriteAddr,UINT16 NumByteToWrite)   
{                                           
        UINT16 pageremain;          
        pageremain=256-WriteAddr%256; //单页剩余的字节数                             
        if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//不大于256个字节
       
        while(1)
        {          
                SpiFlashWritePage(pBuffer,WriteAddr,pageremain);
                if(NumByteToWrite==pageremain)break;//写入结束了
                 else //NumByteToWrite>pageremain
                {
                        pBuffer+=pageremain;
                        WriteAddr+=pageremain;       

                        NumByteToWrite-=pageremain;                              //减去已经写入了的字节数
                        if(NumByteToWrite>256)pageremain=256; //一次可以写入256个字节
                        else pageremain=NumByteToWrite;             //不够256个字节了
                }
        }            
}
STATIC UINT8 szSpiFlashBuf[512];       
/****************************************
*函数名称:SpiFlashWrite
*输    入:pBuffer        -数据存储区
          WriteAddr      -开始写入的地址(24bit)
          NumByteToWrite -要写入的字节数(最大65535)
*输    出:无
*功    能:写SPI FLASH  
在指定地址开始写入指定长度的数据并带擦除操作!
******************************************/
VOID SpiFlashWrite(UINT8* pBuffer,UINT32 WriteAddr,UINT16 NumByteToWrite)   
{
        UINT32   secpos;
        UINT16  secoff;
        UINT16  secremain;          
        UINT32  i;   
        UINT8  *SPI_FLASH_BUF;          
       
  SPI_FLASH_BUF=szSpiFlashBuf;
       
        secpos=WriteAddr/512;//扇区地址  
        secoff=WriteAddr%512;//在扇区内的偏移
        secremain=512-secoff;//扇区剩余空间大小   

        if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//不大于4096个字节
       
        while(1)
        {       
                SpiFlashRead(SPI_FLASH_BUF,secpos*512,512);//读出整个扇区的内容
               
                for(i=0;i<secremain;i++)//校验数据
                {
                        if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;//需要擦除            
                }
               
                if(i<secremain)//需要擦除
                {
                        SpiFlashEraseSector(secpos);//擦除这个扇区
                        for(i=0;i<secremain;i++)             //复制
                        {
                                SPI_FLASH_BUF[i+secoff]=pBuffer[i];          
                        }
                        SpiFlashWriteNoCheck(SPI_FLASH_BUF,secpos*512,512);//写入整个扇区  

                }
                else
                {
                        SpiFlashWriteNoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.        
                }                          
               
                if(NumByteToWrite==secremain)
                {
                         break;//写入结束了
                }               
                else//写入未结束
                {
                        secpos++;//扇区地址增1
                        secoff=0;//偏移位置为0          

                  pBuffer+=secremain;  //指针偏移
                        WriteAddr+=secremain;//写地址偏移          
                  NumByteToWrite-=secremain;                                    //字节数递减
                        if(NumByteToWrite>512)secremain=512;        //下一个扇区还是写不完
                        else secremain=NumByteToWrite;                          //下一个扇区可以写完了
                }         
        }         
}
/****************************************
*函数名称:SpiFlashEraseChip
*输    入:无
*输    出:无
*功    能:擦除整个芯片                  
******************************************/
VOID SpiFlashEraseChip(VOID)   
{                                   
    SpiFlashWriteEnable();             //SET WEL
    SpiFlashWaitBusy();   
          SPI_FLASH_CS(0);                      //使能器件   
    Spi0WriteRead(W25X_ChipErase);        //发送片擦除命令  
          SPI_FLASH_CS(1);                      //取消片选                  
          SpiFlashWaitBusy();                                         //等待芯片擦除结束
}   
/****************************************
*函数名称:SpiFlashEraseSector
*输    入:Dst_Addr  -扇区地址 根据实际容量设置
*输    出:无
*功    能:擦除一个扇区最少150毫秒
******************************************/
VOID SpiFlashEraseSector(UINT32 Dst_Addr)   
{  

          Dst_Addr*=512;
    SpiFlashWriteEnable();                //SET WEL          
    SpiFlashWaitBusy();   
          SPI_FLASH_CS(0);                         //使能器件   
    Spi0WriteRead(W25X_SectorErase);         //发送扇区擦除指令
    Spi0WriteRead((UINT8)((Dst_Addr)>>16));  //发送24bit地址   
    Spi0WriteRead((UINT8)((Dst_Addr)>>8));   
    Spi0WriteRead((UINT8)Dst_Addr);  
          SPI_FLASH_CS(1);                         //取消片选                  
    SpiFlashWaitBusy();                                            //等待擦除完成
}  
/****************************************
*函数名称:SpiFlashWaitBusy
*输    入:无
*输    出:无
*功    能:等待空闲
******************************************/
VOID SpiFlashWaitBusy(VOID)   
{   
        while((SpiFlashReadSR()&0x01)==0x01);   // 等待BUSY位清空
}  
/****************************************
*函数名称:SpiFlashPowerDown
*输    入:无
*输    出:无
*功    能:进入掉电模式
******************************************/
VOID SpiFlashPowerDown(VOID)   
{
          SPI_FLASH_CS(0);                         //使能器件   
    Spi0WriteRead(W25X_PowerDown);           //发送掉电命令  
          SPI_FLASH_CS(1);                         //取消片选                  
    Delayus(3);                              //等待TPD  
}   
/****************************************
*函数名称:SpiFlashWakeUp
*输    入:无
*输    出:无
*功    能:唤醒
******************************************/
VOID SpiFlashWakeUp(VOID)   
{  
          SPI_FLASH_CS(0);                            //使能器件   
    Spi0WriteRead(W25X_ReleasePowerDown);       //发送唤醒指令
          SPI_FLASH_CS(1);                            //取消片选                  
    Delayus(3);                                 //等待TRES1
}   

























使用特权

评论回复
7
wahahaheihei| | 2015-11-17 15:20 | 只看该作者
#include "SmartM_M0.h"
/****************************************
*函数名称:Spi0Length
*输    入:ucLength 数据长度
*输    出:无
*功    能:设置SPI0数据长度
******************************************/
STATIC VOID Spi0Length(UINT8 ucLength)
{
    if(ucLength <= 0x20)
    {
        if((ucLength & 0x01) == 0)
            SPI0_CNTRL &= ~(1<<3);
        else
            SPI0_CNTRL |= (1<<3);
        if((ucLength & 0x02) == 0)
            SPI0_CNTRL &= ~(1<<4);
        else
            SPI0_CNTRL |= (1<<4);

        if((ucLength & 0x04) == 0)
            SPI0_CNTRL &= ~(1<<5);
        else
            SPI0_CNTRL |= (1<<5);

        if((ucLength & 0x08) == 0)
            SPI0_CNTRL &= ~(1<<6);
        else
            SPI0_CNTRL |= (1<<6);

        if((ucLength & 0x10) == 0)
            SPI0_CNTRL &= ~(1<<7);
        else
            SPI0_CNTRL |= (1<<7);
    }
}
/****************************************
*函数名称:Spi0MasterInit
*输    入:无
*输    出:无
*功    能:SPI0初始化为主机模式
******************************************/
VOID Spi0MasterInit(VOID)
{
    P1_MFP &= ~(
                                P15_AIN5_SPI0MOSI |
                                P16_AIN6_SPI0MISO |
                                P17_AIN7_SPI0CLK) ;  
       
                P1_MFP |= (
                                                SPI0MOSI |
                                         SPI0MISO |
                                         SPI0CLK) ;           //使能SPI0相关引脚


                APBCLK |= SPI0_CLKEN;       //SPI0时钟使能

                                                              
    SPI0_SSR &= ~LVL_H;                   //从机选择选择信号通过低电平激活

    SPI0_CNTRL &= ~LSB_FIRST;   //优先发送/接收最高有效位
    SPI0_CNTRL &= ~CLKP_IDLE_H; //SCLK空闲时为低电平
    SPI0_CNTRL |= TX_NEG_F;     //SDO 信号在SPICLK的下降沿改变
    SPI0_CNTRL &= ~RX_NEG_F;    //SDI 信号在SPICLK上升沿锁存
    SPI0_CNTRL &= TX_NUM_ONE;   
    Spi0Length(0x08);

    SPI0_DIVIDER &= 0xFFFF0000;   //DIVIDER = 0x0000, SPIclk = Pclk/((HCLK_N+1)*2)
    SPI0_DIVIDER |= 1;                              //(50Mhz/6)=8.25MHz

    SPI0_CNTRL &= ~SPI_MODE_SLAVE;    //SPI0工作在主机模式
    SPI0_SSR   &= ~ASS_AUTO;                 //Slave Select non-auto
}

/****************************************
*函数名称:Spi0WriteRead
*输    入:ucData 要发送的数据
*输    出:返回字节数据
*功    能:SPI0读写数据
******************************************/
UINT8 Spi0WriteRead(UINT8 ucData)
{
    SPI0_SSR |= SSR_ACT;

    SPI0_TX0 = ucData;

    SPI0_CNTRL |= GO_BUSY;      

                while((SPI0_CNTRL & GO_BUSY)!=0);

                SPI0_SSR &= ~SSR_ACT;

                return (UINT8)SPI0_RX0;
}


VOID Spi0SetSpeedHigh(VOID)
{
    SPI0_DIVIDER &= 0xFFFF0000; //DIVIDER = 0x0000, SPIclk = Pclk/((HCLK_N+1)*2)
    SPI0_DIVIDER |= 1;       
       
}

VOID Spi0SetSpeedLow(VOID)
{
    SPI0_DIVIDER &= 0xFFFF0000; //DIVIDER = 0x0000, SPIclk = Pclk/((HCLK_N+1)*2)
    SPI0_DIVIDER |= 0xFF;               
       
}




使用特权

评论回复
8
rejoice818| | 2015-11-17 21:25 | 只看该作者
顶起!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:不忘初心,积极乐观,勤且道义!

242

主题

1995

帖子

12

粉丝