/********************************************************************
* OLED屏測試程序
* msp430g2553
*
* 調用方法:
* LCD_Init(); // OLED 初始化
* LCD_Fill(0x00); // 全屏填充 0x00
* LCD_GBK16(0, 2, "1.鋤禾日當午,\r2.汗滴禾下土。\r3.誰知盤中餐,");
* LCD_P6x8Str (0,4,"OLED"); // 顯示6*8 字符串
* = HowMuchWidth(Num);// 獲取某數有幾位
* LCD_IntNum(x, y, HowMuchWidth(v), v); // 顯示數字
* LCD_16Pic(unsigned char x,unsigned char y,unsigned char width,unsigned char dat[]);//16像素高度圖片
* LCD_8Pic(unsigned char x,unsigned char y,unsigned char width,unsigned char ch[]);//8像素高度圖片
* LCD_AllPic(unsigned char dat[]);//全局圖像顯示
*
*
* 說明:圖像取模:縱向取模,字節倒序
*
* 作者:星希望(已校驗)
* 日期:2016年7月25日
**********************************************************************/
#include "msp430f149.h"
#include "OLED.h"
#include "OLED_Font.h"
#define LCD_SCL_1 P2OUT |= BIT0
#define LCD_SCL_0 P2OUT &= ~BIT0
#define LCD_SDA_1 P2OUT |= BIT1
#define LCD_SDA_0 P2OUT &= ~BIT1
#define LCD_RST_1 P2OUT |= BIT2
#define LCD_RST_0 P2OUT &= ~BIT2
#define LCD_DC_1 P2OUT |= BIT3
#define LCD_DC_0 P2OUT &= ~BIT3
#define XLevelL 0x00
#define XLevelH 0x10
#define XLevel ((XLevelH&0x0F)*16+XLevelL)
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xCF
#define X_WIDTH 128
#define Y_WIDTH 64
unsigned int hz16_num = 0; // 漢字個數
//======================================
void LCD_WrDat(unsigned char dat)
{
unsigned char i=8;
LCD_DC_1;
LCD_SCL_0;
while(i--)
{
if(dat&0x80) {LCD_SDA_1;}
else {LCD_SDA_0;}
LCD_SCL_1;
dat<<=1;
LCD_SCL_0;
}
}
void LCD_WrCmd(unsigned char cmd)
{
unsigned char i=8;
LCD_DC_0;
LCD_SCL_0;
while(i--)
{
if(cmd&0x80) {LCD_SDA_1;}
else {LCD_SDA_0;}
LCD_SCL_1;
cmd<<=1;
LCD_SCL_0;
}
}
void LCD_Set_Pos(unsigned char x, unsigned char y)
{
LCD_WrCmd(0xb0+y);
LCD_WrCmd(((x&0xf0)>>4)|0x10);
LCD_WrCmd((x&0x0f)|0x00);
}
void LCD_Fill(unsigned char bmp_dat)
{
unsigned char y, x;
for(y=0;y<8;y++)
{
LCD_WrCmd(0xb0+y);
LCD_WrCmd(0x01);
LCD_WrCmd(0x10);
for(x=0;x<X_WIDTH;x++)
LCD_WrDat(bmp_dat);
}
}
void LCD_DLY_ms(unsigned int ms)
{
while(ms--)
{
__delay_cycles(100);
}
return;
}
/*********************************************************************************
* OLED 初始化
*********************************************************************************/
void LCD_Init(void)
{
P2DIR |= BIT0 | BIT1 | BIT2 | BIT3;
LCD_SCL_1;
//LCD_CS=1; //預制SLK和SS為高電平
LCD_RST_0;
LCD_DLY_ms(50);
LCD_RST_1;
/* 計算漢字庫的大小 */
hz16_num = sizeof hz16 / sizeof (struct typFNT_GB162);
//從上電到下面開始初始化要有足夠的時間,即等待RC復位完畢
LCD_WrCmd(0xae);//--關閉OLED面板
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)設置起始行地址設置映射RAM顯示起始行(0×00?0x3F之間)
LCD_WrCmd(0x81);//--set contrast control register設置對比度控制寄存器
LCD_WrCmd(0xcf);// Set SEG Output Current Brightness設置SEG輸出電流亮度
LCD_WrCmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常 設置SEG/列映射0XA0左右反置0xa1正常
LCD_WrCmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常 設置COM/行掃描方向為0xC0上下反置0xc8正常
LCD_WrCmd(0xa6);//--set normal display 設置正常顯示
LCD_WrCmd(0xa8);//--set multiplex ratio(1 to 64) 設置復用率(1~64)
LCD_WrCmd(0x3f);//--1/64 duty 1/64責任
LCD_WrCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F) 置顯示失調漂移映射RAM計數器(為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 設置的分頻比,設置時鐘為100幀/秒
LCD_WrCmd(0xd9);//--set pre-charge period 組預充電期間
LCD_WrCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock 設置預充電為15時鐘和放電為1時鐘
LCD_WrCmd(0xda);//--set com pins hardware configuration 組COM插針的硬件配置
LCD_WrCmd(0x12);
LCD_WrCmd(0xdb);//--set vcomh
LCD_WrCmd(0x40);//Set VCOM Deselect Level 設置VCOM取消等級
LCD_WrCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02) 設置頁面尋址模式(0×00/0×01/0X02)
LCD_WrCmd(0x02);//
LCD_WrCmd(0x8d);//--set Charge Pump enable/disable 設置電荷泵啟用/禁用
LCD_WrCmd(0x14);//--set(0x10) disable 設置(0x10)后關閉
LCD_WrCmd(0xa4);// Disable Entire Display On (0xa4/0xa5) 禁用整個顯示屏(0xa4/到0x55)
LCD_WrCmd(0xa6);// Disable Inverse Display On (0xa6/a7) 禁用逆顯示(0xa6/ A7)
LCD_WrCmd(0xaf);//--turn on oled panel
LCD_Fill(0x00); //初始清屏
LCD_Set_Pos(0,0);
}
/*********************************************************************************
* 函數名:LCD_P6x8Str(unsigned char x,unsigned char y,unsigned char *p)
* 功能描述:寫入一組標準ASCII字符串
* 參數:顯示的位置(x,y),y為頁范圍0~7,要顯示的字符串
* 返回:無
*********************************************************************************/
void LCD_P6x8Str(unsigned char x, unsigned char y, unsigned char ch[])
{
unsigned char c=0,i=0,j=0;
while (ch[j]!='\0')
{
c =ch[j]-32;
if(x>126 || c==13) // 下一行
{x=0;y++;}
LCD_Set_Pos(x,y);
for(i=0;i<6;i++)
LCD_WrDat(F6x8[c][i]);
x+=6;
j++;
}
}
/*********************************************************************************
* 函數名:LCD_8Pic(unsigned char x,unsigned char y,unsigned char *p)
* 功能描述:寫入一組高度為8像素的圖標
* 參數:顯示的位置(x,y),y為頁范圍0~7,
* 返回:無
*********************************************************************************/
void LCD_8Pic(unsigned char x,unsigned char y,unsigned char width,unsigned char ch[])
{
unsigned char j=0;
LCD_Set_Pos(x,y);
while (width)
{
LCD_WrDat(ch[j]);
j++;
width--;
}
}
/*************************************************************************************
* 顯示漢字 及 8x16 ascii碼
* 坐標x,坐標y,內容
* 查找 hz16[] 結構體數組
*************************************************************************************/
void LCD_GBK16(unsigned int x, unsigned int y, unsigned char *s)
{
unsigned char j;
unsigned short k,x0;
x0=x;
while(*s)
{
if((*s) < 128) // ASC段
{
k = *s;
if (k==13) //回車
{
x = x0;
y += 2;
}
else
{
if (k>32) k-=32; //從有效字符開始編碼,避開前面的非字符區
else k=0;
LCD_Set_Pos(x, y);
for(j=0; j<8; j++)
{
LCD_WrDat(F8X16[k*16+j]);
}
LCD_Set_Pos(x, y+1);
for(j=0; j<8; j++)
{
LCD_WrDat(F8X16[k*16+j+8]);
}
x += 8;
}
s++;
}
else // 漢字段
{
for(k=0; k<hz16_num; k++)
{
if( (hz16[k].Index[0]==*(s)) && (hz16[k].Index[1]==*(s+1)) )
{
LCD_Set_Pos(x, y);
for(j=0; j<16; j++) //高8位
{
LCD_WrDat(hz16[k].Msk[j]);
}
LCD_Set_Pos(x, y+1);
for(j=0; j<16; j++) //低8位
{
LCD_WrDat(hz16[k].Msk[j+16]);
}
break;
}
}
if( k==hz16_num )// 沒有找到該漢字
{
LCD_Set_Pos(x, y);
for(j=0; j<16; j++) //高8位
{
LCD_WrDat(UnknowFont[j]);
}
LCD_Set_Pos(x, y+1);
for(j=0; j<16; j++) //低8位
{
LCD_WrDat(UnknowFont[j+16]);
}
}
s += 2;
x += 16;
}
if(x>120) {x=0; y+=2;}
}
}
/*********************************************************************************
* 函數名:LCD_16Pic(unsigned char x,unsigned char y,unsigned char *p)
* 參數:x,y 顯示的位置,y為頁范圍0~7,
* width 圖標寬度
* dat[] 圖像數據
*********************************************************************************/
void LCD_16Pic(unsigned char x,unsigned char y,unsigned char width,unsigned char dat[])
{
unsigned char i=0;
LCD_Set_Pos(x, y);
for(i = 0;i < width;i++)
{
LCD_WrDat(dat[i]);
}
LCD_Set_Pos(x, y + 1);
for(i = 0;i < width;i++)
{
LCD_WrDat(dat[i+width]);
}
}
/*********************************************************************************
* 全屏圖像顯示
*********************************************************************************/
void LCD_AllPic(unsigned char dat[])
{
unsigned char y, x;
for(y=0; y<8; y++)
{
LCD_Set_Pos(0, y);
for(x=0; x<128; x++)
{
LCD_WrDat(dat[y*128+x]);
}
}
}
/************************************************************************************
* 計算某數有幾位
************************************************************************************/
unsigned char HowMuchWidth(unsigned long Num)
{
unsigned char cnt=0;
while(Num)
{
Num /= 10;
cnt++;
}
return cnt;
}
/************************************************************************************
* 顯示數字
* 參數:x,y - 坐標
* Width- 寬度(有幾位數)
* v - 數字
* 說明:右對齊
*************************************************************************************/
void LCD_IntNum(unsigned char x, unsigned char y, unsigned char Width, unsigned long v)
{
unsigned char a[11];
unsigned char *p;
// 數位分解
a[10]= 0;
a[9] = v % 10 + '0';
a[8] = v /10 % 10 + '0';
a[7] = v /100 % 10 + '0';
a[6] = v /1000 % 10 + '0';
a[5] = v /10000 % 10 + '0';
a[4] = v /100000 % 10 + '0';
a[3] = v /1000000 % 10 + '0';
a[2] = v /10000000 % 10 + '0';
a[1] = v /100000000 % 10 + '0';
a[0] = v /1000000000 % 10 + '0';
p = &a[10-Width];
// 顯示
LCD_GBK16(x, y, p); // 顯示 8*16 字符串
}
/************************************************************************************
* 顯示數字
* 參數:x,y - 坐標
* Width- 寬度(有幾位數)
* v - 數字
* 說明:右對齊
*************************************************************************************/
void LCD_IntNum6x8(unsigned char x, unsigned char y, unsigned char Width, unsigned long v)
{
unsigned char a[11];
unsigned char *p;
// 數位分解
a[10]= 0;
a[9] = v % 10 + '0';
a[8] = v /10 % 10 + '0';
a[7] = v /100 % 10 + '0';
a[6] = v /1000 % 10 + '0';
a[5] = v /10000 % 10 + '0';
a[4] = v /100000 % 10 + '0';
a[3] = v /1000000 % 10 + '0';
a[2] = v /10000000 % 10 + '0';
a[1] = v /100000000 % 10 + '0';
a[0] = v /1000000000 % 10 + '0';
p = &a[10-Width];
// 顯示
LCD_P6x8Str(x, y, p); // 顯示 8*16 字符串
}
#ifndef _OLED_H
#define _OLED_H
extern unsigned int hz16_num; // 漢字個數
void LCD_Init(void);
void LCD_CLS(void);
void LCD_P6x8Str(unsigned char x,unsigned char y,unsigned char ch[]);
void LCD_GBK16(unsigned int x, unsigned int y, unsigned char *s);
unsigned char HowMuchWidth(unsigned long Num);
void LCD_IntNum(unsigned char x, unsigned char y, unsigned char Width, unsigned long v);
void LCD_IntNum6x8(unsigned char x, unsigned char y, unsigned char Width, unsigned long v);
void LCD_8Pic (unsigned char x,unsigned char y,unsigned char width,unsigned char ch[]);
void LCD_16Pic(unsigned char x,unsigned char y,unsigned char width,unsigned char dat[]);
void LCD_AllPic(unsigned char dat[]);
void LCD_Fill(unsigned char dat);
#endif
|