2261516_ja-JP

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2261516_ja-JP

2261516_ja-JP

LPC1768+SSP0+GPDMAに問題あり

SSP0 で DMACR を開いて BUF にデータを送信した後、DMACR がゼロにリセットされ、SSP0DR は変化し続けますが、BUF データは変更されないのはなぜでしょうか。割り込み中に DMACR を再度開こうとしましたが、BUF データにはまだ変化がありませんでした。
コード構成は次のとおりです。


#定義 SPI_RX_LEN 5386

外部U8 SPIRXBUF[SPI_RX_LEN];

void DMAInit_SPI_RX(U8 *destAddr, U32 len)
{
U32 パート1 = (長さ > 4095) ?4095 : 長さ;
U32 パート2 = (長さ > 4095) ?(len - 4095) : 0;// 拆分传输(单道最大4095字节)
 
LPC_SC->PCONP |= (1 << 29); // 使用GPDMA時間钟
LPC_GPDMA->DMACConfig |= (1 << 0);//GPDMA を使用する
LPC_GPDMA->DMACIntTCClear |= 0x01; // 清除道0传输完了标志
LPC_GPDMA->DMACIntErrClr |= 0x01; // 清除道0错误标志
 
// 链表项1:传输part1字节
lli[0].srcAddr= (U32)&LPC_SSP0->DR; // ソース:SPI0データ寄存器
lli[0].宛先アドレス= (U32)destAddr; // 目的:缓冲区開始
lli[0].コントロール= (part1 & 0x0FFF) // 传输大小(字节数)
| (0x00 << 12) // 源突発大小
| (0x00 << 15) // 目的発行大小
| (0x00 << 18) //ソースデータ宽度
| (0x00 << 21) //目的データ宽度
| (0x00 << 26) //源地址不变(外设寄存器)
| (0x01 << 27) //目的地址自增
| (1U << 31); // 使用中断
 
// 链表项2:传输part2字节(若必要)
(パート2 > 0)の場合
{
lli[0].nextLLI = (U32)&lli[1]; // 指向链表项2
lli[1].srcAddr= (U32)&LPC_SSP0->DR;
lli[1].destAddr= (U32)(destAddr +part1); // 缓冲区偏移
lli[1].コントロール= (part2 & 0x0FFF) // 传输大小(字节数)
| (0x00 << 12) // 源突発大小
| (0x00 << 15) // 目的発行大小
| (0x00 << 18) //ソースデータ宽度
| (0x00 << 21) //目的データ宽度
| (0x00 << 26) //源地址不变(外设寄存器)
| (0x01 << 27) //目的地址自增
| (1U << 31); // 使用中断
lli[1].nextLLI= 0; // 结束链表
}
そうでない場合、
{
lli[0].nextLLI = 0;
}
 
// 配置DMA通道0
LPC_GPDMACH0->DMACCConfig = 0;
LPC_GPDMACH0->DMACCLLI = (U32)&lli[0]; // 链表開始地址
LPC_GPDMACH0->DMACCSrcAddr = lli[0].srcAddr;// ソース地址(SPI0 DR)
LPC_GPDMACH0->DMACCDestAddr = lli[0].destAddr;// 目的地址
LPC_GPDMACH0->DMACCコントロール = lli[0].control;// 制御文字
LPC_GPDMACH0->DMACCConfig = (0x01 << 15) //中断错误
| (0x01 << 14) //終端计数中断
| (0x02 << 11) // 传输種類:外设到内存
| (0x00 << 6) //目的外设:保存器
| (0x01 << 1) // ソース外设:SSP0 RX(参考手册)
| (0x01 << 0); // 道使い能
 
GPDMAEnabe();
}
 
 
void DMA_IRQHandler(void)
{
if(LPC_GPDMA->DMACIntTCStat & 0x01) // 通道0転送完了
{
LPC_GPDMA->DMACIntTCClear = 0x01; // 清除标志
//SSPSlave_Init();
// RUN_LAMP_GLITTER;
// LPC_SSP0->DMACR |= (1 << 0);
// LPC_GPDMACH0->DMACCConfig |= (0x01 << 0);
LPC_GPDMA->DMACConfig |= (1 << 0);//GPDMA を使用する
時間++;
}
if(LPC_GPDMA->DMACIntErrStat & 0x01) // 通道0错误
{
LPC_GPDMA->DMACIntErrClr = 0x01; // 清除标志
}
}
void SSPSlave_Init(void)
{
LPC_SC->PCONP |= (1 << 21); /* 打开SSP電源 */
/************************************************************************
* 初期化SSPの通信方式、データ長は8bit、フレーム形式はSPI、SCKは低能率に設定されています。
* データは SCK の 2 番目の時間にサンプリングされ、ビットレートが設定されます。
**********************************************************************/
LPC_SSP0->CR0 = (0x00 << | /* SCR 設定 SPI ビット速度 */
(0x01 << 7) | /* CPHA 時間钟输出相位 */
(0x00 << 6) | /* CPOL 時間钟出力性 */
(0x00 << 4) | /* FRF 帧格式 00=SPI,01=SSI, */
/* 10=マイクロワイヤー,11=保留 */
(0x07 << 0); /* DSS データ長度,0000-0010= 保持 */
/* 0011=4 位、0111=8 位、1111=16 位*/
LPC_SSP0->CPSR = 2; /* 時間钟分周波数寄存器*/
 
LPC_SSP0->CR1 = (0x00 << 3) | /* SOD 从机输出禁能,0=允许 */
(0x01 << 2) | /* MS 主从选择,1=从机 */
(0x01 << 1) | /* SSE SSP 使用能,1=使用能 */
(0x00 << 0); /* LBM 回写モード */
 
sysTimeDlay(5);
LPC_SSP0->DMACR |= (1 << 0);
 
}
LPC17xxRe: LPC1768+SSP0+GPDMA some problem

こんにちは@Lee_Lee

DMA は「空の SSP FIFO を読み取っている」と思いますが、アクセス幅が正しくないため、データがメモリに正しく書き込まれていません。

現在何を設定していますか

(0x00<<18)//ソースデータ宽度
(0x00<<21)//目的データ宽度
しかし、LPC では次のようになります。

SSPのDRレジスタは16ビットのレジスタである。

Harry_Zhang_0-1765963833177.png


8 ビット SPI モードを使用している場合でも、SSP0->DR への DMA アクセスは 16 ビット アクセスである必要があります。

DMAは実際にはメモリにデータを正しく書き込んでいない
その結果、BUF は変更されません。

SO、ソースと des の幅を 16 に変更してみると CAN と思います。

BR

ハリー

タグ(1)
評価なし
バージョン履歴
最終更新日:
‎12-18-2025 03:39 AM
更新者: