|
本帖最后由 会潜水的猪 于 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_OPEN nrf_gpio_pin_set(12); //这个是置位,就是对端口写1,
#define LCD_SDA_OPEN nrf_gpio_pin_set(13);
#define LCD_RST_OPEN nrf_gpio_pin_set(14) ; 每当用到这些的时候,就直接调用这些就好了,define的意思是直接置换,前面的换后面的
#define LCD_DC_OPEN nrf_gpio_pin_set(15);
#define LCD_SCL_CLOSE nrf_gpio_pin_clear(12);//这些是复位,就是对端口写0,
#define LCD_SDA_CLOSE nrf_gpio_pin_clear(13);
#define LCD_RST_CLOSE nrf_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 address Set 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;
}
else LCD_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[j]!='\0')
{
c =ch[j]-32;
if(x>120){x=0;y++;}
LCD_Set_Pos(x,y);
for(i=0;i<8;i++)
LCD_WrDat(F8X16[c*16+i]);
LCD_Set_Pos(x,y+1);
for(i=0;i<8;i++)
LCD_WrDat(F8X16[c*16+i+8]);
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]);
adder += 1;
}
LCD_Set_Pos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
LCD_WrDat(F16x16[adder]);
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[j++]);
}
}
}
最后,其实输出的都是字符串
比如要输出 温度(TEMP): 330 这时候呢,最方便的当然不是直接调用上面显示数字的函数啦
首先调用sprintf(buffer,"TEMP: %d",temp);函数来规划字符,buffer是一个数组,用来保存所有的数字
一次性全部输出LCD_P8x16Str(10,4,buffer);就可以啦
这样呢,简单的数据显示就完成了
|
|