搜索
bottom↓
回复: 2

mega16 spi与flash通信收不到数据!

[复制链接]

出0入0汤圆

发表于 2013-8-13 18:21:32 | 显示全部楼层 |阅读模式

flash输出引脚会有正常的信号,但是一连接单片机所有的信号就都没了,布连单片机用示波器看的时候会有信号输出,读不出来,这是我的程序


#ifndef __w25x40_spi_H
#define __w25x40_spi_H


#define uint8 unsigned char
#define uint16 unsigned int
#define uchar unsigned char
#define uint unsigned int
#define uint32 unsigned long
/*接口定义*/
#define CS_H PORTB|=(1<<4);DDRB|=(1<<4)
#define CS_L PORTB&=(0<<4);DDRB|=(1<<4)

#define DO_   (PINB&0X40);DDRB&=(0<<6)


#define WP_H PORTB|=(1<<2);DDRB|=(1<<2)
#define WP_L PORTB&=(0<<2);DDRB|=(1<<2)

#define CLK_H PORTB|=(1<<7);DDRB|=(1<<7)
#define CLK_L PORTB&=(0<<7);DDRB|=(1<<7)

#define DI_H PORTB|=(1<<5);DDRB|=(1<<5)
#define DI_L PORTB&=(0<<5);DDRB|=(1<<5)

#define HOLD_H PORTB|=(1<<3);DDRB|=(1<<3)
#define HOLD_L PORTB&=(0<<3);DDRB|=(1<<3)

/*命令定义*/
#define W25P_WriteEnable 0x06
#define W25P_WriteDisable 0x04
#define W25P_ReadStatusReg 0x05
#define W25P_WriteStatusReg 0x01
#define W25P_ReadData  0x03
#define W25P_FastReadData 0x0B
#define W25P_PageProgram 0x02
#define W25P_SectorErase 0xD8 // 64KB
#define W25P_ChipErase  0xC7
#define W25P_PowerDown  0xB9
#define W25P_ReleasePowerDown 0xAB
#define W25P_DeviceID  0xAB
#define W25P_ManufactDeviceID 0x90

/*所需函数声明*/
void init_cpu(void);
void IO_Send_Byte(uchar out);
uchar IO_Get_Byte();
void delay(uchar tt);
void IO_Wait_Busy();
void IO_init();
uchar IO_Read_StatusReg();
void IO_Write_StatusReg(uchar byte);
void IO_Write_Enable();
void IO_PowerDown();
void IO_ReleasePowerDown();
uchar IO_Read_ID1();
uint IO_Read_ID2(uchar ID_Addr);
uchar IO_Read_Byte(uint32 Dst_Addr);
void IO_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128);
uchar IO_FastRead_Byte(uint32 Dst_Addr);
void IO_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128);
void IO_Write_Byte(uint32 Dst_Addr, uchar byte);
void IO_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128);
void IO_Erase_Chip();
void IO_Erase_Sector(uint32 Dst_Addr);
void Verify(uchar byte, uchar cor_byte);
void IO_Write_Disable();
void trace(uchar *str,uchar len);
uint IO_Read_ID3();

uint8 upper_128[16];
/*发送一个字节*/

void IO_Send_Byte(uchar out)
{
  uchar i=0;
  CS_L;
  for (i=0;i<8;i++)
  {
  if ((out & 0x80)==0x80)
  { DI_H; }
  else
  { DI_L; }
  
  CLK_H;  
   out=(out<<1);
   NOP();
   NOP();
   NOP();
   NOP();
   
  CLK_L;  
}
}


/*读取型号*/
uchar IO_Read_ID1()
{
uchar byte;
CS_L;  /* enable device */
IO_Send_Byte(W25P_DeviceID); /* send read device ID command (ABh) */
IO_Send_Byte(0);  /* send address */
IO_Send_Byte(0);  /* send address */
IO_Send_Byte(0);  /* send 3_Dummy address */
byte = IO_Get_Byte();  /* receive Device ID byte */
CS_H;    /* disable device */
delay(20); /* remain CS high for tRES2 = 1.8uS */  

return byte;
  
}
/*读取一个字节*/
uchar IO_Get_Byte(void)
{
uchar i=0,in=0,temp=0;
CS_L;
for (i=0;i<8;i++)
{
  in=(in<<1);  /* shift 1 place to the left or shift in 0 */
  temp=DO_;  /* save input */
  
  CLK_H;  /* toggle clock high */
  if (temp==1)  /* check to see if bit is high */
   in|=0x01; /* if high, make bit high */
  CLK_L;  /* toggle clock low */
}
return in;
}

