0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

DALI通信的原理及實(shí)現(xiàn)方法

CHANBAEK ? 來源:博客園-斑鳩,一生。 ? 作者:博客園-斑鳩,一生 ? 2023-03-08 14:58 ? 次閱讀

在雙碳目標(biāo)下,具有調(diào)光功能的LED驅(qū)動電源是重要的分支。 DALI通信常用在LED的數(shù)字調(diào)光控制中,下文將通過C語言單片機(jī)結(jié)合,解釋DALI的原理及實(shí)現(xiàn)方法。

一、通信原理

1.1 DALI 的物理電平信號定義如下:

9.5~22.5V: 高電平或者DALI 空閑狀態(tài)

6.5~9.5V: 未定義

-6.5V~6.5V:定義為低電平


1.2 波特率:1200bps + 10%

1.3 DALI 負(fù)載最大短路電流<250mA

當(dāng)從機(jī)發(fā)生故障,例如短路時(shí),DALI總線上的電流,需要限制在250mA以下。

1.4 編碼方式

使用曼切斯特編碼,即上升沿為信號1,下降沿為信號0。

1.5 主機(jī)發(fā)送指令結(jié)構(gòu)

主機(jī)發(fā)送的包含1個(gè)起始位、1個(gè)地址位類型位、6個(gè)地址位、一個(gè)選擇位、8個(gè)數(shù)據(jù)位和兩個(gè)停止位。

1.6 從機(jī)回復(fù)指令結(jié)構(gòu)

從機(jī)向主機(jī)回復(fù)包含1個(gè)起始位、8個(gè)數(shù)據(jù)位和兩個(gè)停止位。

1.7 前向幀與后向幀時(shí)序約束

Te表示半個(gè)位的時(shí)間,即4.16.67uS;

兩個(gè)前向幀時(shí)間間隔大于22個(gè)Te;

前向幀與后向幀之間時(shí)間間隔為7~22個(gè)Te;

后向幀與前向幀之間時(shí)間間隔大于22個(gè)Te;

1.8 主機(jī)與從機(jī)的握手

主機(jī)在發(fā)送指令后,在等候響應(yīng)階段,

如果收到從機(jī)發(fā)送的”0xFF“,就會認(rèn)為從機(jī)接收成功;

如果在這個(gè)階段處于空閑狀態(tài),就會認(rèn)為從機(jī)沒有接收成功;

二、實(shí)現(xiàn)方法

2.1 硬件原理圖

下面的硬件主要是將DALI的電平信號,轉(zhuǎn)為單片機(jī)能夠接受的電平,下面那張是微芯公司DALI的參考通信電路。

2.1 從機(jī)接收思路及實(shí)現(xiàn)

本次從機(jī)的接收端,主要使用了一個(gè)邊沿檢測中斷和一個(gè)定時(shí)器中斷。

代碼思路:

1)由于空閑狀態(tài),接收端的電平為高電平,產(chǎn)生起始信號時(shí),需要從產(chǎn)生一個(gè)上升沿。 于是,使用了外部下降沿觸發(fā)中斷,并關(guān)閉邊沿觸發(fā)中斷;

2)檢測到第一個(gè)下降沿后,定時(shí)器定時(shí)到0.75個(gè)周期,0.75個(gè)周期后讀取第一位數(shù)據(jù),并修改定時(shí)器周期為1個(gè)數(shù)據(jù)位時(shí)長。

3)第二次定時(shí)結(jié)束時(shí)讀取第二位數(shù)據(jù),依次讀取后面的數(shù)據(jù)

4)當(dāng)讀到最后一位數(shù)據(jù)的時(shí)候,也就是LSB后的兩位時(shí),停止定時(shí)器,并初始化定時(shí)器為0.75個(gè)數(shù)據(jù)周期,然后開啟邊沿觸發(fā)中斷。

C語言程序:

1 //配置邊沿觸發(fā)及中斷
  2 void IO_Change_Init(void){  
  3     
  4     //Set the CN2 as the IO state change flag 
  5     CNEN1bits.CN2IE=1;//Open the IO state interrupt
  6     CNPU1bits.CN2PUE=0;//Disable the weak up
  7     
  8     IFS1bits.CNIF=0;//Clear the interrupt flag
  9     IPC4bits.CNIP=7;//Configure the interrupt level 7
 10     IEC1bits.CNIE=1;//Enable this interrupt
 11 }
 12 //檢測到第一個(gè)下降沿
 13 void __attribute__ ((__interrupt__,__no_auto_psv__)) _CNInterrupt(void){
 14    
 15    IFS1bits.CNIF = 0; //Clear the interrupt flag 
 16    
 17    //Disable the IO State Interrupt and start the Time
 18    T1CONbits.TON = 1;
 19    CNEN1bits.CN2IE = 0;
 20    
 21 }
 22 //配置定時(shí)器初使周期為0.75個(gè)數(shù)據(jù)位時(shí)長
 23 void Tim1_Init(void){
 24     T1CON = 0x0020;
 25     
 26     IEC0bits.T1IE = 1;
 27     IPC0bits.T1IP = 7;
 28     IFS0bits.T1IF = 0;
 29     
 30     TMR1 = 0;
 31     PR1 = 390;
 32     T1CONbits.TON = 0;
 33 }
 34 //在定時(shí)器中斷里面讀取數(shù)據(jù)
 35 void __attribute__((__interrupt__,auto_psv,__shadow__)) _T1Interrupt(void)
 36 {
 37     IFS0bits.T1IF = 0;
 38 
 39     if(LLC_DALI_Rx_Mode == 1)
 40     {
 41         switch(Timer_Num)
 42         {
 43             case 0:
 44                 Timer_Num++;
 45                 T1CONbits.TON = 0; //關(guān)閉定時(shí)器
 46                 PR1 = 520; //設(shè)置下一個(gè)定時(shí)時(shí)長為1個(gè)周期
 47                 TMR1 = 0;//初使化定時(shí)器初始值
 48                 T1CONbits.TON = 1;//開啟定時(shí)器
 49                 break;
 50             case 1:
 51                 if(_RB0 == 1 )Address_temp |= (1<<7);
 52                 Timer_Num++;
 53                 break;
 54             case 2:
 55                 if(_RB0 == 1 )Address_temp |= (1<<6);
 56                 Timer_Num++;
 57                 break;
 58             case 3:
 59                 if(_RB0 == 1 )Address_temp |= (1<<5);
 60                 Timer_Num++;            
 61                 break;
 62             case 4:
 63                 if(_RB0 == 1 )Address_temp |= (1<<4);
 64                 Timer_Num++;
 65                 break;
 66             case 5:
 67                 if(_RB0 == 1 )Address_temp |= (1<<3);
 68                 Timer_Num++;            
 69                 break;
 70             case 6:
 71                 if(_RB0 == 1 )Address_temp |= (1<<2);
 72                 Timer_Num++;        
 73                 break;
 74             case 7:
 75                 if(_RB0 == 1 )Address_temp |= (1<<1);
 76                 Timer_Num++;
 77                 break;
 78             case 8:
 79                 if(_RB0 == 1 )Address_temp |= (1<<0);
 80                 Timer_Num++;
 81                 break;
 82             case 9:
 83                 if(_RB0 == 1 )Command_temp |= (1<<7);
 84                 Timer_Num++;
 85                 break;
 86             case 10:
 87                 if(_RB0 == 1 )Command_temp |= (1<<6);
 88                 Timer_Num++;
 89                 break;
 90             case 11:
 91                 if(_RB0 == 1 )Command_temp |= (1<<5);
 92                 Timer_Num++;
 93                 break;
 94             case 12:
 95                 if(_RB0 == 1 )Command_temp |= (1<<4);
 96                 Timer_Num++;
 97                 break;
 98             case 13:
 99                 if(_RB0 == 1 )Command_temp |= (1<<3);
100                 Timer_Num++;
101                 break;
102             case 14:
103                 if(_RB0 == 1 )Command_temp |= (1<<2);
104                 Timer_Num++;
105                 break;
106             case 15:
107                 if(_RB0 == 1 )Command_temp |= (1<<1);
108                 Timer_Num++;
109                 break;
110             case 16:
111                 if(_RB0 == 1 )Command_temp |= (1<<0);
112                 Timer_Num++;
113                 break;
114             case 17:
115                 if(_RB0 == 1 )StopBit_temp |= (1<<1);
116                 Timer_Num++;
117                 break;
118             case 18:
119                 if(_RB0 == 1 )StopBit_temp |= (1<<0);
120                 Timer_Num++;
121                 break;
122             case 19:
123                    T1CONbits.TON = 0;//關(guān)閉定時(shí)器
124                    PR1 = 390;//設(shè)置下一個(gè)定時(shí)器周期為0.75個(gè)數(shù)據(jù)位時(shí)長
125                    TMR1 = 0;//定時(shí)器計(jì)數(shù)初始值置0
126                    CNEN1bits.CN2IE = 1;//開啟邊沿檢測中斷
127                    //數(shù)據(jù)獲取,這里還可以添加數(shù)據(jù)包檢驗(yàn)程序
128                    Command = Command_temp;
129                    Address = Address_temp;
130                    StopBit = StopBit_temp;
131 
132                    Command_temp = 0;
133                    Address_temp = 0;
134                    StopBit_temp = 0;
135                    Timer_Num = 0;
136                 break;
137         }
138     }
139     
140 
141

2.2 從機(jī)思路及實(shí)現(xiàn)

從機(jī)的回復(fù)相對較簡單,只需要在每半個(gè)數(shù)據(jù)位修改輸出引腳的電平。 分別發(fā)送1個(gè)起始位、8個(gè)數(shù)據(jù)位和兩個(gè)停止位。

代碼思路:

1)接收數(shù)據(jù)完成并定時(shí)等待8Te

