基于RiskV的阿里平头哥MCU开箱文章之软硬件i2C驱动oled 12864

  • Risk-V简介
  • 国产单片机及开发环境CDK
  • iic简介
  • iIC代码移植详细介绍
  • # stm32 iic:
  • # 向国产单片机进发

拿到这款国产单片机有一段时间了,今天回头写写入门攻略,就拿一篇自己的iic驱动oled12864工程讲一下。

Risk-V简介

RISC-V读作RISC Five,也即第五代精简指令处理器。RISC-V指令集完全开源,设计简单,易于移植Unix系统,模块化设计,完整工具链,同时有大量的开源实现和流片案例,已在社区得到大力支持。它虽然不是第一个开源的的指令集(ISA),但它是第一个被设计成可以根据具体场景可以选择适合的指令集的指令集架构。基于RISC-V指令集架构可以设计服务器CPU、家用电器CPU、工控CPU和传感器中的CPU。想要了解它先得提一下 RISC。即精简指令集计算机,Reduced Instruction Set Computer-RISC。它和CISC(复杂指令集计算机,Complex Instruction Set Computer-CISC)是CPU的两种架构,区别在于不同的CPU设计理念和方法。早期的CPU全部是CISC架构。重点介绍下RISC。

针对CISC的庞杂的指令系统不但不易实现,而且还可能降低系统性能等弊病,David Patterson教授等人提出了精简指令的设想,即指令系统应当只包含那些使用频率很高的少量指令,并提供一些必要的指令以支持操作系统和高级语言.按照这个原则发展而成的计算机被称为精简指令集计算机(Reduced Instruction Set Computer-RISC)结构。RISC架构要求软件来指定各个操作步骤。这种架构可以降低CPU的复杂性以及允许在同样的工艺水平下生产出功能更强大的CPU,但对于编译器的设计有更高的要求。

国产单片机及开发环境CDK

首先感谢一下深圳A1SEMI矽海半导体公司提供的单片机和下载工具CK-LINK。
平头哥MCU开发环境CDK 下载安装等可以参考下面的文章
https://blog.csdn.net/sqhone/article/details/123015091。
如果你想玩玩这款单片机又没有下载工具的话自己diy一个也不是不可以。链接附上 https://www.bilibili.com/video/BV1L44y1J7Jz?spm_id_from=333.337.search-card.all.click
这款国产单片机确实让我感到震惊,国产真的是赶上了国际水平,在性能使用方面一点也不比STM32单片机差多少,有些方面甚至特别香。比如说同样是基于库函数开发,它在ADC,定时器,IIC等应用上,函数完全给你写的好好的,只需要你改改参数就行了。
当然他也有一些让人头疼的地方,尤其是下载程序。烧录管脚一定不要复用,否则的话,芯片可能就废了,再也烧不进去程序了。

iic简介

IIC(Inter Integrated Circuit,集成电路总线)是一种由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是由数据线 SDA 和时钟 SCL 构成的串行总线,可发送和接收数据。在 CPU (单片机)与IIC模块之间、IIC模块与IIC模块之间进行双向传送。

从上图可以看到时序很简单。SCL 线为高电平期间,SDA 线由高电平向低电平的变化表示起始信号;SCL 线为高电平期间,SDA 线由低电平向高电平的变化表示终止信号。起始信号后跟着是从机地址,共有七位。最后一位是读写位。特别强调地址很重要一旦错误,不可能发送信息的即使发送了也是错误的。一般器件的地址在手册上都会有提到。随后便是应答位,就开始发送数据,这之就看你是停止还是继续收发数据。
根据以上时序图我们很快便可以写出一个软件模拟iIC的程序代码。

以上是一个stm32硬件iIC 时序图。可以看到,它与软件模拟的流程差不多。但又有一些细微差别。那我到底使用软件还是硬件呢。首先你要确定你的板子是否有这个硬件资源,没有的话就没得选择。如果有,具体比较如下
接下来根据参考的文章和自己的理解浅浅的介绍一下软件和硬件iIC。
所谓硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的;软件I2C通常是用GPIO管脚,用软件控制管脚状态以模拟I2C通讯波形。

  1. 硬件IIC用法比较复杂,模拟IIC的流程更清楚一些。

  2. 硬件IIC速度比模拟快,而且在stm32中能够用DMA

  3. 模拟IIC能够在任何管脚上,而硬件只能在固定管脚上。

  4. 硬件iIC比软件模拟更加稳定。

  5. 代码量上硬件较少,软件更多。

  6. 软件i2c是使用程序控制SCL,SDA线输出高低电平,模拟i2c协议的时序。硬件iic调用现成的函数或者给某个寄存器赋值来配置对应的功能。

