- crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
- crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
- crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
- /* set default parameter */
- gpio_default_para_init(&gpio_init_struct);
- /* configure button pin as input with pull-up/pull-down */
- gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_struct.gpio_pins = GPIO_PINS_0 |GPIO_PINS_1|GPIO_PINS_4|GPIO_PINS_8|GPIO_PINS_9|GPIO_PINS_10;
- gpio_init_struct.gpio_pull = GPIO_PULL_UP;
- gpio_init(GPIOA, &gpio_init_struct);
- gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_struct.gpio_pins = GPIO_PINS_0 |GPIO_PINS_4|GPIO_PINS_3|GPIO_PINS_5|GPIO_PINS_10;
- gpio_init_struct.gpio_pull = GPIO_PULL_UP;
- gpio_init(GPIOB, &gpio_init_struct);
- gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_struct.gpio_pins = GPIO_PINS_1 |GPIO_PINS_7;
- gpio_init_struct.gpio_pull = GPIO_PULL_UP;
- gpio_init(GPIOC, &gpio_init_struct);
后面就是对IO口进行赋值操作了,习惯了使用了stm32的HAL了,所以这里还是使用的宏定义对LCD的控制引脚(例如复位 读写 片选)进行操作的,
这样好操作,而且后期移植到其他的程序上也是非常的方便的。
- #define LCD_RD_GPIO_Port GPIOA
- #define LCD_RD_Pin GPIO_PINS_0
- #define LCD_WR_GPIO_Port GPIOA
- #define LCD_WR_Pin GPIO_PINS_1
- #define LCD_RS_GPIO_Port GPIOA
- #define LCD_RS_Pin GPIO_PINS_4
- #define LCD_CS_GPIO_Port GPIOB
- #define LCD_CS_Pin GPIO_PINS_0
- #define LCD_RST_GPIO_Port GPIOC
- #define LCD_RST_Pin GPIO_PINS_1
- #define LCD_D0_GPIO_Port GPIOA
- #define LCD_D0_Pin GPIO_PINS_9
- #define LCD_D1_GPIO_Port GPIOC
- #define LCD_D1_Pin GPIO_PINS_7
- #define LCD_D2_GPIO_Port GPIOA
- #define LCD_D2_Pin GPIO_PINS_10
- #define LCD_D3_GPIO_Port GPIOB
- #define LCD_D3_Pin GPIO_PINS_3
- #define LCD_D4_GPIO_Port GPIOB
- #define LCD_D4_Pin GPIO_PINS_5
- #define LCD_D5_GPIO_Port GPIOB
- #define LCD_D5_Pin GPIO_PINS_4
- #define LCD_D6_GPIO_Port GPIOB
- #define LCD_D6_Pin GPIO_PINS_10
- #define LCD_D7_GPIO_Port GPIOA
- #define LCD_D7_Pin GPIO_PINS_8
- #define LCD_CS_LOW() LCD_CS_GPIO_Port->clr =LCD_CS_Pin //
- #define LCD_CS_HIGH() LCD_CS_GPIO_Port->scr = LCD_CS_Pin //
- #define LCD_RST_LOW() LCD_RST_GPIO_Port->clr = LCD_RST_Pin //
- #define LCD_RST_HIGH() LCD_RST_GPIO_Port->scr = LCD_RST_Pin //
这里需要对屏幕进行操作了,需要用到的按照位进行操作了。
使用右键查询到使用寄存器赋值的方法。
对IO进行赋值需要对scr进行操作,如果是需要置0则对clr进行操作。
具体的代码如下所示,保障了屏幕的刷新速度了。最快的实现置位和置0的操作。
- LCD_WR_GPIO_Port->clr = (uint32_t)LCD_WR_Pin ;
- if(dat&0x01) LCD_D0_GPIO_Port->scr = (uint32_t)LCD_D0_Pin;
- else LCD_D0_GPIO_Port->clr = (uint32_t)LCD_D0_Pin ;
- if(dat&0x02) LCD_D1_GPIO_Port->scr = (uint32_t)LCD_D1_Pin;
- else LCD_D1_GPIO_Port->clr = (uint32_t)LCD_D1_Pin ;
- if(dat&0x04) LCD_D2_GPIO_Port->scr = (uint32_t)LCD_D2_Pin;
- else LCD_D2_GPIO_Port->clr = (uint32_t)LCD_D2_Pin;
- if(dat&0x08) LCD_D3_GPIO_Port->scr = (uint32_t)LCD_D3_Pin;
- else LCD_D3_GPIO_Port->clr = (uint32_t)LCD_D3_Pin;
- if(dat&0x10) LCD_D4_GPIO_Port->scr = (uint32_t)LCD_D4_Pin;
- else LCD_D4_GPIO_Port->clr = (uint32_t)LCD_D4_Pin ;
- if(dat&0x20) LCD_D5_GPIO_Port->scr = (uint32_t)LCD_D5_Pin;
- else LCD_D5_GPIO_Port->clr = (uint32_t)LCD_D5_Pin ;
- if(dat&0x40) LCD_D6_GPIO_Port->scr = (uint32_t)LCD_D6_Pin;
- else LCD_D6_GPIO_Port->clr = (uint32_t)LCD_D6_Pin ;
- if(dat&0x80) LCD_D7_GPIO_Port->scr = (uint32_t)LCD_D7_Pin;
- else LCD_D7_GPIO_Port->clr = (uint32_t)LCD_D7_Pin ;
- LCD_WR_GPIO_Port->scr = (uint32_t)LCD_WR_Pin;
具体怎么配置寄存器,这里就不再赘述了。就是跟配置正常的LCD一样了,主要的实现对数据寄存器的写入。
再根据需要配置的形式,自己实现数据和命令的控制,这个具体的代码,在购买屏幕的时候,他就直接给出了。
自己根据提供的例程,选择一下,自己要实现的方式就行了。屏幕的配置很简单,都是固定的代码。
主要的实现函数就是现实一个点的绘制,点动成线,线动成面。
这样就会绘制出来想要的效果了。这个代码使用的就是淘宝店家的提供的例程了。
- void lcd_point(uint16_t x, uint16_t y,uint16_t color){
- if ((x >= LCD_W) || (y >= LCD_H)) return ;
- LCD_CS_LOW(); //HAL_GPIO_WritePin(LCD_CS,LOW);
- lcd_address_set(x, y, x, y);
- lcd_write_data(color >> 8);
- lcd_write_data(color);
- LCD_CS_HIGH(); //HAL_GPIO_WritePin(LCD_CS,HIGH);
- }
有了这个点,后面就是现实的文字输出,根据自己的字库实现字符和汉字的输出了
字符很简单,就是根据字模输出屏幕了就行了。
这里移植了一个oled的显示程序,里面很简单,可以根据自己的需要选择需要的字符。具体的字库,可以看后面的代码了。
这个代码做的就是非常好,可选择性很高。
- u8 i,m,temp,size2,chr1;
- u8 x0=x,y0=y;
- if(size1==8)size2=6;
- else size2=(size1/8+((size1%8)?1:0))*(size1/2); //得到字体一个字符对应点阵集所占的字节数
- chr1=chr-' '; //计算偏移后的值
- for(i=0; i<size2; i++)
- {
- if(size1==8)
- {
- temp=asc2_0806[chr1][i]; //调用0806字体
- }
- else if(size1==12)
- {
- temp=asc2_1206[chr1][i]; //调用1206字体
- }
- else if(size1==16)
- {
- temp=asc2_1608[chr1][i]; //调用1608字体
- }
- else if(size1==24)
- {
- temp=asc2_2412[chr1][i]; //调用2412字体
- }
- else return;
- for(m=0; m<8; m++)
- {
- if(temp&0x01)lcd_point(x,y,f_color);
- else lcd_point(x,y,b_color);
- temp>>=1;
- y++;
- }
- x++;
- if((size1!=8)&&((x-x0)==size1/2))
- {
- x=x0;
- y0=y0+8;
- }
- y=y0;
- }
至于字符串就是逐个对字符进行输出实现。
这里说明一下如何实现汉字的输出。参考正点原子的方法。
实现字符的取模用的是PC2LCD2000,因为软件的原因,获取的数据,需要修改的内容很多,太麻烦,所以我将正点原子的变量修改了一下,
这样就可以直接实现把内容复制到字模文件中了。
- struct typFNT_GB162
- {char Msk[32];
- unsigned char Index[2];
- unsigned char no;
- };
这样对比一下就行了,直接复制粘贴的效果还是比较好的。省去了,调换字符位置,删除字符内容等一系列的复杂操作。
接下来实现的就是汉字和字符的混合输出了。
根据字符的大小判断是字符还是汉字,如果是字符调用上述的方法就可以实现,如果是汉字,就根据汉字字模,赋值前景色和背景色就行了。
- while(*chr) {
- if((*chr) < 128)
- {
- OLED_ShowChar(x,y,*chr,size1, f_color,b_color);
- if(size1==8)x+=6;
- else x+=size1/2;
- chr++;
- } else {
- for (k=0; k<hz16_num; k++)
- {
- if ((hz16[k].Index[0]==*(chr))&&(hz16[k].Index[1]==*(chr+1)))
- {
- for(i=0; i<16; i++)
- {
- for(j=0; j<8; j++)
- {
- if(hz16[k].Msk[i*2]&(0x80>>j)) lcd_point(x+j,y+i,f_color);//lcd_point(x,y,f_color);
- else {
- lcd_point(x+j,y+i,b_color);
- }
- }
- for(j=0; j<8; j++)
- {
- if(hz16[k].Msk[i*2+1]&(0x80>>j)) lcd_point(x+j+8,y+i,f_color);//lcd_point(x+j,y+i,f_color);
- else
- {
- lcd_point(x+j+8,y+i,b_color);
- }
- }
- }
- }
- }
- chr+=2;
- x+=16;
- }
- }
主要的一些代码已经实现了
- OLED_ShowStringCN(0,20,"bbs.21ic.com",16,GREEN,BLACK);
- OLED_ShowStringCN(0,40,"雅特力AT32 MCU",16,RED,BLACK);
- lcd_show_image(0,60,160,27,gImage_ic21);
- lcd_show_image(0,90,120,80,gImage_at);
让我们来欣赏一下,演示的效果。