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版本 都没有人回复一下啊 25系列的EEP,每写入一段(≤64B),需要有几毫秒的内部保存操作,这期间除了查询状态,其他指令无效;
看主函数里边SPIWrite() 后只有两个空操作就开始读了,这样不行啊 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,说明都没有写使能操作,这是为什么呢
SPI_MasterInit 当中 SS 被置为输出;
PORT_Init 当中又被置为输入,这个应该不对。
另外试试调整SPI速度,例如把SPI分频开到最大。
页:
[1]