在线时间372 小时
UID3135871
注册时间2016-10-9
NXP金币20
TA的每日心情 | 怒 2024-2-5 12:06 |
---|
签到天数: 627 天 [LV.9]以坛为家II
版主
- 积分
- 4429
- 最后登录
- 2024-2-5
|
u8g2是目前用在ardunio上面比较广泛的图形界面,它有着占用空间小,易于配置的有点,很适合单色屏的场合。
今天我们来移植一下U8G2,并通过IIC OLED把它显示出来。
我们下来配对GPIO模拟驱动的IIC接口的OLED:
然后直接上代码,这都是比较成熟的芯片了:
我们先把OLED点亮:
ss1306_oled.c
- /*
- * ss1306_oled.c
- *
- * Created on: 2020年12月24日
- * Author: Administrator
- */
- #include "ss1306_oled.h"
- #include "oledfont.h"
- #include "delay.h"
- uint8_t OLED_GRAM[144][8];
- void OLED_I2C_GPIO_Init(void)
- {
- /* Enables the clock for the I/O controller.: Enable Clock. */
- CLOCK_EnableClock(kCLOCK_Iocon);
- /* Enables the clock for the GPIO0 module */
- CLOCK_EnableClock(kCLOCK_Gpio0);
- /* Enables the clock for the GPIO1 module */
- CLOCK_EnableClock(kCLOCK_Gpio1);
- gpio_pin_config_t oled_sda_config = {
- .pinDirection = kGPIO_DigitalOutput,
- .outputLogic = 0U
- };
- /* Initialize GPIO functionality on pin PIO0_23 (pin 20) */
- GPIO_PinInit(BOARD_INITPINS_oled_sda_GPIO, BOARD_INITPINS_oled_sda_PORT, BOARD_INITPINS_oled_sda_PIN, &oled_sda_config);
- gpio_pin_config_t oled_scl_config = {
- .pinDirection = kGPIO_DigitalOutput,
- .outputLogic = 0U
- };
- /* Initialize GPIO functionality on pin PIO1_7 (pin 9) */
- GPIO_PinInit(BOARD_INITPINS_oled_scl_GPIO, BOARD_INITPINS_oled_scl_PORT, BOARD_INITPINS_oled_scl_PIN, &oled_scl_config);
- IOCON->PIO[0][23] = ((IOCON->PIO[0][23] &
- /* Mask bits to zero which are setting */
- (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK | IOCON_PIO_OD_MASK)))
- /* Selects pin function.
- * : PORT023 (pin 20) is configured as PIO0_23. */
- | IOCON_PIO_FUNC(PIO0_23_FUNC_ALT0)
- /* Select Digital mode.
- * : Enable Digital mode.
- * Digital input is enabled. */
- | IOCON_PIO_DIGIMODE(PIO0_23_DIGIMODE_DIGITAL)
- /* Controls open-drain mode.
- * : Open-drain.
- * Simulated open-drain output (high drive disabled). */
- | IOCON_PIO_OD(PIO0_23_OD_OPEN_DRAIN));
- IOCON->PIO[1][7] = ((IOCON->PIO[1][7] &
- /* Mask bits to zero which are setting */
- (~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK | IOCON_PIO_OD_MASK)))
- /* Selects pin function.
- * : PORT17 (pin 9) is configured as PIO1_7. */
- | IOCON_PIO_FUNC(PIO1_7_FUNC_ALT0)
- /* Select Digital mode.
- * : Enable Digital mode.
- * Digital input is enabled. */
- | IOCON_PIO_DIGIMODE(PIO1_7_DIGIMODE_DIGITAL)
- /* Controls open-drain mode.
- * : Open-drain.
- * Simulated open-drain output (high drive disabled). */
- | IOCON_PIO_OD(PIO1_7_OD_OPEN_DRAIN));
- }
- //延时
- void IIC_delay(void)
- {
- // uint8_t t=3;
- // while(t--);
- delay_us(4);
- }
- //起始信号
- void MyI2C_Start(void)
- {
- OLED_SDA_Set();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SDA_Clr();
- IIC_delay();
- OLED_SCL_Clr();
- IIC_delay();
- }
- //结束信号
- void MyI2C_Stop(void)
- {
- OLED_SDA_Clr();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SDA_Set();
- }
- //等待信号响应
- uint32_t MyI2C_WaitAck(void) //测数据信号的电平
- {
- OLED_SDA_Set();
- IIC_delay();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SCL_Clr();
- IIC_delay();
- }
- //写入一个字节
- void MySend_Byte(uint8_t dat)
- {
- uint8_t i;
- for(i=0;i<8;i++)
- {
- if(dat&0x80)//将dat的8位从最高位依次写入
- {
- OLED_SDA_Set();
- }
- else
- {
- OLED_SDA_Clr();
- }
- IIC_delay();
- OLED_SCL_Set();
- IIC_delay();
- OLED_SCL_Clr();//将时钟信号设置为低电平
- dat<<=1;
- }
- }
- //反显函数
- void OLED_ColorTurn(uint8_t i)
- {
- if(i==0)
- {
- OLED_WR_Byte(0xA6,OLED_CMD);//正常显示
- }
- if(i==1)
- {
- OLED_WR_Byte(0xA7,OLED_CMD);//反色显示
- }
- }
- //屏幕旋转180度
- void OLED_DisplayTurn(uint8_t i)
- {
- if(i==0)
- {
- OLED_WR_Byte(0xC8,OLED_CMD);//正常显示
- OLED_WR_Byte(0xA1,OLED_CMD);
- }
- if(i==1)
- {
- OLED_WR_Byte(0xC0,OLED_CMD);//反转显示
- OLED_WR_Byte(0xA0,OLED_CMD);
- }
- }
- //发送一个字节
- //mode:数据/命令标志 0,表示命令;1,表示数据;
- void OLED_WR_Byte(uint8_t dat,uint8_t mode)
- {
- MyI2C_Start();
- MySend_Byte(0x78);
- MyI2C_WaitAck();
- if(mode){MySend_Byte(0x40);}
- else{MySend_Byte(0x00);}
- MyI2C_WaitAck();
- MySend_Byte(dat);
- MyI2C_WaitAck();
- MyI2C_Stop();
- }
- //开启OLED显示
- void OLED_DisPlay_On(void)
- {
- OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
- OLED_WR_Byte(0x14,OLED_CMD);//开启电荷泵
- OLED_WR_Byte(0xAF,OLED_CMD);//点亮屏幕
- }
- //关闭OLED显示
- void OLED_DisPlay_Off(void)
- {
- OLED_WR_Byte(0x8D,OLED_CMD);//电荷泵使能
- OLED_WR_Byte(0x10,OLED_CMD);//关闭电荷泵
- OLED_WR_Byte(0xAE,OLED_CMD);//关闭屏幕
- }
- //更新显存到OLED
- void OLED_Refresh(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); //设置高列起始地址
- MyI2C_Start();
- MySend_Byte(0x78);
- MyI2C_WaitAck();
- MySend_Byte(0x40);
- MyI2C_WaitAck();
- for(n=0;n<128;n++)
- {
- MySend_Byte(OLED_GRAM[n][i]);
- MyI2C_WaitAck();
- }
- MyI2C_Stop();
- }
- }
- //清屏函数
- void OLED_Clear(void)
- {
- uint8_t i,n;
- for(i=0;i<8;i++)
- {
- for(n=0;n<128;n++)
- {
- OLED_GRAM[n][i]=0;//清除所有数据
- }
- }
- OLED_Refresh();//更新显示
- }
- //画点
- //x:0~127
- //y:0~63
- //t:1 填充 0,清空
- void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t)
- {
- uint8_t i,m,n;
- i=y/8;
- m=y%8;
- n=1<<m;
- if(t){OLED_GRAM[x][i]|=n;}
- else
- {
- OLED_GRAM[x][i]=~OLED_GRAM[x][i];
- OLED_GRAM[x][i]|=n;
- OLED_GRAM[x][i]=~OLED_GRAM[x][i];
- }
- }
- //画线
- //x1,y1:起点坐标
- //x2,y2:结束坐标
- void OLED_DrawLine(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t mode)
- {
- uint16_t t;
- int xerr=0,yerr=0,delta_x,delta_y,distance;
- int incx,incy,uRow,uCol;
- delta_x=x2-x1; //计算坐标增量
- delta_y=y2-y1;
- uRow=x1;//画线起点坐标
- uCol=y1;
- if(delta_x>0)incx=1; //设置单步方向
- else if (delta_x==0)incx=0;//垂直线
- else {incx=-1;delta_x=-delta_x;}
- if(delta_y>0)incy=1;
- else if (delta_y==0)incy=0;//水平线
- else {incy=-1;delta_y=-delta_x;}
- if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
- else distance=delta_y;
- for(t=0;t<distance+1;t++)
- {
- OLED_DrawPoint(uRow,uCol,mode);//画点
- xerr+=delta_x;
- yerr+=delta_y;
- if(xerr>distance)
- {
- xerr-=distance;
- uRow+=incx;
- }
- if(yerr>distance)
- {
- yerr-=distance;
- uCol+=incy;
- }
- }
- }
- //x,y:圆心坐标
- //r:圆的半径
- void OLED_DrawCircle(uint8_t x,uint8_t y,uint8_t r)
- {
- int Na, Nb,num;
- Na = 0;
- Nb = r;
- while(2 * Nb * Nb >= r * r)
- {
- OLED_DrawPoint(x + Na, y - Nb,1);
- OLED_DrawPoint(x - Na, y - Nb,1);
- OLED_DrawPoint(x - Na, y + Nb,1);
- OLED_DrawPoint(x + Na, y + Nb,1);
- OLED_DrawPoint(x + Nb, y + Na,1);
- OLED_DrawPoint(x + Nb, y - Na,1);
- OLED_DrawPoint(x - Nb, y - Na,1);
- OLED_DrawPoint(x - Nb, y + Na,1);
- Na++;
- num = (Na * Na + Nb * Nb) - r*r;//计算画的点离圆心的距离
- if(num > 0)
- {
- Nb--;
- Na--;
- }
- }
- }
- //在指定位置显示一个字符,包括部分字符
- //x:0~127
- //y:0~63
- //size1:选择字体 6x8/6x12/8x16/12x24
- //mode:0,反色显示;1,正常显示
- void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t size1,uint8_t mode)
- {
- uint8_t i,m,temp,size2,chr1;
- uint8_t 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)OLED_DrawPoint(x,y,mode);
- else OLED_DrawPoint(x,y,!mode);
- temp>>=1;
- y++;
- }
- x++;
- if((size1!=8)&&((x-x0)==size1/2))
- {x=x0;y0=y0+8;}
- y=y0;
- }
- }
- //显示字符串
- //x,y:起点坐标
- //size1:字体大小
- //*chr:字符串起始地址
- //mode:0,反色显示;1,正常显示
- void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t size1,uint8_t mode)
- {
- while((*chr>=' ')&&(*chr<='~'))//判断是不是非法字符!
- {
- OLED_ShowChar(x,y,*chr,size1,mode);
- if(size1==8)x+=6;
- else x+=size1/2;
- chr++;
- }
- }
- //m^n
- uint32_t OLED_Pow(uint8_t m,uint8_t n)
- {
- uint32_t result=1;
- while(n--)
- {
- result*=m;
- }
- return result;
- }
- //显示数字
- //x,y :起点坐标
- //num :要显示的数字
- //len :数字的位数
- //size:字体大小
- //mode:0,反色显示;1,正常显示
- void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1,uint8_t mode)
- {
- uint8_t t,temp,m=0;
- if(size1==8)m=2;
- for(t=0;t<len;t++)
- {
- temp=(num/OLED_Pow(10,len-t-1))%10;
- if(temp==0)
- {
- OLED_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
- }
- else
- {
- OLED_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
- }
- }
- }
- //显示汉字
- //x,y:起点坐标
- //num:汉字对应的序号
- //mode:0,反色显示;1,正常显示
- void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1,uint8_t mode)
- {
- uint8_t m,temp;
- uint8_t x0=x,y0=y;
- uint16_t i,size3=(size1/8+((size1%8)?1:0))*size1; //得到字体一个字符对应点阵集所占的字节数
- for(i=0;i<size3;i++)
- {
- if(size1==16)
- {temp=Hzk1[num][i];}//调用16*16字体
- else if(size1==24)
- {temp=Hzk2[num][i];}//调用24*24字体
- else if(size1==32)
- {temp=Hzk3[num][i];}//调用32*32字体
- else if(size1==64)
- {temp=Hzk4[num][i];}//调用64*64字体
- else return;
- for(m=0;m<8;m++)
- {
- if(temp&0x01)OLED_DrawPoint(x,y,mode);
- else OLED_DrawPoint(x,y,!mode);
- temp>>=1;
- y++;
- }
- x++;
- if((x-x0)==size1)
- {x=x0;y0=y0+8;}
- y=y0;
- }
- }
- //num 显示汉字的个数
- //space 每一遍显示的间隔
- //mode:0,反色显示;1,正常显示
- void OLED_ScrollDisplay(uint8_t num,uint8_t space,uint8_t mode)
- {
- uint8_t i,n,t=0,m=0,r;
- while(1)
- {
- if(m==0)
- {
- OLED_ShowChinese(128,24,t,16,mode); //写入一个汉字保存在OLED_GRAM[][]数组中
- t++;
- }
- if(t==num)
- {
- for(r=0;r<16*space;r++) //显示间隔
- {
- for(i=1;i<144;i++)
- {
- for(n=0;n<8;n++)
- {
- OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
- }
- }
- OLED_Refresh();
- }
- t=0;
- }
- m++;
- if(m==16){m=0;}
- for(i=1;i<144;i++) //实现左移
- {
- for(n=0;n<8;n++)
- {
- OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
- }
- }
- OLED_Refresh();
- }
- }
- //x,y:起点坐标
- //sizex,sizey,图片长宽
- //BMP[]:要写入的图片数组
- //mode:0,反色显示;1,正常显示
- void OLED_ShowPicture(uint8_t x,uint8_t y,uint8_t sizex,uint8_t sizey,uint8_t BMP[],uint8_t mode)
- {
- uint16_t j=0;
- uint8_t i,n,temp,m;
- uint8_t x0=x,y0=y;
- sizey=sizey/8+((sizey%8)?1:0);
- for(n=0;n<sizey;n++)
- {
- for(i=0;i<sizex;i++)
- {
- temp=BMP[j];
- j++;
- for(m=0;m<8;m++)
- {
- if(temp&0x01)OLED_DrawPoint(x,y,mode);
- else OLED_DrawPoint(x,y,!mode);
- temp>>=1;
- y++;
- }
- x++;
- if((x-x0)==sizex)
- {
- x=x0;
- y0=y0+8;
- }
- y=y0;
- }
- }
- }
- //OLED的初始化
- void OLED_Init(void)
- {
- OLED_I2C_GPIO_Init();
- OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
- OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
- OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
- OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
- OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
- OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
- OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
- OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
- OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
- OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
- OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
- OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
- OLED_WR_Byte(0x00,OLED_CMD);//-not offset
- OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
- OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
- OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
- OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
- OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
- OLED_WR_Byte(0x12,OLED_CMD);
- OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
- OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
- OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
- OLED_WR_Byte(0x02,OLED_CMD);//
- OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
- OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
- 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_Clear();
- OLED_WR_Byte(0xAF,OLED_CMD);
- }
复制代码 ss1306_oled.h
- /*
- * ss1306_oled.h
- *
- * Created on: 2020年12月24日
- * Author: Administrator
- */
- #ifndef SS1306_OLED_H_
- #define SS1306_OLED_H_
- #include <stdio.h>
- #include "board.h"
- #include "peripherals.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "LPC55S69_cm33_core0.h"
- #include "fsl_gpio.h"
- #define oled_scl(x) GPIO_PinWrite(BOARD_INITPINS_oled_scl_GPIO, BOARD_INITPINS_oled_scl_PORT, BOARD_INITPINS_oled_scl_PIN, x)
- #define oled_sda(x) GPIO_PinWrite(BOARD_INITPINS_oled_sda_GPIO, BOARD_INITPINS_oled_sda_PORT, BOARD_INITPINS_oled_sda_PIN, x)
- #define OLED_SDA_Set() oled_sda(1)
- #define OLED_SDA_Clr() oled_sda(0)
- #define OLED_SCL_Set() oled_scl(1)
- #define OLED_SCL_Clr() oled_scl(0)
- #define OLED_ADDRESS 0x78 //通过调整0R电阻,屏可以选择0x78 0x7A两个地址 默认为0x78
- #define OLED_CMD 0 //写命令
- #define OLED_DATA 1 //写数据
- void MyI2C_Start(void);
- void MyI2C_Stop(void);
- uint32_t MyI2C_WaitAck(void);
- void MySend_Byte(uint8_t dat);
- void OLED_ClearPoint(uint8_t x,uint8_t y);
- void OLED_ColorTurn(uint8_t i);
- void OLED_DisplayTurn(uint8_t i);
- void OLED_WR_Byte(uint8_t dat,uint8_t mode);
- void OLED_DisPlay_On(void);
- void OLED_DisPlay_Off(void);
- void OLED_Refresh(void);
- void OLED_Clear(void);
- void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t);
- void OLED_DrawLine(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t mode);
- void OLED_DrawCircle(uint8_t x,uint8_t y,uint8_t r);
- void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t size1,uint8_t mode);
- void OLED_ShowChar6x8(uint8_t x,uint8_t y,uint8_t chr,uint8_t mode);
- void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t size1,uint8_t mode);
- void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1,uint8_t mode);
- void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1,uint8_t mode);
- void OLED_ScrollDisplay(uint8_t num,uint8_t space,uint8_t mode);
- void OLED_ShowPicture(uint8_t x,uint8_t y,uint8_t sizex,uint8_t sizey,uint8_t BMP[],uint8_t mode);
- void OLED_I2C_GPIO_Init(void);
- void OLED_Init(void);
- #endif /* SS1306_OLED_H_ */
复制代码 在main里面调用,显示图片:
- OLED_Init();
- OLED_ColorTurn(0);//0正常显示,1 反色显示
- OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
复制代码 编译查看现象:
我们去这个网址:https://github.com/olikraus/u8g2 下载u8g2的文件包:
解压下来,用里面的csrc文件夹,其余的不用。把这个文件夹及里面文件添加到工程中:
我们按照之前gui的习惯,同样把配置文件写到一个叫u8g2_support.c和h文件里面:
u8g2_support.h
- /*
- * u8g2_support.h
- *
- * Created on: 2020年12月25日
- * Author: Administrator
- */
- #ifndef U8G2_SUPPORT_H_
- #define U8G2_SUPPORT_H_
- #include "u8g2.h"
- #include <stdio.h>
- #include "board.h"
- #include "peripherals.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "LPC55S69_cm33_core0.h"
- /* TODO: insert other include files here. */
- #include "delay.h"
- #include "ss1306_oled.h"
- #define DATA_BUFFER_SIZE 1024 //the size of buffer depends on how many pages are transfered at once e.g. one page are 128byte 1024
- #define I2C_TIMEOUT 1000
- #define DEVICE_ADDRESS 0x78 //device address is added
- uint8_t u8x8_byte_sw_i2c_lpc55s69(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
- uint8_t u8x8_gpio_and_delay_lpc55s69(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
- #endif /* U8G2_SUPPORT_H_ */
复制代码 u8g2_support.c
- /*
- * u8g2_support.c
- *
- * Created on: 2020年12月25日
- * Author: Administrator
- */
- #include "u8g2_support.h"
- #include "u8g2.h"
- #include "u8x8.h"
- uint8_t u8x8_gpio_and_delay_lpc55s69(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch(msg)
- {
- case U8X8_MSG_GPIO_AND_DELAY_INIT:
- /* only support for software I2C*/
- OLED_I2C_GPIO_Init();
- break;
- case U8X8_MSG_DELAY_NANO:
- /* not required for SW I2C */
- break;
- case U8X8_MSG_DELAY_10MICRO:
- /* not used at the moment */
- break;
- case U8X8_MSG_DELAY_100NANO:
- /* not used at the moment */
- break;
- case U8X8_MSG_DELAY_MILLI:
- delay_ms(arg_int);
- break;
- case U8X8_MSG_DELAY_I2C:
- /* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
- delay_us(arg_int<=2?5:1);
- break;
- case U8X8_MSG_GPIO_I2C_CLOCK:
- /* if ( arg_int == 0 )
- {
- Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
- Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
- }
- else
- {
- //Chip_GPIO_SetPinOutHigh(LPC_GPIO, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
- Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, I2C_CLOCK_PORT, I2C_CLOCK_PIN);
- }*/
- break;
- case U8X8_MSG_GPIO_I2C_DATA:
- /* if ( arg_int == 0 )
- {
- Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
- Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
- }
- else
- {
- //Chip_GPIO_SetPinOutHigh(LPC_GPIO, I2C_DATA_PORT, I2C_DATA_PIN);
- Chip_GPIO_SetPinDIRInput(LPC_GPIO_PORT, I2C_DATA_PORT, I2C_DATA_PIN);
- }
- break;*/
- /*
- case U8X8_MSG_GPIO_MENU_SELECT:
- u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_SELECT_PORT, KEY_SELECT_PIN));
- break;
- case U8X8_MSG_GPIO_MENU_NEXT:
- u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_NEXT_PORT, KEY_NEXT_PIN));
- break;
- case U8X8_MSG_GPIO_MENU_PREV:
- u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_PREV_PORT, KEY_PREV_PIN));
- break;
- case U8X8_MSG_GPIO_MENU_HOME:
- u8x8_SetGPIOResult(u8x8, Chip_GPIO_GetPinState(LPC_GPIO, KEY_HOME_PORT, KEY_HOME_PIN));*/
- break;
- default:
- //u8x8_SetGPIOResult(u8x8, 1);
- break;
- }
- return 1;
- }
- uint8_t u8x8_byte_sw_i2c_lpc55s69(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- uint8_t *ptr;
- static uint8_t buffer_count;
- static uint8_t buffer[DATA_BUFFER_SIZE+1]; //the size of buffer depends on how many pages are transfered at once
- //e.g. one page are 128byte and one byte more for command
- switch(msg)
- {
- case U8X8_MSG_BYTE_SEND: //collect
- {
- ptr = arg_ptr;
- while(arg_int>0)
- {
- MySend_Byte(*(ptr++));
- MyI2C_WaitAck();
- arg_int--;
- }
- }
- break;
- case U8X8_MSG_BYTE_INIT:
- break;
- case U8X8_MSG_BYTE_SET_DC:
- break;
- case U8X8_MSG_BYTE_START_TRANSFER:
- MyI2C_Start();
- MySend_Byte(0x78);
- MyI2C_WaitAck();
- break;
- case U8X8_MSG_BYTE_END_TRANSFER: // send all at once
- MyI2C_Stop();
- break;
- default:
- return 0;
- }
- return 1;
- }
复制代码 其中最重要的就是重构这2个函数。 :
引脚和延时 :uint8_t u8x8_gpio_and_delay_lpc55s69(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
IIC读写: uint8_t u8x8_byte_sw_i2c_lpc55s69(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
然后在主函数里面调用,即可开启u8g2:
- /* setup display */
- u8g2_Setup_ssd1306_i2c_128x64_noname_2(&u8g2, U8G2_R0, u8x8_byte_sw_i2c_lpc55s69, u8x8_gpio_and_delay_lpc55s69);
- u8g2_InitDisplay(&u8g2);
- u8g2_SetPowerSave(&u8g2, 0);
复制代码 我们写一个demo的例子:
u8g2_demo.h
- /*
- * u8g2_demo.h
- *
- * Created on: 2020年12月25日
- * Author: Administrator
- */
- #ifndef U8G2_DEMO_H_
- #define U8G2_DEMO_H_
- #include "u8g2.h"
- #include "u8g2_support.h"
- extern u8g2_t u8g2;
- void demo_u8g2_draw(u8g2_t *u8g2);
- void demo_u8g2_draw2(void);
- void demo_u8g2_init(void);
- void demo_u8g2_task(void);
- #endif /* U8G2_DEMO_H_ */
复制代码 u8g2_demo.c
- /*
- * u8g2.c
- *
- * Created on: 2020年12月25日
- * Author: Administrator
- */
- #include "u8g2_demo.h"
- u8g2_t u8g2; // a structure which will contain all the data for one display
- uint8_t show_delay_max = 0;//等待最长时间
- uint8_t show_delay_cnt = 0; //等待延时标志
- uint8_t show_picture_index =0; //对应图片选择
- void demo_u8g2_draw(u8g2_t *u8g2)
- {
- u8g2_SetFontMode(u8g2, 1); // Transparent
- u8g2_SetFontDirection(u8g2, 0);
- u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(u8g2, 0, 30, "U");
- u8g2_SetFontDirection(u8g2, 1);
- u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
- u8g2_DrawStr(u8g2, 21,8,"8");
- u8g2_SetFontDirection(u8g2, 0);
- u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(u8g2, 51,30,"g");
- u8g2_DrawStr(u8g2, 67,30,"\xb2");
- u8g2_DrawHLine(u8g2, 2, 35, 47);
- u8g2_DrawHLine(u8g2, 3, 36, 47);
- u8g2_DrawVLine(u8g2, 45, 32, 12);
- u8g2_DrawVLine(u8g2, 46, 33, 12);
- u8g2_SetFont(u8g2, u8g2_font_4x6_tr);
- u8g2_DrawStr(u8g2, 1,54,"github.com/olikraus/u8g2");
- }
- //////demo2
- #define hare1_width 25
- #define hare1_height 28
- static unsigned char hare1_bits[] = {
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x80, 0x80, 0x01, 0x00,
- 0x00, 0x01, 0x02, 0x00, 0x00, 0x0e, 0x0c, 0x00, 0x00, 0x01, 0x30, 0x00,
- 0x80, 0x00, 0x40, 0x00, 0x80, 0x00, 0x88, 0x00, 0x40, 0x1c, 0x1c, 0x01,
- 0x80, 0x23, 0x1c, 0x01, 0x00, 0x20, 0x08, 0x01, 0x00, 0x1c, 0x80, 0x00,
- 0x00, 0x03, 0x40, 0x00, 0x80, 0x00, 0x20, 0x00, 0x60, 0x00, 0x20, 0x00,
- 0x10, 0x00, 0x20, 0x00, 0x08, 0x00, 0x40, 0x00, 0x04, 0x00, 0x40, 0x00,
- 0x02, 0x80, 0x87, 0x00, 0x01, 0x40, 0x88, 0x00, 0x01, 0x20, 0x48, 0x00,
- 0x03, 0x20, 0x30, 0x00, 0x1c, 0xc0, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00,
- 0x40, 0x00, 0x01, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00,
- 0x00, 0x18, 0x00, 0x00 };
- #define hare2_width 30
- #define hare2_height 28
- static unsigned char hare2_bits[] = {
- 0x00, 0xc0, 0x03, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00,
- 0x00, 0x40, 0x10, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x70, 0x40, 0x00,
- 0x00, 0x08, 0x80, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x04,
- 0x00, 0x00, 0x81, 0x08, 0x00, 0x00, 0xc1, 0x11, 0x00, 0xfc, 0xc0, 0x11,
- 0x00, 0x03, 0x80, 0x10, 0x80, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x04,
- 0x08, 0x00, 0x00, 0x03, 0x06, 0x00, 0xc0, 0x00, 0x01, 0x00, 0x20, 0x00,
- 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00, 0x06, 0x00, 0x20, 0x00,
- 0x08, 0x00, 0x40, 0x00, 0x08, 0xf0, 0x41, 0x00, 0x08, 0x08, 0x46, 0x00,
- 0x08, 0x04, 0x48, 0x00, 0x08, 0x08, 0x30, 0x00, 0x30, 0x10, 0x00, 0x00,
- 0xc0, 0x0f, 0x00, 0x00 };
- void u8g2_prepare()
- {
- u8g2_SetFont(&u8g2, u8g2_font_courB10_tr);
- u8g2_SetFontRefHeightExtendedText(&u8g2);
- u8g2_SetDrawColor(&u8g2, 1);
- u8g2_SetFontPosTop(&u8g2);
- u8g2_SetFontDirection(&u8g2, 0);
- }
- void u8g2_drawLogo(void)
- {
- u8g2_SetFontMode(&u8g2,1); // Transparent
- u8g2_SetDrawColor(&u8g2,1);
- u8g2_SetFontDirection(&u8g2, 0);
- u8g2_SetFont(&u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(&u8g2, 0, 5, "U");
- u8g2_SetFontDirection(&u8g2, 1);
- u8g2_SetFont(&u8g2, u8g2_font_inb30_mn);
- u8g2_DrawStr(&u8g2, 51,8,"8");
- u8g2_SetFontDirection(&u8g2, 0);
- u8g2_SetFont(&u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(&u8g2, 51,5,"g");
- u8g2_DrawStr(&u8g2, 67,5,"\xb2");
- u8g2_DrawHLine(&u8g2, 2, 35, 47);
- u8g2_DrawHLine(&u8g2, 3, 36, 47);
- u8g2_DrawVLine(&u8g2, 45, 32, 12);
- u8g2_DrawVLine(&u8g2, 46, 33, 12);
- u8g2_SetFont(&u8g2, u8g2_font_5x8_tr);
- u8g2_DrawStr(&u8g2, 1,54,"github.com/olikraus/u8g2");
- }
- void u8g2_box_frame(uint8_t a)
- {
- u8g2_DrawStr(&u8g2, 0,0, "DrawBox");
- u8g2_DrawBox(&u8g2,0,15,20,10);
- u8g2_DrawBox(&u8g2,0+a,15,30,7);
- u8g2_DrawStr(&u8g2, 0, 32, "DrawFrame");
- u8g2_DrawFrame(&u8g2,0,15+32,20,10);
- u8g2_DrawFrame(&u8g2,0+a,15+32,30,7);
- }
- void u8g2_disc_circle(uint8_t a)
- {
- u8g2_DrawStr(&u8g2, 0, 0, "DrawDisc");
- u8g2_DrawDisc(&u8g2,10,22,7,U8G2_DRAW_ALL);
- u8g2_DrawDisc(&u8g2,24+a,20,5,U8G2_DRAW_ALL);
- u8g2_DrawStr(&u8g2, 0, 32, "DrawCircle");
- u8g2_DrawCircle(&u8g2,10,22+32,7,U8G2_DRAW_ALL);
- u8g2_DrawCircle(&u8g2,24+a,20+32,5,U8G2_DRAW_ALL);
- }
- void u8g2_string(uint8_t a)
- {
- u8g2_SetFontDirection(&u8g2,0);
- u8g2_DrawStr(&u8g2,70+a,31, " 0");
- u8g2_SetFontDirection(&u8g2,1);
- u8g2_DrawStr(&u8g2,68,0+a, " 90");
- u8g2_SetFontDirection(&u8g2,2);
- u8g2_DrawStr(&u8g2,70-a,31, " 180");
- u8g2_SetFontDirection(&u8g2,3);
- u8g2_DrawStr(&u8g2,72,64-a, " 270");
- }
- void u8g2_line(uint8_t a)
- {
- u8g2_DrawStr(&u8g2, 0, 0, "DrawLine");
- u8g2_DrawLine(&u8g2,7+a, 15, 60-a, 60);
- u8g2_DrawLine(&u8g2,7+a*2, 15, 80-a, 60);
- u8g2_DrawLine(&u8g2,7+a*3, 15, 100-a, 60);
- u8g2_DrawLine(&u8g2,7+a*4, 15, 120-a, 60);
- }
- void u8g2_hare(uint8_t a)
- {
- u8g2_DrawStr(&u8g2, 0, 0,"DrawXBM");
- if((a&1) == 0)
- {
- u8g2_DrawXBM(&u8g2, 0+a, 30, hare1_width, hare1_height, hare1_bits);
- }
- else
- {
- u8g2_DrawXBM(&u8g2, 0+a, 30, hare2_width, hare2_height, hare2_bits);
- }
- }
- void demo_u8g2_draw2(void)
- {
- u8g2_prepare();
- switch(show_picture_index) {
- case 0:
- //show_delay_max = 12;
- u8g2_drawLogo();
- break;
- case 1:
- show_delay_max = 150;
- u8g2_box_frame(show_delay_cnt);
- break;
- case 2:
- show_delay_max = 150;
- u8g2_disc_circle(show_delay_cnt);
- break;
- case 3:
- show_delay_max = 60;
- u8g2_string(show_delay_cnt);
- break;
- case 4:
- show_delay_max = 50;
- u8g2_line(show_delay_cnt);
- break;
- case 5:
- show_delay_max = 120;
- u8g2_hare(show_delay_cnt);
- break;
- }
- }
- //初始化
- void demo_u8g2_init(void)
- {
- /* setup display */
- u8g2_Setup_ssd1306_i2c_128x64_noname_2(&u8g2, U8G2_R0, u8x8_byte_sw_i2c_lpc55s69, u8x8_gpio_and_delay_lpc55s69);
- u8g2_InitDisplay(&u8g2);
- u8g2_SetPowerSave(&u8g2, 0);
- }
- //循环
- void demo_u8g2_task(void)
- {
- u8g2_FirstPage(&u8g2);
- do
- {
- //demo_u8g2_draw(&u8g2);
- demo_u8g2_draw2();
- } while( u8g2_NextPage(&u8g2) );
- delay_ms(200);
- if (show_delay_cnt <= show_delay_max)
- show_delay_cnt += 3;
- else
- {
- show_delay_cnt = 0;
- show_picture_index++;
- if ( show_picture_index >= 6)
- show_picture_index = 0;
- }
- }
复制代码 我们在main函数里调用:
- int main(void) {
- /* Init board hardware. */
- BOARD_InitBootPins();
- BOARD_InitBootClocks();
- BOARD_InitBootPeripherals();
- OLED_Init();
- OLED_ColorTurn(0);//0正常显示,1 反色显示
- OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
- demo_u8g2_init();
- PRINTF("Hello World\n");
- /* Enter an infinite loop, just incrementing a counter. */
- while(1) {
- demo_u8g2_task();
- }
- return 0 ;
- }
复制代码 编译查看:
|
|