王昱顺 发表于 2024-1-6 13:00:49

lihappy 发表于 2024-1-6 08:20
学习了,程序里面已改加反相,只是目前好像还没办法用DMA传大量灯的数据,受Xdata大小限制。有点好奇市面上 ...

使用双缓冲可以实现DMA传输间隔不中断,这时候其实灯带就不受限于xdata的大小了。

因为灯带的流动多是程序实时生成或者是数组预存花样,生成的自然算是任意长度都可以。
程序空间存储流水花样的,可以利用双缓冲的时间做数据读取

简单的流程如下
开辟SPI-DMA缓冲区1,2,在xdata
time0: SPI-DMA刷新缓冲区1,从code数组读取数据到SPI-DMA缓冲区2
time1:SPI-DMA缓冲区1完成输出,进入中断。切换缓冲区2,开始输出
time2: SPI-DMA刷新缓冲区2,从code数组读取数据到SPI-DMA缓冲区1
time3:SPI-DMA缓冲区2完成输出,进入中断。切换缓冲区1,开始输出

如此循环可以完成超级长的灯带输出。
这里面可能存在一个小问题。就是不知道读内部flash的速度能不能跟上输出的速度。想来跟不上的话就只能在edata区域做预读了。

神农鼎 发表于 2024-1-6 13:19:34

读 DATA-FLASH, 也可以用 MOVC 来读的

嵌入式之路 发表于 2024-1-8 01:46:16

梁工你好,我下载试用了你的代码,正常工作。 但是看的不是太懂,我想请问下,51有没有可能纯使用IO翻转并且控制延时来模拟时序的1 和 0 。我试了其他的单片机, 单片机IO翻转的速度在50us 根本没办法用

梁工 发表于 2024-1-8 10:06:06

嵌入式之路 发表于 2024-1-8 01:46
梁工你好,我下载试用了你的代码,正常工作。 但是看的不是太懂,我想请问下,51有没有可能纯使用IO翻转并 ...
有的,最简单的就是直接IO输出,STC8系列这种1T单片机,都要加延时才行。下面是24MHz主频的程序,超简单:
void      Send_1us(void)
{
      NOP(16);      // 6+16T@24MHz
}

sbit      DIN = P0^0;
void      Send_byte(u8 color)      // 发送一个字节
{
      u8      i;
      i = 8;
      do
      {
                EA = 0;      //发送时禁止中断
                if((color & 0x80) != 0)                //数据1
                {
                        DIN = 1;
                        Send_1us();
                        DIN = 0;
                        EA = 1;                //发送完一个位数据后允许中断, 但任何中断处理时间要小于RES的50us.
                        NOP(6);                        // 6T @24MHz,
                }
                else                //数据0
                {
                        DIN = 1;
                        NOP(6);                        // 7T @24MHz,
                        DIN = 0;
                        EA = 1;                //发送完一个位数据后允许中断, 但任何中断处理时间要小于RES的50us.
                        Send_1us();
                }
                color <<= 1;
      }
      while(--i != 0);
}

void      Send_GRB(u8 g, u8 r, u8 b)
{
      Send_byte(g);
      Send_byte(r);
      Send_byte(b);
}

嵌入式之路 发表于 2024-1-8 11:13:59

梁工 发表于 2024-1-8 10:06
有的,最简单的就是直接IO输出,STC8系列这种1T单片机,都要加延时才行。下面是24MHz主频的程序,超简单: ...

谢谢你梁工,我烧录下 用逻辑分析仪抓一下看看时序

神农鼎 发表于 2024-1-9 08:41:58

SPI方案:
只用到MOSI驱动WS2812,但由于SPI的3个信号是捆绑在一起的,MISO、SCLK不能做它用。本例使用P1.3-MOSI输出驱动信号,用户可以切换到别的脚。
===将 MISO 不做其他用途;
===将 MISO管脚 先设置为对外输出0;
===MOSI 发送完成后,对外停止时输出的是 MISO 读到的状态, 0 ,这 STC-R&D 留了这么个绝活支持 WS2812B !!!

西点钟灵毓秀 发表于 2024-1-9 09:55:58

{:4_168:}

manzunzu 发表于 2024-1-9 15:12:31

有空试试

江哥 发表于 2024-1-10 04:25:48

WS2812B-60灯环-SPI-DMA-跑马灯.c(266): error C130: 'interrupt': value out of range

梁工 发表于 2024-1-10 09:18:00

江哥 发表于 2024-1-10 04:25
WS2812B-60灯环-SPI-DMA-跑马灯.c(266): error C130: 'interrupt': value out of range

拓展Keil的C代码中断号
https://www.stcaimcu.com/forum.php?mod=viewthread&tid=13
(出处: 国芯论坛-STC全球32位8051爱好者互助交流社区)
页: 1 [2] 3 4 5 6 7 8 9 10 11
查看完整版本: SPI-DMA输出控制WS2812三基色彩灯程序@8H系列/32G系列,不加反相器, CPU休息