搜索
bottom↓
回复: 23

16位的SPI怎么发送10位数据,大家有什么好办法吗

[复制链接]

出0入0汤圆

发表于 2021-2-25 17:40:36 | 显示全部楼层 |阅读模式
有一个LED驱动芯片,数据传送方式是10位SPI,现在的问题是单片机SPI只能设置8位或16位,不能设置成10位,想过用模拟SPI。但传送的数据量太大了,用模拟不现实,现在可以这样,一个LED驱动芯片要接收30位数据,单片机可以发送两个16位数据,这样发送的就是32Bit,多发了两个位也能正常工作。那么问题来了,要把10位的数据放到两个16位变量中,通过左移右移,可以实现。但数据很多,感觉这样太麻烦了工作量太大了。不知道大家有没有更好的办法呢

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2021-2-25 17:45:07 | 显示全部楼层
移位操作很高效,就2行代码也不算麻烦,数据量再大也是程序完成,工作量不会大啊

出0入0汤圆

 楼主| 发表于 2021-2-25 17:49:59 | 显示全部楼层
nanfang2000 发表于 2021-2-25 17:45
移位操作很高效,就2行代码也不算麻烦,数据量再大也是程序完成,工作量不会大啊 ...

我不是说程序运行量大,而是这样要一个一个计算要移多少位,要往那个方向移。但数据有几十个,那就要算半天了

出0入0汤圆

发表于 2021-2-25 17:54:39 | 显示全部楼层
你谷歌下 spi ws2812 ,这个用法很常见

出0入0汤圆

发表于 2021-2-25 18:02:55 | 显示全部楼层
泡泡鱼lu 发表于 2021-2-25 17:49
我不是说程序运行量大,而是这样要一个一个计算要移多少位,要往那个方向移。但数据有几十个,那就要算半 ...

做成一个函数就好了,我们公司12bit数据压缩到16bit数组里传输的,没那么复杂。
不如你贴出样例数据格式来,我不相信全部得手工算

出0入0汤圆

 楼主| 发表于 2021-2-25 18:34:06 | 显示全部楼层
wjd40 发表于 2021-2-25 17:54
你谷歌下 spi ws2812 ,这个用法很常见

不是这个

出0入0汤圆

 楼主| 发表于 2021-2-25 18:35:09 | 显示全部楼层
nanfang2000 发表于 2021-2-25 18:02
做成一个函数就好了,我们公司12bit数据压缩到16bit数组里传输的,没那么复杂。
不如你贴出样例数据格式 ...

做成函数也要计算往那个方向移位吧

出0入0汤圆

发表于 2021-2-25 18:46:16 | 显示全部楼层
3个32位的变量分别放3个10bit的数据,每个变量都移位好位置
00xxxxxxxxxx00000000000000000000
000000000000xxxxxxxxxx0000000000
0000000000000000000000xxxxxxxxxx
异或
然后给了一个32位的联合体
union  var
{
    u32  A;
    u16  a1;
    u16  a2;
}
a1 a2即为你要的16位数据

出50入0汤圆

发表于 2021-2-25 22:36:09 | 显示全部楼层
10bit,查表吧,额外消耗1024*2=2KB Flash而已。

出0入0汤圆

发表于 2021-2-25 23:42:18 | 显示全部楼层
楼上说的都是软件实现方案,我说说我想到的一种硬件方案:
硬件将 SPI 的 CLK 脚接在某一个 TIM 的 ETR 脚上,这样就可以利用 TIM 对 SPI_CLK 计数,然后配置 TIM 的一个通道工作在输出比较模式(CCx = 10 - 1),这样 TIM 就实现了计数16个脉冲, 前10个脉冲输出高电平, 后6个脉冲输出低电平,再将这个信号和 SPI_CLK 通过一个与门后输出到LED驱动芯片的CLK,这样就利用 TIM + 与门 实现了 SPI_CLK 的 "截断" 功能,16位数据只发送10个脉冲出去。

不过这样搞可能会对 SPI_CLK 速度有限制,又或者在某种情况下 SPI_CLK 会出现毛刺,没细想,仅提供一种思路方向,楼主可以考虑一下。

出0入0汤圆

发表于 2021-2-26 00:58:02 来自手机 | 显示全部楼层
本帖最后由 sbusr 于 2021-2-26 09:11 编辑
wjd40 发表于 2021-2-25 17:54
你谷歌下 spi ws2812 ,这个用法很常见


刚好前一阵倒腾了ws2812b。
目的是发10位数据,8和16,最小公倍数是40和80,取40位。
40位就是8位的5倍,也就是用5个字节,当作要发也的10个位。这40位,每4位对应真实数据10位里面的1位。
比如,要发0101010101这10位,就是要发00001111 00001111 00001111 00001111 00001111这40位。
but,时钟好像无法匹配,能给时钟做个分频吗?4分频,刚好

出10入120汤圆

发表于 2021-2-26 07:54:22 来自手机 | 显示全部楼层
用cpld做个驱动器

