【兆易GD32F310测评】+OLED屏显示驱动
[复制链接]
对于GD32F310这种引脚不多、能耗低的MCU,要为它配上一个有效的显示器件,I2C接口的OLED屏自然是首先之一。
为便于灵活性的使用,这里是采用GPIO口模拟的方式来实现其显示驱动。
为保证引脚的输出有效,实现对选取的引脚PB6和PB7进行了输出能力的测试,其测试程序如下:
int main(void)
{
systick_config();
rcu_periph_clock_enable(RCU_GPIOB);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7);
gpio_bit_reset(GPIOB, GPIO_PIN_6);
gpio_bit_reset(GPIOB, GPIO_PIN_7);
while(1){
gpio_bit_write(GPIOB, GPIO_PIN_6, SET);
gpio_bit_write(GPIOB, GPIO_PIN_7, SET);
delay_1ms(1000);
gpio_bit_write(GPIOB, GPIO_PIN_6, RESET);
gpio_bit_write(GPIOB, GPIO_PIN_7, RESET);
delay_1ms(1000);
}
}
经下载测试,其效果如图1所示,说明控制有效。
图1 引脚测试
随后,便是模拟I2C来驱动OLED屏。
起初在编译后,一直提示存储空间不足,为此进行了诸段的测试。
首先是只保留了较小规模的汉字字模库,经测试显示效果如图2所示,说明程序不存在问题,只是内存小的问题。
图2 汉字显示
显示汉字显示的主程序为:
int main(void)
{
systick_config();
rcu_periph_clock_enable(RCU_GPIOB);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7);
gpio_bit_reset(GPIOB, GPIO_PIN_6);
gpio_bit_reset(GPIOB, GPIO_PIN_7);
OLED_Init();
OLED_Clear();
OLED_ShowCHinese(0,0,0);
OLED_ShowCHinese(20,0,1);
while(1) ;
}
相应的汉字显示函数为:
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
{
uint8_t t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
}
}
接着去除了汉字库,只添加8*16点阵的字库来显示,其显示效果如图3所示,说明用该字库是可以满足显示的基本需要的。为此,就只使用该字库来支持OLED屏的显示了。
图2 字符串显示
实现字符串显示的主程序为:
int main(void)
{
systick_config();
rcu_periph_clock_enable(RCU_GPIOB);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6|GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7);
gpio_bit_reset(GPIOB, GPIO_PIN_6);
gpio_bit_reset(GPIOB, GPIO_PIN_7);
OLED_Init();
OLED_Clear();
OLED_ShowChar(0,0,'V',16);
OLED_ShowString(20,0,"GD32F310K8T6",16);
OLED_ShowString(20,2,"OLED test",16);
while(1) ;
}
支持该显示效果的字符及字符串显示函数为:
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(x>Max_Column-1)
{
x=0;
y=y+2;
}
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++) OLED_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++;
}
}
这样再有显示输出的工作,就不用完全只靠串口输出功能了!
|