5120|14

7815

帖子

56

TA的资源

裸片初长成(中级)

楼主
 

只为uC而生,uS成长历程23 spi-flash sst25vfxxx [复制链接]

还是拖了很久,今天终于可以继续更新了。

弄了两个晚上加早上一个多小时,先是把原先 独立的用于测试sst25vf080的flash读写例程 改写成可以方便移入 uS的形式。

这里面遵循的是一个分层的原则,在细说这个以前,我先撑现在还记得,先记下两个新的想法,它很可能是 uS-v0.31 uS-v0.32的内容;

1.模块/函数 运行的超时强制退出机制;
2.如果要我从外部植入一个 变量,去作为uS内部的时间单位,这也许并不是一件那么让人深恶痛绝的事情——而且,它也可以配合以后,但系统上采用了RTC时钟或者可以通过网络获得时间的时候,可以自动计算出来;

现在说回这个分层的简单想法:

首先,sst25vf080是一款 flash接口的 大容量存储器芯片;
因此我们首先要知道,它的操作是符合 标准spi操作的;
其次,我们还知道,sst25vfxxx会有很多其它容量的型号;

再者,我们的一个系统上可能不止一个 sst25vf080,或者更一般的,不止一个spi器件。
难道我们要为每一个spi器件写一套spi操作?

那就太傻了。
所以,从一开始——之前的 uSConsole我也是这么干的。
我用结构体封装操作函数指针 来实现 灵活复用。

沙发贴会先简单上 spi 的 结构体定义;

具体的等我吃完午饭,移入uS中再说——因为这个过程可能还会遇到之前没有考虑到的事情。

此帖出自编程基础论坛

最新回复

#include #define CE_H   P5OUT |=BIT3 #define CE_L   P5OUT &=~BIT3 unsigned char temp; void flash_inint(void) { P5DIR |= BIT3;     //  CE P2SEL |= BIT0|BIT1; // BIT0   SI P2DIR |= BIT0;    // SO P1SEL |= BIT7 ;// sck P1DIR |= BIT7; UCB0CTLW0 |= UCSWRST;                            //启用复位                      UCB0CTLW0 |= UCMST | UCSYNC |UCCKPL  ;// //分别为 主模式;同步模式;时钟极性选择 3线模式 UCB0CTLW0 |= UCMSB;       //UCB0CTLW0 |= UCMODE0;                         UCB0CTLW0 |= UCSSEL_1;                           // 选择ACLK时钟 UCB0BRW_L = 0x02;                                //  波特率控制位;fBitClock = fBRCLK/(UCBRx+1) ; UCB0BRW_H = 0;    //UCB0MCTLW = 0;                               // UCB0CTLW0 &= ~UCSWRST;                        //禁止复位 UCB0IE |=UCRXIE; } //******************************* void ID_date()// 这种情况下输出的波形和数据是正确的 {                              unsigned char  i; for(i=0;i  详情 回复 发表于 2015-2-10 16:03
点赞 关注
个人签名

强者为尊,弱者,死无葬身之地

 

回复
举报

7815

帖子

56

TA的资源

裸片初长成(中级)

沙发
 
这是模拟的spi操作。 头文件 很简单,因为spi的基本功能很简单
——我隐隐觉得,为了更好地调试和提升性能,这个模块还应加入一些检测用的判断用的接口。但现在实在没啥感觉。

  1. typedef struct
  2. {
  3.     int DriverValidFlag;
  4.     void (*SpiInitial)(void);
  5.    
  6.     void (*SpiClkHigh)(void);
  7.     void (*SpiClkLow)(void);
  8.    
  9.     void (*SpiMosiHigh)(void);
  10.     void (*SpiMosiLow)(void);
  11.    
  12.     unsigned char (*SpiMisoState)(void);
  13.    
  14.     void (*SpiCeHigh)(void);
  15.     void (*SpiCeLow)(void);
  16. }SpiDriverStr;

  17. void SpiWrite(SpiDriverStr driver,unsigned char character);
  18. unsigned char SpiRead(SpiDriverStr driver);

  19. void SpiDriver_Clear(SpiDriverStr *driver);
  20. int isSpiDriverValid(SpiDriverStr driver);

  21. #endif
