1回答

1收藏

【赚周年币】+技术贴+Fireduino的IIC接口学习(二)

#线上活动 #线上活动 2443 人阅读 | 1 人回复 | 2016-12-27

本帖最后由 9robot 于 2016-12-27 13:39 编辑

      了解了Fireduino有关IIC接口的基本知识就可以开始使用了,第一次使用Arduino环境下的IIC接口,还不太熟悉,不过使用之后感觉Arduino环境确实简化了IIC的操作。简单的几个函数就可以完成对IIC器件的操作,这次使用的是IIC接口的OLED显示屏,由于只是向OLED模块写数据,没有往回读数据的过程,所以只使用了以下几个函数:
Wire.begin();  //初始化I2C
Wire.beginTransmission(OLED_ADDRESS);
Wire.write(addr);
Wire.write(data);
Wire.endTransmission();

在使用这几个函数前要包含  Wire.h文件
  1. #include "Wire.h"
  2. #include "oledfont.h"
  3. #define OLED_ADDRESS  (0x78>>1) //默认0x78

  4. void setup() {
  5.   Serial.begin(9600);
  6.   delay(100);
  7.   pinMode(3, OUTPUT);
  8. digitalWrite(3,HIGH);
  9.   Serial.println("setup");  
  10.   Wire.begin();  //初始化I2C
  11.   delay(100);
  12.   OLED_Init();

  13. }

  14. void loop() {
  15. char tab[]={"Fireduino"};
  16. OLED_ClearScr();
  17. //LCD_P6x8Str(0,0,tab);
  18. //LCD_P6x8Str(0,1,tab);
  19. LCD_P8x16Str(0,0,tab);
  20. while(1)
  21. {
  22.   digitalWrite(3,HIGH);
  23.   delay(1000);
  24.   digitalWrite(3,LOW);
  25.   delay(1000);
  26.   }

  27. }
  28. //写命令函数
  29. void WriteCmd(unsigned char I2C_Command)//写命令
  30. {
  31.   I2C_WriteByte(0x00, I2C_Command);
  32. }
  33. //写数据函数
  34. void WriteDat(unsigned char I2C_Data)//写数据
  35. {
  36.   I2C_WriteByte(0x40, I2C_Data);
  37. }
  38. //写一个字节
  39. void I2C_WriteByte(uint8_t addr,uint8_t data)
  40. {
  41.   Wire.beginTransmission(OLED_ADDRESS);
  42.   Wire.write(addr);
  43.   Wire.write(data);
  44.   Wire.endTransmission();
  45. }
  46. //oled初始化
  47. void OLED_Init(void)
  48. {
  49.    WriteCmd(0xAE ); //关闭显示
  50.    WriteCmd(0xD5 ); //设置时钟分频因子,震荡频率
  51.    WriteCmd(0x80 );   //[3:0],分频因子;[7:4],震荡频率
  52.    WriteCmd(0xA8 ); //设置驱动路数
  53.    WriteCmd(0x1f );
  54.    WriteCmd(0X3F ); //默认0X3F(1/64)
  55.    WriteCmd(0xD3 ); //设置显示偏移
  56.    WriteCmd(0X00 ); //默认为0

  57.    WriteCmd(0x40 ); //设置显示开始行 [5:0],行数.
  58.                               
  59.    WriteCmd(0x8D ); //电荷泵设置
  60.    WriteCmd(0x14 ); //bit2,开启/关闭
  61.    
  62.    WriteCmd(0x20 ); //设置内存地址模式
  63.    WriteCmd(0x02 ); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
  64.    
  65.    WriteCmd(0xA1 ); //段重定义设置,bit0:0,0->0;1,0->127;
  66.    
  67.    WriteCmd(0xC0 ); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
  68.    
  69.    WriteCmd(0xDA ); //设置COM硬件引脚配置   这部分在一开始出现问题  2016.07.10
  70.    WriteCmd(0x00 ); //[5:4]配置
  71.      
  72.    WriteCmd(0x81 ); //对比度设置
  73.    WriteCmd(0xff ); //1~255;默认0X7F (亮度设置,越大越亮)
  74.    
  75.    WriteCmd(0xa1);
  76.     WriteCmd(0xc8);
  77.    
  78.    WriteCmd(0xD9 ); //设置预充电周期
  79.    WriteCmd(0xf1 ); //[3:0],PHASE 1;[7:4],PHASE 2;
  80.    WriteCmd(0xDB ); //设置VCOMH 电压倍率
  81.    WriteCmd(0x30 ); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;

  82.    WriteCmd(0xA4 ); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
  83.    WriteCmd(0xA6 ); //设置显示方式;bit0:1,反相显示;0,正常显示                    
  84.    WriteCmd(0xAF ); //开启显示   
  85.    
  86. }
  87. //清屏
  88. void OLED_ClearScr(void)
  89. {
  90.   uint8_t i,n;      
  91.   for(i=0;i<4;i++)  
  92.   {  
  93.     WriteCmd(0xb0+i);    //设置页地址(0~7)
  94.     WriteCmd(0x00);      //设置显示位置—列低地址
  95.     WriteCmd(0x10);      //设置显示位置—列高地址   
  96.     for(n=0;n<128;n++) WriteDat(0x00);
  97.   }   
  98. }
  99. void LCD_Set_Pos(unsigned char x, unsigned char y)
  100. {
  101.     WriteCmd(0xb0+y);
  102.     WriteCmd(((x&0xf0)>>4)|0x10);
  103.     WriteCmd(x&0x0f);
  104. }
  105. void LCD_P6x8Str(unsigned char x,unsigned char y,char ch[])
  106. {
  107.     char c=0,i=0,j=0;
  108.     while (ch[j]!='\0')
  109.      {
  110.        c =ch[j]-32;
  111.        if(x>128){x=0;y+=2;}
  112.        LCD_Set_Pos(x,y);   
  113.        for(i=0;i<6;i++)     
  114.        WriteDat( F6x8[c][i]);
  115.        x+=8;
  116.        j++;
  117.      }
  118. }
  119. void LCD_P8x16Str(unsigned char x,unsigned char y,char ch[])
  120. {
  121.     char c=0,i=0,j=0;
  122.     while (ch[j]!='\0')
  123.      {
  124.        c =ch[j]-32;
  125.        if(x>128){x=0;y+=2;}
  126.        LCD_Set_Pos(x,y);   
  127.        for(i=0;i<8;i++)     
  128.        WriteDat( F8X16[c][i]);

  129.        LCD_Set_Pos(x,y+1);   
  130.        for(i=0;i<8;i++)     
  131.        WriteDat( F8X16[c][i+8]);

  132.       
  133.        x+=8;
  134.        j++;
  135.      }
  136. }



