` 上次帖子里有提到,wiringPI已经写好了IIC、SPI等外设的驱动,接下来的实验从IIC开始吧
之前已经用 单片机驱动过OLED,底层IIC函数如下:
- void WriteCmd(unsigned char I2C_Command)//写命令
- {
- I2C_WriteByte(0x00, I2C_Command);
- }
- void WriteDat(unsigned char I2C_Data)//写数据
- {
- I2C_WriteByte(0x40, I2C_Data);
- }
复制代码
屏幕的所有操作都是通过这两个函数控制的,所以这里我们只要把这两个函数改成nanoPi的就可以了
- void WriteCmd(unsigned char I2C_Command)//写命令
- {
- // I2C_WriteByte(0x00, I2C_Command);
- wiringPiI2CWriteReg8(fd, 0x00, I2C_Command);
- }
- void WriteDat(unsigned char I2C_Data)//写数据
- {
- // I2C_WriteByte(0x40, I2C_Data);
- wiringPiI2CWriteReg8(fd, 0x40, I2C_Data);
- }
复制代码
wiringPiI2CWriteReg8函数在wiringPiI2C.c中可以找到;
剩下的就是普通OLED的寄存器操作了
完整代码:
- /***
- Copyright (c) 2018
- All rights reserved.
- File name :oled_iic_main.c
- file identification :
- Subject :Say something about the file
- Current Version :V1.0.0
- Author :Hacker
- Date :
- Instead Version :
- Author :Hacker
- Date :
- ***/
- #include
- #include
- #include "wiringPiI2C.h"
- #include "codetab.h"
- #include "pcf8574.h"
- // LED Pin - wiringPi pin 0 is BCM_GPIO 17.
- #define OLED_ADDRESS 0x3C //通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78
- int fd = 0;
- void WriteCmd(unsigned char I2C_Command)//写命令
- {
- // I2C_WriteByte(0x00, I2C_Command);
- wiringPiI2CWriteReg8(fd, 0x00, I2C_Command);
- }
- void WriteDat(unsigned char I2C_Data)//写数据
- {
- // I2C_WriteByte(0x40, I2C_Data);
- wiringPiI2CWriteReg8(fd, 0x40, I2C_Data);
- }
- void OLED_Init(void)
- {
- delay(100); //这里的延时很重要
-
- WriteCmd(0xAE); //display off
- WriteCmd(0x20); //Set Memory Addressing Mode
- WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
- WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
- WriteCmd(0xc8); //Set COM Output Scan Direction
- WriteCmd(0x00); //---set low column address
- WriteCmd(0x10); //---set high column address
- WriteCmd(0x40); //--set start line address
- WriteCmd(0x81); //--set contrast control register
- WriteCmd(0xff); //亮度调节 0x00~0xff
- WriteCmd(0xa1); //--set segment re-map 0 to 127
- WriteCmd(0xa6); //--set normal display
- WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
- WriteCmd(0x3F); //
- WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
- WriteCmd(0xd3); //-set display offset
- WriteCmd(0x00); //-not offset
- WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
- WriteCmd(0xf0); //--set divide ratio
- WriteCmd(0xd9); //--set pre-charge period
- WriteCmd(0x22); //
- WriteCmd(0xda); //--set com pins hardware configuration
- WriteCmd(0x12);
- WriteCmd(0xdb); //--set vcomh
- WriteCmd(0x20); //0x20,0.77xVcc
- WriteCmd(0x8d); //--set DC-DC enable
- WriteCmd(0x14); //
- WriteCmd(0xaf); //--turn on oled panel
- }
- void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
- {
- WriteCmd(0xb0+y);
- WriteCmd(((x&0xf0)>>4)|0x10);
- WriteCmd((x&0x0f)|0x01);
- }
- void OLED_Fill(unsigned char fill_Data)//全屏填充
- {
- unsigned char m,n;
- for(m=0;m<8;m++)
- {
- WriteCmd(0xb0+m); //page0-page1
- WriteCmd(0x00); //low column start address
- WriteCmd(0x10); //high column start address
- for(n=0;n<128;n++)
- {
- WriteDat(fill_Data);
- }
- }
- }
- void OLED_CLS(void)//清屏
- {
- OLED_Fill(0x00);
- }
- //--------------------------------------------------------------
- // Prototype : void OLED_ON(void)
- // Calls :
- // Parameters : none
- // Description : 将OLED从休眠中唤醒
- //--------------------------------------------------------------
- void OLED_ON(void)
- {
- WriteCmd(0X8D); //设置电荷泵
- WriteCmd(0X14); //开启电荷泵
- WriteCmd(0XAF); //OLED唤醒
- }
- //--------------------------------------------------------------
- // Prototype : void OLED_OFF(void)
- // Calls :
- // Parameters : none
- // Description : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
- //--------------------------------------------------------------
- void OLED_OFF(void)
- {
- WriteCmd(0X8D); //设置电荷泵
- WriteCmd(0X10); //关闭电荷泵
- WriteCmd(0XAE); //OLED休眠
- }
- //--------------------------------------------------------------
- // Prototype : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
- // Calls :
- // Parameters : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
- // Description : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
- //--------------------------------------------------------------
- void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
- {
- unsigned char c = 0,i = 0,j = 0;
- switch(TextSize)
- {
- case 1:
- {
- while(ch[j] != '\0')
- {
- c = ch[j] - 32;
- if(x > 126)
- {
- x = 0;
- y++;
- }
- OLED_SetPos(x,y);
- for(i=0;i<6;i++)
- WriteDat(F6x8[c][i]);
- x += 6;
- j++;
- }
- }break;
- case 2:
- {
- while(ch[j] != '\0')
- {
- c = ch[j] - 32;
- if(x > 120)
- {
- x = 0;
- y++;
- }
- OLED_SetPos(x,y);
- for(i=0;i<8;i++)
- WriteDat(F8X16[c*16+i]);
- OLED_SetPos(x,y+1);
- for(i=0;i<8;i++)
- WriteDat(F8X16[c*16+i+8]);
- x += 8;
- j++;
- }
- }break;
- }
- }
- //--------------------------------------------------------------
- // Prototype : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
- // Calls :
- // Parameters : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
- // Description : 显示codetab.h中的汉字,16*16点阵
- //--------------------------------------------------------------
- void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
- {
- unsigned char wm=0;
- unsigned int adder=32*N;
- OLED_SetPos(x , y);
- for(wm = 0;wm < 16;wm++)
- {
- WriteDat(F16x16[adder]);
- adder += 1;
- }
- OLED_SetPos(x,y + 1);
- for(wm = 0;wm < 16;wm++)
- {
- WriteDat(F16x16[adder]);
- adder += 1;
- }
- }
- //--------------------------------------------------------------
- // Prototype : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
- // Calls :
- // Parameters : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
- // Description : 显示BMP位图
- //--------------------------------------------------------------
- void OLED_DrawBMP(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
- {
- OLED_SetPos(x0,y);
- for(x=x0;x
- {
- WriteDat(BMP[j++]);
- }
- }
- }
- int main (void)
- {
- printf ("nanoPi oled
- ") ;
- fd = wiringPiI2CSetup(OLED_ADDRESS);
- printf ("fd = %d
- ", fd) ;
- OLED_Init();
- delay(100);
-
- OLED_Fill(0xa0);
- delay(500);
- OLED_Fill(0x60);
- delay(500);
- OLED_Fill(0);
- delay(500);
- OLED_ShowStr(10, 2, "Haha, nanoPi", 1);
- OLED_ShowStr(10, 3, "Haha, nanoPi", 2);
- printf ("test end
- ") ;
- return 0 ;
- }
复制代码
保存好之后,执行编译
- gcc -g -o oled_iic_main oled_iic_main.c -lwiringPi -lpthread
复制代码
执行
=======================================================
实验难度不大,不过过程却并不简单,实现这个需要很多准本工作 1、首先需要使能IIC,在npi-config中操作 2、由于库函数不同单片机中IIC设备地址是8位,然而本库函数是7位 设备地址的问题排查花了不少时间,这里采用了I2C-tools,经过i2c-tetect检测到设备地址,显示0x3C ,根据这个修改了程序中的设备地址,问题解决了
实验过程比实验结果精彩很多
`
|