复制代码
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

板凳
 
可能是因为这只是一个很简单的 读写功能实现。
不存在什么异步操作,所以整个程序显得很简单。

过后估计有很多细节要考虑。比如对某些边界的设置。
不过,今天好像没啥状态接着弄了,只是集成进uS了。
先把相关代码贴出来吧。

此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

4
 
  1. // Spi部分
  2. #ifndef _US_SPI_
  3. #define _US_SPI_

  4. #include "typedef.h"

  5. typedef struct
  6. {
  7.     int DriverValidFlag;
  8.     void (*SpiInitial)(void);
  9.    
  10.     void (*SpiClkHigh)(void);
  11.     void (*SpiClkLow)(void);
  12.    
  13.     void (*SpiMosiHigh)(void);
  14.     void (*SpiMosiLow)(void);
  15.    
  16.     unsigned char (*SpiMisoState)(void);
  17.    
  18.     void (*SpiCeHigh)(void);
  19.     void (*SpiCeLow)(void);
  20. }SpiDriverStr;

  21. void SpiWrite(SpiDriverStr driver,U8 character);
  22. U8 SpiRead(SpiDriverStr driver);

  23. void SpiDriver_Clear(SpiDriverStr *driver);
  24. int isSpiDriverValid(SpiDriverStr driver);


  25. #endif


  26. //
  27. #include "uS_Spi.h"
  28. #include <stdlib.h>

  29. void SpiDriver_Clear(SpiDriverStr *driver)
  30. {
  31.      driver->DriverValidFlag = 0;
  32.      
  33.      driver->SpiInitial = NULL;
  34.      
  35.      driver->SpiClkHigh = NULL;
  36.      driver->SpiClkLow = NULL;
  37.      
  38.      driver->SpiCeHigh = NULL;
  39.      driver->SpiCeLow = NULL;
  40.      
  41.      driver->SpiMisoState = NULL;
  42.      
  43.      driver->SpiMosiHigh = NULL;
  44.      driver->SpiMosiLow = NULL;
  45. }

  46. int isSpiDriverValid(SpiDriverStr driver)
  47. {
  48.      if(driver.SpiInitial == NULL)
  49.         return 0;
  50.      
  51.      if(driver.SpiClkHigh == NULL)
  52.         return 0;
  53.      if(driver.SpiClkLow == NULL)
  54.         return 0;
  55.         
  56.      if(driver.SpiCeHigh == NULL)
  57.         return 0;
  58.      if(driver.SpiCeHigh == NULL)
  59.         return 0;
  60.         
  61.      if(driver.SpiMisoState == NULL)
  62.         return 0;
  63.         
  64.      if(driver.SpiMosiHigh == NULL)
  65.         return 0;
  66.      if(driver.SpiMosiLow == NULL)
  67.         return 0;
  68.      
  69.      return 1;
  70. }

  71. void SpiWrite(SpiDriverStr driver,U8 character)
  72. {
  73.    U8 count;
  74.    U8 temp = character;
  75.    
  76.    for(count = 8;count > 0;count--)
  77.    {   
  78.       (*(driver.SpiClkLow))();
  79.       
  80.       if(temp&0x80)
  81.           (*(driver.SpiMosiHigh))();
  82.       else
  83.           (*(driver.SpiMosiLow))();
  84.    
  85.        (*(driver.SpiClkHigh))();
  86.       temp<<=1;
  87.    }
  88.    
  89.    count = 0;
  90. }

  91. U8 SpiRead(SpiDriverStr driver)
  92. {
  93.    int count;
  94.    U8 read = 0;
  95.    
  96.    for(count = 8;count > 0;count--)
  97.    {   
  98.        (*(driver.SpiClkLow))();
  99.        (*(driver.SpiClkHigh))();
  100.        read<<=1;
  101.        if((*(driver.SpiMisoState))())  read |= 1;
  102.    }
  103.    return read;
  104. }