出615入1076汤圆

发表于 2021-2-26 08:05:26 | 显示全部楼层
最優解決方案是換 LED 驅動芯片:
https://www.amobbs.com/forum.php ... 25&pid=11556085

--------------------

我不喜歡 ws2812 還有其它幾款常見的,每個顏色只有 8 bit,不能優雅的調光,只能通過修改數據來調光,效率低,而且亮度調低了顏色位數就會少很多。

很早之前用過一款每個顏色 12 bit 的芯片,不過也不理想,數據多,Manchester 編碼,控制麻煩。

我上次幫朋友選型,找了很久,目前我找到比較完美的是: lc8822-2020
每個顏色依然是 8 bit,但是 3 個顏色共享一個 5 bit 亮度,控制有獨立的時鐘,速度高了十幾二十倍,用 SPI 的 2 線驅動很方便(不需要拼湊,內存中 1 bit 就是 1 bit 燈數據)。

手冊:
http://www.szledcolor.com/download/LC8822%202020.pdf

網站:
http://addressable-led.com/Products/addressable-led-chip.html

出0入8汤圆

发表于 2021-2-26 09:41:31 来自手机 | 显示全部楼层
dukelec 发表于 2021-2-26 08:05
最優解決方案是換 LED 驅動芯片:
https://www.amobbs.com/forum.php?mod=redirect&goto=findpost&ptid=574 ...

相见恨晚啊,这种亮度和色差分开调的设计很合理

出15入178汤圆

发表于 2021-2-26 12:46:15 | 显示全部楼层
比较简单的是选个支持10bits模式SPI的MCU,不过既然多发2bit也没问题,那么也就不用换芯片了。

出0入362汤圆

发表于 2021-2-26 14:55:29 | 显示全部楼层
换stm32f0不就行了, 从4位到16位都随便

出0入0汤圆

发表于 2021-2-26 16:32:44 | 显示全部楼层
泡泡鱼lu 发表于 2021-2-25 18:35
做成函数也要计算往那个方向移位吧

难道我理解有误,还要两个方向移位?一个方向不就行了吗
u32 combine(u16 data1, u16 data2, u16 data3)
{
    return (((u32)data1&0x3FF) << 22) | (((u32)data2&0x3FF) << 12) | (((u32)data3&0x3FF) << 2)
}

u32 data = combine(0x51, 0x52, 0x53);
spi_send_16bit(&data, 2);

出0入0汤圆

 楼主| 发表于 2021-2-27 09:03:45 | 显示全部楼层
nanfang2000 发表于 2021-2-26 16:32
难道我理解有误,还要两个方向移位?一个方向不就行了吗
u32 combine(u16 data1, u16 data2, u16 data3)
...

如果数据更多呢,会达到几十或上百个数据

出0入0汤圆

 楼主| 发表于 2021-2-27 09:04:07 | 显示全部楼层
tomzbj 发表于 2021-2-26 14:55
换stm32f0不就行了, 从4位到16位都随便

现在ST的芯片有点用不起

出0入0汤圆

 楼主| 发表于 2021-2-27 09:05:03 | 显示全部楼层
2nd 发表于 2021-2-26 12:46
比较简单的是选个支持10bits模式SPI的MCU,不过既然多发2bit也没问题,那么也就不用换芯片了。 ...

不换芯片,就要把10Bit排成16Bit的,只能通过移位,但很麻烦,因为数据比较多

出0入0汤圆

发表于 2021-2-27 09:35:05 | 显示全部楼层
tomzbj 发表于 2021-2-26 14:55
换stm32f0不就行了, 从4位到16位都随便

这个牛逼,太方便了

出0入362汤圆

发表于 2021-2-27 16:40:29 | 显示全部楼层
泡泡鱼lu 发表于 2021-2-27 09:04
现在ST的芯片有点用不起

本来想说用gd32, 结果查了一下gd32的几个系列还真没有这功能...

你看看其他国产山寨stm32吧

出0入0汤圆

发表于 2021-2-27 17:04:49 | 显示全部楼层
void USCI_SPI_Init(void)
{
    /* Configure USCI_SPI1 as a master, USCI_SPI1 clock rate 2 MHz,
       clock idle low, 16-bit transaction, drive output on falling clock edge and latch input on rising edge. */
    USPI_Open(USPI1, USPI_MASTER, USPI_MODE_0, 16, 2000000);
    /* Enable the automatic hardware slave selection function and configure USCI_SPI_SS pin as low-active. */
    USPI_EnableAutoSS(USPI1, 0, USPI_SS_ACTIVE_LOW);
}

新唐 你值得拥有%

出0入0汤圆

发表于 2021-2-28 18:19:48 | 显示全部楼层
泡泡鱼lu 发表于 2021-2-27 09:03
如果数据更多呢,会达到几十或上百个数据

for循环不就处理了吗,不管你几千几万个数据

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 01:41

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表