【CH579M-R1】驱动OLED为项目做准备
本帖最后由 yangjiaxu 于 2021-1-11 22:02 编辑<p>CH579通过这两周的使用,已经熟悉了基本开发模式,对IO的初始化,一些特殊引脚的配置,ADC,定时器串口等等已经可以正常操作了。今天,就来驱动一下OLED12864,为便携式LCR测试仪做准备。</p>
<p>先看看效果。</p>
<p></p>
<p>本次使用的是SSD1306的OLED显示模块,使用CH579进行驱动。驱动部分还是比较简单,直接贴上代码。</p>
<pre>
<code>#include "oled.h"
#include "oledfont.h"
UINT8 OLED_GRAM; //OLED显示缓存的临时变量
/*******************************************************************************
* Function Name: OLED_WriteCmd
* Description : 向OLED写入命令
* Input : cmd: 命令
* Return : None
*******************************************************************************/
void OLED_WriteCmd(UINT8 cmd)
{
I2C_Start();
I2C_SendByte(0x78);
I2C_WaitAck();
I2C_SendByte(0x00);
I2C_WaitAck();
I2C_SendByte(cmd);
I2C_WaitAck();
I2C_Stop();
}
/*******************************************************************************
* Function Name: OLED_WriteData
* Description : 向OLED写入数据
* Input : data: 数据
* Return : None
*******************************************************************************/
void OLED_WriteData(UINT8 data)
{
I2C_Start();
I2C_SendByte(0x78);
I2C_WaitAck();
I2C_SendByte(0x40);
I2C_WaitAck();
I2C_SendByte(data);
I2C_WaitAck();
I2C_Stop();
}
/*******************************************************************************
* Function Name: OLED_RefreshGram
* Description : 刷新OLED显示
* Input : None
* Return : None
*******************************************************************************/
void OLED_RefreshGram(void)
{
signed char p;
UINT8 x;
for(p=7; p>=0; --p)
{
OLED_WriteCmd(0xB0+p);
OLED_WriteCmd(0x00);
OLED_WriteCmd(0x10);
for(x=0; x<128; ++x)
{
OLED_WriteData(OLED_GRAM);
}
}
}
/*******************************************************************************
* Function Name: OLED_Clear
* Description : 清空OLED显示
* Input : None
* Return : None
*******************************************************************************/
void OLED_Clear(void)
{
UINT8 x, p;
for(p=0; p<8; ++p)
for(x=0; x<128; ++x)
{
OLED_GRAM = 0;
}
OLED_RefreshGram();
}
/*******************************************************************************
* Function Name: OLED_DisplayOn
* Description : 打开OLED显示
* Input : None
* Return : None
*******************************************************************************/
void OLED_DisplayOn(void)
{
OLED_WriteCmd(0x8D);
OLED_WriteCmd(0x14);
OLED_WriteCmd(0xAF);
}
/*******************************************************************************
* Function Name: OLED_DisplayOff
* Description : 关闭OLED显示
* Input : None
* Return : None
*******************************************************************************/
void OLED_DisplayOff(void)
{
OLED_WriteCmd(0x8D);
OLED_WriteCmd(0x10);
OLED_WriteCmd(0xAE);
}
/*******************************************************************************
* Function Name: OLED_DrawPoint
* Description : OLED(x,y)坐标处的灯亮灭
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
s: 1/0 = 亮/灭
* Return : None
*******************************************************************************/
/* OLED描点 */
void OLED_DrawPoint(UINT8 x, UINT8 y, UINT8 s)
{
UINT8 pos, page, temp=0;
if(x>127 || y>63)
return;
page = 7-y/8;
pos = y%8;
temp = 1<<(7-pos);
if(s)
OLED_GRAM|= temp;
else
OLED_GRAM&= ~temp;
}
/*******************************************************************************
* Function Name: OLED_Fill
* Description : OLED(x1,y1)至(x2,y2)对角线的长方形上的灯亮灭
* Input : x1: 横坐标1,显示屏由左到右
y1: 纵坐标1,显示屏由上到下
x2: 横坐标2,显示屏由左到右
y2: 纵坐标2,显示屏由上到下
s: 1/0 = 亮/灭
* Return : None
*******************************************************************************/
void OLED_Fill(UINT8 x1, UINT8 x2, UINT8 y1, UINT8 y2, UINT8 s)
{
UINT8 x, y;
for(x=x1; x<x2; ++x)
{
for(y=y1; y<y2; ++y)
{
OLED_DrawPoint(x, y, s);
}
}
}
/*******************************************************************************
* Function Name: OLED_Fill
* Description : OLED(x,y)处显示字符
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
ch: 显示的字符
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowChar(UINT8 x, UINT8 y, UINT8 ch, UINT8 size)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 chsize = (size/8+((size%8)?1:0))*(size/2);
ch = ch-' ';
for(t=0; t<chsize; ++t)
{
if(size == 12)
temp = asc2_1206;
else if(size == 16)
temp = asc2_1608;
else if(size == 24)
temp = asc2_2412;
else
return;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == size)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: MyPow
* Description : 指数函数
* Input : m: 底数
n: 指数
* Return : result: 计算结果
*******************************************************************************/
UINT32 MyPow(UINT8 m, UINT8 n)
{
UINT32 result = 1;
while(n--)
result *= m;
return result;
}
/*******************************************************************************
* Function Name: OLED_ShowNum
* Description : OLED在(x,y)处显示数字
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
num: 显示的数字
len: 数字长度
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowNum(UINT8 x, UINT8 y, UINT32 num, UINT8 len, UINT8 size)
{
UINT8 t, temp;
UINT8 enshow = 0;
for(t=0; t<len; ++t)
{
temp = (num/MyPow(10,len-t-1))%10;
if(enshow==0 && t<(len-1))
{
if(temp == 0)
{
OLED_ShowChar(x+(size/2)*t, y, ' ', size);
continue;
}
else
enshow = 1;
}
OLED_ShowChar(x+(size/2)*t, y, temp+'0', size);
}
}
/*******************************************************************************
* Function Name: OLED_ShowString
* Description : OLED在(x,y)处显示字符串
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
*p: 字符串的首地址
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowString(UINT8 x, UINT8 y, UINT8 *p, UINT8 size)
{
while ((*p>=' ') && (*p<='~'))
{
if(x>(128-(size/2)))
{
x = 0;
y += size;
}
if(y>(64-size))
{
y = x = 0;
OLED_Clear();
}
OLED_ShowChar(x, y, *p, size);
x += size/2;
++p;
}
}
/*******************************************************************************
* Function Name: OLED_Init
* Description : OLED初始化
* Input : None
* Return : None
*******************************************************************************/
void OLED_Init(void)
{
DelayMs(100);
OLED_WriteCmd(0xAE);//--turn off oled panel
OLED_WriteCmd(0xD5);//--set display clock divide ratio/oscillator frequency(0xd5);//--set
display clock divide ratio/oscillator frequency
OLED_WriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WriteCmd(0xA8);//--set multiplex ratio(1 to 64)
OLED_WriteCmd(0x3F);//--1/64 duty
OLED_WriteCmd(0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WriteCmd(0x00);//-not offset
OLED_WriteCmd(0x40);//Set VCOM Deselect Level
OLED_WriteCmd(0x8D);//--set Charge Pump enable/disable
OLED_WriteCmd(0x14);//--set(0x10) disable
OLED_WriteCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WriteCmd(0x02);//
OLED_WriteCmd(0xA1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WriteCmd(0xC0);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WriteCmd(0xDA);//--set com pins hardware configuration
OLED_WriteCmd(0x12);
OLED_WriteCmd(0x81);//--set contrast control register
OLED_WriteCmd(0XEF); // Set SEG Output Current Brightness
OLED_WriteCmd(0xD9);//--set pre-charge period
OLED_WriteCmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WriteCmd(0xDB);//--set vcomh
OLED_WriteCmd(0x30);//--set vcomh
OLED_WriteCmd(0xA4);// Disable Entire Display On (0xa4/0xa5)
OLED_WriteCmd(0xA6);// Disable Inverse Display On (0xa6/a7)
OLED_WriteCmd(0xAF);//--turn on oled panel
OLED_Clear(); //初始清屏
}
/*******************************************************************************
* Function Name: OLED_ShowResPic
* Description : OLED在(x,y)处显示电阻图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowResPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 64;
for(t=0; t<charsize; ++t)
{
temp = RES_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 16)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowOhmUnit
* Description : OLED在(x,y)处显示'Ω'标识
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowOhmUnit(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 32;
for(t=0; t<charsize; ++t)
{
temp = OHM_UNIT;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 16)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowCapPic
* Description : OLED在(x,y)处显示电容图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowCapPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 64;
for(t=0; t<charsize; ++t)
{
temp = CAP_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 16)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowIndPic
* Description : OLED在(x,y)处显示电感图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowIndPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 64;
for(t=0; t<charsize; ++t)
{
temp = IND_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 16)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowDioPic
* Description : OLED在(x,y)处显示二极管图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowDioPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 64;
for(t=0; t<charsize; ++t)
{
temp = DIO_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 16)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowPBJTPic
* Description : OLED在(x,y)处显示PBJT图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowPBJTPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = PBJT_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowNBJTPic
* Description : OLED在(x,y)处显示NBJTP图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowNBJTPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = NBJT_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowPJEFPic
* Description : OLED在(x,y)处显示PJEF图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowPJEFPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = PJFET_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowNJEFPic
* Description : OLED在(x,y)处显示NJEF图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowNJEFPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = NJFET_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowPEMOSPic
* Description : OLED在(x,y)处显示PEMOS图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowPEMOSPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = PEMOS_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowNEMOSPic
* Description : OLED在(x,y)处显示NEMOS图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowNEMOSPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = NEMOS_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowPDMOSPic
* Description : OLED在(x,y)处显示PDMOS图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowPDMOSPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = PDMOS_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowNDMOSPic
* Description : OLED在(x,y)处显示NDMOS图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowNDMOSPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = NDMOS_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowPEMOSDIOPic
* Description : OLED在(x,y)处显示PEMOSDIO图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowPEMOSDIOPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = PEMOSDIO_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}
/*******************************************************************************
* Function Name: OLED_ShowPEMOSDIOPic
* Description : OLED在(x,y)处显示NEMOSDIO图片
* Input : x: 横坐标,显示屏由左到右
y: 纵坐标,显示屏由上到下
size: 字符的高度
* Return : None
*******************************************************************************/
void OLED_ShowNEMOSDIOPic(UINT8 x, UINT8 y)
{
UINT8 temp, t, p;
UINT8 y0 = y;
UINT8 charsize = 72;
for(t=0; t<charsize; ++t)
{
temp = NEMOSDIO_PIC;
for(p=0; p<8; ++p)
{
if(temp&0x80)
OLED_DrawPoint(x, y, 1);
else
OLED_DrawPoint(x, y, 0);
temp <<= 1;
++y;
if((y-y0) == 32)
{
y = y0;
++x;
break;
}
}
}
}</code></pre>
<hr />
<p>显示界面</p>
<pre>
<code>/*******************************************************************************
* Function Name: Ready_Display
* Description : 显示准备就绪界面
* Input : None
* Return : None
*******************************************************************************/
void Ready_Display(void)
{
UINT8 NAME_BUF[] = "LCR Tester";
UINT8 READY_BUF[] = "Ready!";
OLED_Fill(0, 128, 0, 64, 0);
OLED_ShowString(0, 0, NAME_BUF, 16);
OLED_ShowString(0, 16, READY_BUF, 24);
OLED_RefreshGram();
}</code></pre>
<p> </p>
<p>还不错哈,感谢分享!</p>
<p>谢谢分享!期待后续!</p>
页:
[1]