TCBUS学习笔记


前言

  tcbus类传感器注册的函数为:smoke_init()


#ifdef __TCBUS_VERSION__
    tpos_createTask(do_task_tc_bus, stk_task_tc_bus + (sizeof (stk_task_tc_bus) / sizeof (OS_STK)), NULL, (INT8S *) "TASK_TCBUS", TPOS_TASKPROPERTY_SYS); 
#endif

在这里插入图片描述

示波器反馈TCBUS波形图

在这里插入图片描述

主站发码时序

  PDC-B 协议规定:主站下行发码(命令帧)按字节(帧字符)进行,且需要插入一些控制码。这些控制码包括:帧间隔码(Frame Interval,FI)、时钟同步码(Clock Synchronization,CS)、字节延时(Single Byte Delay,SBD)和命令延时(Command Delay,CD)。PDC-B 主站发码时序如图所示。
在这里插入图片描述
(1)帧间隔码
  PDC-B 协议规定:主站发送每一条命令帧之前首先要持续一段时间的 TH 码,称为帧间隔码,其作用是隔离前后两帧报文。

(2)时钟同步码
  因为从站的mcu内部的自带时钟受温度影响较大,从而导致总线工作不正常。为此需要对从站RC时钟进行定期校准。PDC-B 协议规定:主站按帧字符格式发送时钟同步码 0x7F。其时序如图所示。
在这里插入图片描述
时钟同步码0x7F发送的时候:0111 1111
在这里插入图片描述
按照字节传输方式 0 1111 1110 1 11
  起始位(0)、8位数据位、1位偶校验位以及1~2位停止位(发码帧字符为12位、收码帧字符为11位)

说明
①主站时钟校准速率的典型值 Fcor=2.4Kbps,传递一个bit需要的时间的时间为Tcor ≈ 416.6us;
②t1~t4:发送时钟同步码 0x7F;(与图中一个低电平的下降沿和上升沿之间的间距△x间距近乎一致)
③TCS:同步时间,TCS=t1~t3=Tcor*8≈3333us;
④TCSD:时钟稳定延时(Clock Synchronization Delay,CSD),TCSD=t4~t5,要求 TCSD>3ms,典型值
TCSD=3.5ms;

从站进行 RC 时钟校准的流程如下:
  首先,在捕获到 t1 时刻的下降沿开始计时;然后,在捕获到 t3 时刻的下降沿计时结束;最后,根据 TCS进行 RC 时钟的校准。此外,为保证校准时钟稳定,要求持续一段时间(TCSD)的 TH 码。
如果从站不需要进行时钟校准,此部分内容可略过。

(3) 命令帧与字节延时
  主站在发送命令帧的过程中,为了满足 PDC-B 总线供电条件,每发送一个字节(帧字符)后需要判断是否需要插入字节延时。其依据是要发送帧字符(12 位数据)中 TH 码的个数,如果 TH 码的个数≥8,则该帧字符发送完毕后接着发送下一个帧字符,两者之间无需字节延时。否则,在当前帧字符发送完毕后插入字节延时。字节延时的计算公式如下:假设当前 12 位帧字符中 TH 码的个数为 n0,需发送字节延时 TH 码的个数为 N。如果 0≤n0<8,则 N≥24-3n0;否则 N=0。具体示例如表 3-4 所示。
在这里插入图片描述
命令帧与字节延时时序如图 3-9 所示。
在这里插入图片描述
说明:
①主站发送/从站接收命令帧速率的典型值 FMT=9.6Kbps,TMT ≈ 104.2us;
②t5~t9:发送命令帧和字节延时;
③TFC:帧字符发送时间,TFC=t5~t6 或 t6~t7;
④TSBD:字节延时时间(Single Byte Delay,SBD),TSBD=t7~t8;
⑤从站接收字节超时:从站在接收帧数据的过程中,如果接收到的连续两个字节时间间隔超时(Slave Bytes Timeout,SBT)则直接放弃该帧数据,并重新判断帧起始条件;要求 TSBT>3ms,典型值 TSBT = 10ms;

