用SSI读写EEPROM(25LC1024)芯片
用的是LM4F230H5QR芯片设置为主机模式,
设置1:
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_12MHZ);//系统时钟设置为12M
SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER, 10000000, 8);//ssi位速率设置为1M
按照上面这个设设置1能够正确读写eeprom里面的数据但是如果改成下面的设置2就不行了,完全没法读数据,收数据的数组全是0,
设置2:
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL |SYSCTL_OSC_MAIN | SYSCTL_XTAL_12MHZ);// 设置系统时钟为80MHz
SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER, 10000000, 8);//ssi位速率设置为1M
按照设置2的话,当我把位速率也就是上面的1M改成8M的时候读出来的数据就不对了,虽然能读出来但是不是我写进去的数据,
想请教下给位,我如果系统时钟就设置成80M那么SSI的位速率应该设置成多少,或者怎么配置,麻烦给位给一个在80M系统时钟的情况下的ssi能够读写配置?
还有个问题就是我本来想看看12M的时候系统时钟配置的情况下CPSDVSR , SCR这两个参数所在寄存器的值,从而按照这个值算出80M的时候的ssi位速率应该是多的,但是ccs这个软件看不到这两个寄存器的值,怎么回事,显示的是没法读寄存器的值,
#include "inc/lm4f232h5qd.h"
#include "inc/hw_types.h"
#include "inc/hw_ssi.h"
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "driverlib/ssi.h"
#include "driverlib/fpu.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "grlib/grlib.h"
#include "utils/uartstdio.h"
#define Uint8 unsigned char
unsigned long x;
// Number of bytes to send and receive.
#define NUM_SSI_DATA 3
unsigned char ulDataTx[NUM_SSI_DATA]={0Xfa,0Xbf,0Xcc};
unsigned long ulDataRx[NUM_SSI_DATA];
#define WRITECODE 0x02
#define READCODE 0x03
#define WREN 0x06
#define WRDI 0x04
#define SPI_ADD 0x0000ff
#define SE 0xd8
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif
///////////////////////////////////////////////////////////////////////////////
unsigned char Get_Byte(void) //接收字节
{
unsigned long ReadData;
SSIDataPut(SSI1_BASE, 0xFF); // 发送一个无效字节,以产生接收时钟
SSIDataGet(SSI1_BASE, &ReadData);
return (unsigned char)ReadData;
}
void Send_Byte(unsigned char data) //发送字节
{
unsigned long NullData;
SSIDataPut(SSI1_BASE, data);
SSIDataGet(SSI1_BASE, &NullData);
}
void delay (unsigned long uld) //延时
{
for( ;uld ;uld--);
}
void SSI_WRITE_ENABLE(void) //写使能
{
//SPROM_CSL=0;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);
SSIDataPut(SSI1_BASE, WREN);
delay (10);
//SPROM_CSL=1;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);
}
void SPI_WRITE_DISABLE(void) //写禁止
{
//SPROM_CSL=0;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);
SSIDataPut(SSI1_BASE, WRDI);
delay (10);
// SPROM_CSL=1;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);
}
void SPI_CLEAR(unsigned long SPI_WRITE_ADD)
{
// SPROM_CSL=0;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);
SSIDataPut(SSI1_BASE, SE); //页清除命令
SSIDataPut(SSI1_BASE, ((SPI_WRITE_ADD & 0xFF0000) >> 16));
SSIDataPut(SSI1_BASE, ((SPI_WRITE_ADD & 0x00FF00) >> 8));
SSIDataPut(SSI1_BASE, ((SPI_WRITE_ADD & 0x0000FF) >> 0));
delay (50);
// SPROM_CSL=1;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);
}
///////////////////SSI写数据/////////////////////////////////
void SSI_WRITE(unsigned long SSI_WRITE_ADD ,unsigned char SSI_WRITE_DATA)
{
while(SSIBusy(SSI1_BASE)){}
//delay (10000);
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);//SPROM_CSL=0;
//发送写的命令
SSIDataPut(SSI1_BASE, WRITECODE);
//写地址
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0xFF0000) >> 16));
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0x00FF00) >> 8));
SSIDataPut(SSI1_BASE, (Uint8)(SSI_WRITE_ADD & 0x0000FF));
SSIDataPut(SSI1_BASE, SSI_WRITE_DATA);
while(SSIBusy(SSI1_BASE)){}//等待数据发送完成
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);//SPROM_CSL=1;
}
void SSI_WRITE_NBYTE(unsigned long SSI_WRITE_ADD ,unsigned char *SSI_WRITE_DATA,unsigned char DATA_NUM)
{
int i;
while(SSIBusy(SSI1_BASE)){}
//delay (10000);
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);//SPROM_CSL=0;
//发送写的命令
SSIDataPut(SSI1_BASE, WRITECODE);
//写地址
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0xFF0000) >> 16));
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0x00FF00) >> 8));
SSIDataPut(SSI1_BASE, (Uint8)(SSI_WRITE_ADD & 0x0000FF));
for (i = 0; i < DATA_NUM; i++)
{
SSIDataPut(SSI1_BASE, SSI_WRITE_DATA[i]);
while(SSIBusy(SSI1_BASE)){}//等待数据发送完成
}
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);//SPROM_CSL=1;
}
///////////////////SSI读数据/////////////////////////////////
void SSI_READ(unsigned long SSI_WRITE_ADD,unsigned long *ReadData)
{
unsigned long temp;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);
SSIDataPut(SSI1_BASE, READCODE);
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0xFF0000) >> 16));
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0x00FF00) >> 8));
SSIDataPut(SSI1_BASE, (Uint8)(SSI_WRITE_ADD & 0x0000FF));
while(SSIBusy(SSI1_BASE)){}//!!!
while(HWREG(SSI1_BASE + SSI_O_SR) & SSI_SR_RNE)//重要!!!
{
temp = 0x00FF & SSI1_DR_R ;
}
SSIDataPut(SSI1_BASE, 0xFF); //重要!!! 发送一个无效字节,以产生接收时钟
while(SSIBusy(SSI1_BASE)){}//!!!
SSIDataGetNonBlocking(SSI1_BASE, ReadData);
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);
//return ReadData;
}
void SSI_READ_NBYTE(unsigned long SSI_WRITE_ADD,unsigned long *ReadData,unsigned char DATA_NUM )
{
int i;
unsigned long temp;
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,~GPIO_PIN_3);
SSIDataPut(SSI1_BASE, READCODE);
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0xFF0000) >> 16));
SSIDataPut(SSI1_BASE, (Uint8)((SSI_WRITE_ADD & 0x00FF00) >> 8));
SSIDataPut(SSI1_BASE, (Uint8)(SSI_WRITE_ADD & 0x0000FF));
for (i = 0; i < DATA_NUM; i++)
{
while(SSIBusy(SSI1_BASE)){}//!!!
while(HWREG(SSI1_BASE + SSI_O_SR) & SSI_SR_RNE)//重要!!!
{
temp = 0x00FF & SSI1_DR_R ;
}
SSIDataPut(SSI1_BASE, 0xFF); //重要!!! 发送一个无效字节,以产生接收时钟
while(SSIBusy(SSI1_BASE)){}//!!!
SSIDataGetNonBlocking(SSI1_BASE, ReadData++);
}
GPIOPinWrite(GPIO_PORTF_BASE ,GPIO_PIN_3,GPIO_PIN_3);
//return ReadData;
}
///////////////////SSI初始化/////////////////////////////////
void SSI_init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1); //为SSI提供时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//为GPIOF端口提供时钟
SSIDisable(SSI1_BASE);
// 设置SPI为主机模式0,8位数据宽度,1M的波特率//
SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(),
SSI_FRF_MOTO_MODE_0,SSI_MODE_MASTER, 10000000, 8);
GPIOPinConfigure(GPIO_PF3_SSI1FSS);//SSI功能复用配置
GPIOPinConfigure(GPIO_PF2_SSI1CLK);
GPIOPinConfigure(GPIO_PF1_SSI1TX);
GPIOPinConfigure(GPIO_PF0_SSI1RX);
GPIOPinTypeSSI(GPIO_PORTF_BASE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
SSIEnable(SSI1_BASE);
// 配置片选管脚为输出
GPIODirModeSet(GPIO_PORTF_BASE,GPIO_PIN_3, GPIO_DIR_MODE_OUT);
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_3,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
}
// The interrupt handler for the hardware SSI
void SSI1IntHandler(void)
{
unsigned long ulInts;
//Read the asserted interrupt sources
ulInts = SSIIntStatus(SSI1_BASE, true);
// Clear the asserted interrupt sources
SSIIntClear(SSI1_BASE, ulInts);
}
void main(void)
{
//SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
// SYSCTL_XTAL_12MHZ);
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL |
SYSCTL_OSC_MAIN | SYSCTL_XTAL_12MHZ);// 设置系统时钟为80MHz
x=SysCtlClockGet();
unsigned long ulindex =2;
SSI_init();
while(1)
{
SSI_WRITE_ENABLE();
SSI_WRITE_NBYTE(ulindex,ulDataTx,3);
delay (10000);
SSI_READ_NBYTE(ulindex,ulDataRx,3);
}
}