【点灯鼠教程】K210裸机点灯之旅(1)点亮SSD1306【C开发I2C】

本文详细记录了使用K210芯片通过I2C协议驱动SSD1306 OLED显示屏的过程,包括初始化、地址问题、代码移植和点灯测试。作者遇到并解决了SLK扫描不到最后一位地址的问题,并从MaixPy移植代码实现显示。通过修改I2C入口,实现了代码的通用性。
摘要由CSDN通过智能技术生成

万物基于点灯

——沃兹基硕德

点灯,I2C点灯

就像正常点灯一样,打开勘智IDE,大地球,礼物,find i2c,None。。。
果断下载GPIO,打开百度!
还是None?
自己动手!

API,I2C

翻开手册145页,大写的i2c映入眼前

> 145第14章集成电路内置总线(I²C)

API参考对应的头文件i2c.h为用户提供以下接口
• i2c_init
• i2c_init_as_slave
• i2c_send_data
• i2c_send_data_dma
• i2c_recv_data
• i2c_recv_data_dma
下单I2C_INIT,I2C_SEND_DATA,开始点灯!

码代码,堆积木

注册io6,io8 为i2c0地址线(可以使用ide一键配置,见ide使用)

ret += fpioa_set_function(6, FUNC_I2C0_SCLK);
ret += fpioa_set_function(8, FUNC_I2C0_SDA);

初始化I2C,配置I²C器件从地址、寄存器位宽度和I²C速率。

i2c_init(I2C_DEVICE_0, SSD1306_I2C_ADDR, 7, 400000);

问题出现了,ADDR地址多少?百度,0x78,完美,,,,,?恭喜你进入了第一个大坑

K210的SLK扫描不到最后一位地址——来自某热心群友的分享
折腾了一天一夜,最后祭出 MaixPy (MaixPy大法好)

i2c.scan()
>>>60

60=0x3c=0x78/2(RX78-2?不由自主幻视)
果然是有一位没读到。。

点灯!点1306!

打开1306手册,一堆文字。
果断关掉,打开百度打开maixpy,果然有现成 例程 (才发现这个例程已经给出addr地址 SSD1306_ADDR = 0x3c了,所以白忙活了一天?)
开始移植。。。1.。。2.。。3.。。。
移植好了

uint8 buff[2] = {0x00, 0x01};
void SSD1306_WriteCmd(uint8 cmd) {
  buff[0] = 0x00;
  buff[1] = cmd;
  i2c_send_data(I2C_DEVICE_0, buff, 2);  // cmd
  // i2c_send_data(SSD1306_I2C_ADDR, cmd, 1);
}

void SSD1306_WriteData(uint8 data) {
  buff[0] = 0x40;
  buff[1] = data;
  i2c_send_data(I2C_DEVICE_0, buff, 2);  // cmd
}
// SSD1306初始化
void OLED_Init(void) {
  // SSD1306复位之后,默认的是页寻址方式

  SSD1306_WriteCmd(0xAE);  //--display off

  SSD1306_WriteCmd(0x00);  //--set low column address
  SSD1306_WriteCmd(0x10);  //--set high column address
  SSD1306_WriteCmd(0x40);  //--set start line address

  SSD1306_WriteCmd(0xB0);  //--set page address

  SSD1306_WriteCmd(0x81);  // contract control
  SSD1306_WriteCmd(0xFF);  //--128
  SSD1306_WriteCmd(0xA1);  // set segment re-map  0 to 127
  SSD1306_WriteCmd(0xA6);  // set normal  display
  SSD1306_WriteCmd(0xA8);  // set multiplex ratio(1 to 64)
  SSD1306_WriteCmd(0x3F);  //--1/32 duty

  SSD1306_WriteCmd(0xC8);  // Com scan direction
  SSD1306_WriteCmd(0xD3);  // set display offset
  SSD1306_WriteCmd(0x00);  // no offset

  SSD1306_WriteCmd(0xD5);  // set display clock divide ratio/oscillator
                           // frequency
  SSD1306_WriteCmd(0x80);  //

  SSD1306_WriteCmd(0xD8);  // set area color mode off
  SSD1306_WriteCmd(0x05);  //

  SSD1306_WriteCmd(0xD9);  // Set Pre-Charge Period
  SSD1306_WriteCmd(0xF1);  //

  SSD1306_WriteCmd(0xDA);  // set com pin  hardware configuartion
  SSD1306_WriteCmd(0x12);  //

  SSD1306_WriteCmd(0xDB);  // set Vcomh
  SSD1306_WriteCmd(0x30);  // 0x20,0.77xVcc

  SSD1306_WriteCmd(0x8D);  // set charge pump enable
  SSD1306_WriteCmd(0x14);  //

  SSD1306_WriteCmd(0xAF);  //--turn on oled panel
}