2)發(fā)送一個(gè)引腳低電平,并設(shè)置下一個(gè)定時(shí)周期為Te,定時(shí)器初使值為0,并開啟定時(shí)器;

3)在后面的定時(shí)器中斷里面,發(fā)送起始位;

4)在后面的定時(shí)器中斷里面,發(fā)送數(shù)據(jù)位;

5)在后面的定時(shí)器中斷里面,發(fā)送停止位;

6)初使化發(fā)送數(shù)據(jù)計(jì)數(shù)變量,初始化定時(shí)器計(jì)數(shù)值為零,關(guān)閉定時(shí)器;

7)開啟邊沿觸發(fā)中斷;

C語言程序?qū)崿F(xiàn)

1   if(LLC_DALI_Tx_Mode == 1){
 2         switch(Timer_Num)
 3         {
 4             case 0:
 5                 //Send the Start Bit
 6                 _RF3 = 0;
 7                 T1CONbits.TON = 0;
 8                 PR1 = 260;
 9                 TMR1 = 0;
10                 T1CONbits.TON = 1;
11                 Timer_Num++;
12                 break;
13             case 1:
14                 _RF3 = 1;
15                 Timer_Num++;
16                 break;
17             case 2:
18                  //Send the Data Bits
19                 _RF3 = ((Transfer_Data & 0x80)>0)?0:1;
20                 Timer_Num++;
21                 break;
22             case 3:
23                 _RF3 = ((Transfer_Data & 0x80)>0)?1:0;
24                 Timer_Num++;            
25                 break;
26             case 4:
27                  _RF3 = ((Transfer_Data & 0x40)>0)?0:1;
28                 Timer_Num++;
29                 break;
30             case 5:
31                 _RF3 = ((Transfer_Data & 0x40)>0)?1:0;
32                 Timer_Num++;            
33                 break;
34             case 6:
35                 _RF3 = ((Transfer_Data & 0x20)>0)?0:1;
36                 Timer_Num++;        
37                 break;
38             case 7:
39                 _RF3 = ((Transfer_Data & 0x20)>0)?1:0;
40                 Timer_Num++;
41                 break;
42             case 8:
43                 _RF3 = ((Transfer_Data & 0x10)>0)?0:1;
44                 Timer_Num++;
45                 break;
46             case 9:
47                 _RF3 = ((Transfer_Data & 0x10)>0)?1:0;
48                 Timer_Num++;
49                 break;
50             case 10:
51                 _RF3 = ((Transfer_Data & 0x08)>0)?0:1;
52                 Timer_Num++;
53                 break;
54             case 11:
55                 _RF3 = ((Transfer_Data & 0x08)>0)?1:0;
56                 Timer_Num++;
57                 break;
58             case 12:
59                 _RF3 = ((Transfer_Data & 0x04)>0)?0:1;
60                 Timer_Num++;
61                 break;
62             case 13:
63                 _RF3 = ((Transfer_Data & 0x04)>0)?1:0;
64                 Timer_Num++;
65                 break;
66             case 14:
67                 _RF3 = ((Transfer_Data & 0x02)>0)?0:1;
68                 Timer_Num++;
69                 break;
70             case 15:
71                 _RF3 = ((Transfer_Data & 0x02)>0)?1:0;
72                 Timer_Num++;
73                 break;
74             case 16:
75                 _RF3 = ((Transfer_Data & 0x01)>0)?0:1;
76                 Timer_Num++;
77                 break;
78             case 17:
79                 _RF3 = ((Transfer_Data & 0x01)>0)?1:0;
80                 Timer_Num++;
81                 break;
82             case 18:
83                 //Send the stop bit;
84                 T1CONbits.TON = 0;
85                 TMR1 = 0;
86                 PR1 = 260<<2;
87                 T1CONbits.TON = 1;
88                 _RF3 = 1;
89                 Timer_Num++;
90                 break;
91             case 19:
92                    T1CONbits.TON = 0;  //關(guān)閉定時(shí)器
93                    CNEN1bits.CN2IE = 1;//開啟邊沿檢測中斷
94                    TMR1 = 0;  //定時(shí)器初始值置0
95                    PR1 = 260; //定時(shí)器周期設(shè)置為Te
96                    Timer_Num = 0;//初使定時(shí)器數(shù)據(jù)位計(jì)數(shù)
97                 break;
98         }
99     }

