找回密码
 立即注册
查看: 3148|回复: 8

关于DMA使用详细解说

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-07-02 10:09:53

17

主题

29

回帖

299

积分

中级会员

积分
299
发表于 2023-3-17 17:50:51 | 显示全部楼层 |阅读模式
最近使用DMA_SPI读写W25Q128,参考例程,始终不成功,不用DMA功能SPI读写W25Q128就可以。

不知有没有关于DMA功能寄存器详细原理解说一下呢,我对DMA中断原理不太清楚,是不是一定要写满缓存或读完缓存才会有中断吗?
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-07-02 10:09:53

17

主题

29

回帖

299

积分

中级会员

积分
299
发表于 2023-3-17 17:52:16 | 显示全部楼层
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] = 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[j]);                           
                 }         
          }
               
                           

    while (1)
    {
        delay_ms(1);
               
        if(RX2_TimeOut > 0)
        {
            if(--RX2_TimeOut == 0)  //超时,则串口接收结束
            {
                if(RX2_Cnt > 0)
                {
                    RX2_Check();    //串口1处理数据
                }
                RX2_Cnt = 0;
            }
        }
    }
}
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-07-02 10:09:53

17

主题

29

回帖

299

积分

中级会员

积分
299
发表于 2023-3-17 17:54:41 | 显示全部楼层
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标志
}
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-07-02 10:09:53

17

主题

29

回帖

299

积分

中级会员

积分
299
发表于 2023-3-17 17:55:46 | 显示全部楼层
附件程序

硬件SPI使用DMA访问FLASH-串口1监控 - 副本.zip

73 KB, 下载次数: 146

回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-07-02 10:09:53

17

主题

29

回帖

299

积分

中级会员

积分
299
发表于 2023-3-17 17:56:46 | 显示全部楼层
麻烦有空的兄弟帮忙参考!指点!DMA功能确实是好东西 ,能用就用!
  • 打卡等级:偶尔看看III
  • 打卡总天数:55
  • 最近打卡:2025-05-02 08:32:59

718

主题

1万

回帖

1万

积分

管理员

积分
15630
发表于 2023-3-17 22:39:35 | 显示全部楼层
1.png
  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2024-12-25 10:15:05

47

主题

1350

回帖

8058

积分

荣誉版主

冲哥视频教程和各种开源资料QQ交流群884047237,可群

积分
8058
QQ
发表于 2023-3-18 00:07:28 | 显示全部楼层
1.png

STC32G试验箱有一模一样的历程~就是FLASH型号不一样而已
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-07-02 10:09:53

17

主题

29

回帖

299

积分

中级会员

积分
299
发表于 2023-3-18 10:08:23 | 显示全部楼层
现在DMA_W25Q能写入和读出,只是读出第一个数是0XFF,原本应盖是0X00的,不知什么原因?
另外写入长度256会失败,有碰到这种问题 的兄弟吗?

点评

请您参考STC32G实验箱第62个例程DMA-SPI与存储器自动收发例程(双击点开62个范例:硬件spi使用DmA访问flash):  详情 回复 发表于 2023-3-18 10:43
  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2025-04-30 10:59:33

25

主题

1154

回帖

2391

积分

超级版主

积分
2391
发表于 2023-3-18 10:43:15 | 显示全部楼层
158185*** 发表于 2023-3-18 10:08
现在DMA_W25Q能写入和读出,只是读出第一个数是0XFF,原本应盖是0X00的,不知什么原因?
另外写入长度256会 ...

请您参考STC32G实验箱第62个例程DMA-SPI与存储器自动收发例程(双击点开62个范例:硬件spi使用DmA访问flash):


1.png

2.png

STC官网:https://www.stcai.com/
QQ:2593903262
微信号:18106296598
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:43 , Processed in 0.168616 second(s), 96 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表