打印
[创新制造展示]

【21ic第三届设计大赛】+超强!数字函数发生器(STM8L 主控)

[复制链接]
4675|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 小小电子爱好者 于 2019-7-2 12:54 编辑

先发帖抢第一  不然最后一评   啥都没有第一
终于终于! 我看到活动快结束了,真是不到最后不紧张,其实之前做了STM8L051的因为没有内置DAC,所以画了块板接了DAC芯片加上运放电路,最后测了一下波形效果很差不知道啥原因也没管,应为工作太忙,忙起来就丢一边了。(看一下丑照)



这不是这几天刚好闲了一点,抽了几天闲余时间拉出来之前收集的开发板 STM8L152C6的官方板,带DAC的画了块底座拓展,简单做一下,不想发个帖子啥都没做就结束了,那真太怂了,做的再烂也比偷偷删帖好多了,毕竟二姨家必须要支持得嘛!哈哈 那绝对是当然的!!!


使用特权

评论回复
评论
黄大队长 2019-6-29 22:06 回复TA
来了,老弟 
小小电子爱好者 2019-6-27 13:49 回复TA
@LED2013 :来了 
LED2013 2019-5-23 23:47 回复TA
你的主贴呢 
dirtwillfly 2019-5-21 22:59 回复TA
积极参与 

相关帖子

沙发
小小电子爱好者|  楼主 | 2019-6-27 13:38 | 只看该作者
本帖最后由 小小电子爱好者 于 2019-6-27 20:00 编辑

STM8L152C6 开发板做的数字函数发生器
时间紧,就争取把基本的做好。
刚开始确定了一下功能:
1. OLED12864常规操作 来显示一下信息,知到我们在干嘛。
2. 4个按键切换 4种不同波形(正弦,锯齿,三角,方波)。
3. 旋转编码器来调整波形的 幅度、频率 、通过编码器自带的按键实现切换。
4. 计划加入一些预先准备的自定义波形,放在flash存储区,通过页面来切换 【基本波形页面】【自定义波形页面】。

使用特权

评论回复
板凳
小小电子爱好者|  楼主 | 2019-6-27 20:19 | 只看该作者
本帖最后由 小小电子爱好者 于 2019-6-27 20:37 编辑

硬件外设:

芯片 : STM8L152   
软件 :IAR 3.10.4 固件库
外设 : DAC 、DMA、 定时器4
硬件 : 独立按键*4,编码器+按键  OLED12864


编码器短按 切换 调频 调幅,长按切换页面显示自定义波形。

检测波形的小设计  哈哈 为了方便










使用特权

评论回复
地板
小小电子爱好者|  楼主 | 2019-6-27 20:36 | 只看该作者
本帖最后由 小小电子爱好者 于 2019-6-28 18:23 编辑

软件实现安排:


开启DAC
开启DMA的DAC通道设置数据地址、数据量(数据buff大可以波形更流畅)
开定时器设置成溢出更新事件触发DMA转换(改变定时器值可修改波形频率)

正弦波 锯齿波 三角波 方波
这几个波形用简单算法给数组赋值,可以方便修改幅度。其他自定义波形做个数组,存在内部flash。
然后
按键程序逻辑设计,编码器调节程序


最后
主程序跑按键 OLED显示 等逻辑
然后开启DMA持续运输数组数据跑波形。




使用特权

评论回复
5
小小电子爱好者|  楼主 | 2019-6-28 18:56 | 只看该作者
本帖最后由 小小电子爱好者 于 2019-6-28 18:59 编辑
代码部分:


