这个实验是灯带上有30颗RGB灯,每颗芯片控制3颗RGB灯,要使这30颗灯全亮蓝色。
这个DIN就是输入口,它输出高电平或者低电平,然后将高低电平分配给OUTR(红),OUTG(绿),OUTB(蓝),硬件上用P0_6作为 输入口,配置的时候根据手册配置为输入。
发数据的时候首先高位先发,上面那个输出码型,就是输出高电平和低电平的占空比,
0码就是输出0,前提是输出0的时候要高电平要延时0.3us ,低电平要延时0.9us
1码就是输出1,前提是输出1的时候要高电平延时0.9us , 低电平要延时0.3us
下面那个Reset码也是比较重要的,当我们将24bit数据发送出去后,此时灯是不会亮的,它需要有一个大于80us的低电平过来,然后才会将刚刚发送过来的24bit数据应用到灯上。
发数据的时候如果R7~R0全为0,G7~G0全为0,B7~B0全位1,则亮蓝色,也可以显示其他的颜色,具体可以去找对应的RGB值。
上图是一个级联电路,也就是说当我传输3组数据给第一个芯片后,分配给第一个芯片的三颗灯,DOUT检测到后面还有数据,它就会把数据传输给DIN。
解题思路:定时器每0.3us进入中断,用一个标志位检测数据是否准备好,准备好了就等下一次中断进入发送数据,但是发送因为有占空比,也就是上面说的0码和1码,所以当定时器计时到了进入中断要发送数据,就给一个变量加1,加一次就是0.3us,加两次就是0.6us,加3次就是0.9us,0码就是输出0,前提是输出0的时候要高电平要延时0.3us ,低电平要延时0.9us ,下面有个判断time_cnt < 2就是为1次,也就是0.3us,而ime_cnt < 5,就是0.9us,按照这个逻辑进行发送。
u32 time_cnt;
u16 i=0,j=0,send_over_flag=1,temp;
uint8_t z;
uint8_t rgb_data[3] = {0X00,0X00,0XFF};
//0.31us
void inital_Timer3()
{
TH3 = (65536-5) >> 8; //存储高八位
TL3 = (65536-5); //存储低八位
T3CON = 0x04; //打开定时器3
IE1 |= 0x04; //打开中断
}
void IRQ_TIME3(void) interrupt T3_VECTOR
{
if(send_over_flag == 0) //发送未完成标志位
{
if(z == 0)//要发送逻辑0
{
time_cnt++; //定时器进来一次就加1,表示进来一次就是0.3us,
if(time_cnt < 2)
{
P0_6 = 1;
}
else if(time_cnt < 5)
{
P0_6 = 0;
if(time_cnt == 4)
{
time_cnt = 0;
send_over_flag = 1;
}
}
}
else if(z == 1) //要发送逻辑1
{
time_cnt++;
if(time_cnt < 4)
{
P0_6 = 1;
}
else if(time_cnt < 5)
{
P0_6 = 0;
if(time_cnt == 4)
{
time_cnt = 0;
send_over_flag = 1;
}
}
}
}
else //if(send_over_flag == 1) 1发送1bit完成,可以准备下一个bit
{
if(j > 8)
{
j = 0;
i++;
if(i > 3)
{
i = 0;
}
}
else if(j >= 0&&j <= 7) //j是位数,一个灯有24bit,数组定义了3个十六进制,一个十六进制就是8bit
{
temp = rgb_data[i]; //把8位赋值给临时变量
z=((temp<<j)&0x80); //先移位,再取出高位,例如1000 0000 第一次,i=0,左移没变化,还是取出1
if(z) //取出如果z为真,给1
{
z=1;
} //取出为假,给0
else
{
z=0;
}
j++;
send_over_flag = 0; //发送标志位表示数据准备好了,可以发送了
}
}
}
微信技术交流