看完这些你应该懂了软硬件直接的区别。首先你要确定你使用硬件还是软件模拟,大方向要确定好不然最后就算是问别人你都说不清楚自己的程序是什么。如果还是不太懂那就在接下来的代码中慢慢体会一下吧。
关于iIC通信的时序和流程我觉得也可以看这篇文章写。链接附上:https://www.elecfans.com/d/1845634.html。

iIC代码移植详细介绍

# stm32 iic:

在网上或者某宝店铺随便找便可以找到一大堆关于iIC驱动oled的代码,不过大多是用软件模拟的。关于软件模拟我就简单点介绍一下。

移植程序的时候不能把所有东西都丢进来一定要先把核心程序放进来。
以我移植oled程序为例(程序源码最后奉上可直接下载)。关键程序就是OLED_Init() ;OLED_Write_Byte();和其他显示函数以及刷新函数。而其余的什么字库,显示图片,反色显示,翻转等等这些花的都不是必要的。甚至可以这样说我只要点亮屏幕就可以了,其余什么函数我都可以先不要。只留下最关键的核心程序也就是你要实现的功能的最简单一步。然后在这个基础之上逐步添加你所需要的功能。以下是具体调试步骤:
第一步:先在你源程序上调试,比如我在stm32f103c8t6上确定我的核心程序是哪些(以硬件iic为例,确保点亮屏幕就可以了)。

int main(void)
{DelayInit();I2C_Configuration();OLED_Init();   while(1){OLED_Fill(0xFF);//全屏点亮DelayS(2);OLED_Fill(0x00);//全屏熄灭DelayS(2);}
}

然后再去看具体的函数,比如I2C_Configuration();里面具体是怎么配置的。

void I2C_Configuration(void)
{I2C_InitTypeDef  I2C_InitStructure;GPIO_InitTypeDef  GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);/*STM32F103C8T6оƬµÄÓ²¼þI2C: PB6 -- SCL; PB7 -- SDA */GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//I2C±ØÐ뿪©Êä³öGPIO_Init(GPIOB, &GPIO_InitStructure);I2C_DeInit(I2C1);//ʹÓÃI2C1I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x30;//Ö÷»úµÄI2CµØÖ·,Ëæ±ãдµÄI2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 400000;//400KI2C_Cmd(I2C1, ENABLE);I2C_Init(I2C1, &I2C_InitStructure);
}

这里面有管脚配置,时钟速度,模式等等根据你的需要来选择就好。如果是配套的基本上不需要改什么。在这里在强调一下最为关键的一个函数写字节函数。
可以对比一下软硬件iIC的程序

硬件确实有点不好理解,但是回过头看看时序图就明白了还是按照时序来的。而且硬件是直接调用库函数中的函数来写的,只要你按照时序来事实上你根本就不需要写什么代码。

# 向国产单片机进发

按照你所要移植的单片机规则把你的核心程序一步一步移植过去。一定要从硬件入手,确定你有相应的硬件,否则你再怎么调试也不行。比如我使用的单片机就只有一个硬件iic。相应的管脚、时钟使能、速度配置、从机地址、直接移植过来就好。还是以硬件iIC为例(软件iIC你直接复制过来就好如果出现重定义直接把原来的函数或者变量注释掉)
写字节的函数在我要移植的单片机中的库函数也有以一个。这也是我在程序移植的过程中我遇到的最大的一个问题。相似的函数变量不知道如何处理。首先第一点你肯定是想不费功夫的全都copy过来,当然可以,如果你能实现功能的话。不过哦百分之九十九还是不行吧。我在oled移植就遇到了写字节的函数。在我的单片机标准iic库里自己定义了一套写字节的函数,但是在外面32源程序里面也定义了一个写字节的函数,两个函数定义的还不一样。
怎么办呢。首先肯定是如果你要移植的单片机有自己的iIC例程一定要把它的例程看明白。这是第一步。第二步找不同。举个栗子。
我要移植软件iIC。这个可以说是闭着眼睛就能做。为什么呢,把原来自己带的函数都注释了直接移植。以写一个字节函数为例。