(4)命令延时
PDC-B 协议规定:
主站发送完一命令帧后,需插入命令延时,其目的是给从站预留帧解析时间,同时给从站充电。寻址方式不同,对应的延时时间不同,如表 3-5 所示。命令延时时序如图 3-10 所示。
在这里插入图片描述
在这里插入图片描述
写ID注册标识 3次
首先发 7F (时钟同步码)12×416um≈5ms,再发时钟稳定延时3.5ms
在这里插入图片描述
传输命令帧时,比特率为9600 104.2us/bit 1.25ms/字节 七字节的命令帧
由于每个命令帧的字节(帧字符)起始位置都是 0 因此将x0-x1之间的间隔设定为1.25ms 从 0x7F 开始以1.25ms 为移动窗 以长度为一位(104.2um)的低电平为起始,就可以 一字节 一字节的查找对应的 帧数据了。
其中命令帧的帧起始符是 0x7F,
在这里插入图片描述
其中以帧起始符为例:
每个帧字符包括 1 位起始位(0)、8 位信息位、1 位偶校验位(E)和 1~2 位停止位(1);其中,发码设置帧字符 12 位,收码设置帧字符 11 位。
在这里插入图片描述
因此 0x7F 的帧字符表示为: 0(起始) 1111 1110(8位数据位) 1(偶校验) 11(停止位): 0 1111 1110 1 11
在这里插入图片描述
按照帧格式规定 起始帧字符 后面跟着 帧长度LEN,如下图所示:
在这里插入图片描述
上图说明:
同样以1bit长度的低电平为12位帧字符的起始位,可以看出0x7f以帧长度LEN之间跟着几个位的高电平,这表示字节延时,由于tcbus的采用总线供电没有单独的电源线,因此在判断命令帧中高电平数目不足阈值时需要添加字节延时(高电平)用于主站给从站供电。(上图中0x7f中高定平数目大于阈值,本不需要供电)完全按照tcbus协议的字节延时规定如下图所示:在这里插入图片描述
接下来是控制码CTR(0xF7) :0 1110 1111 1 11 广播寻址方式,写,需要从站应答
接着是帧序号SER (0x01): 0 1000 0000 0 11
数据标识DI(0x60):0 0000 0110 0 11
数据DATA(0xB0)
帧校验FCS (0xB0 0xA4) 占两字节

扫描二维码关注公众号,回复: 12563850 查看本文章

这一帧命令帧传递完以后需要添加 命令延时

命令延时
PDC-B 协议规定:主站发送完一命令帧后,需插入命令延时,其目的是给从站预留帧解析时间,同时给从站充电。寻址方式不同,对应的延时时间不同,如表 3-5 所示。命令延时时序如图 3-10 所示。
在这里插入图片描述
但是USB-tcbus的上的延时是40ms 40ms 和21ms

1、主站发送置ID登录标识有效命令

(写)ID登陆标识 意思就是告诉从机可以ID登录了不需要从站回复

if(send_f8_state==0) //(写)ID登陆标识:置1有效,需要写三次
        {
    
    
            tpos_clrTaskWdt();
            tpos_abs_delay_ms(100);
            for(i=0; i<3; i++)
            {
    
    
                drv_uart_init(2,2400,USART_8E2);
                drv_uart2_write(buffer_7f,1);//时钟同步码   2400bps  12bit  一秒200字节   一字节需要5ms   这里要等发完再去延时
//长度为0就一定是发送完成了吗。需要看发送中断寄存器 UTXISEL 发送中断模式选择位 需要配置为10 当发送缓冲区为空时,产生中断并将相应的中断标志位置 1  
//PLIB_USART_TransmitterInterruptModeSelect(usart_id, USART_TRANSMIT_FIFO_EMPTY);
                while(check_send_complete(2)==0)
                    ;
                Delay_us(3550);//时钟稳定延时       
                drv_uart_init(2,9600,USART_8E2);
                for(send_count=0;send_count<sizeof(ID_join_valid);send_count++)
                {
    
    
                    drv_uart2_write(ID_join_valid+send_count,1);
                    while(check_send_complete(2)==0)
                        ;
                    delay_from_bit1count(*(ID_join_valid+send_count));    //每一帧字符后面的字节延时          
                }
                if(i<2)
                    Delay_us(40000);   //命令帧延时
                else
                    Delay_us(21000);
            }
            send_f8_state = 1;
            case_ser++;
        }

