使用28035编写SPI时主要遇到以下问题:
1.spi写完数据之后,立刻去eeprom去读写进去的数据,发现读出的数据不对或者读不出来数据,后来在读取函数中加入eeprom的工作状态检查解决问题
2.spi的TXbufff发送完成后,会将SpiaRegs.SPISTS.bit.INT_FLAG置1。如果将spi的发送与接收函数分成两个函数写,需要在spi的Txbuff发送完成后,进行读取RXBUFF寄存器,清除SpiaRegs.SPISTS.bit.INT_FLAG位,否则利用SpiaRegs.SPISTS.bit.INT_FLAG判断接受数据时,会进入死循环
3.SPI的TXbuff是左对齐,需要进行移位。RXbuff是右对齐,
#include "spi.h"
#include "shared.h"
void Spi_Init(void)
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; //Enable pull-up on GPIO16 (SPISIMOA)
//GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; //Enable pull-up on GPIO5 (SPISIMOA)
GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; //Enable pull-up on GPIO17 (SPISOMIA)
//GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0; // Enable pull-up on GPIO3 (SPISOMIA)
GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; // Enable pull-up on GPIO18 (SPICLKA)
GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; // Enable pull-up on GPIO19 (SPISTEA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; //Asynch input GPIO16 (SPISIMOA)
//GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 3; //Asynch input GPIO5 (SPISIMOA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
//GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 3; // Asynch input GPIO3 (SPISOMIA)
GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
GpioCtrlRegs.GPADIR.bit.GPIO19=1; // Asynch input GPIO19 (SPISTEA)
GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
//GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 2; // Configure GPIO5 as SPISIMOA
GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
//GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2; // Configure GPIO3 as SPISOMIA
GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
GpioCtrlRegs.GPAMUX2.bit.GPIO19=0; // Configure GPIO19 as SPISTEA
EDIS;
EALLOW;
SpiaRegs.SPICCR.bit.SPISWRESET=0; //初始化之前复位spi寄存器
SpiaRegs.SPICCR.all=0x0007;//一次写入8-bit、
SpiaRegs.SPICTL.all=0x000E;//关闭SPI\溢出中断,设置为主模式,关闭传输
SpiaRegs.SPISTS.all=0x0000;//清除所有标志位
SpiaRegs.SPIBRR=0x0003;//SPI始终频率15M/(3+1)
SpiaRegs.SPIPRI.bit.FREE=1;
SpiaRegs.SPICCR.all=0x0087;//一次写入8-bit、
//SpiaRegs.SPICCR.bit.SPISWRESET=1;//使能SPI
EDIS;
}
//SPI发送一个字节,将发送与接收函数写在一起是为了清除SpiaRegs.SPISTS.bit.INT_FLAG位,
Uint16 SPI_SendWriteByte(Uint16 dat)
{
while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG==1)
{
}
SpiaRegs.SPITXBUF=dat<<8;//此处写入数据会将SpiaRegs.SPISTS.bit.INT_FLAG位置1
while(SpiaRegs.SPISTS.bit.INT_FLAG==0)//
{
}
return (SpiaRegs.SPIRXBUF&0xff);
}
//读取Eeprom的状态寄存器
Uint16 SPI_ReadEepromStatus(void)
{
Uint16 date;
Eeprom_E;
SPI_SendWriteByte(RDSR);
date=SPI_SendWriteByte(0xFF);//写入空数据,清除SpiaRegs.SPISTS.bit.INT_FLAG位,
Eeprom_D;
return date;
}
//改变Eeprom的状态寄存器
void SPI_WriteEepromStatus(void)
{
Eeprom_E;
SPI_SendWriteByte(WRSR);
SPI_SendWriteByte(0x80);
Eeprom_D;
}
//Eeprom写使能
void SPI_WriteEepromEnable()
{
Eeprom_E;
SPI_SendWriteByte(WREN);
Eeprom_D;
}
//判断Eeprom是否空闲
void SPI_EepromWaitBusy()
{
while(SPI_ReadEepromStatus()&0x01);
}
//在Eeprom中读取一个字节
Uint16 SPI_ReadEepromDate(Uint16 addr)
{
Uint16 date;
SPI_EepromWaitBusy();//此处必须加,防止EEPROM处于活动状态,造成数据读写错误
Eeprom_E;
SPI_SendWriteByte(READ);
SPI_SendWriteByte((addr&0xFF00)>>8);
SPI_SendWriteByte(addr&0xFF);
date=SPI_SendWriteByte(0xFF);
Eeprom_D;
return date;
}
//在Eeprom中写入一个字节
void SPI_WriteEepromDate(Uint16 addr,Uint16 date)
{
SPI_EepromWaitBusy();
SPI_WriteEepromEnable();
Eeprom_E;
SPI_SendWriteByte(WRITE);
SPI_SendWriteByte((addr&0xFF00)>>8);
SPI_SendWriteByte(addr&0xFF);
SPI_SendWriteByte(date);
Eeprom_D;
}