DAC部分代码
static void DMA_Config(void)
{
  DMA_GlobalDeInit();
  DMA_DeInit(DMA1_Channel3);
  CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);
  
  DMA_Init(DMA1_Channel3,
              (uint32_t)((uint16_t)&Wave_Buffer),
              0x5388,
              130,
              DMA_DIR_MemoryToPeripheral,
              DMA_Mode_Circular,
              DMA_MemoryIncMode_Inc,
              DMA_Priority_VeryHigh,
              DMA_MemoryDataSize_HalfWord );
  
  DMA_Cmd(DMA1_Channel3, ENABLE);
  DMA_GlobalCmd(ENABLE );
}
static void Timer4_Config()
{
    TIM4_DeInit();
   
    CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, ENABLE);
   
    TIM4_TimeBaseInit(TIM4_Prescaler_1,
                       0x09);
   
    TIM4_SelectOutputTrigger(TIM4_TRGOSource_Update);
    //TIM4_ITConfig( TIM4_IT_Update, ENABLE );
   
    TIM4_Cmd(ENABLE);

}
/**
*
*        DAC初始化
*
**/
void DAC_Config()
{
  DAC_DeInit();
  
  CLK_PeripheralClockConfig(CLK_Peripheral_DAC, ENABLE);
  
  DAC_Init(DAC_Channel_1,
                DAC_Trigger_T4_TRGO,//DAC_Trigger_Software//DAC_Trigger_T4_TRGO
                DAC_OutputBuffer_Disable);//DAC_OutputBuffer_Enable

  DAC_Cmd(DAC_Channel_1, ENABLE);
  
  DAC_DMACmd(DAC_Channel_1, ENABLE);
  
  Timer4_Config();
  
  DMA_Config();

}

编码器部分
void ROTATY_Init()
{
  GPIO_Init(GPIOD,GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5,GPIO_Mode_In_PU_No_IT);
}
void ROTATY_Scan_Driver()
{
  static uint8_t Turn_L=0,Turn_R=0,Rot_Flag=0;
  
  if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7)==GPIO_Pin_7)&&(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==GPIO_Pin_6))
  {
    Rot_Flag=0x01;
  }
  if(Rot_Flag == 0x01)
  {
    if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7)!=GPIO_Pin_7)&&(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)!=GPIO_Pin_6))
    {
      if(Turn_L == 0x01)
      {
        if((Selet_Value == 0x00)&&(Menu_value == 0))
        {
          if(Roty_Value<4000)
          Roty_Value+=Roty_Value2;
          Roty_value3=(uint16_t)((Roty_Value*3.3)*10/4096);
         
          OLED_ShowNum(80,6,Roty_value3/10,1,16);
          OLED_ShowChar(88,6,'.');
          OLED_ShowNum(96,6,Roty_value3%10,1,16);
        }
        else if((Selet_Value == 0x01)&&(Menu_value == 0))
        {
          if(Bias_Value<9)
          Bias_Value+=Bias_Value2;
          OLED_ShowNum(0,6,Bias_Value*1000,5,16);  
          TIM4_TimeBaseInit(Bias_Value,10);
        }
        Rot_Flag=0x00;
      }
      if(Turn_R == 0x01)
      {
        if((Selet_Value == 0x00)&&(Menu_value == 0))
        {
          if(Roty_Value>100)
          Roty_Value-=Roty_Value2;
          Roty_value3=(uint16_t)((Roty_Value*3.3)*10/4096);
          OLED_ShowNum(80,6,Roty_value3/10,1,16);
          OLED_ShowChar(88,6,'.');
          OLED_ShowNum(96,6,Roty_value3%10,1,16);
        }
        else if((Selet_Value == 0x01)&&(Menu_value == 0))
        {
          if(Bias_Value>1)
          Bias_Value-=Bias_Value2;
          OLED_ShowNum(0,6,Bias_Value*1000,5,16);         
          TIM4_TimeBaseInit(Bias_Value,10);
        }        
        Rot_Flag=0x00;
      }
      if(Menu_value == 0)
      {
        if(n_wave == 1)
         getSinTab(130,Roty_Value);
        else if(n_wave == 2)
         getTriaTab(130,Roty_Value);
        else if(n_wave == 3)
         getSawTab(130,Roty_Value);
        else if(n_wave == 4)  
         getSquarTab(130,Roty_Value);
      }
    }
  }
  
  if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7) == GPIO_Pin_7))
  {
    Turn_L =0x01;
  }
