【国民技术N32G457评测】OLED屏显示驱动 与RTC电子时钟
本帖最后由 jinglixixi 于 2022-2-10 09:57 编辑<p style="text-align:justify">OLED屏有多种类型,按接口方式可分I2C接口和SPI接口方式,按色彩可分为单色、双色及彩色方式。此外,按几何尺寸分又有0.91寸、0.96寸等规格。</p>
<p>这里介绍的是驱动I2C接口的0.96寸双色显示屏,由于在实现方式上又分为硬件和软件2种方式,这里仅以软件的方式来实现。</p>
<p>该显示屏与开发板的连接关系为:</p>
<p>CLK---PE2</p>
<p>DIN ---PE4</p>
<p>为实现高低电平的输出所定义语句为:</p>
<p>#define OLED_SCLK_Clr() GPIOE->PBC = GPIO_PIN_2</p>
<p>#define OLED_SCLK_Set() GPIOE->PBSC = GPIO_PIN_2</p>
<p>#define OLED_SDIN_Clr() GPIOE->PBC = GPIO_PIN_4</p>
<p>#define OLED_SDIN_Set() GPIOE->PBSC = GPIO_PIN_4</p>
<p>设置相关引脚为输出功能的函数为:</p>
<pre>
<code class="language-cpp">void OLEDInit(void)
{
GPIO_InitType GPIO_InitStructure;
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOE, ENABLE);
GPIO_InitStructure.Pin = GPIO_PIN_2|GPIO_PIN_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOE, &GPIO_InitStructure);
}</code></pre>
<p>实现I2C启停的函数为:</p>
<pre>
<code class="language-cpp">void IIC_Start()
{
OLED_SCLK_Set();
Delayus(2);
OLED_SDIN_Set();
Delayus(2);
OLED_SDIN_Clr();
Delayus(2);
OLED_SCLK_Clr();
Delayus(2);
}
void IIC_Stop()
{
OLED_SCLK_Set();
Delayus(2);
OLED_SDIN_Clr();
Delayus(2);
OLED_SDIN_Set();
Delayus(2);
}</code></pre>
<p>该显示屏的初始化函数为:</p>
<pre>
<code class="language-cpp">void OLED_Init(void)
{
OLED_SCLK_Set();
OLED_SDIN_Set();
Delayms(800);
OLED_WR_Byte(0xAE,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x81,OLED_CMD);
OLED_WR_Byte(0xff,OLED_CMD);
OLED_WR_Byte(0xA1,OLED_CMD);
OLED_WR_Byte(0xC8,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xA8,OLED_CMD);
OLED_WR_Byte(0x3f,OLED_CMD);
OLED_WR_Byte(0xD3,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xd5,OLED_CMD);
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD);
OLED_WR_Byte(0xF1,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD);
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x20,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x8D,OLED_CMD);
OLED_WR_Byte(0x14,OLED_CMD);
OLED_WR_Byte(0xA4,OLED_CMD)
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
}</code></pre>
<p>实现字符串显示的函数为:</p>
<pre>
<code class="language-cpp">void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
unsigned char j=0;
while (chr!='\0')
{
OLED_ShowChar(x,y,chr,Char_Size);
x+=8;
if(x>120)
{
x=0;
y+=2;
}
j++;
}
}</code></pre>
<p>实现图示效果的主程序为:</p>
<pre>
<code class="language-cpp">int main(void)
{
LedInit(PORT_GROUP2, LED3_PIN);
OLEDInit();
OLED_Init();
OLED_Clear();
OLED_ShowString(20,0,"N32G457 ",16);
OLED_ShowString(20,2,"OLED TEST",16);
while (1)
{
LedBlink(PORT_GROUP2, LED3_PIN);
Delay(0x28FFFF);
}
}</code></pre>
<p>经编译下载,其显示效果如图1所示。</p>
<p>图1 OLED屏显示效果</p>
<p>以该显示功能为基础,结合RTC计时器即可实现电子时钟功能。</p>
<p>实现日期显示的函数为:</p>
<pre>
<code class="language-cpp">void RTC_DateShowP(void)
{
RTC_DateType RTC_DateStructure;
RTC_GetDate(RTC_FORMAT_BIN, &RTC_DateStructure);
OLED_ShowNum(36,4,RTC_DateStructure.Year,2,16);
OLED_ShowNum(60,4,RTC_DateStructure.Month,2,16);
OLED_ShowNum(84,4,RTC_DateStructure.Date,2,16);
}</code></pre>
<p>实现设计显示的函数为:</p>
<pre>
<code class="language-cpp">void RTC_TimeShowP(void)
{
RTC_TimeType RTC_TimeStructure;
RTC_GetTime(RTC_FORMAT_BIN, &RTC_TimeStructure);
OLED_ShowNum(20,6,RTC_TimeStructure.Hours,2,16);
OLED_ShowNum(44,6,RTC_TimeStructure.Minutes,2,16);
OLED_ShowNum(68,6,RTC_TimeStructure.Seconds,2,16);
(void)RTC->DATE;
}</code></pre>
<p>实现RTC电子时钟的主程序为:</p>
<pre>
<code class="language-cpp">int main(void)
{
LEDInit(LED1_PORT,LED1_PIN);
LEDOff(LED1_PORT,LED1_PIN);
OLEDInit();
OLED_Init();
OLED_Clear();
OLED_ShowString(20,0,"N32G457 ",16);
OLED_ShowString(20,2,"OLED & RTC",16);
OLED_ShowString(20,4,"20 - -",16);
OLED_ShowString(20,6," : :",16);
RTC_DateAndTimeDefaultVale();
RTC_CLKSourceConfig(RTC_CLK_SRC_TYPE_LSE, true, true);
RTC_PrescalerConfig();
RTC_DateRegulate();
RTC_TimeRegulate();
RTC_ConfigCalibOutput(RTC_CALIB_OUTPUT_1HZ);
RTC_ConfigOutputType(RTC_OUTPUT_PUSHPULL);
RTC_EnableCalibOutput(ENABLE);
EXTI_PB8_TimeStamp_Configuration();
EXTI20_TimeStampIRQn_Configuration(EXTI_Trigger_Falling);
RTC_ClrFlag(RTC_FLAG_TISF);
RTC_ClrFlag(RTC_FLAG_TISOVF);
RTC_EnableTimeStamp(RTC_TIMESTAMP_EDGE_FALLING, ENABLE);
while (1)
{
if (RTC_GetFlagStatus(RTC_FLAG_TISF) != RESET)
{
RTC_DateShowP();
RTC_TimeShowP();
RTC_ClrFlag(RTC_FLAG_TISF);
RTC_ClrFlag(RTC_FLAG_TISOVF);
}
LEDBlink(LED1_PORT,LED1_PIN);
SysTick_Delay_Ms(1000);
}
}</code></pre>
<p>经编译下载,在连接PC13与PB8的情况下,RTC电子时钟的显示效果如图2和图3所示。</p>
<p>图2 电子时钟计时效果1</p>
<p>图3 电子时钟计时效果2</p>
<p>demo</p><br/>
页:
[1]