复制代码
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

5
 
  1. // sst25vfxxx部分
  2. #ifndef _US_SST25_
  3. #define _US_SST25_

  4.     #define SST25_READ           0x03   
  5.     #define SST25_WRITE          0x02   
  6.     #define SST25_AUTO_INCR      0xAF  
  7.     #define SST25_SECTOR_EREASE  0x20
  8.     #define SST25_BLOCK_EREASE   0x52
  9.     #define SST25_CHIP_EREASE    0x60
  10.     #define SST25_READ_ID        0x90

  11.     #include "uS_Spi.h"

  12.     #define YES 1
  13.     #define NO  0

  14.     void Chip_Erease(SpiDriverStr Operator);

  15.     U8 readFlash(SpiDriverStr Operator,U32 star_addr);
  16.     void FlashRead(SpiDriverStr Operator,U32 star_addr,U16 len,U8 *buffer);

  17.     void writeFlash(SpiDriverStr Operator,U32 start_addr,U8 date);
  18.     void FlashWrite_Auto_BYTE(SpiDriverStr Operator,U32 start_addr,U16 len,U8 *buffer);
  19.     void FlashWrite_AutoIncrement_BYTE(SpiDriverStr Operator,U32 start_addr,U16 len,U8 *buffer);

  20.     U8 Read_State_Register(SpiDriverStr Operator);
  21.     void StateRegister_Write(SpiDriverStr Operator,U8 NewStatus);

  22.     void Wait_Busy(SpiDriverStr Operator);
  23.     void WREN_Check(SpiDriverStr Operator);

  24.     void Write_EN(SpiDriverStr Operator);
  25.     void Write_DISABLE(SpiDriverStr Operator);
  26.     void State_Register_WR_EN(SpiDriverStr Operator);
  27.     void State_Register_WR(SpiDriverStr Operator) ;

  28.     void Sector_Erease(SpiDriverStr Operator,U32 start_addr);
  29.     void Block_Erease(SpiDriverStr Operator,U32 start_addr);

  30.     U16 Read_ID(SpiDriverStr Operator);

  31.     U32 Flash_Read_ID(SpiDriverStr Operator);
  32.     U32 Test_Read_ID(SpiDriverStr Operator);
  33.     void WREN_Check(SpiDriverStr Operator);

  34. #endif

  35. //
  36. #include "uS_sst25vfxxx.h"

  37. static void ChipSelect(SpiDriverStr Operator,int NewState)
  38. {
  39.      if(NewState == YES)
  40.         (*(Operator.SpiCeLow))();
  41.      else
  42.         (*(Operator.SpiCeHigh))();
  43. }

  44. //==============================================================================

  45. U8 Read_State_Register(SpiDriverStr Operator)
  46. {   
  47.   U8 Read_date;
  48.   
  49.   ChipSelect(Operator,YES);   
  50.   SpiWrite(Operator,0x05);
  51.   Read_date = SpiRead(Operator);
  52.   ChipSelect(Operator,NO);
  53.   return Read_date;
  54. }

  55. void StateRegister_Write(SpiDriverStr Operator,U8 NewStatus)
  56. {
  57.   ChipSelect(Operator,YES);   
  58.   SpiWrite(Operator,0x50);
  59.   ChipSelect(Operator,NO);
  60.   
  61.   ChipSelect(Operator,YES);   
  62.   SpiWrite(Operator,0x01);
  63.   SpiWrite(Operator,NewStatus);
  64.   ChipSelect(Operator,NO);
  65. }

  66. void State_Register_WR_EN(SpiDriverStr Operator)
  67. {
  68.   ChipSelect(Operator,YES);   
  69.   SpiWrite(Operator,0x50);
  70. }

  71. void State_Register_WR(SpiDriverStr Operator)
  72. {
  73.   ChipSelect(Operator,YES);   
  74.   SpiWrite(Operator,0x01);
  75.   ChipSelect(Operator,NO);
  76. }

  77. void Wait_Busy(SpiDriverStr Operator)
  78. {
  79.   while( ( Read_State_Register(Operator) & 0x01)  == 0x01);
  80. }

  81. void WREN_Check(SpiDriverStr Operator)
  82. {
  83.    U8 byte;
  84.    
  85.    byte = Read_State_Register(Operator);
  86.    if ((byte&0x02) != 0x02)   Write_EN(Operator);
  87. }

  88. void Write_EN(SpiDriverStr Operator)
  89. {
  90.     ChipSelect(Operator,YES);   
  91.     SpiWrite(Operator,0x06);
  92.     ChipSelect(Operator,NO);
  93. }

  94. void Write_DISABLE(SpiDriverStr Operator)
  95. {
  96.   ChipSelect(Operator,YES);   
  97.   SpiWrite(Operator,0x04);
  98.   ChipSelect(Operator,NO);
  99. }

  100. //==============================================================================

  101. void Chip_Erease(SpiDriverStr Operator)
  102. {
  103.     ChipSelect(Operator,YES);
  104.     Write_EN(Operator);
  105.     ChipSelect(Operator,YES);
  106.     SpiWrite(Operator,SST25_CHIP_EREASE);
  107.     ChipSelect(Operator,NO);   
  108. }

  109. U8 readFlash(SpiDriverStr Operator,U32 star_addr)
  110. {
  111.     U8 byte;
  112.    
  113.     ChipSelect(Operator,YES);

  114.     SpiWrite(Operator,SST25_READ);
  115.     SpiWrite(Operator,(U8)(star_addr>>16));
  116.     SpiWrite(Operator,(U8)(star_addr>>8));
  117.     SpiWrite(Operator,(U8)star_addr);
  118.    
  119.     byte = SpiRead(Operator);
  120.    
  121.     ChipSelect(Operator,NO);
  122.     return byte;
  123. }

  124. void writeFlash(SpiDriverStr Operator,U32 start_addr,U8 date)
  125. {
  126.     Write_EN(Operator);

  127.     ChipSelect(Operator,YES);   
  128.    
  129.     SpiWrite(Operator,SST25_WRITE);
  130.     SpiWrite(Operator,(U8)(start_addr>>16));
  131.     SpiWrite(Operator,(U8)(start_addr>>8));
  132.     SpiWrite(Operator,(U8)start_addr);
  133.    
  134.     SpiWrite(Operator,date);
  135.     ChipSelect(Operator,NO);
  136. }

  137. void Sector_Erease(SpiDriverStr Operator,U32 start_addr)
  138. {
  139.   Write_EN(Operator);
  140.   ChipSelect(Operator,YES);   

  141.   SpiWrite(Operator,SST25_SECTOR_EREASE);
  142.   SpiWrite(Operator,(U8)(start_addr>>8));
  143.   SpiWrite(Operator,(U8)start_addr);
  144.   
  145.   ChipSelect(Operator,NO);
  146. }

  147. void Block_Erease(SpiDriverStr Operator,U32 start_addr)
  148. {
  149.   Write_EN(Operator);
  150.   ChipSelect(Operator,YES);   
  151.   SpiWrite(Operator,SST25_BLOCK_EREASE);
  152.   SpiWrite(Operator,(U8)(start_addr>>8));
  153.   SpiWrite(Operator,(U8)start_addr);

  154.   ChipSelect(Operator,NO);
  155. }