/*一段延时*/
void delay(uchar tt)
{
while(tt--);
}


/*忙检测*/
void IO_Wait_Busy()
{
/*  waste time until not busy WEL & Busy bit all be 1 (0x03). */
while (IO_Read_StatusReg() == 0x03)
  IO_Read_StatusReg();
}



/*读取状态寄存器*/
uchar IO_Read_StatusReg()

{
uchar byte = 0;
CS_L;   /* enable device */
IO_Send_Byte(W25P_ReadStatusReg); /* send Read Status Register co mmand */
byte = IO_Get_Byte();   /* receive byte */
CS_H;    /* disable device */
return byte;
}




/*状态寄存器赋值*/
void IO_Write_StatusReg(uchar byte)
{
CS_L;    /* enable device */
IO_Send_Byte(W25P_WriteStatusReg); /* select write to status register */
IO_Send_Byte(byte); /* data that will change the status(only bits 2,3,7 can be written) */
CS_H;    /* disable the device */
}



/*写使能*/
void IO_Write_Enable()
{
CS_L;   /* enable device */
IO_Send_Byte(W25P_WriteEnable); /* send W25P_Write_Enable command */
CS_H;   /* disable device */
}





uint IO_Read_ID2(uchar ID_Addr)
{
uint IData16;
CS_L;   /* enable device */
IO_Send_Byte(W25P_ManufactDeviceID); /* send read ID command (90h) */
IO_Send_Byte(0x00);   /* send address */
IO_Send_Byte(0x00);   /* send address */
IO_Send_Byte(ID_Addr);   /* send W25Pxx selectable ID address 00H or 01H */
IData16 = IO_Get_Byte()<<8;  /* receive Manufature or Device ID byte */
IData16 |= IO_Get_Byte();  /* receive Device or Manufacture ID byte */
CS_H;    /* disable device */
  return IData16;
}


/*读取固定地址下一个字节*/
uchar IO_Read_Byte(uint32 Dst_Addr)

{
uchar byte = 0;
CS_L;     /* enable device */
IO_Send_Byte(W25P_ReadData);    /* read command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16)); /* send 3 address bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF);
byte = IO_Get_Byte();
CS_H;   /* disable device */
return byte;   /* return one byte read */
}



/*读取数据*/
void IO_Read_nBytes(uint32 Dst_Addr, uchar nBytes_128)
{
uint32 i = 0;
CS_L;     /* enable device */
IO_Send_Byte(W25P_ReadData);    /* read command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));  /* send 3 address  bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF);
for (i = 0; i < nBytes_128; i++)  /* read until no_bytes is reached */
{
  upper_128[i] = IO_Get_Byte(); /* receive byte and store at address 80H - FFH */
}
  CS_H;    /* disable device */
}




/*快速读取一个字节*/
uchar IO_FastRead_Byte(uint32 Dst_Addr)

{
uchar byte = 0;
CS_L;     /* enable device */
IO_Send_Byte(W25P_FastReadData);   /* fast read command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16)); /* send 3 address bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF);
IO_Send_Byte(0xFF);  /*dummy byte*/
byte = IO_Get_Byte();
CS_H;   /* disable device */
return byte;   /* return one byte read */
}


/*快速读取数据*/
void IO_FastRead_nBytes(uint32 Dst_Addr, uchar nBytes_128)
{
uchar i = 0;
CS_L;     /* enable device */
IO_Send_Byte(W25P_FastReadData);   /* read command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));  /* send 3 address bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF);
IO_Send_Byte(0xFF);   /*dummy byte*/
for (i = 0; i < nBytes_128; i++) /* read until no_bytes is reached */
{
  upper_128[i] = IO_Get_Byte(); /* receive byte and store at address 80H - FFH */
}
CS_H;    /* disable device */
}

/*写一个字节*/
void IO_Write_Byte(uint32 Dst_Addr, uchar byte)

