- void OLED_Init(void)
- {
- delay_ms(1000);
-
- WriteCmd(0xAE);//--turn off oled panel
- WriteCmd(0x00);//---set low column address
- WriteCmd(0x10);//---set high column address
- WriteCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
- WriteCmd(0x81);//--set contrast control register
- WriteCmd(0xCF);// Set SEG Output Current Brightness
- WriteCmd(0xA1);//--Set SEG/Column Mapping 0xa0���ҷ��� 0xa1����
- WriteCmd(0xC8);//Set COM/Row Scan Direction 0xc0���·��� 0xc8����
- WriteCmd(0xA6);//--set normal display
- WriteCmd(0xA8);//--set multiplex ratio(1 to 64)
- WriteCmd(0x3f);//--1/64 duty
- WriteCmd(0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
- WriteCmd(0x00);//-not offset
- WriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
- WriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
- WriteCmd(0xD9);//--set pre-charge period
- WriteCmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
- WriteCmd(0xDA);//--set com pins hardware configuration
- WriteCmd(0x12);
- WriteCmd(0xDB);//--set vcomh
- WriteCmd(0x40);//Set VCOM Deselect Level
- WriteCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
- WriteCmd(0x02);//
- WriteCmd(0x8D);//--set Charge Pump enable/disable
- WriteCmd(0x14);//--set(0x10) disable
- WriteCmd(0xA4);// Disable Entire Display On (0xa4/0xa5)
- WriteCmd(0xA6);// Disable Inverse Display On (0xa6/a7)
- OLED_Clear();
- WriteCmd(0xAF); //Set display on added by sensoryoung
- delay_ms(200);
- }
然后刷新屏幕:
- void OLED_Refresh(void)
- {
- uint8_t i,n;
- for(i=0;i<8;i++)
- {
- WriteCmd(0xb0+i);
- WriteCmd(0x00);
- WriteCmd(0x10);
- for(n=0;n<128;n++)
- {
- WriteDat(OLED_GRAM[n][i]);
- }
- }
- }
这里有关键的两个函数:WriteCmd 与 WriteDat。实现如下:
- /**************************************************************
- Prototype : void WriteCmd(uint8_t IIC_Command)
- Parameters : IIC_Command
- return : none
- Description : 写命令(通过HAL_I2C_WriteByte中的HAL_I2C_Master_Transmit
- 向0x00写入命令)
- ***************************************************************/
- void WriteCmd(uint8_t IIC_Command)
- {
- HAL_I2C_WriteByte(0x00, IIC_Command);
- }
- /**************************************************************
- Prototype : void WriteDat(uint8_t IIC_Data)
- Parameters : IIC_Data
- return : none
- Description : 写数据(通过HAL_I2C_WriteByte中的HAL_I2C_Master_Transmit
- 向0x40写入数据)
- ***************************************************************/
- void WriteDat(uint8_t IIC_Data)
- {
- HAL_I2C_WriteByte(0x40, IIC_Data);
在调用I2C模块向总线发送数据之前,封装了一下:
- /***************************************************
- I2C总线传出数据函数:
- addr : 要写入的地址(OLED的地址一般为0x40;指令地址为0x00)
- data : 要写入的数据
- ***************************************************/
- void HAL_I2C_WriteByte(uint8_t addr,uint8_t data)
- {
- //uint8_t TxData[2] = {addr,data};
- uint8_t TxData[2];
- TxData[0] = addr;
- TxData[1] = data;
- if((i2c_status = i2c_master_transmit(&hi2cx, 0X78, TxData, 2, I2C_TIMEOUT)) != I2C_OK)
- {
- error_handler(i2c_status);
- }
- }
实际效果还不错,完整代码如下:
- /*Reference: https://blog.csdn.net/Reasally/article/details/126789505*/
- #include "oled.h"
- #include "stdlib.h"
- #include "oledfont.h"
- //For ARTEY ATL021
- extern void error_handler(uint32_t error_code);
- extern i2c_handle_type hi2cx;
- extern i2c_status_type i2c_status;
- #define I2C_TIMEOUT 0xFFFFFFF
- uint8_t OLED_GRAM[144][8];
- //���Ժ���
- void OLED_ColorTurn(uint8_t i)
- {
- if(i==0)
- {
- WriteCmd(0xA6);
- }
- if(i==1)
- {
- WriteCmd(0xA7);
- }
- }
- //��Ļ��ת180��
- void OLED_DisplayTurn(uint8_t i)
- {
- if(i==0)
- {
- WriteCmd(0xC8);
- WriteCmd(0xA1);
- }
- if(i==1)
- {
- WriteCmd(0xC0);
- WriteCmd(0xA0);
- }
- }
- //��ʱ
- void IIC_delay(void)
- {
- uint16_t t=300;
- while(t--);
- }
- /***************************************************
- I2C总线传出数据函数:
- addr : 要写入的地址(OLED的地址一般为0x40;指令地址为0x00)
- data : 要写入的数据
- ***************************************************/
- void HAL_I2C_WriteByte(uint8_t addr,uint8_t data)
- {
- //uint8_t TxData[2] = {addr,data};
- uint8_t TxData[2];
- TxData[0] = addr;
- TxData[1] = data;
- if((i2c_status = i2c_master_transmit(&hi2cx, 0X78, TxData, 2, I2C_TIMEOUT)) != I2C_OK)
- {
- error_handler(i2c_status);
- }
- }
- /**************************************************************
- Prototype : void WriteCmd(uint8_t IIC_Command)
- Parameters : IIC_Command
- return : none
- Description : 写命令(通过HAL_I2C_WriteByte中的HAL_I2C_Master_Transmit
- 向0x00写入命令)
- ***************************************************************/
- void WriteCmd(uint8_t IIC_Command)
- {
- HAL_I2C_WriteByte(0x00, IIC_Command);
- }
- /**************************************************************
- Prototype : void WriteDat(uint8_t IIC_Data)
- Parameters : IIC_Data
- return : none
- Description : 写数据(通过HAL_I2C_WriteByte中的HAL_I2C_Master_Transmit
- 向0x40写入数据)
- ***************************************************************/
- void WriteDat(uint8_t IIC_Data)
- {
- HAL_I2C_WriteByte(0x40, IIC_Data);
- }
- //����һ���ֽ�
- //mode:����/�����־ 0,��ʾ����;1,��ʾ����;
- void OLED_WR_Byte(uint8_t dat,uint8_t mode)
- {
-
- if(mode){
- //Send_Byte(0x40);
- WriteDat(dat);
- }
- else{
- //Send_Byte(0x00);
- WriteCmd(dat);
- }
- //Send_Byte(dat);
- //I2C_Stop();
- }
- //����OLED��ʾ
- void OLED_DisPlay_On(void)
- {
- WriteCmd(0x8D);
- WriteCmd(0x14);
- WriteCmd(0xAF);
- }
- //�ر�OLED��ʾ
- void OLED_DisPlay_Off(void)
- {
- WriteCmd(0x8D);
- WriteCmd(0x10);
- WriteCmd(0xAE);
- }
- //�����Դ浽OLED
- void OLED_Refresh(void)
- {
- uint8_t i,n;
- for(i=0;i<8;i++)
- {
- WriteCmd(0xb0+i);
- WriteCmd(0x00);
- WriteCmd(0x10);
- for(n=0;n<128;n++)
- {
- WriteDat(OLED_GRAM[n][i]);
- }
- }
- }
- //��������
- void OLED_Clear(void)
- {
- uint8_t i,n;
- for(i=0;i<8;i++)
- {
- for(n=0;n<128;n++)
- {
- OLED_GRAM[n][i]=0;//�����������
- }
- }
- }
- //����
- //x:0~127
- //y:0~63
- //t:1 ��� 0,���
- void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t)
- {
- uint8_t i,m,n;
- i=y/8;
- m=y%8;
- n=1<<m;
- if(t){OLED_GRAM[x][i]|=n;}
- else
- {
- OLED_GRAM[x][i]=~OLED_GRAM[x][i];
- OLED_GRAM[x][i]|=n;
- OLED_GRAM[x][i]=~OLED_GRAM[x][i];
- }
- }
- //����
- //x1,y1:�������
- //x2,y2:��������
- void OLED_DrawLine(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t mode)
- {
- uint16_t t;
- int xerr=0,yerr=0,delta_x,delta_y,distance;
- int incx,incy,uRow,uCol;
- delta_x=x2-x1; //������������
- delta_y=y2-y1;
- uRow=x1;//�����������
- uCol=y1;
- if(delta_x>0)incx=1; //���õ�������
- else if (delta_x==0)incx=0;//��ֱ��
- else {incx=-1;delta_x=-delta_x;}
- if(delta_y>0)incy=1;
- else if (delta_y==0)incy=0;//ˮƽ��
- else {incy=-1;delta_y=-delta_x;}
- if(delta_x>delta_y)distance=delta_x; //ѡȡ��������������
- else distance=delta_y;
- for(t=0;t<distance+1;t++)
- {
- OLED_DrawPoint(uRow,uCol,mode);//����
- xerr+=delta_x;
- yerr+=delta_y;
- if(xerr>distance)
- {
- xerr-=distance;
- uRow+=incx;
- }
- if(yerr>distance)
- {
- yerr-=distance;
- uCol+=incy;
- }
- }
- }
- //x,y:Բ������
- //r:Բ�İ뾶
- void OLED_DrawCircle(uint8_t x,uint8_t y,uint8_t r)
- {
- int a, b,num;
- a = 0;
- b = r;
- while(2 * b * b >= r * r)
- {
- OLED_DrawPoint(x + a, y - b,1);
- OLED_DrawPoint(x - a, y - b,1);
- OLED_DrawPoint(x - a, y + b,1);
- OLED_DrawPoint(x + a, y + b,1);
-
- OLED_DrawPoint(x + b, y + a,1);
- OLED_DrawPoint(x + b, y - a,1);
- OLED_DrawPoint(x - b, y - a,1);
- OLED_DrawPoint(x - b, y + a,1);
-
- a++;
- num = (a * a + b * b) - r*r;//���㻭�ĵ���Բ�ĵľ���
- if(num > 0)
- {
- b--;
- a--;
- }
- }
- }
- //��ָ��λ����ʾһ���ַ�,���������ַ�
- //x:0~127
- //y:0~63
- //size1:ѡ������ 6x8/6x12/8x16/12x24
- //mode:0,��ɫ��ʾ;1,������ʾ
- void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t size1,uint8_t mode)
- {
- uint8_t i,m,temp,size2,chr1;
- uint8_t x0=x,y0=y;
- if(size1==8)size2=6;
- else size2=(size1/8+((size1%8)?1:0))*(size1/2); //�õ�����һ���ַ���Ӧ������ռ���ֽ���
- chr1=chr-' '; //����ƫ�ƺ��ֵ
- for(i=0;i<size2;i++)
- {
- if(size1==8)
- {temp=asc2_0806[chr1][i];} //����0806����
- else if(size1==12)
- {temp=asc2_1206[chr1][i];} //����1206����
- else if(size1==16)
- {temp=asc2_1608[chr1][i];} //����1608����
- else if(size1==24)
- {temp=asc2_2412[chr1][i];} //����2412����
- else return;
- for(m=0;m<8;m++)
- {
- if(temp&0x01)OLED_DrawPoint(x,y,mode);
- else OLED_DrawPoint(x,y,!mode);
- temp>>=1;
- y++;
- }
- x++;
- if((size1!=8)&&((x-x0)==size1/2))
- {x=x0;y0=y0+8;}
- y=y0;
- }
- }
- //��ʾ�ַ���
- //x,y:�������
- //size1:�����С
- //*chr:�ַ�����ʼ��ַ
- //mode:0,��ɫ��ʾ;1,������ʾ
- void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t size1,uint8_t mode)
- {
- while((*chr>=' ')&&(*chr<='~'))//�ж��Dz��ǷǷ��ַ�!
- {
- OLED_ShowChar(x,y,*chr,size1,mode);
- if(size1==8)x+=6;
- else x+=size1/2;
- chr++;
- }
- }
- //m^n
- uint32_t OLED_Pow(uint8_t m,uint8_t n)
- {
- uint32_t result=1;
- while(n--)
- {
- result*=m;
- }
- return result;
- }
- //��ʾ����
- //x,y :�������
- //num :Ҫ��ʾ������
- //len :���ֵ�λ��
- //size:�����С
- //mode:0,��ɫ��ʾ;1,������ʾ
- void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size1,uint8_t mode)
- {
- uint8_t t,temp,m=0;
- if(size1==8)m=2;
- for(t=0;t<len;t++)
- {
- temp=(num/OLED_Pow(10,len-t-1))%10;
- if(temp==0)
- {
- OLED_ShowChar(x+(size1/2+m)*t,y,'0',size1,mode);
- }
- else
- {
- OLED_ShowChar(x+(size1/2+m)*t,y,temp+'0',size1,mode);
- }
- }
- }
- //��ʾ����
- //x,y:�������
- //num:���ֶ�Ӧ�����
- //mode:0,��ɫ��ʾ;1,������ʾ
- void OLED_ShowChinese(uint8_t x,uint8_t y,uint8_t num,uint8_t size1,uint8_t mode)
- {
- uint8_t m,temp;
- uint8_t x0=x,y0=y;
- uint16_t i,size3=(size1/8+((size1%8)?1:0))*size1; //�õ�����һ���ַ���Ӧ������ռ���ֽ���
- for(i=0;i<size3;i++)
- {
- if(size1==16)
- {temp=Hzk1[num][i];}//����16*16����
- else if(size1==24)
- {temp=Hzk2[num][i];}//����24*24����
- else if(size1==32)
- {temp=Hzk3[num][i];}//����32*32����
- else if(size1==64)
- {temp=Hzk4[num][i];}//����64*64����
- else return;
- for(m=0;m<8;m++)
- {
- if(temp&0x01)OLED_DrawPoint(x,y,mode);
- else OLED_DrawPoint(x,y,!mode);
- temp>>=1;
- y++;
- }
- x++;
- if((x-x0)==size1)
- {x=x0;y0=y0+8;}
- y=y0;
- }
- }
- //num ��ʾ���ֵĸ���
- //space ÿһ����ʾ�ļ��
- //mode:0,��ɫ��ʾ;1,������ʾ
- void OLED_ScrollDisplay(uint8_t num,uint8_t space,uint8_t mode)
- {
- uint8_t i,n,t=0,m=0,r;
- while(1)
- {
- if(m==0)
- {
- OLED_ShowChinese(128,24,t,16,mode); //д��һ�����ֱ�����OLED_GRAM[][]������
- t++;
- }
- if(t==num)
- {
- for(r=0;r<16*space;r++) //��ʾ���
- {
- for(i=1;i<144;i++)
- {
- for(n=0;n<8;n++)
- {
- OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
- }
- }
- OLED_Refresh();
- }
- t=0;
- }
- m++;
- if(m==16){m=0;}
- for(i=1;i<144;i++) //ʵ������
- {
- for(n=0;n<8;n++)
- {
- OLED_GRAM[i-1][n]=OLED_GRAM[i][n];
- }
- }
- OLED_Refresh();
- }
- }
- //x,y���������
- //sizex,sizey,ͼƬ����
- //BMP[]��Ҫд���ͼƬ����
- //mode:0,��ɫ��ʾ;1,������ʾ
- void OLED_ShowPicture(uint8_t x,uint8_t y,uint8_t sizex,uint8_t sizey,uint8_t BMP[],uint8_t mode)
- {
- uint16_t j=0;
- uint8_t i,n,temp,m;
- uint8_t x0=x,y0=y;
- sizey=sizey/8+((sizey%8)?1:0);
- for(n=0;n<sizey;n++)
- {
- for(i=0;i<sizex;i++)
- {
- temp=BMP[j];
- j++;
- for(m=0;m<8;m++)
- {
- if(temp&0x01)OLED_DrawPoint(x,y,mode);
- else OLED_DrawPoint(x,y,!mode);
- temp>>=1;
- y++;
- }
- x++;
- if((x-x0)==sizex)
- {
- x=x0;
- y0=y0+8;
- }
- y=y0;
- }
- }
- }
- //OLED�ij�ʼ��
- void OLED_Init(void)
- {
- delay_ms(1000);
-
- WriteCmd(0xAE);//--turn off oled panel
- WriteCmd(0x00);//---set low column address
- WriteCmd(0x10);//---set high column address
- WriteCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
- WriteCmd(0x81);//--set contrast control register
- WriteCmd(0xCF);// Set SEG Output Current Brightness
- WriteCmd(0xA1);//--Set SEG/Column Mapping 0xa0���ҷ��� 0xa1����
- WriteCmd(0xC8);//Set COM/Row Scan Direction 0xc0���·��� 0xc8����
- WriteCmd(0xA6);//--set normal display
- WriteCmd(0xA8);//--set multiplex ratio(1 to 64)
- WriteCmd(0x3f);//--1/64 duty
- WriteCmd(0xD3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
- WriteCmd(0x00);//-not offset
- WriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
- WriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
- WriteCmd(0xD9);//--set pre-charge period
- WriteCmd(0xF1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
- WriteCmd(0xDA);//--set com pins hardware configuration
- WriteCmd(0x12);
- WriteCmd(0xDB);//--set vcomh
- WriteCmd(0x40);//Set VCOM Deselect Level
- WriteCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
- WriteCmd(0x02);//
- WriteCmd(0x8D);//--set Charge Pump enable/disable
- WriteCmd(0x14);//--set(0x10) disable
- WriteCmd(0xA4);// Disable Entire Display On (0xa4/0xa5)
- WriteCmd(0xA6);// Disable Inverse Display On (0xa6/a7)
- OLED_Clear();
- WriteCmd(0xAF); //Set display on added by sensoryoung
- delay_ms(200);
- }