//坐标设置:也就是在哪里显示
void OLED_SetPos(uint8 x, uint8 y) {
  //以下3个寄存器只在页寻址的模式下有效
  SSD1306_WriteCmd(0xb0 + y);                  //页地址设置     0xb0~0xb7
  SSD1306_WriteCmd(((x & 0xf0) >> 4) | 0x10);  //列高位地址设置
  SSD1306_WriteCmd((x & 0x0f));                //列低位地址设置
}

//开启OLED显示
void OLED_DisplayOn(void) {
  SSD1306_WriteCmd(0X8D);  // SET DCDC命令
  SSD1306_WriteCmd(0X14);  // DCDC ON
  SSD1306_WriteCmd(0XAF);  // DISPLAY ON
}

//关闭OLED显示
void OLED_DisplayOff(void) {
  SSD1306_WriteCmd(0X8D);  // SET DCDC命令
  SSD1306_WriteCmd(0X10);  // DCDC OFF
  SSD1306_WriteCmd(0XAE);  // DISPLAY OFF
}

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样
void OLED_Clear(void) {
  uint8 i, n;

  for (i = 0; i < 8; i++) {
    SSD1306_WriteCmd(0xb0 + i);  //设置页地址(0~7)
    SSD1306_WriteCmd(0x00);      //设置显示位置—列低地址
    SSD1306_WriteCmd(0x10);      //设置显示位置—列高地址
    for (n = 0; n < 128; n++) SSD1306_WriteData(0);
  }  //更新显示
}

好吧哪有那么无聊一个一个移植。这里使用的是freemote的 一文彻底了解SSD1306驱动0.96寸OLED

通过修改I2C的入口,绑定到K210的I2C上,代码就可以直接使用了(这才是写代码的好习惯,只需要修改入口,就可以轻松移植代码,而不是将代码与设备深度绑定,修改代码要从内部一点一点改)
修改方法如下,重写WriteCmd和WriteData

typedef __uint8_t uint8;
uint8 buff[2] = {0x00, 0x01};
void SSD1306_WriteCmd(uint8 cmd) {
  buff[0] = 0x00;
  buff[1] = cmd;
  i2c_send_data(I2C_DEVICE_0, buff, 2);  // cmd
  // i2c_send_data(SSD1306_I2C_ADDR, cmd, 1);
}

void SSD1306_WriteData(uint8 data) {
  buff[0] = 0x40;
  buff[1] = data;
  i2c_send_data(I2C_DEVICE_0, buff, 2);  // cmd
}
  
void SSD1306_WriteData(uint8 data) {  
buff[0] = 0x40;  
buff[1] = data;  
i2c_send_data(I2C_DEVICE_0, buff, 2); // cmd  
}  

入口修改好了,接下来就该点灯了。

测试!听从我的呼唤,闪烁吧,1306!

从maixpy移植oled_fill()进行测试:

void oled_fill(uint8 data) {
  uint8 x, y;
  for (x = 0; x < 8; x++) {
    SSD1306_WriteCmd(0xb0 + x);
    SSD1306_WriteCmd(0x10);
    SSD1306_WriteCmd(0x01);
    for (y = 0; y < 128; y++) {
      SSD1306_WriteData(data);
    }
  }
} 

主函数输入

  i2c_init(I2C_DEVICE_0, SSD1306_I2C_ADDR, 7, 400000);
  OLED_Init();
  oled_fill(0xff);
  OLED_DisplayOn();  

一次点亮!效果如下:

在这里插入图片描述

尾章,打印字符

点灯的最终目的是打印字符,画图出来。由于精力有限,目前只测试了字符,画图还等后续。
代码占空间,就不发了,将以附件形式上传整个工程。
先看看效果吧:
在这里插入图片描述

文章来源于Sipeed点灯鼠,原文链接:https://bbs.sipeed.com/thread/588

搬运请注明原文地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值