求助:DMA_SPI驱动WS2812B
芯片:STC8H4K64TLCD功能:DMA_SPI模拟WS2812B数据
MOSI口:P3.4,外接2K下拉电阻
程序:
#include<STC8H.H>
#include<absacc.h>
#include<stdio.h>
#include<math.h>
#include <intrins.h>
//多次测试得不到想要验收,全部置零,5颗WS2818B驱动的全彩LED。
unsigned char xdata LED_DATA={0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,};
char *LED=&LED_DATA;
char (*R)=&RGB;
int xdata ENSPI=0; //DMA_SPI开始标志
/*------------------延时,WS2812B归零---------------*/
void Delay50us() //@32MHz
{
unsigned char i, j;
i = 3;
j = 17;
do
{
while (--j);
} while (--i);
}
/*------------------------------------------------------
DMA_SPI输出
SPIIF SPI中断 用于判断SPI是否完成
输出完成关闭SPI,P3.4输出低电平
--------------------------------------------------------*/
void SPI()
{
ENSPI=DMA_SPI_CR;
ENSPI&=0xC0;
if(ENSPI==0)
{
P34=0;
Delay50us();
DMA_SPI_AMT=119; //传输168字节。24*5=120字节
DMA_SPI_TXA=LED_DATA;//数据起始位。
SPCTL=0xD7;//1101 01116.使能SPI5主机模式,4空闲时钟线低电平,3前沿写 2后沿读 1:0主时钟2分频 16Mhz”
DMA_SPI_CR=0xC0; //11000000 开始DMA_SPI
}
}
//DM_SPI中断
void DMA_SPI_Routine(void)interrupt 49
{
SPCTL=0x00;//关闭SPI
P34=0;
DMA_SPI_CR=0x00; //关闭SPI_DMA
DMA_SPI_STA=0x00;//中断标志位清零
}
void main()
{
CLKSEL=0; //内部高速时钟 下载设置25.6MHZ
EA=1; //打开总中断
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x7f;
P3M0 = 0x10; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
/*---------------------SPI设置-----------------------------------------*/
P_SW2|=128; //1000 0000 允许访问片内SFR0FA00H~0FFFFHFB50-FB6F 触摸阈值寄存器
P_SW1=12; //00-- **0- MOSI输出设置P3.4 **=11
AUXR=0; //允许访问内部扩展RAM
DMA_SPI_CFG2=4; //00000100 不使用SS脚 SS脚P1.2”
DMA_SPI_CFG=0xCF; //1100 1111,允许DMA_SPI中断,允许发送禁止接收数据,中断优先最高 访问级最大
while(1)
{
SPI();
}
}
SCLK与MOSI脚波形
DMA_SPI传输时,每两个数据有500ns的时间间隙,间隙期间MOSI为高电平。
请问:在MOSI脚外部增加三极管反向电路能否行得通。是否有其他办法使得2个数据间隙MOSI为低电平
外加反向电路,问题解决了,能得到需要的延时了,另外如果外加三极管的话,要注意三极管截止时间问题。另外需要注意归零延时,短了会导致前面几颗LED不亮 MOSI口:P3.4,外接2K下拉电阻===为何 2K 下拉电阻,一般是加10K 上拉,加下拉的目的 ? 非要加 ? 10K ? 神农鼎 发表于 2022-12-31 08:01
MOSI口:P3.4,外接2K下拉电阻===为何 2K 下拉电阻,一般是加10K 上拉,加下拉的目的 ? 非要加 ? 10K ? ...
最初未考虑外部反向电路,WS2812B需要50us以上的低电平才能按接收到的数据点亮LED。下拉的目的是考虑DMA_SPI发送完成,关闭SPI后 P3.4自动输出低电平。思路没错,能点亮LED,但是因为DMA_SPI传输2个字节之间有500ns的间隙,这个时间MOSI是高电平。导致LED不能显示设置的颜色。所以最终是取消这个下拉电阻外加反向电路解决这个问题的。 您好,硬件原理图能给一份嘛 SPI方案:
只用到MOSI驱动WS2812,但由于SPI的3个信号是捆绑在一起的,MISO、SCLK不能做它用。本例使用P1.3-MOSI输出驱动信号,用户可以切换到别的脚。
===将 MISO 不做其他用途;
===将 MISO管脚 先设置为对外输出0;
===MOSI 发送完成后,对外停止时输出的是 MISO 读到的状态, 0 ,这 STC-R&D 留了这么个绝活支持 WS2812B !!!
页:
[1]