void OLED_WR_Byte(u8 dat,u8 mode)
{I2C_Start();//起始信号Send_Byte(0x78);//发送从机地址I2C_WaitAck();//等待应答if(mode){Send_Byte(0x40);}//写数据else{Send_Byte(0x00);}//写命令I2C_WaitAck();//等待应答Send_Byte(dat);//发送数据I2C_WaitAck();//iic等待应答I2C_Stop();//停止信号
}

以上便是我要移植的函数 。若是通过软件模拟iIC 那我直接copy就可以。一个字都不用改动。
但是如果我是用硬件iIC ,那就要好好琢磨一下了。

void I2C_WriteByte(uint8_t addr,uint8_t data)
{while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));I2C_GenerateSTART(I2C1, ENABLE);//¿ªÆôI2C1while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,Ö÷ģʽ*/I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//Æ÷¼þµØÖ· -- ĬÈÏ0x78while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, addr);//¼Ä´æÆ÷µØÖ·while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_SendData(I2C1, data);//·¢ËÍÊý¾Ýwhile (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));I2C_GenerateSTOP(I2C1, ENABLE);//¹Ø±ÕI2C1×ÜÏß
}

以上是硬件iIC 的stm32 程序。该程序实现写一个字节的功能。看起来比软件复杂多了不是。但是仔细推敲实际上也不是太难。
对比软件函数发现他们基本上是同样的功能时许基本相似。但是一个是对SCL SDA 高低电平进行操作模拟信号,另一个是直接对寄存器操作。废话不多说,开始我的表演。
看懂了这个移植的程序每一步在干嘛之后,对比你要移植的单片机语法规则。起始信号函数,停止信号函数,发送数据函数,地址函数这些函数在你要移植的单片机中是怎么写的,是否都有,你怎么把按照iIC时序把这些组织起来。或者说你要移植的单片机的库函数中自带了iIC 写一个字节的函数,那你就要去跑一下例程看看他是怎么运行的,然后自己是否需要改动。先假设你不需要,那么把其他的函数照搬过来,编译没有错误后烧录看程序是否运行。如果不能说明你的函数有概率有问题需要改动,也有很大可能是你的整个程序哪有问题,比如iIC从机地址不对,引脚连接或者设置错误。或者说是板子上某个跳线帽没连接等等。
以下是我要移植的单片机自带的库函数写字节函数。

  void I2C_WRITE_Byte(U8_T write_adds,U8_T i2c_data)
{U16_T R_EEROR_CONT=0;I2C0->DATA_CMD = I2C_CMD_WRITE|write_adds ;I2C0->DATA_CMD = i2c_data |I2C_CMD_STOP;do{if(R_EEROR_CONT++>=10000){R_EEROR_CONT=0;f_ERROR=1;I2C_Disable();I2C_Enable();break;}}while( (I2C0->STATUS & I2C_BUSY) != I2C_BUSY );      //Wait for FSM workingdo{if(R_EEROR_CONT++>=10000){R_EEROR_CONT=0;f_ERROR=1;I2C_Disable();I2C_Enable();break;}}while(((I2C0->STATUS) & I2C_TFE) != I2C_TFE);
}