复制代码
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

6
 
也许是呆在房间里觉得冷还是下午刚睡醒的原因,感觉人有点迟钝。
或者觉得对这段代码也没什么好说的,因为对我来说,用回调函数指针的方法也不算什么新鲜,值得特别说明的地方。
或者我觉得光看代码已经足够说明一切了吧。

但是我却隐隐觉得这个实现方案相当粗糙。
另外就是,我一直在想 楼主贴里 提到的 那个 0.31 0.32的事情。
不过不管怎么说,这个周末,至少,真的是把这个 uS-v0.3搞定了。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

7
 
终于想起差了些什么了。
按照我以往的惯例,完成一个模块,我就会加一个测试,我还没加,所以漏了。
周末也差不多了,这个事情干脆推后一两天。
先整理整理别的事情。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

8
 
你好版主:
   我现在用SST25VF040B这个芯片 有个问题想麻烦你一下:
  能正确读取出芯片的id     但是不能对芯片读写  这是什么问题   我用的单片机是msp430带 SPI 接口。
   谢谢
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

9
 
f127314 发表于 2015-2-9 16:44
你好版主:
   我现在用SST25VF040B这个芯片 有个问题想麻烦你一下:
  能正确读取出芯片的id     但是不能对芯片读写  这是什么问题   我用的单片机是msp430带 SPI 接口。
   谢谢