三、測試結(jié)果

3.1 從機(jī)發(fā)送測試

從機(jī)發(fā)送數(shù)據(jù)100,對應(yīng)二進(jìn)制為0b0110 0100,實(shí)際發(fā)送波形見下圖:

實(shí)際發(fā)送數(shù)據(jù)為0b01100100,發(fā)送正常。

3.2 主機(jī)發(fā)送從機(jī)識別測試

主機(jī)通過上位機(jī)發(fā)送調(diào)光指令為239,從機(jī)在線調(diào)試識別出來的數(shù)據(jù)為239。 接收正常。

四、小結(jié)

從機(jī)的接收程序,定時(shí)器的定時(shí)步長先是1.5個(gè)Te,然后是2個(gè)Te;

從機(jī)的發(fā)送程序,定時(shí)器的定時(shí)步長為1個(gè)Te;

從機(jī)的接收程序,邊沿觸發(fā)只觸發(fā)依次就關(guān)閉了。

從機(jī)的發(fā)送程序,發(fā)送完畢開啟邊沿觸發(fā)。

在定時(shí)器中斷里面,修改下一個(gè)定時(shí)時(shí)長,理論上可以做到每一個(gè)定時(shí)周期都不一樣,這思維可以用于實(shí)現(xiàn)更加復(fù)雜的功能。

注意:

1)以上代碼發(fā)送和接收是獨(dú)立的,沒有遵循通信的時(shí)序。 1.7節(jié)里面有具體時(shí)序要求,根據(jù)時(shí)序稍做修改就可以啦。

