找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6633|回复: 8
打印 上一主题 下一主题
收起左侧

关于STM32F103VC的SPI通信问题(AT45DB642D)

[复制链接]
跳转到指定楼层
楼主
ID:58348 发表于 2014-8-21 10:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 姗姗 于 2014-8-21 10:54 编辑

写数据总是写不进去,有关程序如下:              /***SPI_ReadWrite_Byte()****SPI发送或接收1字节***********************/

static u8 SPI_ReadWrite_Byte(u8 byte)
        {
         /*等待发送寄存器空*/
         while((SPI2->SR & SPI_I2S_FLAG_TXE)==RESET);
            /*发送一个字节*/
         SPI2->DR = byte;
         /* 等待接收寄存器有效*/
         while((SPI2->SR & SPI_I2S_FLAG_RXNE)==RESET);
         return (SPI2->DR);
                                                 }


/***Dataflash_read_status()*****读取状态寄存器**************************/

u8 Dataflash_read_status(void)
        {
         u8 data;
        
         SPI_Data_Flash_AT_SELECT();                      //片选Dataflash
         SPI_ReadWrite_Byte(AT45DB_READ_STATE_REGISTER);
         data = SPI_ReadWrite_Byte(0x00);
         SPI_Data_Flash_AT_DESELECT();
         return data;
                                                                   }

/***SPI_Data_Flash_Busy_Detect()*******Data Flash  检测忙*******************/                  

u8 SPI_Data_Flash_Busy_Detect(void)
        {
         u16 i=0;
         
         if((Dataflash_read_status() & AT45DB_DATAFLASH_BUSY_BIT) == 0)
          {
              for(i=0;i<0xff;i++);
          if((Dataflash_read_status() & AT45DB_DATAFLASH_BUSY_BIT) == 0)
            return 0; //空闲返回0
          else
            return 1;  //忙返回1
                                                            }
         else
         {
           return 1;  //忙返回1
                                                           }
                                                                }

bufferPageWrite(u8* data,u16 size,u16 buffer_add,FLASH_BUFFER_NUM buffer_num)
     {
          u16 i;
           if(SPI_Data_Flash_Busy_Detect()==0)               //==0 Data Flash空闲
                 {
                  SPI_Data_Flash_AT_SELECT();                        //片选Dataflash if (buffer_num == FLASH_BUFFER1)
                  if (buffer_num == FLASH_BUFFER1)
                  {
                   SPI_ReadWrite_Byte(AT45DB_BUFFER_1_WRITE);
                  }
                  else
                  {
                   SPI_ReadWrite_Byte(AT45DB_BUFFER_2_WRITE);
                  }
                  SPI_ReadWrite_Byte(0x00);
                  SPI_ReadWrite_Byte(0x00|(buffer_add>>8));
                  SPI_ReadWrite_Byte(buffer_add);
                                
                  for (i=0; i<size; i++)               
                  {
                   SPI_ReadWrite_Byte(data);

                                          }
                  SPI_Data_Flash_AT_DESELECT();
                                                       }
                                                                    }

void FlashPageWrite(u16 page,u8 *Data)               //写一整页
        {                                                                                            
         u16 i;
                 while(SPI_Data_Flash_Busy_Detect());

                 SPI_Data_Flash_AT_SELECT();                      //片选Dataflash if (buffer_num == FLASH_BUFFER1)

                 SPI_ReadWrite_Byte(AT45DB_B1_TO_MM_PAGE_PROG_WITH_ERASE);
                 while(SPI_Data_Flash_Busy_Detect());  
                 if ( page < 8192)
                 {
                  SPI_Data_Flash_AT_SELECT();                     //片选Dataflash if (buffer_num == FLASH_BUFFER1)                          
                  SPI_ReadWrite_Byte((u8)(page>>5));
                  SPI_ReadWrite_Byte((u8)(page<<3));
                  SPI_ReadWrite_Byte(0x00);


                  while(SPI_Data_Flash_Busy_Detect());

                                                      }


                 for (i = 0;i <512; i++)
                 {

                  SPI_ReadWrite_Byte(Data);

                                                 }
                 SPI_Data_Flash_AT_DESELECT();
                                                             }


在线等,谢谢!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2014-8-21 13:43 | 只看该作者
/*******************************************************
说明:
       次程序成功实现SPI简单通信配置,能实现SPI1发送
数据,SPI2接收数据简单通信功能,仅供测试使用。
*******************************************************/
#include "stm32f10x_lib.h"
#include "stm32f10x_conf.h"
#include "ili9320.h"
/****************************/
#define  LCD_X_ADDR  190
#define  LCD_Y_ADDR  100

