用STC12C5A60S2開發(fā)96路信號(hào)輸出,可接485 多層主機(jī) ,自制串口通信協(xié)議
附件中有PDF版AD原理圖,源代碼 開發(fā)文檔。
原創(chuàng)。
上位機(jī)對(duì)于這些信號(hào)機(jī)的控制就是基于這塊--96路信號(hào)燈板。顧名思義,96路信號(hào)燈板可以同時(shí)實(shí)現(xiàn)對(duì)96個(gè)信號(hào)燈的控制,操作人員只需在上位機(jī)電腦端,發(fā)送通信協(xié)議,單片機(jī)做出應(yīng)答,外接設(shè)備軌道信號(hào)機(jī)實(shí)現(xiàn)列車指示作用。 左上角選定單片機(jī)型號(hào),數(shù)據(jù)通信端口號(hào);發(fā)送緩沖區(qū)發(fā)送通信協(xié)議,這塊96路信號(hào)燈板的通信協(xié)議為AB 02 01 07(主機(jī)地址,可根據(jù)現(xiàn)場實(shí)際情況進(jìn)行更改) 10(端口控制量,十六進(jìn)制) FF FF FF FF FF FF FF FF FF FF FF FF(十二路控制端口控制96路燈) 00 00 00 00 02(最后一位為奇偶校驗(yàn),可根據(jù)之前的數(shù)據(jù)進(jìn)行更改) CD。 二、96路信號(hào)燈板原理圖及PCB圖 96路信號(hào)燈板所用的控制原理是:STC12C5A60S2單片機(jī)通過操作P0口的電平高低,控制SN74HC573芯片,進(jìn)而控制四-十六譯碼器CD4514,然后譯碼器控制十二路信號(hào)燈的控制芯片SN74HC573和ULN2803,實(shí)現(xiàn)信號(hào)燈的亮滅。  
單片機(jī)源程序如下:
- /*-----------------------------------------------
- 名稱:串口通信
- 日期:2019.6.10
- 內(nèi)容: 多機(jī)通信,第一層機(jī),485通信 本機(jī)為輸出功能從機(jī) YN防485信號(hào)接收沖突
- ------------------------------------------------*/
- #include<stc12c5a60s2.h> //包含頭文件,一般情況不需要改動(dòng),頭文件包含特殊功能寄存器的定義
- #include<intrins.h>
-
- void datapro(); //總數(shù)據(jù)處理函數(shù)
- unsigned char a[20],c[25],b[25],ca[25]; //a[20]暫存數(shù)據(jù)包,一些計(jì)算在這個(gè)數(shù)組里面完成 c[25],ca[25]串口接收緩沖數(shù)據(jù)包
- sbit DE=P1^1; //485通信方向控制
- sbit W=P3^7; // 鎖存的地址輸出控制
- sbit LE=P3^6; //地址信號(hào)鎖存到573
- sbit XZ=P1^0; //信號(hào)控制線
- unsigned char flag=1,i=0,m=0,flag_1=0,flag_2=0; //地址信號(hào)鎖存 flag=1 串口發(fā)送完標(biāo)志,i=0,m=0,全局變量 為串口接收數(shù)組小標(biāo),flag_1=0,flag_2=0串口接收數(shù)據(jù)接收完標(biāo)志
- unsigned char address_1; //本機(jī)地址
- unsigned char YN=0,k=1; // k 接收數(shù)據(jù)時(shí) 轉(zhuǎn)義用 ;YN 串口接收狀態(tài)值
- unsigned char ZY_1=0,ZY_2=0;
- /*------------------------------------------------
- uS延時(shí)函數(shù)
- ------------------------------------------------*/
- void DelayUs2x(unsigned short int t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延時(shí)函數(shù)
- ------------------------------------------------*/
- void DelayMs(unsigned short int t)
- {
- while(t--)
- {
- //大致延時(shí)1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*------------------------------------------------
- 串口和心跳定時(shí)器初始化
- ------------------------------------------------*/
- void InitUART(void)
- {
- SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
- TMOD = 0x21; // TMOD: timer 1, mode 2, 8-bit 重裝
- PCON=0X80;
- TH1 = 0xFD; // TH1: 重裝值 253 波特率19200 晶振 11.0592MHz
- TH0 = 0x4b ; // TH0,TL0: 重裝值 15536 定時(shí)約50ms
- TL0 = 0xfd ;
- WDT_CONTR=0x3f; //看門狗
- IP =0x10; //串口優(yōu)先 ,心跳信息次之
- TR1 = 1; // TR1: timer 1 打開
- TR0 = 1; // TR0: timer 0 打開
-
- DE=0; //485通信默認(rèn)狀態(tài)為接收
-
- EA =1; //總中斷開
- ET0 = 1; //定時(shí)中斷開
-
-
-
- }
- /*------------------------------------------------
- 校驗(yàn)情況函數(shù)
- ------------------------------------------------*/
- void check(unsigned char x)
- { unsigned char j; //函數(shù)功能 告訴上位機(jī)奇偶校驗(yàn)的結(jié)果 暫時(shí)未用
- unsigned char d=0;
- a[1]=0x01; //ab 01 01 ad_1 x R cd
- a[2]=0x01;
- a[3]=address_1;
- a[4]=x;
-
- d=a[1]+a[2]+a[3]+a[4];
-
- if(d%2==0) a[5]=0x02;
- if(d%2==1) a[5]=0x01; //計(jì)算奇偶 奇數(shù) 01 偶數(shù) 02
-
- DE=1; //使485芯片處于發(fā)送狀態(tài)
- DelayMs(1);
- flag=1 ;SBUF=0xab; while(flag==1); //發(fā)送報(bào)文頭
- for(j=1;j<6;j++)
- {
- if(a[j]==0xfe||a[j]==0xab||a[j]==0xcd) { flag=1 ;SBUF=0xfe; while(flag==1); flag=1 ; SBUF=a[j]; while(flag==1); }
- else { flag=1 ;SBUF=a[j]; while(flag==1); }
- }
- flag=1;SBUF=0xcd;while(flag==1); //發(fā)送報(bào)文尾
- DE=0; //使485芯片回到接收狀態(tài)
- }
- /*------------------------------------------------
- 控制輸出函數(shù)
- ------------------------------------------------*/
- void control_out(void)
- {
- unsigned char A,j; //函數(shù)功能 開關(guān)量的輸出
- A=b[4]; //數(shù)據(jù)幀,,要輸出的字節(jié)數(shù)
- for(j=0;j<A;j++)
- {
- P0=j; //4-16譯碼地址
- LE=1; //573 使能引腳
- DelayMs(10);
- LE=0; //地址鎖存到地址存儲(chǔ)573芯片
- P0=b[j+5]; //要輸出的數(shù)據(jù)
- W=0;
- DelayMs(10);
- W=1; //已經(jīng)鎖存的地址信號(hào)輸出
-
- }
- }
- /*------------------------------------------------
- 接收數(shù)據(jù)處理程序
- ------------------------------------------------*/
- void datapro()
- {
- unsigned char d=0;
- unsigned char j,t;
- if((c[0]==0xab&&c[i-1]==0xcd)||(ca[0]==0xab&&ca[m-1]==0xcd)) // 數(shù)據(jù)報(bào)文頭報(bào)文尾確認(rèn)
- {
-
- if(flag_1==1) {for(j=0;j<25;j++) { b[j]=c[j];c[j]=0;} t=i;i=0;flag_1=0;} //數(shù)據(jù)存儲(chǔ)區(qū)轉(zhuǎn)移
- else if(flag_2==1) { for(j=0;j<25;j++) { b[j]=ca[j];ca[j]=0;} t=m;m=0;flag_2=0;} // 數(shù)據(jù)存儲(chǔ)區(qū)轉(zhuǎn)移
-
-
-
- for(j=1;j<(t-2);j++)
- {
- d=d+b[j] ;
- }
- if(d%2==0x00) d=0x02;
- else d=0x01; // 奇偶計(jì)算
-
- if(b[t-2]==d) //計(jì)算的奇偶與上位機(jī)發(fā)送過來的數(shù)據(jù)的奇偶校驗(yàn)字節(jié)相比較
- {
- if(b[1]==0x02&&b[2]==0x01&&b[3]==address_1) {/*check(0x01); */ control_out(); for(j=0;j<25;j++) {b[j]=0;} ;t=0; }
- //上位機(jī)發(fā)送過來的命令 本機(jī)發(fā)送給上位機(jī)校驗(yàn)情況,再控制輸出
- else if(b[1]==0x04) { for(j=0;j<25;j++) {b[j]=0;} ;t=0; }
- //上位機(jī)發(fā)送過來的命令 本機(jī)為輸出功能從機(jī),不作反應(yīng)
- else if(b[1]==0x05||b[1]==0x03){ for(j=0;j<25;j++) {b[j]=0;} ;t=0; }
- //上位機(jī)發(fā)送過來的多余數(shù)據(jù) 此為廣播方式進(jìn)行多級(jí) 多機(jī)通信弊端
- else if(b[1]==0x01) { for(j=0;j<25;j++) {b[j]=0;} ;t=0;}
- //上位機(jī)發(fā)送過來的上位機(jī)校驗(yàn)情況命令 ,本機(jī)為輸出功能機(jī),該命令是另外功能機(jī)的命令,所以不作反應(yīng),是廣播通信弊端
-
- }
- else { if(b[1]==0x02) {check(0x02); } //上位機(jī)發(fā)送過來的命令 校驗(yàn)失敗
- for(j=0;j<25;j++) {b[j]=0;} ;t=0;
- }
- }
-
- }
- /*------------------------------------------------
- 單片機(jī)心跳信息函數(shù)
- ------------------------------------------------*/
- void heartb()
- {
- unsigned char d=0;
- if(YN==0)
- {
- DE=1;
- DelayMs(1); // ab 05 ad1 R cd
- flag=1 ;
- SBUF=0xab;
- while(flag==1);
-
- flag=1 ;
- a[1]=0x05;
- SBUF=a[1];
- while(flag==1);
- flag=1 ;
- a[2]=0x01;
- SBUF=a[2];
- while(flag==1);
-
- flag=1;
- a[3]=address_1;
- if(a[3]==0xfe||a[3]==0xab||a[3]==0xcd) {SBUF=0xfe;while(flag==1);} ;
- flag=1 ;
- SBUF=a[3];
- while(flag==1);
- d=a[1]+a[2]+a[3];
- if(d%2==0x00) d=0x02;
- else d=0x01;
- flag=1;
- a[4]=d;
- SBUF=a[4];
- while(flag==1);
- flag=1 ;
- SBUF=0xcd;
- while(flag==1);
- DE=0;
- }
- }
- /*------------------------------------------------
- 主函數(shù)
- ------------------------------------------------*/
- void main (void)
- {
- unsigned char j;
- unsigned char x;
- x=5;
- P0M1=0X00;
- P0M0=0XFF;
- address_1=0x04; //本機(jī)地址
- for(j=0;j<25;j++)
- {
- a[j]=0;b[j]=0;c[j]=0; ca[j]=0; //數(shù)組初始化
- };
- InitUART();
- ES=1;
- b[4]=0x10; //數(shù)據(jù)長度 16個(gè)字節(jié)
- b[5]=0x00;
- b[6]=0x00;
- b[7]=0x00;
- b[8]=0x00;
- b[9]=0x00;
- b[10]=0x00;
- b[11]=0x00;
- b[12]=0x00;
- b[13]=0x00;
- b[14]=0x00;
- b[15]=0x00;
- b[16]=0x00;
- b[17]=0x00;
- b[18]=0x00;
- b[19]=0x00;
- b[20]=0x00;
- control_out(); //使所有信號(hào)輸出為0
- x=(x-1);
- XZ=1;
- while(1)
- {
-
- DelayMs(10);
- datapro();
-
- }
- }
- /*------------------------------------------------
- 串口中斷程序
- ------------------------------------------------*/
- void UART_SER (void) interrupt 4 //串行中斷服務(wù)程序
- {
- unsigned char Temp; //定義臨時(shí)變量
- if(RI) //判斷是接收中斷產(chǎn)生
- {
-
- RI=0; //標(biāo)志位清零
- Temp=SBUF;
-
- if(flag_1==0) // flag_1==1 表示按照協(xié)議接收到了一串完整的數(shù)據(jù)
- {
- YN=1; //YN=1表示串口處于接收狀態(tài)
- if(i==0&&Temp!=0xab){ YN=0;} //如果 接收到的第一個(gè)字節(jié)不是報(bào)文頭0xab,則放棄接收該字節(jié)
- else{
- if(Temp==0xfe)
- { if(k==1) {k++;ZY_1=0XFE;}
- else { k=1; ZY_1=0; c[i]=Temp;i++; } //轉(zhuǎn)義 處理
- }
-
- else {c[i]=Temp;
- if(c[i]==0xcd&&ZY_1!=0xfe) {flag_1=1; k=1;YN=0;} ; //判斷是否處于報(bào)文尾
- if(ZY_1==0xfe)if(c[i]==0xcd||c[i]==0xab){k=1; ZY_1=0;};
- i++;
- };
-
-
-
- }
- }
- else if(flag_2==0)
- {
- YN=1;
- if(m==0&&Temp!=0xab){ YN=0;}
- else{
- if(Temp==0xfe)
- { if(k==1) {k++;ZY_2=0XFE;}
- else { k=1;ZY_2=0;ca[m]=Temp;m++; } //轉(zhuǎn)義
- }
- else { ca[m]=Temp;
- if(ca[m]==0xcd&&ZY_2!=0xfe) {flag_2=1; k=1; YN=0;}
- if(ZY_2==0xfe){ if(ca[m]==0xcd||ca[m]==0xab){k=1;ZY_2=0;}; }
- m++;
- }
-
- } ;
-
- }
- }
-
-
-
- if(TI){flag=0; TI=0;}
- }
- /*------------------------------------------------
- 心跳中斷程序
- ------------------------------------------------*/
- void timer0(void) interrupt 1
- { static unsigned char n=0 ;
- n++;
- if(n==110) {WDT_CONTR=0x3f;/* heartb(); n=0;*/ } // 6秒 喂看門狗,發(fā)送心跳信息
- if(n==220) {WDT_CONTR=0x3f; heartb(); n=0; }
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
全部資料51hei下載地址:
|