浅要分析QI协议下无线充的编码方案和电路分析

作为盛世无线充电的研发人员,我最近把手上的资料和公司没涉密的一些资料整理了一下,希望大家对协议有一个大概的认识。上代码的时候也会好一些。毕竟英文文档大篇幅的看会很痛苦。
 
数据包部分预计两天左右跟新完毕。后面会上传解码的源代码。同时也对无线充的原理图进行解析。能力有限,如有错误还希望大家指正。互相学习。目前本人无线充的项目完成度是完成数据解码。5W,10W,12W后续会都有涉及。为了大家能有一个讨论的话题。第一帖先贴一下我的解码程序。
代码的话排版也不是很好,可以复制下来贴到本地整理一下格式。代码是放在定时器里面的。
位编码的方案:
协议规定时钟信号的频率应该是Fclk = 2(4%)KHZ,所以每一位的传输时间约500us,如下图所示:
 
0:500us的高电平,或者500us的低电平
1:250us高电平+250us低电平,或者250us低电平+250us高电平
值得一提的是电源接收器负载的纹波会在电源发射机的电流上面产生纹波,这样的情况下,会出现比特错误,如果纹波的频率与调制频率相近,则比特错误数量会非常高。
字节编码方案
电源接收器应使用11位异步串行格式传输数据字节。
起始位:位:0
数据位:低位在前,高位在后
效验位:数据位偶数个1,校验位为1,数据位奇数个1,校验位为0
停止位:位:1
以0x35示例:
 
数据包格式(接收器给发射器)
数据包由4部分组成,:前导、页眉、消息和校验和。
 


前导位:数据包包括4个以上的前导位,每个位都为“1”

包头和数据部分在下面另外说明,内容比较多。
校验位:包头和数据部分进行异或处理
数据包格式(发射器给接收器)
数据包由4部分组成,:包头、消息和校验和。
 




包头和数据部分在下面另外说明,内容比较多。
校验位:包头和数据部分进行异或处理
响应结构:
ACK:承认,接受请求
NAK:不承认,拒绝请求
ND:未定义,无法识别或者无效请求
 
数据包长度:




                       由包头可以获得数据包的长度。
 
 
 
电源发射端接收的数据包
struct WireTime VoitTime = {0x00,0x00,0x00,0x00};
struct WireCode VoitCode = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0000};

unsigned char xdata VoitCodeBuf[Len] = {0x00};


void Tim3_Irt(void) interrupt T3_VECTOR
{
        VoitTime.BitStu = 0x00;
        
        if(WIREIO != VoitTime.PinOldStu)
        {
                if((VoitTime.Tclk >= TIM250MSDOWN)&&(VoitTime.Tclk <= TIM250MSUP))
                {//'1'½ÓÊÕ£¬1ÓÉÁ¬ÐøÁ½´Î×é³É
                        if(VoitTime.LastClkStu)
                        {
                                VoitTime.LastClkStu = 0x00;
                                VoitTime.BitStu = 0x0C;                                        //λ1
                        }
                        else VoitTime.LastClkStu = 0x01;
                }
                else if((VoitTime.Tclk >= TIM500MSDOWN)&&(VoitTime.Tclk <= TIM500MSUP))
                {//'0'½ÓÊÕ,Èç¹û'1'½ÓÊÕµ½Ò»°ë¾ÍÊÕµ½0£¬ÄÇô¾ÍÐèÒªÆÁ±Îµô´íÎó'1'
                        if(VoitTime.LastClkStu)VoitTime.LastClkStu = 0x00;
                        VoitTime.BitStu = 0x03;                                                //λ0
                }
                else
                {
                        VoitTime.BitStu = 0x0E;
                }
                VoitTime.Tclk = 0x00;
                VoitTime.PinOldStu = WIREIO;
        }
        else
        {
                if(VoitTime.Tclk < 10)VoitTime.Tclk ++;
        }
        
        switch(VoitTime.BitStu)
        {
                case 0x00://ûÓÐÊÕµ½Êý¾Ý
                                                        break;
                case 0x0E://½ÓÊÕ´íÎó
                                                        memset(&VoitTime,0x00,sizeof(VoitTime));
                                                        memset(&VoitCode,0x00,sizeof(VoitCode));
                                                        break;
                case 0x0C://×Ö½Ú'1'
                                                        if(VoitCode.CodeStep == 0x00)
                                                        {//Òýµ¼Âë
                                                                VoitCode.BitCnt ++;
                                                        }
                                                        else
                                                        {
                                                                VoitCode.BitCnt ++;                                                        //Êý¾ÝλÔö¼Ó'1'
                                                                VoitCode.ByteData = (VoitCode.ByteData >> 1) | 0x8000;
                                                                if(VoitCode.BitCnt == 11)
                                                                {//Êý¾Ý½ÓÊÕÍê±Ï
                                                                        VoitCodeBuf[VoitCode.DataReceLen ++] = (unsigned char)((VoitCode.ByteData & 0x3FFF) >> 6);
                                                                        if(VoitCode.DataReceLen == 0x02)
                                                                        {
                                                                                if(VoitCodeBuf[1] <= 0x1F) VoitCode.DataSetLen = (VoitCodeBuf[1] >> 5) + 1;
                                                                                else if(VoitCodeBuf[1] <= 0x7F)VoitCode.DataSetLen = (VoitCodeBuf[1] >> 4);
                                                                                else if(VoitCodeBuf[1] <= 0xDF)VoitCode.DataSetLen = (VoitCodeBuf[1] >> 3) - 8;
                                                                                else VoitCode.DataSetLen = (VoitCodeBuf[1] >> 2) - 36;
                                                                                
                                                                                VoitCode.DataSetLen += 0x03;        //Êý¾Ý볤¶È + Ò»¸öÒýµ¼Î»£¬Ò»¸öЧÑé룬һ¸öÊý¾Ý°üÍ·
                                                                        }
                                                                        else if((VoitCode.DataReceLen == VoitCode.DataSetLen)&&(VoitCode.DataSetLen != 0x00))
                                                                        {
                                                                                Usart_SendArry(VoitCodeBuf,VoitCode.DataSetLen);
                                                                                memset(VoitCodeBuf,0x00,VoitCode.DataSetLen);
                                                                                memset(&VoitTime,0x00,sizeof(VoitTime));
                                                                                memset(&VoitCode,0x00,sizeof(VoitCode));
                                                                        }
                                                                        VoitCode.BitCnt = 0x00;
                                                                }
                                                        }
                                                        break;
                case 0x03://×Ö½Ú'0'
                                                        if((VoitCode.CodeStep == 0x00)&&(VoitCode.BitCnt >= 4))
                                                        {//Òýµ¼Âë
                                                                VoitCodeBuf[VoitCode.DataReceLen ++] = VoitCode.BitCnt;
                                                                VoitCode.BitCnt         = 0x01;                                //Òýµ¼Âë¼ÆÊýÇå³ý£¬²¢½«Æðʼλ¼ÆÈë×Ö½ÚÊý¾Ý
                                                                VoitCode.CodeStep = 0x01;                                //Òýµ¼Âë½áÊø
                                                        }
                                                        else
                                                        {
                                                                VoitCode.ByteData >>= 1;                                //¶ÁÈëÊý¾Ýλ
                                                                VoitCode.BitCnt ++;                                                        //Êý¾ÝλÔö¼Ó'1'
                                                        }
                                                        break;
        }
        PINTF0 &=~ 0x02;
}