他是直接对寄存器操作的,一开始我也不是太明白,不过我一上来假设它不需要改动,是完整的。(还假设对了)把其他函数复制过来结果程序就是不运行,屏幕点不亮,最后才排查出来从机地址错误。
如果你的单片机没有这些库函数或者时同款32的单片机建议你移植的时候一定要仔细比对,哪有有,哪些没有,哪些需要改动,怎么改动。建议在纸上写好大致改动思路。
这是我在学习国产单片机遇到的问题希望能对大家有所帮助。最后感谢一下深圳A1SEMI矽海半导体公司提供的技术支持和帮助,我所使用的正是此公司生产的ASM32s003单片机。
拿一个简单的实例请大家看看。

  int main(void)
{float ADC_Buffer[2];
float temp;
float temp1;char buff[10];char  buff1[10];ASM32S003_init();//管脚、iic初始化OLED_Init();OLED_Fill(0xFF);//全屏点亮delay_nms(2000);OLED_Fill(0x00);//全屏熄灭delay_nms(4000);while(1)
{OLED_ShowStr(42,0,“ABC",2)
}
}

基于阿里平头哥的单片机软、硬件i2C驱动oled相关推荐

  1. 串口助手驱动_STM32Cube22(补充) | 使用硬件I2C驱动OLED(SSD1306)

    点上方蓝字关注我们 每天都有好玩的东西等着你 本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设驱动0.96'OLED屏幕. 1. 准备工作 硬件准备 开发板 ...

  2. stm32驱动ssd1306配置_STM32F7片上硬件I2C驱动OLED(SSD1306),寄存器配置的。

    最近在学习STM32F7的片上I2C硬件,看到原子哥的OLED模块可以用I2C来驱动,于是就试了下.现在将试验结果与大家分享,目前还没有毕业经历过的项目比较少,只是为了抛砖引玉,有什么不合理的地方,请 ...

  3. 1.27 Cubemx_STM32H7 软\硬件I2C

    Cubemx_STM32H7 软\硬件I2C 1. I2C简介 1.1 I2C物理拓扑结构 1.2 I2C总线特征 1.3 I2C协议 1.4 I2C总线操作 1.5原理图 2.硬件IIC Cubem ...

  4. MSP430G2553 Launchpad 硬件I2C驱动

    一.USCI I2C 驱动介绍 对于MSP430G2553,硬件I2C由外设USCI(Universal Serial Communication Interface)提供.USCI又分为USCI_A ...

  5. 12. STM32——硬件IIC驱动OLED屏幕显示

    STM32--硬件IIC驱动OLED屏幕显示 OLED屏幕 OLED屏幕特点 OLED屏幕接线说明 OLED屏幕显存 OLED屏幕原理 OLED屏幕常用指令 OLED屏幕字模软件的使用 写命令 写数据 ...

  6. STM32硬件SPI驱动OLED

    文章目录 一.OLED相关 1.OLED简介 2.0.96寸的OLED模块概述 3.模块引脚说明 4.汉字点阵编码原理 二.硬件SPI 1.SPI简介 2.SPI的引脚映射关系 三.SPI驱动的OLE ...

  7. ​HC32L130/HC32L136华大单片机硬件I2C驱动代码(从机为存储芯片EEPROM(AT24C02,FM24CL64B))​

    由于同事嫌弃模拟I2C速度太慢了 所以想改成硬件I2C 我试过例程的驱动代码 不太行 存储地址也是8位的 所以参考了一些博文 修改了下例程的代码 亲测有效 希望能帮到大家 代码如下 这里用的是I2C0 ...

  8. STM32配合cubeMX硬件I2C驱动0.96寸OLED

    目录 一.简单介绍 1.1   OLED 1.2   I2C协议 二.实战 2.1 工程配置 2.2 测试工程 2.3 波形分析 三.驱动OLED 3.1 初始化代码 3.2 清屏函数 3.3 设置坐 ...

  9. CC2541硬件I2C驱动SD3078填坑指南

    关于CC2541的硬件I2C TI的hal库已经写好了相关的驱动,不需要自己硬着头皮去看数据手册了,hal_i2c.c文件存放路径是:C:\Texas Instruments\BLE-CC254x-1 ...

最新文章

  1. ThreadPoolExecutor使用详解
  2. 如何使用.NET配置文件(二)
  3. 开发者们,「Innovation 2021」网易应用创新开发者大赛正式开赛了!
  4. 专精开发还是转管理?程序员的职业规划选择,没有想象中那么难
  5. jquery 使用方法
  6. L1-018 大笨钟 (10 分)
  7. Python运维插件——psutil
  8. Python常见的17个错误
  9. JS中的事件委托/事件代理详解
  10. VS2013默认打开HTML文件没有设计视图的解决办法
  11. java derby xsai2,java-j内的引用罐
  12. openCV5-getTickCount
  13. 实现Android手机屏幕投影到电脑进行演示
  14. ngx-datatable中文教程
  15. (linux)idr(integer ID management)机制
  16. Laravel5.4中文分词搜索-使用 Laravel Scout,Elasticsearch,ik 分词(三)
  17. 微信小程序自定义编译模式
  18. iPhone视频播放器(1)
  19. Day4 Hailstone
  20. varnish 4.0 官方文档翻译9-用户手册- 向Vanish下发指令

热门文章

  1. 软件测试入门全流程精华总结【必看 知识点很全】
  2. js 判断IOS版本号
  3. 仪器科学与技术毕业论文范文
  4. js 操作字符串,
  5. 下单账号与支付账号不一致,请核实后再支付 问题原因
  6. php 正则保留数字和,只保留汉字,字母,数字正则
  7. Visio中插入Mathtype公式
  8. Android WebView 加载https网页白屏,空白解决方案
  9. cfadisk,让电脑把sd卡识别成硬盘
  10. powerquery分组_power query 分组合并展示