12864 OLED 驱动程序三线SPI接口的电烙铁
本帖最后由 会潜水的猪 于 2014-1-6 01:54 编辑蛋疼发点无聊的东西
先看效果吧,用了PMOS之后的效果开关频率在20hz吧
不用PMOS的时候用继电器,开关速度真是蛋疼啊,由于处理速度挺快的,那连续闪动火花(可以说叫做拉弧),那一股焦味,刺激着我脆弱的过敏烂鼻子
用继电器的时候,加热的频率上不去,一个周期0.5秒才正常,但是问题就是温度飘的优点多,10多度啊(为了使用继电器,我用了低功率的电源,好让加热慢点),不过为了听滴答声也就无所谓了
关于OLED好处自然是不用说了,超高对比度,看起来非常舒服,特别是晚上,即使不开灯也非常的舒适,功耗极低,0.0几W,很爽的,100ma就把整个控制部分全部带起来了,而且余量大直接一个锂电池,能用很久很久很久
发这个帖子主要不在说明烙铁,主要是想闲扯下12864 OLED屏幕三线SPI驱动
三线SPI接口的好处是只用三根线即可完成通信,在加上供电线,总共5根
12864屏幕可以单片机内建GRAM,只不过要用掉1K罢了,128*8 = 1K,或者直接写字节都可
其实为了简单,且用不上显示图片的时候,直接写字节最方便
由于用到了5个管脚,其中三个是数据接口,当然要在单片机里定义数据接口了
直接调用库函数是最方便的了
#define LCD_SCL_OPENnrf_gpio_pin_set(12); //这个是置位,就是对端口写1,
#define LCD_SDA_OPENnrf_gpio_pin_set(13);
#define LCD_RST_OPENnrf_gpio_pin_set(14) ; 每当用到这些的时候,就直接调用这些就好了,define的意思是直接置换,前面的换后面的
#define LCD_DC_OPEN nrf_gpio_pin_set(15);
#define LCD_SCL_CLOSEnrf_gpio_pin_clear(12);//这些是复位,就是对端口写0,
#define LCD_SDA_CLOSEnrf_gpio_pin_clear(13);
#define LCD_RST_CLOSEnrf_gpio_pin_clear(14);
#define LCD_DC_CLOSE nrf_gpio_pin_clear(15);
主要用到的启动函数有这些
* . void LCD_WrDat(unsigned char dat) -- 写数据用的
* . void LCD_WrCmd(unsigned char cmd) -- 写命令用的
* . void LCD_Set_Pos(unsigned char x, unsigned char y) --设置坐标点的
* . void LCD_CLS(void) -- ¸清屏幕
* . void LCD_Init(void) --初始化显示屏
* . void LCD_P8x16Str(unsigned char x, y,unsigned char ch[]) --写数字和英文,
* .void LCD_P16x16Ch(unsigned char x, y, N) -- 取模显示中文
* .void Draw_BMP(unsigned char x0, y0,x1, y1,unsigned char BMP[]) -- 画图像
工作的时候呢,线初始化IO接口
void GPIO_SPI_Int()
{
nrf_gpio_cfg_output(12); //GPIO-P0.12把这些个接口都配置为输出模式,就是可以输出高低电平
nrf_gpio_cfg_output(13);
nrf_gpio_cfg_output(14);
nrf_gpio_cfg_output(15);
}
然后初始化屏幕
其实不用太注意里面初始化过程,除非厂家不提供,自己写还是很麻烦的,容易漏掉东西
里面的东西就不太解释了,各种开关,各种设置了
/*********************LCD³õʼ»¯************************************/
void LCD_Init(void)
{
LCD_SCL_OPEN;
LCD_RST_CLOSE;
LCD_DLY_ms(50);
LCD_RST_OPEN; //´ÓÉϵ絽ÏÂÃæ¿ªÊ¼³õʼ»¯ÒªÓÐ×㹻ʱ¼ä£¬ÓÃÓڵȴýRC¸´Î»Íê³É
LCD_WrCmd(0xae);//--turn off oled panel
LCD_WrCmd(0x00);//---set low column address
LCD_WrCmd(0x10);//---set high column address
LCD_WrCmd(0x40);//--set start line addressSet Mapping RAM Display Start Line (0x00~0x3F)
LCD_WrCmd(0x81);//--set contrast control register
LCD_WrCmd(0xcf); // Set SEG Output Current Brightness
LCD_WrCmd(0xa1);//--Set SEG/Column Mapping 0xa0×óÓÒ·´Öà 0xa1ÉÏÏ·´ÖÃ
LCD_WrCmd(0xc8);//Set COM/Row Scan Direction 0xc0ÉÏÏ·´Öà 0xc8Õý³£
LCD_WrCmd(0xa6);//--set normal display
LCD_WrCmd(0xa8);//--set multiplex ratio(1 to 64)
LCD_WrCmd(0x3f);//--1/64 duty
LCD_WrCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
LCD_WrCmd(0x00);//-not offset
LCD_WrCmd(0xd5);//--set display clock divide ratio/oscillator frequency
LCD_WrCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
LCD_WrCmd(0xd9);//--set pre-charge period
LCD_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
LCD_WrCmd(0xda);//--set com pins hardware configuration
LCD_WrCmd(0x12);
LCD_WrCmd(0xdb);//--set vcomh
LCD_WrCmd(0x40);//Set VCOM Deselect Level
LCD_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
LCD_WrCmd(0x02);//
LCD_WrCmd(0x8d);//--set Charge Pump enable/disable
LCD_WrCmd(0x14);//--set(0x10) disable
LCD_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
LCD_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
LCD_WrCmd(0xaf);//--turn on oled panel
LCD_Fill(0x00);//³õʼ»¯ÇåÆÁ
LCD_Set_Pos(0,0);
}
然后就是需要使用的函数啦
最基本的就是这三个,写命令,写数据,设置坐标点
/********************写数据******************************/
void LCD_WrDat(unsigned char dat)
{
unsigned char i;
LCD_DC_OPEN;
for(i=0;i<8;i++) //主要是移位操作
{
if((dat << i) & 0x80)
{
LCD_SDA_OPEN;
}
elseLCD_SDA_CLOSE;
LCD_SCL_CLOSE;
LCD_SCL_OPEN;
}
}
/*********************写命令***********************/
void LCD_WrCmd(unsigned char cmd)
{
unsigned char i;
LCD_DC_CLOSE;
for(i=0;i<8;i++) //也是不停的移位
{
if((cmd << i) & 0x80)
{
LCD_SDA_OPEN;
}
else
{
LCD_SDA_CLOSE;
}
LCD_SCL_CLOSE;
LCD_SCL_OPEN;
}
}
/******************设置坐标点****************************/
void LCD_Set_Pos(unsigned char x, unsigned char y)
{
LCD_WrCmd(0xb0+y);
LCD_WrCmd(((x&0xf0)>>4)|0x10);
LCD_WrCmd((x&0x0f)|0x01);
}
然后就是需要调用函数了
主要是显示各种字符
用来显示数字英语,汉字,画图
/******************8*16个点的数字和英文***************/
void LCD_P8x16Str(unsigned char x,unsigned char y,uint8_t ch[])
{
unsigned char c=0,i=0,j=0;
while (ch!='\0')
{
c =ch-32;
if(x>120){x=0;y++;}
LCD_Set_Pos(x,y);
for(i=0;i<8;i++)
LCD_WrDat(F8X16);
LCD_Set_Pos(x,y+1);
for(i=0;i<8;i++)
LCD_WrDat(F8X16);
x+=8;
j++;
}
}
/*****************1616的中文***************************/
void LCD_P16x16Ch(uint8_t x,uint8_t y,uint8_t N)
{
unsigned char wm=0;
unsigned int adder=32*N;
LCD_Set_Pos(x , y);
for(wm = 0;wm < 16;wm++)
{
LCD_WrDat(F16x16);
adder += 1;
}
LCD_Set_Pos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
LCD_WrDat(F16x16);
adder += 1;
}
}
/***********整个屏幕的画图*****************/
void Draw_BMP(unsigned char x0, unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0) y=y1/8;
else y=y1/8+1;
for(y=y0;y<y1;y++)
{
LCD_Set_Pos(x0,y);
for(x=x0;x<x1;x++)
{
LCD_WrDat(BMP);
}
}
}
最后,其实输出的都是字符串
比如要输出 温度(TEMP): 330这时候呢,最方便的当然不是直接调用上面显示数字的函数啦
首先调用sprintf(buffer,"TEMP: %d",temp);函数来规划字符,buffer是一个数组,用来保存所有的数字
一次性全部输出LCD_P8x16Str(10,4,buffer);就可以啦
这样呢,简单的数据显示就完成了
卧槽,我发错了地方,求版主帮忙移动到综合DIY好么,发完才发现 oled效果很好的 好看。 技术贴,顶起来 不明觉厉
做什么用的? 老山东 发表于 2014-1-6 13:20 static/image/common/back.gif
oled效果很好的
嗯,很舒服,回头再看LCD就觉得差了点 minibear 发表于 2014-1-7 13:38 static/image/common/back.gif
好看。
必须的,各种好看
sy8202 发表于 2014-1-9 11:08 static/image/common/back.gif
技术贴,顶起来
发错了区,真是蛋疼啊,各种蛋疼
死翘翘 发表于 2014-1-10 21:42 static/image/common/back.gif
不明觉厉
就是简单的说了一下如何驱动一个OLED SPI屏幕罢了
都是程序
Z4V 发表于 2014-1-10 22:28 static/image/common/back.gif
做什么用的?
上面简单说明了如何驱动SPI接口OLED12864屏幕
对想要用这种屏幕但是不太了解其驱动方式的人,算是一种参考吧
大家各种找资料,找来找去,找多了,就明白了
牛啊,对编程神马的一窍不通,看着好厉害,只想问有没有成品买,啥价格{:1_292:} zfyfeixiang 发表于 2014-1-18 14:31 static/image/common/back.gif
牛啊,对编程神马的一窍不通,看着好厉害,只想问有没有成品买,啥价格 ...
额,成品几乎不可能出,因为里面有三片DCDC降压。一片Op07C,这都是业余低价不可能使用的期间,价格也贵了
会潜水的猪 发表于 2014-1-18 16:15 static/image/common/back.gif
额,成品几乎不可能出,因为里面有三片DCDC降压。一片Op07C,这都是业余低价不可能使用的期间,价格也贵 ...
原来这样,那是不能奢望了,看看眼馋一下好了,照片也拍的很漂亮,没经过允许,忍不住私自P了一下{:1_303:}
zfyfeixiang 发表于 2014-1-18 16:38 static/image/common/back.gif
原来这样,那是不能奢望了,看看眼馋一下好了,照片也拍的很漂亮,没经过允许,忍不住私自P了一下{:1_303 ...
是啊,三片 DCDC,一片最高电压支持到32V,降压到5V然后两片DCDC到双12V给OP07供电,一片1113给stm32和OLED屏幕供电
有点麻烦的。虽然精度和市场上的358完全不是一个等级的
一个烙铁,用OP07,没必要这么精确吧,不过OLED确实比普通的液晶漂亮。我有个想法,楼主这么能折腾,应该把1080P的5寸以上手机屏当显示,这样才真的漂亮,这个OLED和1080P的手机屏比,弱爆了! w36066 发表于 2014-1-19 13:11 static/image/common/back.gif
一个烙铁,用OP07,没必要这么精确吧,不过OLED确实比普通的液晶漂亮。我有个想法,楼主这么能折腾,应该把 ...
我还想到了更疯狂的想法,用MAX6675,
MAX6675冷端温度补偿、热电偶数字转换器可进行冷端温度补偿,并将K型热电偶信号转换成数字信号。数据输出为12位分辨率、SPI™兼容、只读格式。
转换器温度分辨率为0.25°C,可读取温度达+1024°C,热电偶在0°C至+700°C温度范围内精度为8 LSB。
MAX6675采用小尺寸、8引脚SO封装。
而且已经下单了
会潜水的猪 发表于 2014-1-19 13:22 static/image/common/back.gif
我还想到了更疯狂的想法,用MAX6675,
MAX6675冷端温度补偿、热电偶数字转换器可进行冷端温度补偿,并将K ...
再好也没有意义,因为不同头子温度不一样,新旧头子也不一样,同样温度焊点不一样感觉不一样,焊接是个模拟的技术活,精确温度也不等于精确结果,当然兄弟折腾好玩也不错的,一种精神寄托罢了。
楼主我记得我的OLED是4线SPI接口。好像可以2线IIC,不过没学会。
楼主这个似乎是STM??
我只会点51.
顺便问一下,
51中可以用SBIT 定义某一个GPIO的状态(高低j电平)
而STM中明显没这个功能,用库函数岂不是要多好多条指令?
如果方便可否共享下你的源码(部分也可),你这种书写习惯我比较容易看懂。
我打处今年入门STM。。。做些小东西方便,51的单片机RAM大带ADC的价格贵太多了。
页:
[1]
2