官网地址:http://www.shengshiwireless.com

联系方式:

技术咨询及售前:张生 13536600262

售后:吕生 13246203996

公司地址:广东省佛山市乐从物联天下产业园B座429室

现在常用的都是电压+电流解码出数据,然后检测电压,检测电流,检测温度。(MCU被我去掉了,不要限制了大家的想象,这个图是我自己画的,建议大家去网上找找其他人的电路资料,因为毕竟是量产的,比我这个靠谱很多。而且这个图主要的目的是说明,也是参考网上的电路,希望不存在版权啥啥的问题)
电流检测和电流解码(低成本的话,就用一个358做着一些方面就好了。解码,电流检测都已经实现了,也可以进行异物检测了):
电流检测电路就是一个低通同向放大器,低通是为了滤除电路中高频的部分,主要就是那个100K以上的PWM,同时会保留低频的部分(2K的数据部分)电路中的H桥下面(Ic)有一个0.02的电阻这个用于将电流信号转换成电压,如果是1A的电流,则是0.02V,所以要通过运放来进行放大,这个可以根据自己的需求来重新设计。
如果是现在说的5W,15W,10W,电流不一样,可以设计一个电路完全包含的。计算方式就是同相放大器的计算方式。不会的小伙伴可以百度下,或者下面提问拉。


电流检测结束以后就是电流的解码(我上面图里面没有)这里由两个低通滤波器组成的比较器。这个电路我尝试用文字解释一下。听不懂就自己搞个仿真,用参数直接仿真一下就好。这两个滤波器的截至频率不一样,导致一个滤波效果好,交流波形会区域平缓,可以近视看作一条直线,另一个效果不好,会上下波动,也就是我手绘的那个效果
然后嘛,就是进行比较拉啦啦啦啦啦。会结果就是输出一个方波,然后单片机进行数据的解码。解码的内容见上一个文章。


电压检测和电压解码
电压检测是不需要运放的,只需要一个无源高通滤波器+一个无源低通滤波器中间再来一个二极管就可以进行电流检测(如果检测5V,12V,24V什么的比较高的电压,可以用电阻分个压),参数的设计保证2K和100K以上的频率的这两个的滤波。这里提一下LC线圈那边会产生一个和PWM同样频率的正弦波。

电压解码和电流解码一样,都是滤波器的组合。这里就不多说了!

好了,暂时就先这样,后面还有三部分的内容,一个是计算公式和程序。二个是解码,电流,电压这三个参数在系统中的作用。三是实现远距离无线充的理论基础。敬请期待。。。。。。。

猜你喜欢

转载自www.cnblogs.com/shengshiwireless/p/10799855.html