/******************************************************************
?
編? 譯? 器:Haawking IDE V0.1.2
?
? D? S? P:dsc28034湖人板
?
電 腦 配 置:Windows10 專業版; 64 位操作系統
?
仿? 真? 器:HX100v2
?
使? 用? 庫:無
?
作? ? ? ? ?用:在OLED屏上顯示文字及數字
?
說? ? ? ? ?明:無
?
版? ? ? ? ?本:V0.0.1
?
******************************************************************/
?
OLED屏資料:
?
鏈接:https://pan.baidu.com/s/1sQlrV6J09XKWtcQlFHXdXQ?
提取碼:8034
?
四針的OLED屏用IIC來寫,原理在資料中 ,再結合以下例程,定能夠輕松上手:
?
IIC_OLED.c、
//GPIO配置
?
void I2C_GPIO_Config_OLED(void)
{
? ? EALLOW;
? ? GpioCtrlRegs.GPAPUD.bit.GPIO14 = 0;
? ? GpioCtrlRegs.GPAPUD.bit.GPIO15 = 0;
?
? ? GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 3;
? ? GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 3;
?
? ? GpioCtrlRegs.GPADIR.bit.GPIO14 = 1;
? ? GpioCtrlRegs.GPADIR.bit.GPIO15 = 1;
?
? ? GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0;?
? ? GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0;
?
? ? GpioDataRegs.GPASET.bit.GPIO14 = 1;
? ? GpioDataRegs.GPASET.bit.GPIO15 = 1;
?
? ? EDIS;
}
?
//得到輸入數字的長度
?
?int Data_len(int data)
{
? ? ? ? int n=0;
? ? ? ? if(data==0)
? ? ? ? return ++n;
? ? while(data!=0)
? ? {
? ? ? ? n++;
? ? ? ? data/=10;
? ? }
? ? return n;
}
?
//延時
?
void I2C_OLED_delay(void)? ?//延時函數
{
? ? int i =50;
? ? while(i)
? ? {
? ? ? ? i--;
? ? }
}
?
//延時
?
void I2C_OLED_delay_more(void)
{
? ? int i =200;
? ? while(i)
? ? {
? ? ? ? i--;
? ? }
}
?
//以GPIO14為SCL,GPIO15為SDA向OLED模塊傳送起始位
?
bool I2C_OLED_start(void)//IIC起始位
{
? ? SDA1_H;
? ? SCL1_H;
? ? I2C_OLED_delay();
? ? if(!SDA1_read)//SDA線為低電平,總線忙,退出
? ? {
? ? ? ? return 0;
? ? }
? ? SDA1_L;
? ? I2C_OLED_delay();
? ? if(SDA1_read)//SDA線為高電平則總線出錯,退出
? ? {
? ? ? ? return 0;
? ? }
? ? SDA1_L;
? ? I2C_OLED_delay();
? ? return 1;
}
?
//以GPIO14為SCL,GPIO15為SDA向OLED模塊傳送停止位
?
void I2C_OLED_stop(void)
{
? ? SCL1_L;
? ? I2C_OLED_delay();
? ? SDA1_L;
? ? I2C_OLED_delay();
? ? SCL1_H;
? ? I2C_OLED_delay();
? ? SDA1_H;
}
?
//以GPIO14為SCL,GPIO15為SDA向OLED模塊傳送響應位
?
void I2C_OLED_ack(void)
{
? ? SCL1_L;
? ? I2C_OLED_delay();
? ? SDA1_L;
? ? I2C_OLED_delay();
? ? SCL1_H;
? ? I2C_OLED_delay();
? ? SCL1_L;
? ? I2C_OLED_delay();
}
?
//以GPIO14為SCL,GPIO15為SDA向OLED模塊傳送不響應位
?
void I2C_OLED_noack(void)//不響應位
{
? ? SCL1_L;
? ? I2C_OLED_delay();
? ? SDA1_H;
? ? I2C_OLED_delay();
? ? SCL1_H;
? ? I2C_OLED_delay();
? ? SCL1_L;
? ? I2C_OLED_delay();
}
?
//接受ACK,有返回1,無返回0
?
bool I2C_OLED_WaitAck(void)//0無ACK,1有ACK
{
? ? EALLOW;
? ? GpioCtrlRegs.GPADIR.bit.GPIO15 = 0;? ? ? ? ? ? //配置GPIO15(SDA)為輸入模式
? ? SCL1_L;
? ? I2C_OLED_delay();
? ? SDA1_H;
? ? I2C_OLED_delay();
? ? SCL1_H;
? ? I2C_OLED_delay();
? ? if(SDA1_read)
? ? {
? ? ? SCL1_L;
? ? ? I2C_OLED_delay();
? ? ? return 0;
? ? }
? ? SCL1_L;
? ? I2C_OLED_delay();
? ? GpioCtrlRegs.GPADIR.bit.GPIO15 = 1;? ? ? ? //配置GPIO15為輸出模式
? ? EDIS;
? ? return 1;
}
?
//判斷是否有ACK,有返回1,無返回0
?
bool Juge_ACK_OLED(void)//判斷有無ACK
{
? ? ?if(!I2C_OLED_WaitAck())
? ? ? ? {
? ? ? ? ?I2C_OLED_stop();
? ? ? ? ? ? return 0;
? ? ? ? }
? ? ?return 1;
}
?
//用IIC協議寫數據SendByte
?
void I2C_OLED_SendByte(uint8 SendByte)? ?//寫入
{
? ? uint8 i=8;
? ? while(i--)
? ? {
? ? ? ? SCL1_L;
? ? ? ? I2C_OLED_delay();
? ? ? if(SendByte&0x80)
? ? ? ? SDA1_H;
? ? ? else
? ? ? ? SDA1_L;
? ? ? ? SendByte=SendByte<<1;
? ? ? ? I2C_OLED_delay();
? ? ? ? SCL1_H;
? ? ? ? I2C_OLED_delay();
? ? }
? ? SCL1_L;
}
?
//向OLED模塊傳送寫命令的要求,0x00,寫命令IIC_Command(OLED模塊的寫時序)
?
bool Write_IIC_OLED_Command(uint8 IIC_Command)//寫命令
{
? ? if(!I2C_OLED_start())
? ? {
? ? ? ? return 0;//總線忙或出錯
? ? }
? ? I2C_OLED_SendByte(OLED_addr);? ? ? ? ? ? //Slave address,SA0=0
? ? if(!Juge_ACK_OLED())
? ? ? ? return 0;
? ? I2C_OLED_SendByte(0x00);? ? //write command
? ? if(!Juge_ACK_OLED())
? ? ? ? return 0;
? ? I2C_OLED_SendByte(IIC_Command);
? ? if(!Juge_ACK_OLED())
? ? ? ? return 0;
? ? I2C_OLED_stop();
? ? return 1;
}
?
//向OLED模塊傳送寫數據的要求,0x40,寫數據IIC_Data(OLED模塊的寫時序)
?
bool Write_IIC_OLED_Data(uint8 IIC_Data)//寫數據
{
? ? if(!I2C_OLED_start())
? ? {
? ? ? ? return 0;//總線忙或出錯
? ? }
? ? I2C_OLED_SendByte(OLED_addr);? ? ? ? ? ? ?//D/C#=0; R/W#=0
? ? if(!Juge_ACK_OLED())
? ? ? ? return 0;
? ? I2C_OLED_SendByte(0x40);? ? ? ? ? ? //write data
? ? if(!Juge_ACK_OLED())
? ? ? ? return 0;
? ? I2C_OLED_SendByte(IIC_Data);
? ? if(!Juge_ACK_OLED())
? ? ? ? return 0;
? ? I2C_OLED_stop();
? ? return 1;
}
?
//選擇是寫數據還是寫命令,cmd==1則寫數據,否則寫命令
?
void OLED_WR_Byte(uint8 dat,int cmd)//寫數據或命令
{
? ? if(cmd)
? ? {
? ? ? ? Write_IIC_OLED_Data(dat);
? ? }
? ? else
? ? {
? ? ? ? Write_IIC_OLED_Command(dat);
? ? }
}
?
//寫入fill_Data整個OLED屏幕
?
void fill_picture(uint8 fill_Data)
{
? ? uint8 m,n;
? ? for(m=0;m<8;m++)
? ? {
? ? ? ? OLED_WR_Byte(page_address+m,0);?
? ? ? ? OLED_WR_Byte(low_column_address,0);? ??
? ? ? ? OLED_WR_Byte(high_column_address,0);? ? ? ??
? ? ? ? for(n=0;n<128;n++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OLED_WR_Byte(fill_Data,1);
? ? ? ? ? ? }
? ? }
}
?
//坐標設置,y為頁地址設置,x為列地址設置
?
void OLED_Set_Pos(int x,int y)//y>=0,y<=7,x>=0,x<=127
{
? ? OLED_WR_Byte(page_address+y,OLED_CMD);//頁地址
? ? OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);//列高地址
? ? OLED_WR_Byte((x&0x0f),OLED_CMD);? ? ? ? ? ? ? ? //列低地址
}
?
?
//開啟OLED顯示
?
void OLED_Display_On(void)
{
? ? OLED_WR_Byte(SET_DCDC,OLED_CMD);? //SET DCDC命令
? ? OLED_WR_Byte(0X14,OLED_CMD);? //DCDC ON
? ? OLED_WR_Byte(display_on,OLED_CMD);? //DISPLAY ON
}
?
//關閉OLED顯示
?
void OLED_Display_Off(void)
{
? ? OLED_WR_Byte(SET_DCDC,OLED_CMD);? //SET DCDC命令
? ? OLED_WR_Byte(0X10,OLED_CMD);? //DCDC OFF
? ? OLED_WR_Byte(display_off,OLED_CMD);? //DISPLAY OFF
}
?
?
//清屏
?
void OLED_Clear(void)
{
? ? uint8 i,n;
? ? for(i=0;i<8;i++)
? ? {
? ? ? ? OLED_WR_Byte (page_address+i,OLED_CMD);? ? //設置頁地址(0~7)
? ? ? ? OLED_WR_Byte (low_column_address,OLED_CMD);? ? ? //設置顯示位置—列低地址
? ? ? ? OLED_WR_Byte (high_column_address,OLED_CMD);? ? ? //設置顯示位置—列高地址
? ? ? ? for(n=0;n<128;n++)
? ? ? ? {
? ? ? ? ? ? OLED_WR_Byte(0,OLED_DATA);
? ? ? ? ? ? I2C_OLED_delay_more();
? ? ? ? }
? ? }
}
?
//全亮,將屏幕全變亮
?
void OLED_On(void)
{
? ? uint8 i,n;
? ? for(i=0;i<8;i++)
? ? {
? ? ? ? OLED_WR_Byte (page_address+i,OLED_CMD);? ? //設置頁地址(0~7)
? ? ? ? OLED_WR_Byte (low_column_address,OLED_CMD);? ? ? //設置顯示位置—列低地址
? ? ? ? OLED_WR_Byte (high_column_address,OLED_CMD);? ? ? //設置顯示位置—列高地址
? ? ? ? for(n=0;n<128;n++)
? ? ? ? {
? ? ? ? ? ? OLED_WR_Byte(0xff,OLED_DATA);
? ? ? ? ? ? I2C_OLED_delay_more();
? ? ? ? }
? ? }?
}
?
//在指定位置顯示一個字符
?
void OLED_ShowChar(int x,int y,uint8 chr,int Char_Size)
{
? ? ? ? unsigned char c=0,i=0;
? ? ? ? c=chr;
? ? ? ? if(x>Max_Column-1)
? ? ? ? {
? ? ? ? ? ? x=0;
? ? ? ? ? ? y=y+2;
? ? ? ? }
? ? ? ? if(Char_Size ==16)
? ? ? ? {
? ? ? ? ? ? OLED_Set_Pos(x,y);
? ? ? ? ? ? for(i=0;i<8;i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
? ? ? ? ? ? ? ? I2C_OLED_delay_more();
? ? ? ? ? ? }
? ? ? ? ? ? OLED_Set_Pos(x,y+1);
? ? ? ? ? ? for(i=0;i<8;i++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
? ? ? ? ? ? ? ? I2C_OLED_delay_more();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? OLED_Set_Pos(x,y);
? ? ? ? ? ? for(i=0;i<6;i++)
? ? ? ? ? ? ? ? OLED_WR_Byte(F6x8[c][i],OLED_DATA);
? ? ? ? }
}
?
//指數函數,m^n
?
uint32 oled_pow(int m,int n)
{
? ? uint32 result=1;
? ? while(n--)
? ? ? ? result*=m;
? ? return result;
}
?
//在指定位置(x,y)顯示一串數字
?
void OLED_ShowNum(int x,int y,uint32 num,int len,int size2)
{
? ? int t,temp;
? ? int enshow=0;
? ? for(t=0;t;t++)<>
? ? {
? ? ? ? temp=(num/oled_pow(10,len-t-1))%10;
? ? ? ? if(enshow==0&&t<(len-1))
? ? ? ? {
? ? ? ? ? ? if(temp==0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? OLED_ShowChar(x+(size2/2)*t,y,0,size2);
? ? ? ? ? ? ? ? I2C_OLED_delay_more();
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? }else enshow=1;
? ? ? ? }
? ? ? ? ?OLED_ShowChar(x+(size2/2)*t,y,temp,size2);
? ? ? ? I2C_OLED_delay_more();
? ? }
}
?
//在指定位置(x,y)顯示漢字
?
void OLED_ShowCHinese(int x,int y,uint8 no)
{
? ? uint8 t;
? ? OLED_Set_Pos(x,y);
? ? for(t=0;t<16;t++)
? ? {
? ? ? ? OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
? ? ? ? I2C_OLED_delay_more();
? ? }
? ? OLED_Set_Pos(x,y+1);
? ? for(t=0;t<16;t++)
? ? {
? ? ? ? OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
? ? ? ? I2C_OLED_delay_more();
? ? }
}
?
?
void OLED_Init(void)
{
? ? OLED_WR_Byte(display_off,OLED_CMD);//--display off
? ? OLED_WR_Byte(low_column_address,OLED_CMD);//---set low column address
? ? OLED_WR_Byte(high_column_address,OLED_CMD);//---set high column address
? ? OLED_WR_Byte(start_line,OLED_CMD);//--set start line address
? ? OLED_WR_Byte(page_address,OLED_CMD);//--set page address
? ? OLED_WR_Byte(contract_control,OLED_CMD); // contract control
? ? OLED_WR_Byte(0xFF,OLED_CMD);//--128
? ? OLED_WR_Byte(segment_remap,OLED_CMD);//--set segment remap
? ? OLED_WR_Byte(normal_dispaly,OLED_CMD);//--normal / reverse
? ? OLED_WR_Byte(multiplex_ratio,OLED_CMD);//--set multiplex ratio(1 to 64)
? ? OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
? ? OLED_WR_Byte(scan_direction,OLED_CMD);//Com scan direction
? ? OLED_WR_Byte(display_offset,OLED_CMD);//-set display offset
? ? OLED_WR_Byte(0x00,OLED_CMD);//復位
?
? ? OLED_WR_Byte(clock_division,OLED_CMD);//set osc division
? ? OLED_WR_Byte(0x80,OLED_CMD);//
?
? ? OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
? ? OLED_WR_Byte(0x05,OLED_CMD);//
?
? ? OLED_WR_Byte(Pre_Charge_Period,OLED_CMD);//Set Pre-Charge Period
? ? OLED_WR_Byte(0xF1,OLED_CMD);//
?
? ? OLED_WR_Byte(pin_configuartion,OLED_CMD);//set com pin configuartion
? ? OLED_WR_Byte(0x12,OLED_CMD);//復位
?
? ? OLED_WR_Byte(0x20,OLED_CMD);
? ? OLED_WR_Byte(0x02,OLED_CMD);
?
? ? OLED_WR_Byte(Vcomh,OLED_CMD);//set Vcomh
? ? OLED_WR_Byte(0x30,OLED_CMD);//復位
?
? ? OLED_WR_Byte(SET_DCDC,OLED_CMD);//set charge pump enable
? ? OLED_WR_Byte(0x14,OLED_CMD);//DCDC ON
?
? ? OLED_WR_Byte(display_on,OLED_CMD);//--turn on oled panel
}
?
IIC_OLED.h
#define OLED_CMD? 0? ? //寫命令
#define OLED_DATA 1? ? //寫數據
?
#define OLED_addr 0x78
#define display_off? ? 0xAE//關顯示
#define low_column_address 0x00//列低地址
#define high_column_address 0x10 //設置列高地址
#define start_line 0x40 //設置起始行
#define page_address 0xB0 //起始頁
#define contract_control 0x81 //對比度設置
#define segment_remap? 0xA1
#define normal_dispaly 0xA6 //普通顯示
#define multiplex_ratio 0xA8
#define scan_direction 0xC8? ?//掃描
#define display_offset 0xD3
#define clock_division 0xD5
#define Pre_Charge_Period 0xD9
#define pin_configuartion 0xDA
#define Vcomh 0xDB
#define display_on 0xAF
#define SET_DCDC 0X8D
?
#define SCL1_H GpioDataRegs.GPASET.bit.GPIO14=1
#define SCL1_L GpioDataRegs.GPACLEAR.bit.GPIO14=1
#define SDA1_H? ? ?GpioDataRegs.GPASET.bit.GPIO15=1
#define SDA1_L? GpioDataRegs.GPACLEAR.bit.GPIO15=1
?
#define SCL1_read? ? ?GpioDataRegs.GPADAT.bit.GPIO14
#define SDA1_read? ? ?GpioDataRegs.GPADAT.bit.GPIO15
?
#define SIZE 16
#define Max_Column? ? 128
#define Max_Row? ? ? ? 64
?
void I2C_GPIO_Config_OLED(void);
int Data_len(int data);
void I2C_OLED_delay(void);
void I2C_OLED_delay_more(void);
bool I2C_OLED_start(void);
void I2C_OLED_stop(void);
void I2C_OLED_ack(void);
void I2C_OLED_noack(void);
bool I2C_OLED_WaitAck(void);
bool Juge_ACK_OLED(void);
void I2C_OLED_SendByte(uint8 SendByte);
bool Write_IIC_OLED_Command(uint8 IIC_Command);
bool Write_IIC_OLED_Data(uint8 IIC_Data);
void OLED_WR_Byte(uint8 dat,int cmd);
void fill_picture(uint8 fill_Data);
void OLED_Set_Pos(int x,int y);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Clear(void);
void OLED_On(void);
void OLED_ShowChar(int x,int y,uint8 chr,int Char_Size);
uint32 oled_pow(int m,int n);
void OLED_ShowNum(int x,int y,uint32 num,int len,int size2);
void OLED_ShowCHinese(int x,int y,uint8 no);
void OLED_Init(void);
?
main.c
int main(void)
{
? ? int data;
? ? EALLOW;
? ? P_SysCtrlRegs->INTOSC1TRIM.bit.COARSETRIM = 0;
? ? P_SysCtrlRegs->INTOSC2TRIM.bit.COARSETRIM= 0;
? ? EDIS;
? ? InitSysCtrl();
? ? DINT;
? ? InitPieCtrl();
? ? IER_DISABLE(0xffff);
? ? IFR_DISABLE(0xffff);
? ? InitPieVectTable();
? ? I2C_GPIO_Config_OLED();
? ? OLED_Init();
? ? EINT;
? ? OLED_Clear();
? ? OLED_ShowCHinese(28,0,0);
? ? OLED_ShowCHinese(44,0,1);
? ? OLED_ShowCHinese(60,0,2);
? ? OLED_ShowCHinese(76,0,3);
? ? OLED_ShowChar(16,4,16,16);
? ? OLED_ShowChar(24,4,17,16);
? ? OLED_ShowChar(32,4,16,16);
? ? OLED_ShowChar(40,4,13,16);
? ? OLED_ShowChar(48,4,22,16);
? ? OLED_ShowChar(56,4,17,16);
? ? OLED_ShowChar(64,4,25,16);
? ? OLED_ShowChar(72,4,19,16);
? ? OLED_ShowChar(80,4,20,16);
? ? OLED_ShowChar(88,4,21,16);
? ? OLED_ShowChar(96,4,22,16);
? ? OLED_ShowChar(104,4,17,16);
? ? while(1){}
? ? return 0;
}
?
接線以及顯示效果:
?
?
?
詳細例程請參考
?
鏈接:https://pan.baidu.com/s/1C8I7OSgjKifGP8UX-U6Tmg?
提取碼:8034
————————————————
特別鳴謝 原創作者? 博主「晟逸軒」
評論
查看更多