文章目录

  • 前言
  • 一、硬件选择
  • 二、代码讲解
    • 1.SPI配置
    • 2.灯带代码
  • 总结

前言

今天被疫情管控在家,因为太过突然,完全没准备,也没办法远程办公访问,正好闲下来一天整理一下前段时间弄的一个小玩意。
一个智能灯带,这玩意看起来简单,但是坑蛮多的,特别是我选择了一个比较少见的模块。那坑就更多了。

因为这次是被管控在家,我设备和代码啥都没有,只能通过之前的文档和笔记给大家分享一下这次开发遇到的坑,所以没办法像之前那样直接将代码分享给大家,但是我还是会尽量讲清楚WS2812要如何使用的。


一、硬件选择

首先,就是翼辉的 边缘计算机 Spirit 1 边缘计算机,这玩意给开发者用确实好使,我已经习惯用这个玩意协助开发调试设备了。

至于开发板,这次终于不是祖传的ESP32了,是杰里科技的AC791N开发板!当然,本穷逼只买得起最便宜的单独的开发板模块,这玩意单板子就特么100块啊!

灯带我选择的是WS2812B一种很常见,资料很多的灯带,但是实际上网上的资料很多都不对。我查着资料用示波器抓了半天波形才搞定。

因为设备不在家,这里没办法给大家配图了QWQ

驱动WS2812一般就三种方法
直接控制IO口拉高拉低来产生波形,但是WS2812对电平翻转速度要求有点高,很难达到这么高的速度,而且直接这么控制误差比较大,所以我没采用。

我在网上看见用得比较多的是 PWM+DMA的方式,然后蛋疼的地方来了,AC791N开发板开发板的资料比较少,只有官方的一个文档,官方文档只简单的说了一下PWM的使用,有很多的功能和宏并没有介绍,我折腾了半天,实在是调不通,去找他们的官方支持才知道,他们的PWM是直连的,没有DMA。

最后在官方人员的帮助下,我才终于成功使用SPI单线模式+DMA的方式驱动WS2812,官方文档上没有SPI单线模式的介绍,就很蛋疼

接线:
5V->5V
PH1(SPI DO)->DO
GND->GND

二、代码讲解

1.SPI配置

因为这次代码不在身边,我只能找我笔记里的关键部分来讲了

采用SPI单线模式+DMA,主要是SPI_UNIDIR_MODE这个宏将SPI配置为单线模式
使用SPI2 portA
SPI速率为8M
输出引脚为 :IO_PORTH_01

SPI配置代码如下(示例):

port A 的引脚定义

/************************** SPI config ****************************/
SPI2_PLATFORM_DATA_BEGIN(spi2_data).clk    = 8000000,.mode   = SPI_1WIRE_MODE,.port   = 'A',.attr   = SPI_SCLK_L_UPH_SMPH | SPI_UNIDIR_MODE,
SPI2_PLATFORM_DATA_END()注册SPI设备:
REGISTER_DEVICES(device_table) = {{"uart2", &uart_dev_ops, (void *)&uart2_data },{"rtc", &rtc_dev_ops, NULL},{"spi2", &spi_dev_ops, (void *)&spi2_data },
};

2.灯带代码

WS2812的逻辑0和逻辑1的定义
代码如下(示例):

//需要设定灯带长度和ws2812的逻辑0和逻辑1
#define LED_NUM  100                    // LED灯珠个数#define EIGHTBIT_0CODE    0xc0            // 逻辑0
#define EIGHTBIT_1CODE  0xf8            // 逻辑1

这是将数据结构中传入的颜色和亮度数组转换成SPI发送数据的函数