2、主站发送ID登录命令(读从站ID)

然后主机对从设备的ID进行读取:
  (读)ID登录,读一次有返回后就结束读取,存下此ID,执行下一个流程
          HEAD LEN CTR SER   DI   CS
INT8U ID_read[7] = {0x7F, 0xFB, 0xFF, 0x01, 0x3C, 0x00, 0x00};

3、从站应答主站回复自身ID

  由于tcbus收发报文共用一根总线,因此主站通过读从站回码片段的总线的状态,获取从站的回码数据。
  在某些特殊应用场合(例如,设备注册和事件上报),报文不按帧字符传输,而是按位传输。也就是设备注册时,从站设备注册时采用位传输(而不是12或者11位组成的帧字符),即8位一字节。

3.1、单从站回码

  应答ID登录标识 置零无效、写LA使能、写LA等一系列操作与实际连接了几个从站无关。
这时的波特率是:19200bps 每一位的占的时间间隔是 52.1us
单从站回码/主站收码速率的典型值 FSSR=19.2Kbps,TSSR≈52.1us;

  PDC-B 协议规定:当应答帧长度大于 10 个字节时,从站每发送 10 个字节(称为一个块)一停顿,主站给从站充电一定时间 TMBD(块延时),然后从站继续以 10 个字节为单位发送后续数据,直到发送完毕,时序如图 3-11 所示。
在这里插入图片描述

3.2、多从站回码(回复ID注册)

  多从站回码时序(现在无论是接连多个传感器还是单独一个传感器,回码都遵循多从站的回码时序(主站发送设备注册命令采用广播寻址方式,DI=0x3A、0x3B 或 0x3C 为特殊寄存器寻址。从站采用竞争上报机制上传设备 ID))

2.1 单传感器

在这里插入图片描述在这里插入图片描述
多从站回码/主站收码速率的典型值 FMSR=3.2Kbps,TMSR≈312.5us
下面是直接一个烟温传感器时,USB tc-bus上位机软件的报文分析:
只接一个传感器时,从站回码波形(局部):
在这里插入图片描述
从站回码波形(全局):
在这里插入图片描述
当只连接烟温传感器时,从节点(烟温传感器)回复ID(设备识别号):
  (读取id时候,传感器先回复高字节的高bit。id_buffer和真实地址字节序相反)
01 05 10 08 60 00 11 93 09 00 04 54
在这里插入图片描述
可见与从站设备的产品标识一致

2.2 多传感器
接下来是接两个传感器(烟温传感器、门磁开关传感器)
在这里插入图片描述
  PDC-B 协议规定:多从站同时回码按位进行、采用“竞争”机制,且需要插入一些控制码。这些控制码包括:多从站回码延时(Multiple Response Delay,MRD)、位确认码(Bit Confirm,BC)和收发冲突延时(Transmit and Receive Conflict,TRC)。多从站回码时序如图 3-12 所示。
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

3.3、设备巡检时的回码(单从站回码和多从站回码)

  在设备巡检时,被LA点名的设备除了上报自己身的LA地址(单从站回码)以后,若对应设备有事件需要上报(多从站回码),采用多从站回码,如图1所示。
如果从站有信息需要上报主站,则在t10’时刻发送应答请求位RF(RF=0),时间长度为312.5us;(多从站回码/主站收码速率的典型值FMSR=3.2Kbps)

在这里插入图片描述

图1 有事件上报从站应答时序

与没有事件上报的回码报文对比:
在这里插入图片描述

