|
|
最近想试试用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);
}
}
}
|
|