会潜水的猪 发表于 2014-1-6 01:49

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);就可以啦

这样呢,简单的数据显示就完成了









会潜水的猪 发表于 2014-1-6 01:55

卧槽,我发错了地方,求版主帮忙移动到综合DIY好么,发完才发现

老山东 发表于 2014-1-6 13:20

oled效果很好的

minibear 发表于 2014-1-7 13:38

好看。

sy8202 发表于 2014-1-9 11:08

技术贴,顶起来

死翘翘 发表于 2014-1-10 21:42

不明觉厉

Z4V 发表于 2014-1-10 22:28

做什么用的?

会潜水的猪 发表于 2014-1-15 22:43

老山东 发表于 2014-1-6 13:20 static/image/common/back.gif
oled效果很好的

嗯,很舒服,回头再看LCD就觉得差了点

会潜水的猪 发表于 2014-1-15 22:44

minibear 发表于 2014-1-7 13:38 static/image/common/back.gif
好看。

必须的,各种好看

会潜水的猪 发表于 2014-1-15 22:44

sy8202 发表于 2014-1-9 11:08 static/image/common/back.gif
技术贴,顶起来

发错了区,真是蛋疼啊,各种蛋疼

会潜水的猪 发表于 2014-1-15 22:45

死翘翘 发表于 2014-1-10 21:42 static/image/common/back.gif
不明觉厉

就是简单的说了一下如何驱动一个OLED    SPI屏幕罢了

都是程序

会潜水的猪 发表于 2014-1-15 23:01

Z4V 发表于 2014-1-10 22:28 static/image/common/back.gif
做什么用的?

上面简单说明了如何驱动SPI接口OLED12864屏幕
对想要用这种屏幕但是不太了解其驱动方式的人,算是一种参考吧
大家各种找资料,找来找去,找多了,就明白了

zfyfeixiang 发表于 2014-1-18 14:31

牛啊,对编程神马的一窍不通,看着好厉害,只想问有没有成品买,啥价格{:1_292:}

会潜水的猪 发表于 2014-1-18 16:15

zfyfeixiang 发表于 2014-1-18 14:31 static/image/common/back.gif
牛啊,对编程神马的一窍不通,看着好厉害,只想问有没有成品买,啥价格 ...

额,成品几乎不可能出,因为里面有三片DCDC降压。一片Op07C,这都是业余低价不可能使用的期间,价格也贵了

zfyfeixiang 发表于 2014-1-18 16:38

会潜水的猪 发表于 2014-1-18 16:15 static/image/common/back.gif
额,成品几乎不可能出,因为里面有三片DCDC降压。一片Op07C,这都是业余低价不可能使用的期间,价格也贵 ...

原来这样,那是不能奢望了,看看眼馋一下好了,照片也拍的很漂亮,没经过允许,忍不住私自P了一下{:1_303:}

会潜水的猪 发表于 2014-1-18 17:46

zfyfeixiang 发表于 2014-1-18 16:38 static/image/common/back.gif
原来这样,那是不能奢望了,看看眼馋一下好了,照片也拍的很漂亮,没经过允许,忍不住私自P了一下{:1_303 ...

是啊,三片 DCDC,一片最高电压支持到32V,降压到5V然后两片DCDC到双12V给OP07供电,一片1113给stm32和OLED屏幕供电
有点麻烦的。虽然精度和市场上的358完全不是一个等级的

w36066 发表于 2014-1-19 13:11

一个烙铁,用OP07,没必要这么精确吧,不过OLED确实比普通的液晶漂亮。我有个想法,楼主这么能折腾,应该把1080P的5寸以上手机屏当显示,这样才真的漂亮,这个OLED和1080P的手机屏比,弱爆了!

会潜水的猪 发表于 2014-1-19 13:22

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封装。




而且已经下单了

w36066 发表于 2014-1-20 00:05

会潜水的猪 发表于 2014-1-19 13:22 static/image/common/back.gif
我还想到了更疯狂的想法,用MAX6675,

MAX6675冷端温度补偿、热电偶数字转换器可进行冷端温度补偿,并将K ...

再好也没有意义,因为不同头子温度不一样,新旧头子也不一样,同样温度焊点不一样感觉不一样,焊接是个模拟的技术活,精确温度也不等于精确结果,当然兄弟折腾好玩也不错的,一种精神寄托罢了。

Junyee 发表于 2014-2-11 21:37

楼主我记得我的OLED是4线SPI接口。好像可以2线IIC,不过没学会。
楼主这个似乎是STM??
我只会点51.

顺便问一下,
51中可以用SBIT 定义某一个GPIO的状态(高低j电平)
而STM中明显没这个功能,用库函数岂不是要多好多条指令?

如果方便可否共享下你的源码(部分也可),你这种书写习惯我比较容易看懂。
我打处今年入门STM。。。做些小东西方便,51的单片机RAM大带ADC的价格贵太多了。
页: [1] 2
查看完整版本: 12864 OLED 驱动程序三线SPI接口的电烙铁