能读ID,说明时序没问题。

按道理和 硬软SPI没太大关系。

比对一下 操作的顺序、命令字什么的。

另外,写要记得先擦除片区。

我突然怀疑你的片子是新的话,就是从来没擦除过,是不是应该首先擦除一次整个片子。

我猜测你是 写进去再读出来,所以如果你根本就没成功写进去过,你自然会觉得读出来也是错的——比如说你读出来的都是 0xff,那很可能读是没错的;



此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

10
 
#include
#include "flash.h"
//unsigned char num[]={0,0,0};
//unsigned char i;
//******F LASH inint函数 ******************************
void flash_inint(void)
{
P5DIR |= BIT3;//  CE使能管脚
P2SEL |= BIT0|BIT1;
P2DIR |=BIT1;
P1SEL |= BIT7 ;
P1DIR |=BIT7;
UCB0CTLW0 |= UCSWRST;                            //启用复位                     
UCB0CTLW0 |= UCMST | UCSYNC | UCMSB| UCCKPL;//  |UCCKPL //分别为 主模式;同步模式;时钟极性选择  0是低 1是高;
//UCB0CTLW0 |= UCSTEM ; // | UCMODE1                        // 选择输出是  MSB还是LSB
//UCBOSTATW_SPI |= UCFE; |UCBUSY;
UCB0CTLW0 |= UCSSEL_1;                           // 选择ACLK时钟
UCB0BRW_L = 0x02;                                //  波特率控制位;fBitClock = fBRCLK/(UCBRx+1) ;
UCB0BRW_H = 0;   
//UCB0MCTLW = 0;                               //
UCB0CTLW0 &= ~UCSWRST;                        //禁止复位
UCB0IE |=UCRXIE;
//UCB0IE |=UCTXIE;
}
//*************写使能函数**********************
void wren_date(void)
{
CE_L;
UCB0TXBUF=0X06;
CE_H;
}
//**************读取状态寄存器**********************************
void RDSR_date(void)
{
CE_L;
UCB0TXBUF=0X05;
while (!(UCB0IFG & UCTXIFG)) ;
temp=UCB0RXBUF;
/*for(i=0;i<7;i++)
{
temp=(num & 0x80)<<8;
}*/
UCA1TXBUF=temp;
__delay_cycles(24);
//CE_H;
}
//****************写状态寄存器***************************************、
void WRSR_date(void)
{
wren_date();
CE_L;
UCB0TXBUF=0X06;
//CE_H;
__delay_cycles(10);
CE_L;
UCB0TXBUF=0X01;
UCB0TXBUF=0X00;
//CE_H;

}

