【沁恒 CH32V208 开发板免费试用】+OLED屏显示与RTC电子时钟 - RISC-V MCU技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

【沁恒 CH32V208 开发板免费试用】+OLED屏显示与RTC电子时钟

在CH32V208 开发板上配有Arduino接口,见图1所示,用它连接OLED屏与RTC计时器配合可轻松地实现电子时钟的功能。

image.png

图1 Arduino接口

  1. OLED屏显示驱动

这里所用的OLED屏是一款0.96寸的双色屏,该显示屏采用I2C接口工作,它与开发板的连接关系为:

SCL---PB13

SDA---PB14

所用引脚输出高低电平的语句定义为:

#define SCL_high GPIO_WriteBit(GPIOB,GPIO_Pin_13, Bit_SET)

#define SCL_low GPIO_WriteBit(GPIOB, PIO_Pin_13,it_RESET)

#define SDA_high GPIO_WriteBit(GPIOB,GPIO_Pin_14, Bit_SET)

#define SDA_low GPIO_WriteBit(GPIOB,GPIO_Pin_14, Bit_RESET)

在使用GPIO口模拟I2C的情况下,其发送字节数据的函数为:

void Write_IIC_Byte(unsigned char IIC_Byte)
{
    unsigned char i;
    unsigned char m,da;
    da=IIC_Byte;
    SCL_low;
    for(i=0;i<8;i++)
    {
        m=da;
        m=m&0x80;
        if(m==0x80)
        {
            SDA_high;
        }
        else  SDA_low;
        da=da<<1;
        SCL_high;
        SCL_low;
     }
}

实现OLED屏清除的函数为:

void OLED_Clear(void)
{
    uint8_t i,n;
    for(i=0;i<8;i++)
    {
        OLED_WR_Byte(0xb0+i,OLED_CMD);
        OLED_WR_Byte(0x00,OLED_CMD);
        OLED_WR_Byte(0x10,OLED_CMD);
        for(n=0;n<128;n++)
               OLED_WR_Byte(0x00,OLED_DATA);
    }
}

实现字符显示的函数为:

void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t
chr,uint8_t Char_Size)
{
     unsigned char c=0,i=0;
     c=chr-' ';    
     if(Char_Size ==16)
     {           
          OLED_Set_Pos(x,y);           
          for(i=0;i<8;i++)           
               OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);           
               OLED_Set_Pos(x,y+1);           
                     for(i=0;i<8;i++)           
                           LED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); 
      }
}

实现数值显示的函数为:

void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
{
    uint8_t t,temp;
    uint8_t enshow=0;
    for(t=0;t<len;t++)
    {       
         temp=(num/oled_pow(10,len-t-1))%10;       
         if(enshow==0&&t<(len-1))
         {
            if(temp==0)
            {               
                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                continue;
            }
            else enshow=1;
        }       
        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
    }
}

实现字符串显示的函数为:

void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
    unsigned char j=0;
    while (chr[j]!='\0')
    {       
            OLED_ShowChar(x,y,chr[j],Char_Size);
            x+=8;
            if(x>120){x=0;y+=2;}
            j++;
    }
}

实现图2所示效果的主程序为:

int main(void)
{   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    GPIO_INIT();
    OLED_Init();
    OLED_Clear();
    OLED_ShowString(20,0,"CH32V208",16);
    OLED_ShowString(20,4,"jinglixixi",16);
    while(1)
    {
             Delay_Ms(250);
             GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
             Delay_Ms(250);
             GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
    }
}

image.png

图2 显示效果

  1. RTC计时

在官方的例程中提供了RTC的示例,提供RTC的初始化函数可对计时器的初始值进行设置,该函数的内容如下:

u8 RTC_Init(void)
{
    u8 temp = 0;   
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    PWR_BackupAccessCmd(ENABLE);   
    if(BKP_ReadBackupRegister(BKP_DR1) != 0xA1A1)
    {
        BKP_DeInit();
        RCC_LSEConfig(RCC_LSE_ON);       
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && temp <250)
        {
            temp++;
            Delay_Ms(20);
        }
        if(temp >= 250)
            return 1;       
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
        RCC_RTCCLKCmd(ENABLE);
        RTC_WaitForLastTask();
        RTC_WaitForSynchro();
        RTC_ITConfig(RTC_IT_SEC,ENABLE);
        RTC_WaitForLastTask();
        RTC_EnterConfigMode();
        RTC_SetPrescaler(32767);
        RTC_WaitForLastTask();
        RTC_Set(2023, 4, 18, 8, 30,00);  // 更新初始计时值
        RTC_ExitConfigMode();       
        BKP_WriteBackupRegister(BKP_DR1, 0XA1A1);
    }
    else
    {       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR |     RCC_APB1Periph_BKP, ENABLE);
        PWR_WakeUpPinCmd(DISABLE);
        RTC_WaitForSynchro();
        RTC_ITConfig(RTC_IT_SEC,ENABLE);
        RTC_WaitForLastTask();
    }
    RTC_NVIC_Config();
    RTC_Get();
    return 0;
}
  1. 电子时钟显示

实现电子时钟功能的主程序为:

int main(void)
{
    u8 i = 0;   
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    GPIO_INIT();
    OLED_Init();
    OLED_Clear();   
    OLED_ShowString(28,0,"CH32V208",16);
    OLED_ShowString(20,3,"    - -",16);
    OLED_ShowString(36,5,"  : :",16);
    RTC_Init();
    while(1)
    {
        Delay_Ms(1000);       
        OLED_ShowNum(20,3,calendar.w_year,4,16);       
        OLED_ShowNum(60,3,calendar.w_month,2,16);       
        OLED_ShowNum(84,3,calendar.w_date,2,16);       
        OLED_ShowNum(36,5,calendar.hour,2,16);       
        OLED_ShowNum(60,5,calendar.min,2,16);       
        OLED_ShowNum(84,5,calendar.sec,2,16);
        GPIO_WriteBit(GPIOA,GPIO_Pin_0, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
    }
}

经编程的编译下载,其运行效果如图3所示。

image.png
图3 电子时钟显示效果

RTC

更多回帖

×
发帖