鸿蒙通信开发Wi-Fi IoT套件连PCF8563实现电子钟功能

开发
首先跟同样新入手单片机开发的小伙伴分享一点I2C通信的知识。我估计大部分入手开发板的小伙伴都有一定程序开发的能力,但是底层开发可能是新接触,我看有的小伙伴配置开发环境都有障碍,其实并不是多复杂,只是首次接触很陌生罢了,大胆试,多搞几回就轻松应对了。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

首先跟同样新入手单片机开发的小伙伴分享一点I2C通信的知识。我估计大部分入手开发板的小伙伴都有一定程序开发的能力,但是底层开发可能是新接触,我看有的小伙伴配置开发环境都有障碍,其实并不是多复杂,只是首次接触很陌生罢了,大胆试,多搞几回就轻松应对了。

通信开发是单片机主要开发内容,通信方式和协议有很多种,针对应用场景和模块的情况选用合适的协议。各种协议大同小异,开始了解通透一种,理解其思想,其他协议也就很容易理解了。


如果是第一次看到这种图是不是有点懵。

大概过程就是:

1. 发送一段模块地址信息 + 读/写。

等待…

模块如果收到,会给你个回复 ACK

2. 你看到ACK响应,进行下一步

再发送一段,读/写寄存器地址信息。

模块收到,再给你回复ACK

3. 如果是写,就再发送写的内容信息。

如果是读,就接收模块发送来的返回信息。

换个现实场景理解一下,假设你喊你室友帮你取快递:

你:三胖子!(发送模块地址)

三胖子:干啥。(接听ACK)

你:给我取份快递。(发送寄存器地址)

三胖子:好的。(接听ACK)

你:接收室友给你送来的快递。(接收信息)

整个通信过程就是一问一答,双方不能同时问答,一方说话一方只能接听。当然具体过程还要复杂一些,比如接收信息也要给模块回复应答,但是主体过程就是这样的。这个过程大概了解一下就行,所有通信的细节部分都已经被鸿蒙下的函数封装好了,具体过程交由鸿蒙做就好,你只需要考虑要说什么做什么就行了。这个过程真的好简单。

看一下鸿蒙真对WifiIoT智能设备提供的I2C相关函数:

将数据写入I2C设备。

  1. unsigned int I2cWrite(WifiIotI2cIdx id, unsigned short deviceAddr, const WifiIotI2cData *i2cData); 

在i2c.h文件里有详细的说明,这里复制过来一一对照看一下每个参数的意义。

将数据写入I2C设备。

id表示I2C设备id。

deviceAddr表示I2C设备地址。

i2cData表示指向要写入的数据描述符的指针。

如果操作成功,返回WIFI_IOT_ SUCCESS;

否则返回在wifiiot_errno.h中定义的错误代码。

(百度翻译还是很准确的哦!哈)

从I2C设备读取数据。

  1. unsigned int I2cRead(WifiIotI2cIdx id, unsigned short deviceAddr, const WifiIotI2cData *i2cData); 

读取的数据将保存到i2cData指定的地址。

id表示I2C设备id。

deviceAddr表示I2C设备地址。

i2cData表示指向要读取的数据描述符的指针。

如果操作成功,返回WIFI_IOT_ SUCCESS;

否则返回在wifiiot_errno.h中定义的错误代码。

鸿蒙把I2C所使用的数据封装在一个结构体中。我们只需要把数据写入到这个结构体中,然后让函数自己处理就可以了。

  1. typedef struct { 
  2.     /** Pointer to the buffer storing data to send */ 
  3.     unsigned char *sendBuf; 
  4.     /** Length of data to send */ 
  5.     unsigned int  sendLen; 
  6.     /** Pointer to the buffer for storing data to receive */ 
  7.     unsigned char *receiveBuf; 
  8.     /** Length of data received */ 
  9.     unsigned int  receiveLen; 
  10. } WifiIotI2cData; 

 定义I2C数据传输属性。

指向存储要发送的数据的缓冲区的指针

  1. unsigned char *sendBuf; 

要发送的数据长度

  1. unsigned int sendLen; 

指向用于存储要接收的数据的缓冲区的指针

  1. unsigned char *receiveBuf; 

接收数据的长度

  1. unsigned int receiveLen; 

具体用的时候,我们可以根据实际情况再封装一下。这是主要根据使用场景和模块所提供的功能。我针对我要使用PCF8563模块把I2C过程做了一点包装。可以看看我写的代码,也许能给你一点启发。参看我的代码。

在这次开发过程中还用到了GPIO管脚中断

很多老师都专门写了按键的中断触发,我也是仔细研读然后做了我这个程序的触发控制,老师的文章写的太详细了,实在没什么好再说明的,我在使用中也没有遇到什么问题,最多就是,要关闭看门狗功能,否者会重启,再就是当暂中断发的时候用到这个方法。

  • GpioSetIsrMask(WIFI_IOT_IO_NAME_GPIO_8, 0); 正常
  • GpioSetIsrMask(WIFI_IOT_IO_NAME_GPIO_8, 1); 暂停

ADC模数转换

用到OLED模块上的按键的时候碰到了ADC功能,这里先做个伏笔,主要是还没把鸿蒙下的ADC方法研究明白,而且数模转换应用场景非常多,以后用到专门的模块再仔细写写心得吧。暂时看老师们的代码照猫画虎也能运行,有时候会不稳定。

PCF8563是个比价常用的模块。