else
{
  Turn_L =0;
}
  if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6) == GPIO_Pin_6))
  {
    Turn_R =0x01;
  }
else
{
  Turn_R =0;
}
}
OLED部分
void Delay_5us()
{
  uint8_t i,x;
  for(i = 0;i>45;x++)
    {
    }
}
void iic_start()
{
  GPIO_WriteBit( GPIOB, IIC_DAT,SET);
  GPIO_WriteBit( GPIOB, IIC_CLK,SET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
  GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
  Delay_5us();
}
void iic_stop()
{
  GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
  GPIO_WriteBit( GPIOB, IIC_CLK,SET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_DAT,SET);
  
}
uint8_t iic_ReadByte(void)
{
        uint8_t i;
        uint8_t value;

        /* 读到第1个bit为数据的bit7 */
        value = 0;
        GPIO_Init( GPIOB,  IIC_DAT, GPIO_Mode_In_FL_No_IT);
        for (i = 0; i < 8; i++)
        {
                value <<= 1;
                GPIO_WriteBit( GPIOB, IIC_CLK,SET);
                 Delay_5us();
                if (GPIO_ReadInputDataBit( GPIOB,  IIC_DAT) ==IIC_DAT)
                {
                        value++;
                }
                GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
                Delay_5us();
        }
       GPIO_Init( GPIOB,  IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
       GPIO_WriteBit( GPIOB, IIC_DAT,SET);
        return value;
}
uint8_t iic_waitAck()
{
  uint8_t res=1;
  uint8_t i=0;
  
  GPIO_WriteBit( GPIOB, IIC_CLK,SET);
  Delay_5us();
  
  GPIO_Init( GPIOB,  IIC_DAT, GPIO_Mode_In_FL_No_IT);
  
  while((res)&&(i<5))
  {
    if(GPIO_ReadInputDataBit( GPIOB,  IIC_DAT) ==IIC_DAT )
    {
      res = 1;
    }
    else
    {
      res= 0;
    }
    i++;
  }

  GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
  GPIO_Init( GPIOB,  IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
  return  res;  
}

void iic_rack()
{
  GPIO_Init( GPIOB,  IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
  GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_CLK,SET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_DAT,SET);  
}
void iic_nack()
{
  GPIO_Init( GPIOB,  IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
  GPIO_WriteBit( GPIOB, IIC_DAT,SET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_CLK,SET);
  Delay_5us();
  GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
  Delay_5us();
}
uint8_t iic_sendbyte(uint8_t data)
{
  uint8_t i;
  for(i=0;i<8;i++)
  {
    if(data & 0x80)
    {
      GPIO_WriteBit( GPIOB, IIC_DAT,SET);
    }
    else
    {
      GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
    }
    data<<=1;
    GPIO_WriteBit( GPIOB, IIC_CLK,SET);
    Delay_5us();
    GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
    Delay_5us();   
  }
  GPIO_WriteBit( GPIOB, IIC_DAT,SET);
  return data;
}
/**
  * @函数名       Write_OELD_Command
  * @功  能       对OLED写入命令
  * @参  数       IIC_Command:写入的命令字节
  * @返回值       无
  */
void Write_OLED_Command(unsigned char IIC_Command)
{
  iic_start();
  
  iic_sendbyte(0x78);
  
  iic_waitAck();
  
  iic_sendbyte(0x00);

  iic_waitAck();
  
  iic_sendbyte(IIC_Command);
  
  iic_waitAck();
  
  iic_stop();
}


/**
  * @函数名       Write_OELD_Data
  * @功  能       对OLED写入数据
  * @参  数       IIC_Data:写入的数据字节
  * @返回值       无
  */
void Write_OLED_Data(unsigned char IIC_Data)
{
  iic_start();
  
  iic_sendbyte(0x78);
  
  iic_waitAck();
  
  iic_sendbyte(0x40);

  iic_waitAck();
  
  iic_sendbyte(IIC_Data);
  
  iic_waitAck();
  
  iic_stop();
}


/**
  * @函数名       OLED_WR_Byte
  * @功  能       OLED写入一字节命令/数据
  * @参  数       dat:写入的数据/命令字节
  * @返回值       cmd:1-写入数据;0-写入命令
  */
void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{
  if(cmd)
    {
      Write_OLED_Data(dat); //写入数据
    }
  else {
      Write_OLED_Command(dat); //写入命令
    }
}


/**
  * @函数名       OLED_Set_Pos
  * @功  能       在坐标X,Y初开始花店
  * @参  数       x:X坐标;y:Y坐标
  * @返回值       无
  */
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
  OLED_WR_Byte(0xb0+y,OLED_CMD);        //写入页地址
  OLED_WR_Byte((x&0x0f),OLED_CMD);        //写入列低地址
  OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);        //写入列高地址
}            


/**
  * @函数名       OLED_Display_On
  * @功  能       开OLED显示
  * @参  数       无
  * @返回值       无
  */
void OLED_Display_On(void)
{
  OLED_WR_Byte(0X8D,OLED_CMD);  //设置OLED电荷泵
  OLED_WR_Byte(0X14,OLED_CMD);  //使能,开
  OLED_WR_Byte(0XAF,OLED_CMD);  //开显示
}

/**
  * @函数名       OLED_Display_Off
  * @功  能       关OLED显示
  * @参  数       无
  * @返回值       无
  */
void OLED_Display_Off(void)
{
  OLED_WR_Byte(0X8D,OLED_CMD);  //设置OLED电荷泵
  OLED_WR_Byte(0X10,OLED_CMD);  //失能,关
  OLED_WR_Byte(0XAE,OLED_CMD);  //关显示
}                                            


/**
  * @函数名       OLED_Clear
  * @功  能       清屏
  * @参  数       无
  * @返回值       无
  */
void OLED_Clear(void)  
{  
  unsigned char i,n;                    //定义变量
  for(i=0;i<8;i++)  
    {  
      OLED_WR_Byte (0xb0+i,OLED_CMD);    //从0~7页依次写入
      OLED_WR_Byte (0x00,OLED_CMD);      //列低地址
      OLED_WR_Byte (0x10,OLED_CMD);      //列高地址  
      for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); //写入 0 清屏
    }
}

/**
  * @函数名       OLED_ShowChar
  * @功  能       在指定位置显示字符
  * @参  数       x:X坐标;y:Y坐标;chr:显示的字符
  * @返回值       无
  */
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr)
{              
  unsigned char c=0,i=0;        
  c=chr-' '; //获取字符的偏移量        
  if(x>Max_Column-1){x=0;y=y+2;} //如果列书超出了范围,就从下2页的第0列开始
  if(SIZE ==16) //字符大小如果为 16 = 8*16
    {
      OLED_Set_Pos(x,y);        //从x y 开始画点
      for(i=0;i<8;i++)  //循环8次 占8列
        OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); //找出字符 c 的数组位置,先在第一页把列画完
      OLED_Set_Pos(x,y+1); //页数加1
      for(i=0;i<8;i++)  //循环8次
        OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); //把第二页的列数画完
    }
  else  //字符大小为 6 = 6*8
    {        
      OLED_Set_Pos(x,y+1); //一页就可以画完
      for(i=0;i<6;i++) //循环6次 ,占6列
      OLED_WR_Byte(F6x8[c][i],OLED_DATA); //把字符画完
    }
}