{
CS_L;     /* enable device */
IO_Write_Enable();    /* set WEL */
IO_Wait_Busy();
  CS_L;
IO_Send_Byte(W25P_PageProgram);   /* send Byte Program command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16)); /* send 3 address bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF);
IO_Send_Byte(byte);   /* send byte to be programmed */
CS_H;    /* disable device */
}


void IO_Write_nBytes(uint32 Dst_Addr, uchar nBytes_128)
{
uchar i, byte;
CS_L;     /* enable device */
IO_Write_Enable();    /* set WEL */
CS_L;
IO_Send_Byte(W25P_PageProgram);   /* send Byte Program command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16)); /* send 3 address bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF);
for (i = 0; i < nBytes_128; i++)
{
  byte = upper_128[i];
  IO_Send_Byte(byte);  /* send byte to be programmed */
}
CS_H;    /* disable device */
//printf("\nPage program (%d nBytes)! please waiting....\n");
}

/*擦出芯片*/
void IO_Erase_Chip()

{
CS_L;    /* enable device */
IO_Write_Enable();    /* set WEL */
CS_L;
IO_Wait_Busy();
CS_L;
IO_Send_Byte(W25P_ChipErase);  /* send Chip Erase command */
CS_H;    /* disable device */
}


/*擦出寄存器*/
void IO_Erase_Sector(uint32 Dst_Addr)

{
CS_L;     /* enable device */
IO_Write_Enable();    /* set WEL */
CS_L;
IO_Send_Byte(W25P_SectorErase);   /* send Sector Erase command */
IO_Send_Byte(((Dst_Addr & 0xFFFFFF) >> 16));  /* send 3 address bytes */
IO_Send_Byte(((Dst_Addr & 0xFFFF) >> 8));
IO_Send_Byte(Dst_Addr & 0xFF );
CS_H;     /* disable device */
}


/*检验*/
void Verify(uchar byte, uchar cor_byte)
{
if (byte != cor_byte)
{
  while(1);
   //LED_Error = 0; /* display to view error on LED. */   
}
}




/*禁止写*/
void IO_Write_Disable()

{

CS_L;    /* enable device */
IO_Send_Byte(W25P_WriteDisable); /* send W25P_Write_Disable command */
CS_H;    /* disable device */
}

下面是主程序

//ICC-AVR application builder : 2013/8/12 13:23:46
// Target : M8515
// Crystal: 16.000Mhz

#include <iom8515v.h>
#include <macros.h>
#include "w25x40_spi.h"

/*端口初始化*/
void IO_init()
{
CLK_L; /* set clock to low initial state for SPI operation mode 0 *
// _clk = 1; /* set clock to low initial state for SPI operation mode 3 */
HOLD_H;
// _hold = 1;
WP_H;
CS_H;
IO_Write_Disable();

}

void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x67; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x08;
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
IO_init();
uart0_init();
SEI(); //re-enable interrupts
//all peripherals are now initialized
}

//
void main(void)
{
init_devices();
//insert your functional code here...


while(1)
{



// IO_Read_ID2(0x22);
  UDR=IO_Read_ID1();

  

}


}



大神帮忙看看啊!!
布连单片机的时候flash会有数据输出,连单片机就没有了

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

 楼主| 发表于 2013-8-13 21:35:49 | 显示全部楼层
这个问题解决了  就是PB6要开启内部上拉,但是...单片机读不到示波器显示有连到单片机上也会有洗好但是单片机读不到

出0入0汤圆

 楼主| 发表于 2013-8-13 22:59:24 | 显示全部楼层
自己解决了,,,,读取时的程序有一个地方写错了,
/*读取一个字节*/
uchar IO_Get_Byte(void)
{
uchar i=0,in=0,temp=0;
CS_L;
for (i=0;i<8;i++)
{
  in=(in<<1);  /* shift 1 place to the left or shift in 0 */
  temp=DO_;  /* save input */
  
  CLK_H;  /* toggle clock high */
  if (temp==1)  /* check to see if bit is high */      if(temp!=0)就是这句,改 了就可以了
   in|=0x01; /* if high, make bit high */
  CLK_L;  /* toggle clock low */
}                 
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 16:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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