图2 无事件上报从站应答时序

  检测到RF位没有事件上报(RF=1),则延时40ms开始下一次巡检

4、主站发送置ID登录标识无效命令

  (写)ID登陆标识:置0无效

INT8U ID_join_unvalid[19] = 
HEAD  LEN CTR ADDR
{
    
    0x7F,0xEF,0xF5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x00,0x00};

0 1111 1110 1 11 7F
0 1111 0111 1 11 EF
0 1010 1111 0 11 F5
0 0010 1010 1 11 54
0 0010 0000 1 11 04
0 0000 0000 0 11 00
0 1001 0000 0 11 09
0 1100 1001 0 11 93

在这里插入图片描述
代码如下:

 else if(send_f8_state==2)//(写)ID登陆标识:置0无效
        {
    
    
            ID_join_unvalid[15] = case_ser; //写帧序号
            mem_cpy(ID_join_unvalid+3, id_buffer, 12);  //写设备ID
            crc = CRC16_XY_CN(ID_join_unvalid,17,0xff,0xff);   //CRC校验码
            mem_cpy_reverse(ID_join_unvalid+17,(INT8U *)(&crc),2);  
            drv_uart_init(2,2400,USART_8E2);
            drv_uart2_write(buffer_7f,1);  // 发送一字节的时钟同步码:0x7F
            while(check_send_complete(2)==0) // 等待发送完成
                ;
            Delay_us(3550); // 时钟同步延时
            drv_uart_init(2,9600,USART_8E2); // 更换9600波特率 准备发送命令帧ID_join_unvalid[]
            for(send_count=0;send_count<sizeof(ID_join_unvalid);send_count++)
            {
    
    
                drv_uart2_write(ID_join_unvalid+send_count,1);   //每次写一个字节
                while(check_send_complete(2)==0);//等待发送完成
                delay_from_bit1count(*(ID_join_unvalid+send_count));  //字节延时            
            } 
            //写完了ID登录标识报文9600 1.25×19字节
            tpos_abs_delay_ms(20); //延时20ms
            drv_uart_init(2,19200,USART_8E1);
            drv_tcbus_dir(TCBUS_DIR_RECE); //  总线接收控制位?
            drv_uart2_rece_ctl(1);//置一是使能接收器
            Delay_us(6590);//7.6ms
            drv_tcbus_dir(TCBUS_DIR_SEND);
            drv_uart2_rece_ctl(0);		
            for(i=0;i<10;i++)
            {
    
    
                data = drv_uart2_read();
                if((data>0)&&(data!=0xe0))
                {
    
    
                    tcbus_recv_buffer2[i] = data;
                }
            }
            Delay_us(14000);  //14ms
            drv_uart_init(2,19200,USART_8E1);
            drv_tcbus_dir(TCBUS_DIR_RECE);
            drv_uart2_rece_ctl(1);
            Delay_us(6590);//1ms
            drv_tcbus_dir(TCBUS_DIR_SEND);
            drv_uart2_rece_ctl(0);
            for(i=10;i<20;i++)
            {
    
    
                data = drv_uart2_read();
                if((data>0)&&(data!=0xe0))
                {
    
    
                    tcbus_recv_buffer2[i] = data;
                }
            }
            tpos_abs_delay_ms(21);
            send_f8_state = 3;
            case_ser++;            //  帧序号
        }

在这里插入图片描述
结合代码和波形,我们可以发现当主站发送置ID登陆标 识无效命令后,tcbus总线换为接收模式,接收单从站的回码(19200bps)

drv_uart_init(2,19200,USART_8E1);
drv_tcbus_dir(TCBUS_DIR_RECE); //  总线接收控制位?
drv_uart2_rece_ctl(1);//置一是使能接收器

上图中两个6570us的接收槽就是单从站回码的波形,波特率FSSR=19.2Kbps,每一位传输长度为:TSSR≈52.1us;10字节的总长度包含在一个接收槽中,每发送十字节(块发送)就要一个14ms的块延时:典型值 TMBD=14ms;
注:
PDC-B 协议规定:当应答帧长度大于 10 个字节时,从站每发送 10 个字节(称为一个块)一停顿,主站给从站充电一定时间 TMBD(块延时),然后从站继续以 10 个字节为单位发送后续数据,直到发送完毕。