/**
  * @函数名       oled_pow
  * @功  能       计算m的n次方
  * @参  数       无
  * @返回值       result:计算结果
  */
unsigned int oled_pow(unsigned char m,unsigned char n)
{
  unsigned int result=1;         
  while(n--)result*=m;   
  return result;
}

/**
  * @函数名       OLED_ShowNum
  * @功  能       在指定的位置显示指定长度&大小的数字
  * @参  数       x:X坐标;y:Y坐标;num:显示的数字;len:数字的长度;size2:字体的大小
  * @返回值       无
  */                  
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int num,unsigned char len,unsigned char size2)
{                 
  unsigned char t,temp;  //定义变量
  unsigned char enshow=0;                //定义变量
  for(t=0;t<len;t++)
    {
      temp=(num/oled_pow(10,len-t-1))%10;//取出输入数的每个位,由高到低
      if(enshow==0&&t<(len-1)) //enshow:是否为第一个数;t<(len-1):判断是否为最后一个数
        {
          if(temp==0) //如果该数为0
            {
              OLED_ShowChar(x+(size2/2)*t,y,' ');//显示 0 ;x+(size2/2)*t根据字体大小偏移的列数(8)
              continue; //跳过剩下语句,继续重复循环(避免重复显示)
            }else enshow=1;
        }
      OLED_ShowChar(x+(size2/2)*t,y,temp+'0'); //显示一个位;x+(size2/2)*t根据字体大小偏移的列数(8)
    }
}

