搜索
bottom↓
回复: 4

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

[复制链接]

出0入0汤圆

发表于 2013-5-31 11:45:20 | 显示全部楼层 |阅读模式
#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_COM  PORTD ^= (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[16],RX_buff[16],SPI_buff[16];
unsigned char LED_Counter;
unsigned char RX_Flag;
unsigned char M95256_status;

void  delay(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版本

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

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2013-6-2 11:39:05 | 显示全部楼层
都没有人回复一下啊

出200入2554汤圆

发表于 2013-6-2 15:50:43 | 显示全部楼层
25系列的EEP,每写入一段(≤64B),需要有几毫秒的内部保存操作,这期间除了查询状态,其他指令无效;

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

出0入0汤圆

 楼主| 发表于 2013-6-3 11:15:46 | 显示全部楼层
t3486784401 发表于 2013-6-2 15:50
25系列的EEP,每写入一段(≤64B),需要有几毫秒的内部保存操作,这期间除了查询状态,其他指令无效;

看 ...

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

出200入2554汤圆

发表于 2013-6-8 19:10:10 | 显示全部楼层
SPI_MasterInit 当中 SS 被置为输出;
PORT_Init 当中又被置为输入,这个应该不对。

另外试试调整SPI速度,例如把SPI分频开到最大。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-26 23:49

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

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