我在W5500上使用STM32F030,并且HAL SPI库出现问题。首先,我使用的是不带DMA的SPI(1 Mbit / s),但是Cortex M0不支持数据不对齐,并且会产生hard_Fault。为了避免这种情况,他们建议我们将SPI与DMA或IT配合使用。
嗯,W5500在CS激活期间需要Write + Read,因此我将CS设置为软件。
当SPI写入一个值时,它会正确执行。但是,当使用读取功能时,CS将在CLK完成之前被停用。
这是主要功能(来自W5500库的原始功能):
void WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len)
{
uint8_t spi_data[3];
uint16_t i;
WIZCHIP_CRITICAL_ENTER();
WIZCHIP.CS._select();
AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_);
if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte operation
{
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8);
WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0);
for(i = 0; i < len; i++)
pBuf[i] = WIZCHIP.IF.SPI._read_byte();
}
else // burst operation
{
spi_data[0] = (AddrSel & 0x00FF0000) >> 16;
spi_data[1] = (AddrSel & 0x0000FF00) >> 8;
spi_data[2] = (AddrSel & 0x000000FF) >> 0;
WIZCHIP.IF.SPI._write_burst(spi_data, 3);
WIZCHIP.IF.SPI._read_burst(pBuf, len);
}
WIZCHIP.CS._deselect();
WIZCHIP_CRITICAL_EXIT();
}
WIZCHIP_CRITICAL_ENTER和EXIT是空函数。 CS软件的选择是通过(重定向)的:
void wizchip_cs_select(void) {
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
}
void wizchip_cs_deselect(void) {
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
}
写入/读取功能为:
uint8_t wizchip_spi_readbyte(void) {
uint8_t datain;
uint8_t dataout=0xAA;
HAL_SPI_TransmitReceive_DMA(&hspi1, &dataout, &datain, 1);
return datain;
}
void wizchip_spi_writebyte(uint8_t wb) {
HAL_SPI_Transmit_DMA(&hspi1, &wb, 1);
}
void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {
uint8_t dataout=0xAA;
HAL_SPI_TransmitReceive_DMA(&hspi1, &dataout, pBuf, len);
}
void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {
HAL_SPI_Transmit_DMA(&hspi1, pBuf, len);
}
这是我只写功能的结果:
这是使用读取功能的时候:
为什么会这样?