/**
  * @函数名       OLED_ShowString
  * @功  能       在指定位置显示字符串
  * @参  数       x:X坐标;y:Y坐标;*chr:显示的字符串
  * @返回值       无
  */
void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr)
{
  unsigned char j=0; //定义变量
  while (chr[j]!='\0') //如果不是最后一个字符
    {               
      OLED_ShowChar(x,y,chr[j]); //显示字符
      x+=8; //列数加8 ,一个字符的列数占8
      if(x>120){x=0;y+=2;} //如果x超过128,切换页,从该页的第一列显示
        j++; //下一个字符
    }
}

/**
  * @函数名       OLED_ShowCHinese
  * @功  能       在指定的位置显示汉字
  * @参  数       x:X坐标;y:Y坐标;no:汉字的数组位置
  * @返回值       无
  */
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no)
{                                 
  unsigned char t; //定义变量
  OLED_Set_Pos(x,y);        //从 x y 开始画点,先画第一页
  for(t=0;t<16;t++) //循环16次,画第一页的16列
    {
      OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);//画no在数组位置的第一页16列的点
    }        
  OLED_Set_Pos(x,y+1); //画第二列
  for(t=0;t<16;t++)        //循环16次,画第二页的16列
    {        
      OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);//画no在数组位置的第二页16列的点
    }                                       
}


/**
  * @函数名       OLED_DrawBMP
  * @功  能       在指定的范围显示图片
  * @参  数       x0:起始X坐标;y0:起始X坐标;x1:起始X坐标;y1:起始X坐标;BMP[]:图片的数组起始地址
  * @返回值       无
  */
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{         
unsigned int j=0; //定义变量
unsigned char x,y; //定义变量
  
  if(y1%8==0) y=y1/8;   //判断终止页是否为8的整数倍
  else y=y1/8+1;
  
  for(y=y0;y<y1;y++) //从起始页开始,画到终止页
    {
      OLED_Set_Pos(x0,y); //在页的起始列开始画
      for(x=x0;x<x1;x++) //画x1 - x0 列
        {
          OLED_WR_Byte(BMP[j++],OLED_DATA);        //画图片的点            
        }
    }
}

/**
  * @函数名       OLED_Init
  * @功  能       OLED初始化
  * @参  数       无
  * @返回值       无
  */                                    