vu16  SPI_IDx  = 0; //Reveive Data
u16   SPI_ID_Temp = 0; //接收数据备份,用于判断接收到的数据是否发生变化
u16   SPI_ID[4];   //位显示数据
/********** 函数声明 *********/
void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void SPI_Configuration(void);
void Sys_Init(void);
void LCD_Print_Out(void);
/********** 系统初始化 ******************/
void Sys_Init(void)
{
#ifdef DEBUG
    debug();
#endif
     //----- 模块初始化配置 -------
     RCC_Configuration();
     NVIC_Configuration();
     GPIO_Configuration();
     SPI_Configuration();
      //--------- LCD -----------
     Lcd_Configuration();
     ili9320_Initializtion();
     ili9320_Clear(0);
     ili9320_PutChar(LCD_X_ADDR,     LCD_Y_ADDR, 0x30 + 0, 65535, 0);
}
/******* 主函数 **********/
int main(void)
{
     Sys_Init();
     while(1)
     {
           LCD_Print_Out();
     }
}
/******** 用于调试LCD显示数据界面 *********/
void LCD_Print_Out(void)
{
      //如果数据发生变化,则执行数据更新
     if(SPI_ID_Temp != SPI_IDx)
     {
          if(SPI_IDx >= 1000)
          {
               SPI_ID[0] = SPI_IDx  % 10;
               SPI_ID[1] = (SPI_IDx % 100) / 10;
               SPI_ID[2] = (SPI_IDx / 100) % 10;
               SPI_ID[3] = SPI_IDx  / 1000;
               ili9320_PutChar(LCD_X_ADDR,      LCD_Y_ADDR, 0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR, 0x30 + SPI_ID[1], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 65535, 0);
          }
          else if(SPI_IDx >= 100)
          {
               SPI_ID[0] = SPI_IDx  % 10;
               SPI_ID[1] = (SPI_IDx / 10) % 10;
               SPI_ID[2] = SPI_IDx  / 100;
               ili9320_PutChar(LCD_X_ADDR,      LCD_Y_ADDR, 0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR, 0x30 + SPI_ID[1], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 0,     0);
         }
         else if(SPI_IDx >= 10)
         {
               SPI_ID[0] = SPI_IDx % 10;
               SPI_ID[1] = SPI_IDx / 10;
               ili9320_PutChar(LCD_X_ADDR,      LCD_Y_ADDR,  0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR,  0x30 + SPI_ID[1], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 0,     0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 0,     0);
        }
        else
        {
               SPI_ID[0] = SPI_IDx % 10;
               ili9320_PutChar(LCD_X_ADDR,   LCD_Y_ADDR, 0x30 + SPI_ID[0], 65535, 0);
               ili9320_PutChar(LCD_X_ADDR - 8,  LCD_Y_ADDR, 0x30 + SPI_ID[1], 0, 0);
               ili9320_PutChar(LCD_X_ADDR - 16, LCD_Y_ADDR, 0x30 + SPI_ID[2], 0, 0);
               ili9320_PutChar(LCD_X_ADDR - 24, LCD_Y_ADDR, 0x30 + SPI_ID[3], 0, 0);
         }
         SPI_ID_Temp = SPI_IDx;  //数据备份,为判断数据是否发生变化
    }
}
/**************************************************************************/
/**************************************************************************/
/****** 系统时钟配置函数 ********/
void RCC_Configuration(void)
{
      ErrorStatus  HSEStartUpStatus;

      RCC_DeInit();         //RCC system reset(for debug purpose)
      RCC_HSEConfig(RCC_HSE_ON);      //Enable HSE
      HSEStartUpStatus = RCC_WaitForHSEStartUp();  //Wait till HSE is ready
      if(HSEStartUpStatus == SUCCESS)
      {
            FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
            FLASH_SetLatency(FLASH_Latency_2);      //Set 2 Latency cycles
            RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB clock  = SYSCLK
            RCC_PCLK2Config(RCC_HCLK_Div2);  //APB2 clock = HCLK/2
            RCC_PCLK1Config(RCC_HCLK_Div4);  //APB1 clock = HCLK/4
            RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz
            RCC_PLLCmd(ENABLE);          //Enable PLL
            while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  //Wait till PLL is ready  
            RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock source
            while(RCC_GetSYSCLKSource() != 0x08);  //Wait till PLL is used as system clock source
            //-----------------------------------------------------
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
                  | RCC_APB2Periph_SPI1, ENABLE); //GPIOD clock ENABLE
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //TIM2  clock ENABLE
      }
}
/****** 中断配置函数 ********/
void NVIC_Configuration(void)
{
      NVIC_InitTypeDef NVIC_InitStructure;

      //--- 在内存中进行调试 -----   
#ifdef VECT_TAB_RAM
      NIVC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
     //--- 在FLASH中进行调试 ----
#else
      NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x0);
