找回密码
 立即注册
楼主: 大明狐

用AiCube配置硬件SPI和DMA点亮OLED12864 | 跟帖问OLED12864程序给您全搞定

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-03-22 12:02:18
已绑定手机

1

主题

7

回帖

143

积分

注册会员

积分
143
发表于 2026-3-7 19:25:08 | 显示全部楼层
版主 你好  void OLED_Refresh(void)
{
    uint8_t page;
    uint8_t cmd[4];
   
    for( page=0; page<8; page++ )
    {
        cmd[0] = 0x40;                      //设置屏幕最顶上一行作为第0行
        cmd[1] = 0xB0+page;             //设置行起始地址
        cmd[2] = 0x10;                      //设置低列起始地址(高四位)
        cmd[3] = 0x00;                      //设置高列起始地址(低四位)
        OLED_WR_CMD( cmd, 4 );  

        OLED_WR_DAT( OledCache + page*128, 128 );
    }        
}

也可以写成
void OLED_Refresh(void)
{
    uint8_t page;
    uint8_t cmd[3];
   
    for( page=0; page<8; page++ )
    {
        cmd[0] = 0xB0+page;             //设置行起始地址
        cmd[1] = 0x10;                      //设置低列起始地址(高四位)
        cmd[2] = 0x00;                      //设置高列起始地址(低四位)
        OLED_WR_CMD( cmd, 3 );  

        OLED_WR_DAT( OledCache + page*128, 128 );
    }        
}
这是你的代码  我更改下想一次发送1024个字节  为啥总是配置不成
uint8_t cmd[6];
               
                cmd[0]=0x21;//
                cmd[1]=0x00;
                cmd[2]=0x7f;//
                cmd[3]=0x22;
                cmd[4]=0x00;//
                cmd[5]=0x07;
               
                OLED_WR_CMD(&cmd[0],6);
                OLED_WR_DAT(&ShowBUFF[0][0],8*128);

初始化时已配置为水平寻址模式了!???请指教

点评

你的代码没看出问题。 要连续发送1024个字节,屏幕初始化的时候要设置成 水平地址模式: 0x20, 0x00, 重点是,DMA发送的数据必须放在 xdata 区 你的 cmd[] 应该写成 uint8_t xdata cmd[6]; 另外不知道你的 ShowBU  详情 回复 发表于 2026-3-8 10:48
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:721
  • 最近打卡:2026-04-01 04:36:57

40

主题

457

回帖

4407

积分

荣誉版主

积分
4407
发表于 2026-3-8 10:48:54 | 显示全部楼层
kac*** 发表于 2026-3-7 19:25
版主 你好  void OLED_Refresh(void)
{
    uint8_t page;

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

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

另外,不知道你的DMA缓存数组有没有放在xdata区
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-03-22 12:02:18
已绑定手机

1

主题

7

回帖

143

积分

注册会员

积分
143
发表于 2026-3-8 13:24:44 | 显示全部楼层
kac*** 发表于 2026-3-7 19:25
版主 你好  void OLED_Refresh(void)
{
    uint8_t page;

uint8_t xdata pu8SPIDMATxBuffer[1024];  //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[n],OLED_DATA);
    }
#else               
/*************************************************************
                u8 xdata cmd[3];
                cmd[1]=0x02;//设置低列起始地址 +2右侧屏幕不再漏光
                cmd[2]=0x10;//设置高列起始地址
                for(i=0;i<8;i++)
    {
       cmd[0]=(u8)(0xb0+i);
                         OLED_WR_CMD(&cmd[0],3);                        
                         OLED_WR_DAT(&ShowBUFF[0],128);
    }        使用这段一定能成功
******************************************************************/
                uint8_t xdata cmd[8];
                //uint8_t xdata *data buf;
                //buf=cmd;
                cmd[0]=0x20;               
                cmd[1]=0x00;
                cmd[2]=0x21;               
                cmd[3]=0x02;
                cmd[4]=0x81;               
                cmd[5]=0x22;
                cmd[6]=0x00;               
                cmd[7]=0x07;
               
   
                OLED_WR_CMD(&cmd[0],8);                        
                OLED_WR_DAT(&ShowBUFF[0][0],1024);使用这段就不能成功
        
#endif               
}

我把SPI-DMA包装了一下,包装成 命令DMA和数据DMA,
ShowBUFF[8][128]定义在 xdata ???????????????????????????请耐心看下,指导一下


一下发送1024  就是搞不定
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:7
  • 最近打卡:2026-03-22 12:02:18
已绑定手机

1

主题

7

回帖

143

积分

注册会员

积分
143
发表于 2026-3-14 12:05:16 来自手机 | 显示全部楼层
kache 发表于 2026-3-8 13:24
uint8_t xdata pu8SPIDMATxBuffer[1024];  //SPI DMA发送缓冲区数组

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

我搞定了,显示屏的驱动有问题,不是1306!
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-4-1 08:57 , Processed in 0.110679 second(s), 60 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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