drv_uart_init(2,19200,USART_8E1);
drv_tcbus_dir(TCBUS_DIR_RECE);
drv_uart2_rece_ctl(1);
Delay_us(6590);//7.6ms
drv_tcbus_dir(TCBUS_DIR_SEND);
drv_uart2_rece_ctl(0);	
for(i=0;i<10;i++)
{
    
    
   data = drv_uart2_read();
   if((data>0)&&(data!=0xe0))
   {
    
    
      tcbus_recv_buffer2[i] = data;
   }
}
Delay_us(14000);//14ms  单从站回码块延时  用于总线给从站充电

5、主站发送解除LA写保护命令

else if(send_f8_state==3)//解除LA写保护命令,参数写使能???
        {
    
    
            Write_enable[15] = case_ser;//写 帧序号
            mem_cpy(Write_enable+3, id_buffer, 12); //写从节点地址
            crc = CRC16_XY_CN(Write_enable,17,0xff,0xff);  // 算校验
            mem_cpy_reverse(Write_enable+17,(INT8U *)(&crc),2);  
            drv_uart_init(2,2400,USART_8E2);
            drv_uart2_write(buffer_7f,1);
            while(check_send_complete(2)==0)
				;
			Delay_us(3550);
            drv_uart_init(2,9600,USART_8E2);
            for(send_count=0;send_count<sizeof(Write_enable);send_count++)
            {
    
    
                drv_uart2_write(Write_enable+send_count,1);
                while(check_send_complete(2)==0)
                    ;
                delay_from_bit1count(*(Write_enable+send_count));              
            }
            tpos_abs_delay_ms(20);
            drv_uart_init(2,19200,USART_8E1);
            drv_tcbus_dir(TCBUS_DIR_RECE);
            drv_uart2_rece_ctl(1);
            Delay_us(6590);//7.6ms
            drv_tcbus_dir(TCBUS_DIR_SEND);
            drv_uart2_rece_ctl(0);		
            for(i=0;i<10;i++)
            {
    
    
                data = drv_uart2_read();
                if((data>0)&&(data!=0xe0))
                {
    
    
                    tcbus_recv_buffer2[i] = data;
                }
            }
            Delay_us(14000);//14ms  单从站回码块延时  用于总线给从站充电
            drv_uart_init(2,19200,USART_8E1);
            drv_tcbus_dir(TCBUS_DIR_RECE);
            drv_uart2_rece_ctl(1);
            Delay_us(6590);//10ms
            drv_tcbus_dir(TCBUS_DIR_SEND);
            drv_uart2_rece_ctl(0);
            for(i=10;i<20;i++)
            {
    
    
                data = drv_uart2_read();
                if((data>0)&&(data!=0xe0))
                {
    
    
                    tcbus_recv_buffer2[i] = data;
                }
            }
            tpos_abs_delay_ms(21);
            send_f8_state = 4;
            case_ser++;
        }

此步骤主站没有对于从站(传感器)的回码内容进行解析,由于从站只是恢复确认命令。

6、主站发送写LA命令

除了常规的主站发送写LA命令帧,从站接收应答以外,这个else if 函数还 增加了对传感器类型(烟雾、烟温一体、门磁开关)的判断并记录,以及传感器LA逻辑地址随检测到传感器数目的增加而增加。
在这里插入图片描述

if((tcbus_recv_buffer2[15]==0xf1)&&(tcbus_recv_buffer2[16]==0x46))//判断从站回码帧中数据标识DI。
            {
    
    
                tcbus_online[la_count].dev_la = logic_addr;
                mem_cpy(tcbus_online[la_count].dev_id,id_buffer,12);
                if(id_buffer[10]==0x04)//烟雾传感器
                {
    
    
                    tcbus_online[la_count].dev_type = 1;
                }
                else if(id_buffer[10]==0x05)//烟温一体传感器
                {
    
    
                    tcbus_online[la_count].dev_type = 2;
                    temp_smoke_dev_count++;//温度烟雾一体传感器个数
                }
                else//目前用作门磁开关  10是USB-PDC调试器
                {
    
    
                    tcbus_online[la_count].dev_type = 3;
                }
                la_count++;
                logic_addr++;
            }