void OLED_Init(void)
{

  delay_ms(200);        //延迟,由于单片机上电初始化比OLED快,所以必须加上延迟,等待OLED上电初始化完成

  OLED_WR_Byte(0xAE,OLED_CMD);        //关闭显示
  OLED_WR_Byte(0x2e,OLED_CMD);        //关闭滚动

  OLED_WR_Byte(0x00,OLED_CMD);        //设置低列地址
  OLED_WR_Byte(0x10,OLED_CMD);        //设置高列地址
  OLED_WR_Byte(0x40,OLED_CMD);        //设置起始行地址
  OLED_WR_Byte(0xB0,OLED_CMD);        //设置页地址

  OLED_WR_Byte(0x81,OLED_CMD);         // 对比度设置,可设置亮度
  OLED_WR_Byte(0xFF,OLED_CMD);        //  265  

  OLED_WR_Byte(0xA1,OLED_CMD);        //设置段(SEG)的起始映射地址;column的127地址是SEG0的地址
  OLED_WR_Byte(0xA6,OLED_CMD);        //正常显示;0xa7逆显示

  OLED_WR_Byte(0xA8,OLED_CMD);        //设置驱动路数
  OLED_WR_Byte(0x3F,OLED_CMD);        //1/32 duty
         
  OLED_WR_Byte(0xC8,OLED_CMD);        //重映射模式,COM[N-1]~COM0扫描

  OLED_WR_Byte(0xD3,OLED_CMD);        //设置显示偏移
  OLED_WR_Byte(0x00,OLED_CMD);        //无偏移
         
  OLED_WR_Byte(0xD5,OLED_CMD);        //设置震荡器分频(默认)大概370KHz
  OLED_WR_Byte(0x80,OLED_CMD);        
         
  OLED_WR_Byte(0xD8,OLED_CMD);        //设置 area color mode off(没有)
  OLED_WR_Byte(0x05,OLED_CMD);
         
  OLED_WR_Byte(0xD9,OLED_CMD);        //设置 Pre-Charge Period(默认)
  OLED_WR_Byte(0xF1,OLED_CMD);
         
  OLED_WR_Byte(0xDA,OLED_CMD);        //设置 com pin configuartion(默认)
  OLED_WR_Byte(0x12,OLED_CMD);
         
  OLED_WR_Byte(0xDB,OLED_CMD);        //设置 Vcomh,可调节亮度(默认)
  OLED_WR_Byte(0x30,OLED_CMD);
         
  OLED_WR_Byte(0x8D,OLED_CMD);        //设置OLED电荷泵
  OLED_WR_Byte(0x14,OLED_CMD);        //开显示

  OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)

  OLED_WR_Byte(0xAF,OLED_CMD);//开启OLED面板显示
  OLED_Clear();        //清屏
  OLED_Set_Pos(0,0);          //画点
}  

/**
  * @函数名       OLED_Scroll
  * @功  能       滚动效果配置函数
  * @参  数       无
  * @返回值       无
  */        
void OLED_Scroll(void)
{
  OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动
  OLED_WR_Byte(0x27,OLED_CMD);        //水平向左滚动
  OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
  OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0
  OLED_WR_Byte(0x00,OLED_CMD);        //滚动时间间隔
  OLED_WR_Byte(0x01,OLED_CMD);        //终止页 1
  OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节
  OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节
  OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动
}



使用特权

评论回复
6
小小电子爱好者|  楼主 | 2019-6-28 19:15 | 只看该作者
本帖最后由 小小电子爱好者 于 2019-6-28 19:16 编辑

波形实现:

正弦波


锯齿波


三角波

方波


自定义波形1:





使用特权

评论回复
7
小小电子爱好者|  楼主 | 2019-6-28 19:42 | 只看该作者
本帖最后由 小小电子爱好者 于 2019-6-28 19:43 编辑

随手录了个无声演示视频 :
嘿嘿   完结了   跟帖吐槽吧!

使用特权

评论回复
8
fnndp| | 2019-6-29 22:06 | 只看该作者

使用特权

评论回复
9
小小电子爱好者|  楼主 | 2019-7-2 13:03 | 只看该作者

使用特权

评论回复
10
爱电脑爱生活| | 2019-7-16 16:12 | 只看该作者

使用特权

评论回复
11
springvirus| | 2019-7-16 16:44 | 只看该作者
**就是胜利!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

52

主题

609

帖子

9

粉丝