Embedded AT91SAM7X512';s SPI外围设备在写入SPI_TDR时被禁用
我的AT91SAM7X512的SPI外设在我写入Embedded AT91SAM7X512';s SPI外围设备在写入SPI_TDR时被禁用,embedded,arm,spi,atmel,Embedded,Arm,Spi,Atmel,我的AT91SAM7X512的SPI外设在我写入SPI\u TDR的X时间(X变化)被禁用。 因此,处理器挂起while循环,该循环检查SPI\u SR中的TDRE标志。该while循环位于函数SPI_Write()中,该函数属于ATMEL提供的软件包/库。 这个问题是任意发生的——有时一切正常,有时重复尝试就会失败(attemp=将相同的二进制文件下载到MCU并运行程序) 配置(按编写顺序定义): const short int dataSize = 5; // Filling array w
SPI\u TDR
的X时间(X变化)被禁用。
因此,处理器挂起while循环,该循环检查SPI\u SR
中的TDRE
标志。该while循环位于函数SPI_Write()
中,该函数属于ATMEL提供的软件包/库。
这个问题是任意发生的——有时一切正常,有时重复尝试就会失败(attemp=将相同的二进制文件下载到MCU并运行程序)
配置(按编写顺序定义):
const short int dataSize = 5;
// Filling array with random data
unsigned char data[dataSize] = {0xA5, 0x34, 0x12, 0x00, 0xFF};
short int i = 0;
volatile unsigned short dummyRead;
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummyRead = SPI_Read(); // SPI_Read() from Atmel's library
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0); // <-- This is where
// the processor hangs, because that the SPI peripheral is disabled
// (SPIENS equals 0), which makes TDRE equal to 0 forever.
}
SPI\u MR
:
=1MSTR
=0PS
=0PCSDEC
=0111PCS
=0DLYBCS
SPI\u CSR[3]
:
=0CPOL
=1NCPHA
=0CSAAT
=0000位
=20SCBR
=0DLYBS
=0DLYBCT
SPI\u CR
:
=1SPIEN
SPIENS
标志来验证SPI是否已启用
我执行如下字节传输:
const short int dataSize = 5;
// Filling array with random data
unsigned char data[dataSize] = {0xA5, 0x34, 0x12, 0x00, 0xFF};
short int i = 0;
volatile unsigned short dummyRead;
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummyRead = SPI_Read(); // SPI_Read() from Atmel's library
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0); // <-- This is where
// the processor hangs, because that the SPI peripheral is disabled
// (SPIENS equals 0), which makes TDRE equal to 0 forever.
}
const short int dataSize = 5;
// Filling array with random data
unsigned char data[dataSize] = {0xA5, 0x34, 0x12, 0x00, 0xFF};
short int i = 0;
volatile unsigned short dummyRead;
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummyRead = SPI_Read(); // SPI_Read() from Atmel's library
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0); // <-- This is where
// the processor hangs, because that the SPI peripheral is disabled
// (SPIENS equals 0), which makes TDRE equal to 0 forever.
}
- NPCS线路编号3是一条GPIO线路(即,在PIO模式下),不受SPI控制器控制。 我在代码中自己控制这一行,在需要时取消/断言ChipSelect#3(NPCS3)引脚。 我这样做的原因是,在尝试让SPI控制器控制该引脚时出现了问题
- 我没有使用PDC/DMA控制器,更喜欢不使用它
- 我没有两次重置SPI外围设备,因为勘误表告诉我只有在执行重置时才重置它两次-我没有这样做。引用勘误表:
如果执行软件复位(SPI控制寄存器中的SWRST),SPI可能无法工作
正确(时钟在芯片选择之前启用。)
问题修复/解决方法
SPI控制寄存器字段SWRST(软件复位)需要写入两次才能进行校正- 直线设置 - 我注意到,有时,如果我在写入
寄存器(在SPI\u TDR
中)之前加上一个延迟,那么代码工作正常,通信成功SPI\u write()
const short int dataSize = 5;
// Filling array with random data
unsigned char data[dataSize] = {0xA5, 0x34, 0x12, 0x00, 0xFF};
short int i = 0;
volatile unsigned short dummyRead;
SetCS3(); // NPCS3 == PIOA15
while(i-- < dataSize) {
mySPI_Write(data[i]);
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
dummyRead = SPI_Read(); // SPI_Read() from Atmel's library
}
ClearCS3();
/**********************************/
void mySPI_Write(unsigned char data) {
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
AT91C_BASE_SPI0->SPI_TDR = data;
while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0); // <-- This is where
// the processor hangs, because that the SPI peripheral is disabled
// (SPIENS equals 0), which makes TDRE equal to 0 forever.
}
while(i-- < dataSize)
while(i--
递减有符号整数i
,不递增并访问数据[i]
,直到i
溢出为正值。谁知道会发生什么,您正在访问什么内存或寄存器?如果不需要保留负值,则使用无符号整数通常更好
另外,您已经在检查TXEMPTY
,这意味着数据被移动到移位寄存器并发送出去。因此,您也不需要检查TDRE
,这意味着数据被移动到移位寄存器,但可能不会被发送出去
另外,如果您不同时交换数据,我强烈建议您使用PDC,我认为情况并非如此。您是否解决了此Dor?我们很想知道你是否找到了根本原因。我不记得我是如何解决这个问题的。我认为我在处理器时钟的初始化过程中遇到了一个问题:init的步骤没有如数据表中所述。值得注意的是,这段代码没有“传输五个字节的数据”。