#endif

      //---- 配置TIM2中断,并使能 -----
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
      NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      
      NVIC_Init(&NVIC_InitStructure);
    //------------------------------------
    NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_Init(&NVIC_InitStructure);
}

/********** 通用I/O配置函数 ***************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//------------------
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*****************************************************
函数名称:SPI_Configuration(void)
功能说明:SPI通信模块配置,配置SPI工作模式;
输入参数:无
返回值  :无
*****************************************************/
void SPI_Configuration(void)
{
   SPI_InitTypeDef SPI_InitStructure;
   //--------------------- SPI1 configuration ------------------
   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
   SPI_InitStructure.SPI_Mode   = SPI_Mode_Master;
   SPI_InitStructure.SPI_DataSize  = SPI_DataSize_16b;
   SPI_InitStructure.SPI_CPOL   = SPI_CPOL_Low;
   SPI_InitStructure.SPI_CPHA   = SPI_CPHA_2Edge;
   SPI_InitStructure.SPI_NSS   = SPI_NSS_Soft;
   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
   SPI_InitStructure.SPI_FirstBit    = SPI_FirstBit_MSB;
   SPI_InitStructure.SPI_CRCPolynomial  = 7;
   SPI_Init(SPI1, &SPI_InitStructure);
   //--------- SPI2 configuration ------------------
   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
   SPI_Init(SPI2, &SPI_InitStructure);
   //--------- Enable SPI1 TXE interrupt ------------
   SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
   //--------- Enable SPI2 RXNE interrupt -------------
   SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
   //----- Enable SPI2 ------
   SPI_Cmd(SPI2, ENABLE);
   //----- Enable SPI1 ----
   SPI_Cmd(SPI1, ENABLE);
}
/*************************************************/
#ifdef DEBUG
void assert_failed(u8 *file, u32 line)
{
   while(1)
  {}
}
#endif


/***********************************************************/
/***********************************************************/

#include "stm32f10x_it.h"
/****************************/
extern vu16  SPI_IDx;
/*********** TX发送中断服务子程序 *********************/
void SPI1_IRQHandler(void)
{
//-------- 发送数据 ----------
SPI_I2S_SendData(SPI1, 47);
}
/*********** RX接收中断服务子程序 ****************/
void SPI2_IRQHandler(void)
{
//------------- 接收数据 ------------
SPI_IDx = SPI_I2S_ReceiveData(SPI2);
}
回复

使用道具 举报

板凳
ID:58348 发表于 2014-8-21 13:50 | 只看该作者
admin 发表于 2014-8-21 13:43
/*******************************************************
说明:
       次程序成功实现SPI简单通信配 ...

谢谢,好的,我试下。。
回复

使用道具 举报

地板
ID:1 发表于 2014-8-21 16:24 | 只看该作者
m3的 AT45DB642D 驱动 打开这里下载:http://www.51hei.com/stm32/4165.html
回复

使用道具 举报

5#
ID:58348 发表于 2014-8-22 14:14 | 只看该作者
admin 发表于 2014-8-21 16:24
m3的 AT45DB642D 驱动 打开这里下载:http://www.51hei.com/stm32/4165.html

非常感谢!
回复

使用道具 举报

6#
ID:58348 发表于 2014-8-22 14:14 | 只看该作者
admin 发表于 2014-8-21 16:24
m3的 AT45DB642D 驱动 打开这里下载:http://www.51hei.com/stm32/4165.html

非常感谢!
回复

使用道具 举报

7#
ID:26188 发表于 2014-8-22 14:15 来自手机 | 只看该作者
搞定了吗  美女
回复

使用道具 举报

8#
ID:58348 发表于 2014-9-10 10:19 | 只看该作者
hujia 发表于 2014-8-22 14:15
搞定了吗  美女

已搞定,谢谢!!
回复

使用道具 举报

9#
ID:210996 发表于 2017-12-12 09:53 | 只看该作者
666666,感谢分享
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表