/*** 将传入数据转换成ws2812缓存*  8个SPI bit 表示一个ws2812bit,要求SPI发送速率为8Mhz,ws2812信号频率为1M*     经实测,还是8bit/1M 的模式比较准确,灯带不会误识别造成乱码,SPI为6.4M时会出现乱码*  */
int convert2ws2812(struct frame_buf* fbuf, uint8_t *ws_buf, uint16_t buf_len)
{union ws2812_pixel pcolor;uint8_t *subpixel = NULL;ws_buf[0] = 0;for (uint16_t pos = 0; pos < LED_NUM; pos++) {// 处理当前像素点颜色pcolor.color.r = fbuf->color.r * fbuf->pixel_brightness[pos] / UINT8_MAX;pcolor.color.g = fbuf->color.g * fbuf->pixel_brightness[pos] / UINT8_MAX;pcolor.color.b = fbuf->color.b * fbuf->pixel_brightness[pos] / UINT8_MAX;// 转换每个颜色通道memset(ws_buf + pos * 24, 0, 24);for(uint16_t i = 0; i < 3; i++) {subpixel = ws_buf + pos * 24 + i * 8 + 0;subpixel[0] |= ((pcolor.data[i] & 0x80) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[1] |= ((pcolor.data[i] & 0x40) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[2] |= ((pcolor.data[i] & 0x20) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[3] |= ((pcolor.data[i] & 0x10) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[4] |= ((pcolor.data[i] & 0x08) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[5] |= ((pcolor.data[i] & 0x04) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[6] |= ((pcolor.data[i] & 0x02) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);subpixel[7] |= ((pcolor.data[i] & 0x01) ? EIGHTBIT_1CODE : EIGHTBIT_0CODE);}}return 0;
}

而在主业务循环函数中有个需要注意的是SPI do 端口默认为高电平,我尝试在发送前将GPIO端口拉低也没用,这会导致数据的第一个信号被吞掉,所以要在所有数据前填充一段0数据将电平拉低


总结

这次东西,不难,主要是的坑有点多:
1、AC97的PWM是不支持DMA的,以及SPI的单线模式。
2、WS2812并不需像网上资料写的理论上将SPI 的CLK设置为6.4M,亲测,6.4M情况下会有错乱的情况。8.0M才能稳定。
3、SPI默认高电平会吃掉第一个数据,导致会有一个灯颜色异常,所有要手动在所有发送前往数据前塞0,拉低电平,通过GPIO控制函数拉低没用,我抓过波形看过了。
4、还是AC97的问题,因为我这是两线程在跑,一个线程接收数据,一个线程发送数据,发送线程不知道为什么在有的情况下会调度得慢,几秒甚至几十秒才跑一次,我已经把发送线程的优先级拉到很高了,理论上他调度的机会应该比接收线程多,但是接收线程一切正常,发送线程响应就很慢,而我什么都没改,有时候重新上电就正常了,有时候重新烧录一下代码就好,什么都没改。

从零开始 DIY 智能家居 - AC791N通过单线SPI驱动WS2812相关推荐

  1. 从零开始的DIY智能家居--自己在家手搓一套人脸识别智慧猫眼系统

    前言 ​ 最近整理资料的时候,才发现之前写的一个智慧猫眼的爱智场景没有给大家写文章介绍,可能有的小伙伴之前也看到爱智官方引用我的这个代码给大家进行了一个直播演示,我个人还是觉得自己也有必要简单介绍一下 ...

  2. 安卓手机远程控制DIY智能家居设备(ESP8266)

    一.准备材料: 手机(安卓手机,如果没有请忽略整篇文章). 电脑(windows, 如果没有请忽略整篇文章,此文章不适合大神阅读). DIY智能设备(ESP8266基本上是绕不过去的,如果没有那就买一 ...

  3. 从零开始的DIY智能家居 -- 智能红外接近传感器

    文章目录 前言 硬件选择 代码解析 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 数据获取与发送流程 效果展示 总结 前言 自从有了 Spirit 1 这个超便宜的个人 ...

  4. 从零开始的DIY智能家居 - 基于 ESP32 的土壤湿度传感器

    文章目录 前言 硬件选择 代码解析 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 数据获取与发送流程 总结 前言 自从上次做了那个 甲醛传感器 和 水浊度传感器 之后开 ...

  5. DIY 智能家居语音助理 —— 语音控制万物

    本文作者:默. 开源电子平台兴起以来,诞生了不少的创客们,他们用天马行空的想象力,创造出各种新鲜有趣的作品,他们热衷于改变千篇一律的生活,享受科技创造带来的乐趣.其中与我们的生活息息相关的就包括智能家 ...

  6. DIY智能家居设备:基于esp32和阿里云云智能APP完成智能灯泡的开发

    esp32 开发 一. 芯片介绍 ESP32 是一套 Wi-Fi (2.4 GHz) 和蓝牙 (4.2) 双模解决方案,集成了高性能的 CPU 内核.超低功耗协处理器和丰富的外设.ESP32 采用 4 ...

  7. 光大证券:智能家居 “双网”引擎共同驱动

    基于智能家居所带来的巨大个人.社会及技术效益,以及"中国制造2025"的提出,我们看好智能家居在中国未来的发展.逾25%的市场增长率及相比国外极低的智能化渗透率也佐证了行业未来巨大 ...

  8. 基于ARM7的嵌入式智能家居系统---系统的图形驱动与界面设计

    目录 1 绪论 1 1.1 智能家居及其发展趋势 1 1.2 嵌入式系统与智能家居 1 1.3 图形用户界面与智能家居 2 2 硬件体系结构 4 2.1 开发板硬件资源 4 2.2 CPU-S3C44 ...

  9. 从零开始的DIY智能家居 - 基于 ESP32 的智能水浊度传感器

    文章目录 前言 硬件选择 代码解析 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 数据获取与发送流程 总结 前言 家里有个鱼缸养了几条鱼来玩玩,但是换水的问题着实头疼, ...

最新文章

  1. java存款程序_JAVA实现账户取款和存款操作
  2. 工作中涉及运维知识点的汇总
  3. oracle 9i aix 迁移,Oracle 9i 在AIX上的安装 (转)
  4. flex 引入css,Flex常用布局
  5. 根据百度地图的api自动获取地理位置
  6. 《哪吒》票房超25亿元 进入中国电影票房总榜前十
  7. PostgreSQL 辟谣存在任意代码执行漏洞:消息不实
  8. wndows make images
  9. java daemon 线程_【转】关于Java的Daemon线程的理解
  10. Python实现批量处理扫描特定目录
  11. cocos2d-x 播放视频 on Android
  12. 实用工具【SqlPrompt】 【Subline】 【XMind】 【PhotoShop】 【TakeColor】 【Q+】本次只讨论SqlPrompt...
  13. 数字孪生新型智慧城市一网统管云平台建设方案(44页PPT)
  14. JPG图片比较大如何压缩,图片压缩的简单方法
  15. java整数最大_Java 整数最大值
  16. Clonezilla笔记----安装Clonezilla Live到U盘
  17. 南京工资个税计算机,最新南京工资扣税标准
  18. 《甄嬛传》影评(整理)
  19. rdms系统_什么是关系数据库管理系统(RDMS)?
  20. 面向建筑应用的三维点云数据获取和处理的计算方法

热门文章

  1. 程伟健:珠海游玩指南请收好!十大主题十条线路吃喝玩乐一条龙体验
  2. matlab图像处理相关函数
  3. python中一个函数只允许有一条return语句_一个函数应该只有一个return语句吗?
  4. 宁静优美景色动态特效404网页源码
  5. DateSerial 函数
  6. 常用数字与字母的正则表达式
  7. 4_1Linux概述
  8. java referrer_JavaScript中document.referrer的用法详解
  9. 基于51单片机的数码管按键控制
  10. Volly的简单封装