大明狐 发表于 2026-3-8 10:48:54

kache 发表于 2026-3-7 19:25
版主 你好void OLED_Refresh(void)
{
    uint8_t page;

代码没看出问题。
要连续发送1024个字节,屏幕初始化的时候要设置成 水平地址模式:
0x20, 0x00,

至于0x21和0x22两条设置显示区域的指令,如果设置成水平地址模式,屏幕默认就是全屏,
所以如果中途不需要更改显示区域大小,可以不写或者直接放在初始化函数里,
这样,每次发送的时候就不用重复设置了,节约运行时间。

另外,不知道你的DMA缓存数组有没有放在xdata区

kache 发表于 2026-3-8 13:24:44

kache 发表于 2026-3-7 19:25
版主 你好void OLED_Refresh(void)
{
    uint8_t page;

uint8_t xdata pu8SPIDMATxBuffer;//SPI DMA发送缓冲区数组

////////////////////////////////////////
// SPI DMA中断服务程序
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void DMA_SPI_ISR(void) interrupt DMA_SPI_VECTOR
{
    //<<AICUBE_USER_SPI_ISR_CODE2_BEGIN>>
    // 在此添加中断函数用户代码
    if (DMA_SPI_CheckFlag())            //判断SPI DMA中断
    {
      DMA_SPI_ClearFlag();            //清除SPI DMA中断标志
                              DMA_SPI_ClearFIFO();            //清空SPI DMA FIFO缓冲区
                              fSPIDMABusy=0;
    }
    //<<AICUBE_USER_SPI_ISR_CODE2_END>>
}

////////////////////////////////////////
// 发送OLED数据
// 入口参数: dat (数据序列)
//         len (数据长度)
// 函数返回: 无
////////////////////////////////////////
void OLED_SPI_SendData(uint8_t *dat, uint16_t len)
{                        
      memcpy(pu8SPIDMATxBuffer, dat, len);         //将数据复制到DMA缓冲区
      while(fSPIDMABusy);
            DMA_SPI_SetAmount(len - 1);               //设置DMA发送字节数
            DMA_SPI_MasterTrigger();                  //触发SPI主机DMA
      
                fSPIDMABusy=1;
                OLED_DC = 1;
}
void OLED_WR_CMD(uint8_t *cmd, uint16_t len)
{
    OLED_DC = 0;                        //写命令
    OLED_SPI_SendData(cmd, len);
}
////////////////////////////////////////
// 写OLED数据
// 入口参数: dat (数据序列)
//         len (数据长度)
// 函数返回: 无
////////////////////////////////////////
void OLED_WR_DAT(uint8_t *dat, uint16_t len)
{
   
    OLED_DC = 1;                        //写数据
    OLED_SPI_SendData(dat, len);
}

void OLED_BuffShow(void)   
{
   
#if(OLED_SPI_DMA==0)
                u8 xdata i;
                u8 xdata n;
    for(i=0;i<8;i++)
    {
       OLED_WR_Byte((u8)(0xb0+i),OLED_CMD); //设置行起始地址
       OLED_WR_Byte(0x02,OLED_CMD);   //设置低列起始地址 +2右侧屏幕不再漏光
       OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址

       for(n=0;n<128;n++)
         OLED_WR_Byte(ShowBUFF,OLED_DATA);
    }
#else               
/*************************************************************
                u8 xdata cmd;
                cmd=0x02;//设置低列起始地址 +2右侧屏幕不再漏光
                cmd=0x10;//设置高列起始地址
                for(i=0;i<8;i++)
    {
       cmd=(u8)(0xb0+i);
                         OLED_WR_CMD(&cmd,3);                        
                         OLED_WR_DAT(&ShowBUFF,128);
    }      使用这段一定能成功
******************************************************************/
                uint8_t xdata cmd;
                //uint8_t xdata *data buf;
                //buf=cmd;
                cmd=0x20;               
                cmd=0x00;
                cmd=0x21;               
                cmd=0x02;
                cmd=0x81;               
                cmd=0x22;
                cmd=0x00;               
                cmd=0x07;
               
   
                OLED_WR_CMD(&cmd,8);                        
                OLED_WR_DAT(&ShowBUFF,1024);使用这段就不能成功
      
#endif               
}
我把SPI-DMA包装了一下,包装成 命令DMA和数据DMA,
ShowBUFF定义在 xdata ???????????????????????????请耐心看下,指导一下

一下发送1024就是搞不定

kache 发表于 2026-3-14 12:05:16

kache 发表于 2026-3-8 13:24
uint8_t xdata pu8SPIDMATxBuffer;//SPI DMA发送缓冲区数组

////////////////////////////////// ...

我搞定了,显示屏的驱动有问题,不是1306!
页: 1 2 [3]
查看完整版本: 用AiCube配置硬件SPI和DMA点亮OLED12864 | 跟帖问OLED12864程序给您全搞定