关于DMA使用详细解说
最近使用DMA_SPI读写W25Q128,参考例程,始终不成功,不用DMA功能SPI读写W25Q128就可以。不知有没有关于DMA功能寄存器详细原理解说一下呢,我对DMA中断原理不太清楚,是不是一定要写满缓存或读完缓存才会有中断吗?
void main(void)
{
u8 i,j;
WTST = 0;//设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
P2SR = 0x00; //电平转换速度快(提高IO口翻转速度)
P1SR = 0x00; //电平转换速度快(提高IO口翻转速度)
P4SR = 0x00; //电平转换速度快(提高IO口翻转速度)
P2DR=0x00;
P1DR=0x00;
P4DR=0x00;
UartInit();
DMA_Config();
EA = 1; //允许总中断
/*
printf("命令设置:\r\n");
printf("E 0x001234 --> 扇区擦掉十六进制地址\r\n");
printf("W 0x001234 1234567890 --> 写入操作十六进制地址写入内容\r\n");
printf("R 0x001234 10 --> 读出操作十六进制地址读出字节内容\r\n");
printf("C --> 如果检测不到PM25LV040/W25X40CL/W25Q80BV, 发送C强制允许操作.\r\n\r\n");
*/
SPI_init();
// FlashCheckID();
delay_ms(100);
FlashSectorErase(0);
for(j=0; j<255; j++)
{
DmaTxBuffer = j;
}
for(i=0; i<16; i++)
{
SPI_Write_Nbytes(256*i,256); //写N个字节
}
for(i=0; i<16; i++)
{
SPI_Read_Nbytes(256*i,256);
for(j=0; j<255; j++)
{
printf("%c", DmaRxBuffer);
}
}
while (1)
{
delay_ms(1);
if(RX2_TimeOut > 0)
{
if(--RX2_TimeOut == 0)//超时,则串口接收结束
{
if(RX2_Cnt > 0)
{
RX2_Check(); //串口1处理数据
}
RX2_Cnt = 0;
}
}
}
}
void DMA_Config(void)
{
DMA_SPI_STA = 0x00;
DMA_SPI_CFG = 0xE0; //bit7 1:Enable Interrupt
DMA_SPI_AMT = 0xff; //设置传输总字节数:n+1
DMA_SPI_TXAH = (u8)((u16)&DmaTxBuffer >> 8); //SPI发送数据存储地址
DMA_SPI_TXAL = (u8)((u16)&DmaTxBuffer);
DMA_SPI_RXAH = (u8)((u16)&DmaRxBuffer >> 8); //SPI接收数据存储地址
DMA_SPI_RXAL = (u8)((u16)&DmaRxBuffer);
DMA_SPI_CFG2 = 0x00; //01:P2.2
DMA_SPI_CR = 0x81; //bit7 1:使能 SPI_DMA, bit6 1:开始 SPI_DMA 主机模式, bit0 1:清除 SPI_DMA FIFO
}
void SPI_init(void)
{
SSIG = 1; //忽略 SS 引脚功能,使用 MSTR 确定器件是主机还是从机
SPEN = 1; //使能 SPI 功能
DORD = 0; //先发送/接收数据的高位( MSB)
MSTR = 1; //设置主机模式
CPOL = 1; //SCLK 空闲时为高电平,SCLK 的前时钟沿为下降沿,后时钟沿为上升沿
CPHA = 1; //数据在 SCLK 前时钟沿驱动,后时钟沿采样
SPCTL = (SPCTL & ~3) | 3; //SPI 时钟频率选择, 0: 4T, 1: 8T,2: 16T,3: 2T
P_SW1 |= 0X00;//IO口切换. 0: P1.2/P5.4 P1.3 P1.4 P1.5, 1: P2.2 P2.3 P2.4 P2.5, 2: P5.4 P4.0 P4.1 P4.3, 3: P3.5 P3.4 P3.3 P3.2
P_PM25LV040_SCK = 0; // set clock to low initial state
P_PM25LV040_SI = 1;
SPI_CE_High();
SPIF = 1; //清SPIF标志
WCOL = 1; //清WCOL标志
}
附件程序 麻烦有空的兄弟帮忙参考!指点!DMA功能确实是好东西 ,能用就用!
STC32G试验箱有一模一样的历程~就是FLASH型号不一样而已
现在DMA_W25Q能写入和读出,只是读出第一个数是0XFF,原本应盖是0X00的,不知什么原因?
另外写入长度256会失败,有碰到这种问题 的兄弟吗?
15818564352 发表于 2023-3-18 10:08
现在DMA_W25Q能写入和读出,只是读出第一个数是0XFF,原本应盖是0X00的,不知什么原因?
另外写入长度256会 ...
请您参考STC32G实验箱第62个例程DMA-SPI与存储器自动收发例程(双击点开62个范例:硬件spi使用DmA访问flash):
页:
[1]