jiongeyes 发表于 2013-5-31 11:45:20

mega16+25LC256通过SPI写不进,或者是读不出数据

#include<iom16v.h>

#define BAUD 9600               //波特率采用9600ps
#define CRYSTAL 8000000         //系统时钟8MHz
#define BAUD_SETTING (unsigned char)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1)// 设置波特率
#define BAUD_H (unsigned char)(BAUD_SETTING>>8)
#define BAUD_L (unsigned char)(BAUD_SETTING)      

#define _nop()   asm("nop")
#define LED_COMPORTD ^= (1<<PD5)
//25LC256//////////////////////
#define WRSR   0x01    //写状态寄存器
#define WRITE    0x02    //写命令
#define READ   0x03    //读命令
#define WRDI   0x04    //写禁止
#define RDSR   0x05    //读状态寄存器
#define WREN   0x06    //写允许
//PORTB////////////////////////
#define SS       4
#define MOSI   5
#define MISO   6
#define SCK      7
//PORTD////////////////////////
#define EN_485   4
#define RUN      5

unsigned char TX_buff,RX_buff,SPI_buff;
unsigned char LED_Counter;
unsigned char RX_Flag;
unsigned char M95256_status;

voiddelay(unsigned char k) //延时ms
{   
    unsigned char j;
        for (;k>0;k--)
           for(j=220;j>0;j--)
       {
            _nop();
            _nop();
            _nop();
            _nop();
            _nop();
            _nop();
            _nop();
            _nop();
            _nop();
            _nop();   
       }   
}   
   
////////////////RS232////////////////////
void USART_Init()         //232波特率初始化
{
    UBRRH = BAUD_H;
    UBRRL = BAUD_L;
    UCSRB |= (1<<RXEN)|(1<<TXEN);            //接收器与发送器使能
    UCSRC = (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);      //设置帧格式:8个数据位,1个停止位
}

///////////////458发送///////////////////
void UART_TX485( unsigned char data )   
{
    PORTD |= (1<<EN_485);
    delay(2);   
    while ( !( UCSRA & (1<<UDRE)) );
    UDR = data;
    while(!(UCSRA & (1<<UDRE)));
    delay(4);
    PORTD &= ~(1<<EN_485);                        // 将数据放入缓冲器,发送数据
}

/////////////////SPI 主机设置//////////////////////////////
void SPI_MasterInit(void)
{      
    DDRB |= (1<<SS)|(1<<MOSI)|(1<<SCK);
    PORTB |= (1<<SS);//|(1<<MOSI)|(1<<MISO)|(1<<SCK);
    SPCR = (1<<SPE)|(1<<MSTR);//|(1<<SPR1);//|(1<<SPR0)//|(1<<CPOL);   设置为主机模式,使能SPI,时钟为fosc/64
   
}

////////////////////SPI发送////////////////
void SPI_TX(unsigned char cdata)
{         
    SPDR = cdata;
    while(!(SPSR & (1<<SPIF)));
}

//25LC256_SPI设置///////////////////////////
void SPI_25LC256_Init()
{
    PORTB &= ~(1<<SS);
    SPI_TX(WRSR);//写寄存器状态
    PORTB |= (1<<SS);   
}

//================================================
//SPI读
//================================================
unsigned char SPIRead(unsigned int SpiAddress)
{
    unsigned char i,add_H,add_L;        
        PORTB &= ~(1<<SS);       //拉低SS激活从机SPI
        _nop();
    add_H = SpiAddress >> 8;
    add_L = SpiAddress && 0x00FF;       
        SPI_TX(READ);
    SPI_TX(add_H);
    SPI_TX(add_L);
    SPI_TX(0xFF);
    i = SPDR;
        PORTB |= (1<<SS);
    return i;               
}

//==================================================
//SPI写
//==================================================
void SPIWrite(unsigned int SpiAddress,unsigned char edata)
{
    unsigned char i,add_H,add_L;
    PORTB &= ~(1<<SS);            //chip select EEPROM, enable IC
    SPI_TX(WREN);
    PORTB |= (1<<SS);
        _nop();
    add_H = SpiAddress >> 8;
    add_L = SpiAddress && 0x00FF;
        PORTB &= ~(1<<SS);
    SPI_TX(WRITE);
        SPI_TX(add_H);
    SPI_TX(add_L);
    SPI_TX(edata);
        PORTB |= (1<<SS);
}

//字符初始化///////////////////////
void DATA_Init()
{
    LED_Counter = 0;
    RX_Flag = 0;
}

//端口初始化///////////////////////////
void PORT_Init()
{
    DDRB = 0x00;
    DDRD |= (1<<EN_485)|(1<<RUN);
    PORTD |= (1<<RUN);
}

//主程序////////////////////////
void main(void)
{   
    unsigned char temp,i;
    temp = 0x42;                           
    SREG = 0x00;
    UCSRB |= (1<<RXCIE);    //接收结束中断使能
    TIMSK |= (1<<TOIE1);    //T/C1溢出中断使能
    TCCR1B = 0x00;
    TCNT1 = 0x3CAF;   //50MS   
    TCCR1B |= (1<<CS11);    //每秒=fosc/8时钟
    USART_Init();
    SPI_MasterInit();
    SPI_25LC256_Init();
    PORT_Init();
    DATA_Init();
    SREG = 0x80;

    while(1)
    {   
      SPIWrite(0x0001,0x42);
      _nop();
      _nop();
      i = SPIRead(0x0001);
      _nop();
      _nop();
      UCSRB &= ~(1<<RXCIE);
      _nop();
      UART_TX485(i);
      _nop();
      UCSRB |= (1<<RXCIE);               
      _nop();
      _nop();         
    }
}

485发送出来的永远是00
CVAVR2.03.4版本

jiongeyes 发表于 2013-6-2 11:39:05

都没有人回复一下啊

t3486784401 发表于 2013-6-2 15:50:43

25系列的EEP,每写入一段(≤64B),需要有几毫秒的内部保存操作,这期间除了查询状态,其他指令无效;

看主函数里边SPIWrite() 后只有两个空操作就开始读了,这样不行啊

jiongeyes 发表于 2013-6-3 11:15:46

t3486784401 发表于 2013-6-2 15:50 static/image/common/back.gif
25系列的EEP,每写入一段(≤64B),需要有几毫秒的内部保存操作,这期间除了查询状态,其他指令无效;

看 ...

加了延时还是不行的
portb &= ~(1<ss);
spi_tx(WREN)
PORTB |= (1<<SS)
然后再
PORTB &=~(1<<SS)
SPI_TX(RDSR)
SPI_TX(0xFF)
这样读出来的寄存器WEL位还是0都没有置1,说明都没有写使能操作,这是为什么呢

t3486784401 发表于 2013-6-8 19:10:10

SPI_MasterInit 当中 SS 被置为输出;
PORT_Init 当中又被置为输入,这个应该不对。

另外试试调整SPI速度,例如把SPI分频开到最大。
页: [1]
查看完整版本: mega16+25LC256通过SPI写不进,或者是读不出数据