When I use SPI within XEP100 to write to and read data from an RAM chip(FM25640),I found the program stop in while(!SPI0SR_SPIF) ,I dont know how to solve this problem,anyone who have a good idea give me some suggestion,thank you!
Here are init ,write and read programs.
void SPI0_Init(void)
{
SPI_SO_DD=0;// MISO设置成输入
CS_D=1;
CS_DD=1;//SS设置为输出
SPI_SI=1;
SPI_SI_DD=1;//MOSI设置为输出
SPI_SCK=0;
SPI_SCK_DD=1;//SCK设置为输出
MODRR = 0x00;//使用SPI0口
SPI0CR1=0X52;//使能SPI模块为主模式,使能SPI0,禁止SPI中断CHOL CPHA = 00
SPI0CR2=0X10;//SS引脚作为通用IO,用户程序控制其信号。 通讯字节为8位
//SPI0BR=0X42; //设置通讯波特率,分频因子40
SPI0BR=0x77; //设置通讯波特率,分频因子2048
}
/***********************写一个字节********************/
unsigned char Write_Byte(unsigned char data)
{
unsigned char temp;
while(!SPI0SR_SPTEF);
SPI0DR=data;
while(!SPI0SR_SPIF);
return SPI0DR;
}
/***********************写数据********************/
void write_Data(unsigned int start_address,unsigned int length,unsigned char *dat)
{
unsigned int i;
CS_D=ON;
Write_Byte(WREN);
Write_Byte(WRITE);
Write_Byte(start_address >> 8);
Write_Byte(start_address);
for (i=0;i<length;i++)
{
Write_Byte(*dat);
dat++;
}
CS_D=OFF;
}
/**********************读一个字节************************/
unsigned char Read_Byte(void)
{
unsigned char rByte=0;
unsigned char temp;
while(!SPI0SR_SPIF);
rByte=SPI0DR;
return rByte;
}
/***********************读数据********************/
void Read_Data(unsigned int start_address,unsigned int length,unsigned char *dat)
{
unsigned int i;
CS_D=ON;
Write_Byte(READ);
Write_Byte(start_address >> 8);
Write_Byte(start_address);
for(i=0;i<length;i++)
{
*dat = Read_Byte() ;
dat++;
}
CS_D=OFF;
}
Solved! Go to Solution.
Hi 刘 银
I am slightly confused from your CS(SS) bit configuration. The SPI0CR1 and SPI0CR2 configuration specifies, that SS pin is driven by SPI module. While CS_D=ON; commands looks like manual driven SS pin.
Anyway, you selected CPOL=0 and CPHA=0. In that case, bytes (or words if XFRW=1) must by divided by SS pin line toggling (SS line is always deasserted and reasserted between successive transfers for at least minimum idle time)
So, if you use manual driven SS, you must toggle SS pin twice between bytes.
Possible solutions:if
1. If you use manual driven SS, add code for SS pin toggle between byte transfers.
2. Use SS pin signal generated by SPI module
3. Use CPOL=1, CPHA=1 configuration (SPI Mode 3 per FM25640 datasheet)
Important note:
Please be aware, that while(!SPI0SR_SPIF); command cannot be debugged in stepping mode. The SPIF flag is cleared by read SPISR register with SPIF == 1 and then read SPIDRL register. That reading is applied also by debugger when you step over code – debugger clears SPIF flag by register reading when CPU halt.
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi 刘 银
I am slightly confused from your CS(SS) bit configuration. The SPI0CR1 and SPI0CR2 configuration specifies, that SS pin is driven by SPI module. While CS_D=ON; commands looks like manual driven SS pin.
Anyway, you selected CPOL=0 and CPHA=0. In that case, bytes (or words if XFRW=1) must by divided by SS pin line toggling (SS line is always deasserted and reasserted between successive transfers for at least minimum idle time)
So, if you use manual driven SS, you must toggle SS pin twice between bytes.
Possible solutions:if
1. If you use manual driven SS, add code for SS pin toggle between byte transfers.
2. Use SS pin signal generated by SPI module
3. Use CPOL=1, CPHA=1 configuration (SPI Mode 3 per FM25640 datasheet)
Important note:
Please be aware, that while(!SPI0SR_SPIF); command cannot be debugged in stepping mode. The SPIF flag is cleared by read SPISR register with SPIF == 1 and then read SPIDRL register. That reading is applied also by debugger when you step over code – debugger clears SPIF flag by register reading when CPU halt.
I hope it helps you.
Have a great day,
Radek
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Radek,
Thank you for your suggestions. I tried the third soulution(Use CPOL=1, CPHA=1 configuration), and it worked.I used the CS as an I/O port, not the SPI module.Although I dont know how it worked .Thanks a lot .
Have a great day,
Ben
Hi Ben,
You are welcome. I am glad that it works now correctly.
Yes, the CPHA = 1 is most typical solution.
This difference is visible also on SPI waveforms in RM:
I hope it helps you.
Have a great day,
Radek