2020/10/22小记:这里在读取从节点的回码报文时,实测出现了多个TCBUS传感器接在终端下方时,只有一个设备可以进入上述if函数,因此只实现了一个设备数目加一(重庆精品台区测试点:同时接烟温一体传感器以及门磁开关只能识别门磁设备数目加一,第二次运行到if语句时由于回码时序问题,tcbus_recv_buffer2[15]和[16]窜位,无法实现设备数目加一,然而在回复2801温度检测的报文时,需要先识别到设备数temp_smoke_dev_count才会检测温度,因此出现了 门磁开关与烟温一体传感器同时挂载在分支终端上时,无法读取温度信息)

7、主站发送读取UC用户编码命令(20字节以后没有读取)

在这里插入图片描述
目前这个还没有用到,固没有提取。

8、主站发送读取描述信息DESC命令 (20字节以后没有读取)

在这里插入图片描述
目前这个还没有用到,固没有提取。

if((data==0x00)&&(data_previous==0x84))//门磁开关开了&&(PRO_rece == 0x04)
      {
    
                                               
         switch_state &= (~(0x01<<(LA_rece-1))); //对应的位置设置为0                                
                                        //门磁开主动上报                                        
         if(0 == switch_event[LA_rece-1].switch_over_happend)//发生标志,1表示发生开门,0表示处于关门
          {
    
    
            switch_event[LA_rece-1].switch_over_happend = 1;
            reported_count[4]++;
           //PositiveReport_StateWord_ALL[9] |= 0x20;
            tpos_datetime(&switch_date_time);
            switch_event[LA_rece-1].switch_over_start_time[0][0] = switch_date_time.time.second;                                              
            switch_event[LA_rece-1].switch_over_start_time[0][1] = switch_date_time.time.minute;
            switch_event[LA_rece-1].switch_over_start_time[0][2] = switch_date_time.time.hour;
            switch_event[LA_rece-1].switch_over_start_time[0][3] = switch_date_time.time.day;
            switch_event[LA_rece-1].switch_over_start_time[0][4] = switch_date_time.time.month;
            switch_event[LA_rece-1].switch_over_start_time[0][5] = switch_date_time.time.year;                                                 
            mem_set(switch_event[LA_rece-1].switch_over_end_time[0], 0x00, 6);
            if(switch_event[LA_rece-1].switch_over_count == 0xFF) switch_event[LA_rece-1].switch_over_count = 0;
            switch_event[LA_rece-1].switch_over_count++;
            switch_over_newest = LA_rece-1;                                           
            if_gpio_event(1);
         }

9、主站读CRIT

10、主站写成功标识

11、主站读3次ID

  • 由于前面的第二步就是读从站的ID命令,这里又读一遍是查找下一个TCBUS设备,有回复就继续之前的流程2-10,若读取三次没有回复就表示没有未注册设备就break了

12、设备巡检

  • 主站发出巡检上报命令帧后,从站的回码包括两部分:一是巡检应答,即被点名到从站设备的应答;二是事件上报,即有事件需要上报的从站应答。
  • TC-BUS 通信规范规定:巡检应答时,被巡检到的从站仅上传自身LA(帧字符格式),但需按序、定时应答;主站根据应答信息确定从站状态是正常或不正常。当主站发现某一从站不能正确应答时,需通过多次巡检点名进行状态确认。事件上报时,从站采用采用“竞争”方式。
  • 巡检上报命令帧格式
    在这里插入图片描述
    巡检上报应答时序

猜你喜欢

转载自blog.csdn.net/luopeng12345/article/details/108996869
今日推荐