复制代码
一开始调试时就准备用Fireduino自带的IIC接口,但是调了一下午也没出来,拿逻辑分析仪测了一下波形也没问题,整个人都不好了,这个驱动OLED的程序是从其他板子移植过来,是不应该有问题的。但就是不好用,又去使用IO软件模拟IIC,还是不好使。又折腾了半天才发现一个问题,就是这个OLED模块虽然说电压范围是2.6~3.5V,但3V左右时亮度很低,几乎就看不见了,发现Fireduino的板子上标注的是3V,而不是3.3V。找了另外一块板子为OLED模块提供电压,一切正常。

拿电压表实测了一下,Fireduino上标3V的口确实是3V(实际2.96V),但是和硬件手册上对比了一下,电路图上确实3.3V,虽然0.3V的电压差多数情况下影响不大,但这次确实把我坑了

IMG_20161227_130521.jpg (1.86 MB, 下载次数: 36)

IMG_20161227_130521.jpg

IMG_20161227_130556.jpg (2.66 MB, 下载次数: 41)

IMG_20161227_130556.jpg

IMG_20161227_132419.jpg (1.93 MB, 下载次数: 45)

IMG_20161227_132419.jpg

硬件1.JPG (112.98 KB, 下载次数: 44)

硬件1.JPG

硬件2.JPG (80.96 KB, 下载次数: 51)

硬件2.JPG

i2c.zip

4.47 KB, 下载次数: 3

评分

参与人数 1 +25 收起 理由
loveeeboard + 25

查看全部评分

分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

jackten

发表于 2016-12-27 14:37:24 | 只看该作者

谢谢分享                              
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条