找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 26|回复: 0
打印 上一主题 下一主题
收起左侧

求助:STC8G1K08A SPI模拟WS2812单总线,电平时间不符合预期

[复制链接]
跳转到指定楼层
楼主
最近想试试用SPI模拟2812彩灯的单总线,理论上是可行的,因为SPI的特性是MOSI和MISO都是不归零码,只有需要改变的时候才改变,不会归零。理论上是可行的。
于是我就根据STC的手册写了简单的测试程序,手册给的很清楚,寄存器也很少,很快便测试完成,但是电平时间不及预期。
这次使用的是24MHZ主频的STC8G1K08A 8pin,SPI主频选择系统时钟4分频,也就是6MHZ,MOSI是P54。计算可得SPI在6mhz下传输1bit的时间是166.7ns,因此可以发送两个数据来模拟逻辑1和逻辑0。(要注意STC的SPI MOSI在空闲时会输出MISO读到的电平,因此需要关闭MISO的数字输入)
#define High_Code 0xf8//11111000
#define Zero_Code 0xC0//11000000

理论上来说逻辑0应该得到333ns高电平,1000ns高电平,但是实际测试并不是如此,高电平时间是正常的接近350ns,但是低电平时间长了接近一倍,有1700ns了
这是怎么回事呢?我用P33电平来检测程序执行的时间,结果确实没问题,1.5us左右,加上程序执行时间是合理的。但是不知道从哪多了几百ns时间,总不能是主循环循环到这里要几百ns吧?我手里没有双通道示波器,也就没法测试两个电平的相对关系了。
大家知道为什么吗?现在这个代码也不是不能用,2812彩灯只看高电平时间,低电平时间影响不大,但是如果之后做其他SPI控制,如果在传输期间也有这莫名其妙多出来的时间,会很影响使用的吧。
测试代码如下:
void WS2812_Init(bit If_STC8G1K08A_8Pin,unsigned char Pin_Sel){//对于STC8G1K08A 8Pin需要执行不同的引脚初始化
    //初始化,并决定是否为主机从机
    P_SW1 &= 0XF3;//B3B2 = 0;
    SPSTAT = 0XC0;//清零中断标志
    SPCTL = 0XD4;//SPEN = 1;SSIG = 1;先发高位;主机模式;时钟空闲低电平;后时钟沿采样;SPI CLK为sysclk/4;
    if(If_STC8G1K08A_8Pin){
        WS2812_PinSet_8Pin(Pin_Sel);}
    else{
        WS2812_PinSet(Pin_Sel);}
}

void SPI_Send_1_Byte(unsigned char SPI_Data){
    P33 = 1;
    SPDAT = SPI_Data;//写入后,硬件置SPIF = 0;
    while(!(SPSTAT & 0x80));//SPI控制器发送完数据后,退出while循环
    SPSTAT = 0xC0;//清空中断标志
    P33 = 0;
}
void main(){
    P_SW2 |= 0x80;
    P3IE = 0x04;
    P3M0 |= 0x08; P3M1 &= ~0x08;
    WS2812_Init(1,54);//是8PIN单片机,引脚选择P33
    while(1){
        if(P32){
        SPI_Send_1_Byte(Zero_Code);}
        else{
        SPI_Send_1_Byte(High_Code);
        }
    }
}


IMG_20260223_165223.jpg (1.82 MB, 下载次数: 0)

IMG_20260223_165223.jpg

IMG_20260223_165254.jpg (2.31 MB, 下载次数: 0)

IMG_20260223_165254.jpg
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1155837 发表于 2026-2-23 17:29 | 只看该作者
好消息,我将Send_1_Byte函数直接展开到主循环进行测试
    while(1){
    P33 = 1;
    SPDAT = Zero_Code;//写入后,硬件置SPIF = 0;
    while(!(SPSTAT & 0x80));//SPI控制器发送完数据后,退出while循环
    SPSTAT = 0xC0;//清空中断标志
    P33 = 0;
    }
结果很明显,现在观察到低电平时间只有1400ns了。
理论上传输11 00 00 00,这一个字节的时间,低电平时间是1us,但是实际上却是1.4us。
手册说,写SPDAT之后1bit时间之后,数据才会出现在SPI管脚上,也就是说这有166.7ns的延时。
结论是执行完P33 = 0,主循环回跳到P33 = 1这一行,中间隔了233.3ns?
测试了P33电平,结论确实如此。
大佬们,为什么主循环回跳需要这么长时间呢?
(图片为P33波形)

IMG_20260223_172845.jpg (2.38 MB, 下载次数: 0)

IMG_20260223_172845.jpg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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