//***********读取flash 函数******************************
void read_date()//unsigned long addess
{
wren_date();
CE_L;
UCB0TXBUF=0x03;
UCB0TXBUF=0x55;
UCB0TXBUF=0x55;
UCB0TXBUF=0x50;
__delay_cycles(24);
//CE_H;

}
//******************** FLASH写入数据 **************************
void Write_date(unsigned char temp)//unsigned long addess,
{
wren_date();
CE_L;
UCB0TXBUF=0X02;
wren_date();
UCB0TXBUF=0x55;
wren_date();
UCB0TXBUF=0x55 ;
wren_date();
UCB0TXBUF=0x50;
wren_date();
UCB0TXBUF=temp;
//CE_H;
}
//**************** 扇区擦除FLAH 4KB 32KB 64KB 扇形区***********************
void wipe_date(unsigned char wp ,unsigned long addess )
{
wren_date();
CE_L;
UCB0TXBUF=wp;
UCB0TXBUF=((addess & 0xFF0000)>>16);
UCB0TXBUF=((addess & 0xFF00)>>8);
UCB0TXBUF=(addess & 0xFF);
CE_H;
}
//****************全片擦除******************************
void ERASE_ALL(void)
{
wren_date();  
UCB0TXBUF=0X60;
delayms(4);
//CE_H;
}
//*********读芯片id**********************************
void ID_date()
{
//CE_H;
CE_L;
UCB0TXBUF=0X9F;
//__delay_cycles(24);

//

}
//******************读取RDID*************************************
void RDID_date(void)
{
CE_L;
UCB0TXBUF=0x90;
UCB0TXBUF=0x00;
UCB0TXBUF=0x00;
UCB0TXBUF=0x00;
__delay_cycles(24);
//CE_H;
}
//*******************测试函数****************************
void ceshi(void)
{
CE_L;
UCB0TXBUF=0X05;


}
//****************中断服务函数***************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch (__even_in_range(UCB0IV, 4))
    {
        case USCI_NONE: break;              // No interrupt
        case USCI_SPI_UCRXIFG:              // RXIFG
            while (!(UCA1IFG & UCTXIFG)) ;
                UCA1TXBUF= UCB0RXBUF;
                __delay_cycles (2);                                   // USCI_A0 TX buffer ready?
                 break;
               
            
        case USCI_SPI_UCTXIFG: break;       // TXIFG
        default: break;
    }
}
我又擦除过哦     现在是这样  CE这个管教必须一直为低才能读出来  这是为什么?
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

11
 