2)本次代碼,沒有考慮到時(shí)序有10%的誤差。 有待改善。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6023

    文章

    44375

    瀏覽量

    628288
  • 通信
    +關(guān)注

    關(guān)注

    18

    文章

    5876

    瀏覽量

    135304
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134011
  • DALI
    +關(guān)注

    關(guān)注

    4

    文章

    66

    瀏覽量

    20702
  • 驅(qū)動電源
    +關(guān)注

    關(guān)注

    22

    文章

    399

    瀏覽量

    42202
收藏 人收藏

    評論

    相關(guān)推薦

    照明照明控制系統(tǒng)中DALI總線調(diào)試方法

    隨著樓宇自動化和照明工業(yè)的快速發(fā)展,傳統(tǒng)的照明控制逐步被智能控制取代,DALI作為新的智能燈光控制協(xié)議,定義了電子鎮(zhèn)流器與控制器之間的通信方式,實(shí)現(xiàn)智能照明系統(tǒng)的自動化控制。那么如何快速調(diào)試照明控制
    的頭像 發(fā)表于 10-22 08:55 ?1.1w次閱讀

    什么是DALI?數(shù)字可尋址照明接口(DALI)的實(shí)現(xiàn)方法

    DALI是首字母縮寫,代表“數(shù)字可尋址照明接口”。這是一個(gè)國際標(biāo)準(zhǔn),可保證不同制造商的可調(diào)光鎮(zhèn)流器的互換性。
    的頭像 發(fā)表于 04-21 16:08 ?1.8w次閱讀
    什么是<b class='flag-5'>DALI</b>?數(shù)字可尋址照明接口(<b class='flag-5'>DALI</b>)的<b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>方法</b>

    DALI通信協(xié)議有什么想法嗎?

    嗨,伙計(jì)們,我是DALI的新成員,現(xiàn)在我需要在我的橙色PI零板上實(shí)現(xiàn)DALI主協(xié)議,有人對硬件要求有什么想法或建議嗎?謝謝。 以上來自于百度翻譯 以下為原文 Hi guys, I am new
    發(fā)表于 04-29 13:51

    ST7DALI-EVAL,在DALI可調(diào)光鎮(zhèn)流器應(yīng)用中需要微控制器進(jìn)行通信

    ST7DALI-EVAL,ST7 MCU電子鎮(zhèn)流器照明控制評估系統(tǒng)。在DALI可調(diào)光鎮(zhèn)流器應(yīng)用中需要微控制器進(jìn)行通信。通信協(xié)議和接口參數(shù)已由領(lǐng)先的照明設(shè)備制造商定義
    發(fā)表于 10-11 08:42

    采用SAMD2x參考設(shè)計(jì)的DALI從機(jī)堆棧,使用SAM D20實(shí)現(xiàn)DALI主站

    采用SAMD2x參考設(shè)計(jì)的DALI從機(jī)堆棧。該參考設(shè)計(jì)使用SAM D20實(shí)現(xiàn)DALI(IEC 62386)主站。 Dali master用于大理奴隸在樓宇自動化和家庭網(wǎng)絡(luò)中的控制照明
    發(fā)表于 05-27 12:28

    DALI - DALI電源調(diào)試的難點(diǎn)

    在介紹了大量的DALI標(biāo)準(zhǔn)背景和發(fā)展趨勢之后,我們還需要盡力解決產(chǎn)品落地和工程應(yīng)用中的痛點(diǎn),唯有如此,DALI生態(tài)才會有健康發(fā)展的可能。基于DALI標(biāo)準(zhǔn)的產(chǎn)品中,當(dāng)前應(yīng)用最廣的當(dāng)屬LED...
    發(fā)表于 10-29 09:22

    DALI系統(tǒng)的研究與開發(fā)

    DALI協(xié)議的開發(fā)背景和應(yīng)用范圍的基礎(chǔ)上,分析了DALI協(xié)議的電氣特性,編碼格式和傳輸規(guī)則。重點(diǎn)論述了DALI主從式模塊的設(shè)計(jì),該模塊采用MC68HC908KX8芯片為CPU,實(shí)現(xiàn)
    發(fā)表于 08-09 14:50 ?88次下載
    <b class='flag-5'>DALI</b>系統(tǒng)的研究與開發(fā)

    如何使用示波器分析DALI協(xié)議?

    隨著樓宇自動化和照明工業(yè)的快速發(fā)展,傳統(tǒng)的照明控制逐步被智能控制取代,DALI作為新的智能燈光控制協(xié)議,定義了電子鎮(zhèn)流器與控制器之間的通信方式,實(shí)現(xiàn)智能照明系統(tǒng)的自動化控制,那么,如何快速調(diào)試照明控制的
    發(fā)表于 06-14 17:13 ?1595次閱讀
    如何使用示波器分析<b class='flag-5'>DALI</b>協(xié)議?

    使用示波器分析DALI協(xié)議

    隨著樓宇自動化和照明工業(yè)的快速發(fā)展,傳統(tǒng)的照明控制逐步被智能控制取代,DALI作為新的智能燈光控制協(xié)議,定義了電子鎮(zhèn)流器與控制器之間的通信方式,實(shí)現(xiàn)智能照明系統(tǒng)的自動化控制,那么,如何快速調(diào)試照明
    發(fā)表于 11-08 11:42 ?12次下載
    使用示波器分析<b class='flag-5'>DALI</b>協(xié)議

    DALI解碼模塊調(diào)光

    、DALI功能具備完整的DALI接口功能,符合IEC 60929/IEC 62386標(biāo)準(zhǔn),兼容性好,可以兼容任何符合DALI協(xié)議的設(shè)備,通過輸入標(biāo)準(zhǔn)的DALI信號,
    發(fā)表于 07-25 01:02 ?716次閱讀

    DALI解碼

    接口功能,符合IEC 60929/IEC 62386標(biāo)準(zhǔn),兼容性好,可以兼容任何符合DALI協(xié)議的設(shè)備,通過輸入標(biāo)準(zhǔn)的DALI信號,實(shí)現(xiàn)產(chǎn)品的開關(guān)、調(diào)光、場景、群組、編址等功能。4、靈活性本模塊輸出
    的頭像 發(fā)表于 09-06 13:39 ?5211次閱讀

    DALI調(diào)色溫解碼

    DALI調(diào)色溫 一、概述(13923882807,QQ:813267849) 歡迎使用本公司的DALI解碼模塊,擁有DALI第一套協(xié)議 (DALI 1.0),
    的頭像 發(fā)表于 09-28 09:56 ?3577次閱讀

    DALI調(diào)光方案與DALI解碼模塊使用手冊介紹

    DALI解碼模塊使用手冊 一、概述 歡迎使用本公司的DALI解碼模塊,我公司擁有DALI第一套協(xié)議(DALI 1.0),DALI第二套協(xié)議(
    發(fā)表于 10-22 15:59 ?1.4w次閱讀

    DALI2.0-DALI2.1-DALI NFC調(diào)光解碼模塊協(xié)議方案

    DALI接口功能,符合IEC 60929/IEC 62386標(biāo)準(zhǔn),兼容性好,可以兼容任何符合DALI協(xié)議的設(shè)備,通過輸入標(biāo)準(zhǔn)的DALI信號,實(shí)現(xiàn)產(chǎn)品的開關(guān)、調(diào)光、場景、群組、編址等功
    發(fā)表于 11-23 21:54 ?1559次閱讀

    數(shù)字可尋址照明接口(DALI通信

    數(shù)字可尋址照明接口(Digitally Addressable Lighting Interface,DALI)已成為歐洲應(yīng)對能源危機(jī)的一項(xiàng)標(biāo)準(zhǔn),主要針對商業(yè)和工業(yè)用途。DALI是IEC 60929
    發(fā)表于 04-02 10:47 ?42次下載
    數(shù)字可尋址照明接口(<b class='flag-5'>DALI</b>)<b class='flag-5'>通信</b>