PCF8563 是PHILIPS 公司推出的一款工业级内含I2C 总线接口功能的具有极低功耗的多功能时钟/日历芯片。PCF8563 的多种报警功能、定时器功能、时钟输出功能以及中断输出功能能完成各种复杂的定时服务,甚至可为单片机提供看门狗功能。是一款性价比极高的时钟芯片,它已被广泛用于电表、水表、气表、电话、传真机、便携式仪器以及电池供电的仪器仪表等产品领域。


PCF8563并不是我们套件里所带的模块,只是赶巧我手上刚好有这么个模块。官方套件提供的模块有限,但是涵盖了单片开发的所有应用场景,如果每个模块都认真走一遍,那么基本解锁了鸿蒙单片机开发的所有知识了。在实际应用中,我们还是要使用各种功能的电子模块来实现更有趣的功能的。所以以后还是要更多尝试新模块的使用,也能提高鸿蒙系统的应用范围。

前面已经开发过AHT20温湿度模块,SSD1306模块,所以再开发PCF8563的过程就变的很简单。有很多内容都是重叠的,整体思路也是相通的,所以过程变得非常轻松。

任何一个模块上手第一步都是读它的技术手册,了解功能寄存器的配置。读手册的过程是枯燥的,只有坚持把手册读透,那么这个模块才算真正属于你。

我想要实现的功能是一个时钟功能,然后按需求和过程写一大坨流水账代码,测试走通,再把代码整理一下,最后归结为2部分,一部分设置时间,一部分读取时间。完了!

当你拥有了一个写时钟的能力,你就拥有了各种计时的能力,比如写个万年历,做个股票投资报时,等等。我通过一部电影获得灵感,做了一个到计数时钟,看时间飞快的流逝,会不会让看钟的人有压力感,治治拖延症呢。但结果除了无聊一点用没有。

PCF8563模块可以输出时钟信号,我开始设想通过Hi3861的1个端口接收时钟信模块发出的周期性低电平,把间隔设定为1秒,触发中断,然后读取模块的时间信息,发送到OLED上显示出来。这样就能每隔1秒显示一次。

OLED模块上有2个按键,想通过它们实现时间设置功能。这个两个按键很有趣,通过1个端口接收信号,通过测试信号的电压强度来区分是那个按键再工作。这时候需要通过ADC能来实现,(坑王艾希已经上线,哈开玩笑。)数模转换功能,难道不能通过2个端口来实现吗?当然不是,这可能是这套开发板设计的初衷,就是让你充分学习未来可能遇到的所有知识。闲话少叙,又解锁新姿势了。

通过2个按键实现功能控制:早期机械计算机用齿轮实现功能的切换,比如可编曲发音盒,有一种可编曲的,中间转子每个音节都可调,实现编曲功能,那种太高级了,没找到图片。我借鉴这种工作原理,来实现2个按键的复杂控制。


按键功能实现的原理就跟那个齿轮是一样的,S1驱动gear这个大齿轮,他有9齿,按一下,转1齿,循环往复,每一齿联动1个功能。S2驱动gears组的7个小齿轮,每个小齿轮针对1个时间的值。当然这不是唯一的控制方法,也可以做个大数组什么的,只是一种方法而已。

  • gear = 9 正常时间显示
  • gear = 0 进入设置状态
  • gear = 1 秒设置 gears[0]可以驱动
  • gear = 2 分设置 gears[1]可以驱动
  • gear = 3 时设置 gears[2]可以驱动
  • gear = 4 日设置 gears[3]可以驱动
  • gear = 5 周设置 gears[4]可以驱动
  • gear = 6 月设置 gears[5]可以驱动
  • gear = 7 年设置 gears[6]可以驱动
  • gear = 8 将设置好的值输入到时间模块
  • gear = 9 正常时间显示

因为不是套件中的模块,我只简单说一下主体程序工作结构。

1. 所有功能先初始化,准备好。

2. 做中断触发,每按1次驱动gear加1循环往复。

3. 建1个主循环,所有的工作就这个循环里了。

4. 针对gear的值,调用执行不同的功能。

完了! 谢谢。~哈

看代码吧,代码写的像流水账,我也懒了改了,欢迎纠错,有问题欢迎问。

随着代码越写越多,也深感C语言知识太少。我会再好好看看C教程,希望以后写的代码,能更好些。

©著作权归作者和HarmonyOS技术社区共同所有,如需转载,请注明出处,否则将追究法律责任。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com/#zz

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2020-10-30 17:57:11

鸿蒙HiSpark

2020-10-23 09:50:15

HiSpark Wi-开发套件

2020-10-15 09:53:55

iSpark Wi-F开发套件板

2020-12-07 11:28:02

Wi-FiWi-Fi 6

2024-01-29 10:26:00

Wi-Fi

2020-11-04 13:20:14

HiSpark

2020-10-26 10:21:39

Wi-Fi IoT智能家居套件

2011-11-28 14:36:41

2022-10-19 12:18:56

家庭智能设备Wi-Fi网络

2012-07-13 10:23:04

Wi-Fi

2016-01-13 10:45:57

Wi-FiHalow

2020-03-20 10:11:38

网络安全数据技术

2020-04-08 16:09:37

机器学习Wi-Fi网络

2018-03-29 16:34:05

Wi-Fi

2012-07-04 10:49:54

Wi-Fi

2018-10-11 14:45:53

Wi-Fi无线通信网络

2018-02-27 16:12:30

Wi-Fi

2016-11-02 15:23:06

华为

2015-01-09 12:04:37

Wi-FiWi-Fi AwareCES2015
点赞
收藏

51CTO技术栈公众号