f127314 发表于 2015-2-9 17:27
#include
#include "flash.h"
//unsigned char num[]={0,0,0};
//unsigned char i;
//******F LASH inint函数 ******************************
void flash_inint(void)
{
P5DIR |= BIT3;//  CE使能管脚
P2SEL |= BIT0|BIT1;
P2DIR |=BIT1;
P1SEL |= BIT7 ;
P1DIR |=BIT7;
UCB0CTLW0 |= UCSWRST;                            //启用复位                     
UCB0CTLW0 |= UCMST | UCSYNC | UCMSB| UCCKPL;//  |UCCKPL //分别为 主模式;同步模式;时钟极性选择  0是低 1是高;
//UCB0CTLW0 |= UCSTEM ; // | UCMODE1                        // 选择输出是  MSB还是LSB
//UCBOSTATW_SPI |= UCFE; |UCBUSY;
UCB0CTLW0 |= UCSSEL_1;                           // 选择ACLK时钟
UCB0BRW_L = 0x02;                                //  波特率控制位;fBitClock = fBRCLK/(UCBRx+1) ;
UCB0BRW_H = 0;   
//UCB0MCTLW = 0;                               //
UCB0CTLW0 &= ~UCSWRST;                        //禁止复位
UCB0IE |=UCRXIE;
//UCB0IE |=UCTXIE;
}
//*************写使能函数**********************
void wren_date(void)
{
CE_L;
UCB0TXBUF=0X06;
CE_H;
}
//**************读取状态寄存器**********************************
void RDSR_date(void)
{
CE_L;
UCB0TXBUF=0X05;
while (!(UCB0IFG & UCTXIFG)) ;
temp=UCB0RXBUF;
/*for(i=0;i>8);
UCB0TXBUF=(addess & 0xFF);
CE_H;
}
//****************全片擦除******************************
void ERASE_ALL(void)
{
wren_date();  
UCB0TXBUF=0X60;
delayms(4);
//CE_H;
}
//*********读芯片id**********************************
void ID_date()
{
//CE_H;
CE_L;
UCB0TXBUF=0X9F;
//__delay_cycles(24);

//

}
//******************读取RDID*************************************
void RDID_date(void)
{
CE_L;
UCB0TXBUF=0x90;
UCB0TXBUF=0x00;
UCB0TXBUF=0x00;
UCB0TXBUF=0x00;
__delay_cycles(24);
//CE_H;
}
//*******************测试函数****************************
void ceshi(void)
{
CE_L;
UCB0TXBUF=0X05;


}
//****************中断服务函数***************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch (__even_in_range(UCB0IV, 4))
    {
        case USCI_NONE: break;              // No interrupt
        case USCI_SPI_UCRXIFG:              // RXIFG
            while (!(UCA1IFG & UCTXIFG)) ;
                UCA1TXBUF= UCB0RXBUF;
                __delay_cycles (2);                                   // USCI_A0 TX buffer ready?
                 break;
               
            
        case USCI_SPI_UCTXIFG: break;       // TXIFG
        default: break;
    }
}
我又擦除过哦     现在是这样  CE这个管教必须一直为低才能读出来  这是为什么?
我没做过  硬SPI 的情形
但从代码来看,显然是因为,如果按照你程序里的写法,总是存在SPI操作未完成之时你就已经拉高了CE,即禁止了SPI操作。

所以你不能靠简单的延迟判断,要依赖其他动作,比如说,什么标志位一类的。

另外就是,硬SPI,我记得在引脚上是看到有CE脚的,为什么不用硬SPI本来的操作,要自己另外 写CE脚状态?

此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

12
 
但是我给他__delay_cycles(24); 之后时间足够用了  CE这个管脚还是不能为高,我用示波器测试 单片机的输   si  sck 管脚有数据输出   flash芯片的  so  管脚输出的波形 单片机无法识别。
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

13
 
f127314 发表于 2015-2-9 17:45
但是我给他__delay_cycles(24); 之后时间足够用了  CE这个管脚还是不能为高,我用示波器测试 单片机的输   si  sck 管脚有数据输出   flash芯片的  so  管脚输出的波形 单片机无法识别。
你所认为的 这个延迟时间足够用了,是来源于什么判断?
spi的理论操作时间么?

呵呵,坦白说,先不说这种思维方式是不对的——肯定是要来自实际事件、动作的反馈是最好的,靠计算理论时间是很不靠谱的。

另一点就是,stm32的库,关于硬件SPI的操作时间,你有没测试过?这玩意简直是一塌糊涂,相信它能表现的如同标准时序那就死定了。

你最后提到 单片机的 SI SCK是对的。
但是,FLASH芯片的SO接收的波形单片机无法识别。

这话听着有点奇怪啊。

你想说的是不是 单片机的SI 接着 FLASH芯片的 SO,SO你测到波形是对的,但单片机无法识别?

如果是这样,那我觉得就是 STM32 硬SPI的时序表现有问题,也就是我之前提到的意见。
STM32的库所实现的硬SPI功能其实是很乱的。

此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

14
 
#include
#define CE_H   P5OUT |=BIT3
#define CE_L   P5OUT &=~BIT3
unsigned char temp;

void flash_inint(void)
{
P5DIR |= BIT3;     //  CE
P2SEL |= BIT0|BIT1; // BIT0   SI
P2DIR |= BIT0;    // SO
P1SEL |= BIT7 ;// sck
P1DIR |= BIT7;
UCB0CTLW0 |= UCSWRST;                            //启用复位                     
UCB0CTLW0 |= UCMST | UCSYNC |UCCKPL  ;// //分别为 主模式;同步模式;时钟极性选择 3线模式
UCB0CTLW0 |= UCMSB;      
//UCB0CTLW0 |= UCMODE0;                        
UCB0CTLW0 |= UCSSEL_1;                           // 选择ACLK时钟
UCB0BRW_L = 0x02;                                //  波特率控制位;fBitClock = fBRCLK/(UCBRx+1) ;
UCB0BRW_H = 0;   
//UCB0MCTLW = 0;                               //
UCB0CTLW0 &= ~UCSWRST;                        //禁止复位
UCB0IE |=UCRXIE;
}

//*******************************
void ID_date()// 这种情况下输出的波形和数据是正确的
{                             
unsigned char  i;
for(i=0;i<3;i++)
{
CE_L;
UCB0TXBUF=0X9f;
UCA1TXBUF=temp;
}
if(UCRXIFG==0){CE_H;}  // 判断SPI 接收标志位 是否为0;为0 结束
else          {CE_L;}
}
//********************************
void ceshi(void)  
{
CE_L;
UCB0TXBUF=0X05;
if(UCRXIFG==0){CE_H;}   // 判断SPI 接收标志位 是否为0;为0 结束
else          {CE_L;}
}
//******************************************

int main()
{
WDTCTL = WDTPW | WDTHOLD;
flash_inint();
//usci_init();
__bis_SR_register(GIE);
//__bis_SR_register(LPM3_bits | GIE);
CE_L;
UCB0TXBUF=0x06;  // 写使能
UCB0TXBUF=0x60;  //全片擦除
__delay_cycles(20); // 全片擦除时间

while(1)
{

CE_L;
UCB0TXBUF=0x06; // 写使能
UCB0TXBUF=0x02; // 编程一个数据字节
UCB0TXBUF=0x70; // 地址
UCB0TXBUF=0x00;
UCB0TXBUF=0x00;
UCB0TXBUF=0xF0; // 数据
CE_L;
__delay_cycles(20);
CE_L;
UCB0TXBUF=0x06;  //写使能
UCB0TXBUF=0x03;   
UCB0TXBUF=0x70; // 地址
UCB0TXBUF=0x00;
UCB0TXBUF=0x00;
if(UCRXIFG==0){CE_H;}    // 判断SPI 接收标志位 是否为0;为0 结束
else          {CE_L;}     // FALSH 芯片  SO 口输出的波形用示波器观察 只有 200mv time 2.000us
__delay_cycles(100); // 延时
}


}

//***********************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch (__even_in_range(UCB0IV, 4))
{
case USCI_NONE: break;              // No interrupt
case USCI_SPI_UCRXIFG:              // RXIFG
while (!(UCB0IFG & UCTXIFG));
temp=UCB0RXBUF;
break;                                // USCI_A0 TX buffer ready?
case USCI_SPI_UCTXIFG: break;       // TXIFG
default: break;
}
}
我用的MSP430F6733 这个单片机 ,  我采用3线模式  SO  输出的波形 只有200mv   单片机根本无法识别啊。。

67333.png (19.02 KB, 下载次数: 0)

67333.png
此帖出自编程基础论坛
 
 
 

回复

7815

帖子

56

TA的资源

裸片初长成(中级)

15
 
f127314 发表于 2015-2-10 16:03
#include
#define CE_H   P5OUT |=BIT3
#define CE_L   P5OUT &=~BIT3
unsigned char temp;

void flash_inint(void)
{
P5DIR |= BIT3;     //  CE
P2SEL |= BIT0|BIT1; // BIT0   SI
P2DIR |= BIT0;    // SO
P1SEL |= BIT7 ;// sck
P1DIR |= BIT7;
UCB0CTLW0 |= UCSWRST;                            //启用复位                     
UCB0CTLW0 |= UCMST | UCSYNC |UCCKPL  ;// //分别为 主模式;同步模式;时钟极性选择 3线模式
UCB0CTLW0 |= UCMSB;      
//UCB0CTLW0 |= UCMODE0;                        
UCB0CTLW0 |= UCSSEL_1;                           // 选择ACLK时钟
UCB0BRW_L = 0x02;                                //  波特率控制位;fBitClock = fBRCLK/(UCBRx+1) ;
UCB0BRW_H = 0;   
//UCB0MCTLW = 0;                               //
UCB0CTLW0 &= ~UCSWRST;                        //禁止复位
UCB0IE |=UCRXIE;
}

//*******************************
void ID_date()// 这种情况下输出的波形和数据是正确的
{                             
unsigned char  i;
for(i=0;i
哦,不过这个和 单片机类型无关。
看来是波形有问题。

嗯,我想是不是你没把SPI的几个脚 加上上拉电阻。
不然怎么这么低?

总之好好查查IO口配置


此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表