一個用電腦的com串口命令單片機控制開關輸出的小程序,如串口發送led0_open回車后,單片機點亮led0
請多指教!.......
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- /* 發一個用串口命令單片機控制開關輸出的小程序,如串口發送led0_open回車后,單片機點亮led0 */
- #include<reg51.h>
- #include<string.h> //后面有一個比較函數
- bit UART_Flag=0; //定義串口接收標志位
- idata unsigned char str[50]; //定義一數組,用于串口接收命令緩存
- unsigned char length=0; //數組長度從0開始
- unsigned char ID=0; //用于查找命令數組ID
- sbit led0=P1^0; //定義led接口
- sbit led1=P1^1; //同上
- sbit led2=P1^2; //同上
- sbit led3=P1^3; //同上
- sbit led4=P1^4; //同上
- sbit led5=P1^5; //同上
- sbit led6=P1^6; //同上
- sbit led7=P1^7; //同上
- code unsigned char *coun[16]= //命令數組(字符串數組必須定義為指針型),用于查找swtish case命令對應ID執行對應功能
- {
- {"led0_open"}, //ID 0
- {"led0_close"},
- {"led1_open"},
- {"led1_close"},
- {"led2_open"},
- {"led2_close"},
- {"led3_open"},
- {"led3_close"},
- {"led4_open"},
- {"led4_close"},
- {"led5_open"},
- {"led5_close"},
- {"led6_open"},
- {"led6_close"},
- {"led7_open"},
- {"led7_close"} //ID 15
- };
-
- code char *com_face[19]= //分配使用 idata\xdata\code.
- {
- " ~★★ ★★~* \r\n",
- " *★ ∴*★ * ∴°★\r\n",
- "★ *°★\r\n",
- "★°* 心想事成 *°★\r\n",
- " ★‘& ?*°∴°°☆☆★ *°☆☆\r\n",
- " ★ °∴°°☆°∴★*°☆∴新°∴*☆\r\n",
- " ★*°∴°°☆★∴°∴*°年°∴*°☆\r\n",
- " ★°∴★☆∴° ∴*快°∴*°☆\r\n",
- " ★ ☆∴*樂°∴°☆\r\n",
- " ﹨ ☆* ☆\r\n",
- " ﹨ ☆\r\n",
- " ﹨ │\r\n",
- " ﹨/ \r\n",
- " ▏\r\n",
- " ﹨● \r\n",
- " ■﹨\r\n",
- " A.y / ﹨\r\n",
- "-----------------------------------------------\r\n",
- " 串口通信測試v2.0\r\n"
- };
- /****************************************************************************************************
- // SCON D7 D6 D5 D4 D3 D2 D1 D0
- // 98H SM0 SM1 SM2 REN TB8 RB8 TI RI
- // SM0、SM1:串行口工作方式選擇 01 為方式1、8位異步通信、波特率可變。SM2多機通訊控制位
- // REN:接收允許控制位,TB8:要發送數據的第9位,RB8:接收到的數據的第9位。
- // TI: 發送中斷標志,RI:接收中斷標志。
- *****************************************************************************************************/
- void init() //串口初始化
- {
- /******************設定定時器*********************/
- TMOD=0X20; //定時器1定時器方式 工作模式2,可自動重載的8位計數器常把定時/計數器1以模式2作為串行口波特率發生器.
- TH1=0XFD; //11.0592 19200MHz=9600*2
- TL1=0XFD;
- ET1=0; //打開定時器中斷
- TR1=1; //打開中時器
- /*******************設定串口**********************/
- SCON=0X50; //選擇工作模式1使能接收,允許發送,允許接收
- /*******************設定中斷**********************/
- EA=1; //開總中斷
- ES=1; //打開串口中斷
- /****************設定波特率加倍*******************/
- PCON=0X80; //8位自動重載,波特率加倍
- }
- void UART_Send_Byte(unsigned char dat) //輸出一個字符
- {
- SBUF=dat; //把數據送給sbuf緩存器中
- while(TI!=1); //發送標志位 TI如果發送了為1,沒發送為0,沒發送等待,到了退出循環
- TI=0; //到了,TI清為0
- }
- void UART_Send_Enter() //改送回車換行(\r\n 或 0x0d、0x0a)
- {
- UART_Send_Byte(0x0d);
- UART_Send_Byte(0x0a);
- }
- void UART_Send_String(unsigned char *p) //串口發送字符串
- {
- EA=0;
- while(*p != '\0') //字符串會以 '\0'結束存在,遇到'\0'則結束發送
- {
- UART_Send_Byte(*p); //發送單個字符
- p++;
- }
- EA=1;
- }
- void UART_service() interrupt 4 //uart中斷服務 ,4為串口中斷
- {
- if(RI==1) //如果數據已經接收完,即RI=1
- {
- unsigned char m=SBUF; //m為計算機發送給串口的數據,例,open //總體思想是,計算機通知串口,我要發數據了
- RI=0; //收到清0
-
- if(m=='\r') //判斷m這位數據有無\r
- {
- UART_Send_Enter(); //回車換行
- str[length]='\0'; //數據最后位加0標志位表示發完了數據
- UART_Flag=1; // 傳 完 標 志 位
- }
- else if(m=='\n')
- { }
- else if(m=='\b') //b表退格 //下面幾句不要刪除
- {
- UART_Send_Byte('\b');
- UART_Send_Byte(' ');
- UART_Send_Byte('\b');
- length=length-1; //刪除了后總長度減一
- }
- else
- {
- str[length++]=m; //比如m為open,先傳0后傳p,length加一
- if(length>45) //命令緩存數組最大是50.
- length=0; //防止接收過長錯誤命令造成檔機
- UART_Send_Byte(m); //輸出 比如open
- }
- }
- }
- void Get_command_ID(unsigned char *str) //獲取命令在命令數組中的ID
- {
- for (ID = 0; ID < 16; ID++) //"16"為命令數組的層數
- {
- if(strcmp(coun[ID],str)==0) //"strcmp"函數用于命令數組的命令與接收到的命令進行對比,相同結果為0.
- break; //相同則結束對比
- }
- if (ID >= 16) //所有命令不符。
- {
- ID=255; //得到提示命令錯誤的ID
- }
- }
- void Command_function() //得到命令對應命令數組的層數ID后執行相對功能
- {
- switch(ID)
- {
- case 0: //命令數組第1個命令
- led0 = 0;
- UART_Send_String("led0_open OK\r\n\r\n");
- break;
- case 1: //命令數組第2個命令
- led0 = 1;
- UART_Send_String("led0_close OK\r\n\r\n");
- break;
- case 2:
- led1 = 0;
- UART_Send_String("led1_open OK\r\n\r\n");
- break;
- case 3:
- led1 = 1;
- UART_Send_String("led1_close OK\r\n\r\n");
- break;
- case 4:
- led2 = 0;
- UART_Send_String("led2_open OK\r\n\r\n");
- break;
- case 5:
- led2 = 1;
- UART_Send_String("led2_close OK\r\n\r\n");
- break;
- case 6:
- led3 = 0;
- UART_Send_String("led3_open OK\r\n\r\n");
- break;
- case 7:
- led3 = 1;
- UART_Send_String("led3_close OK\r\n\r\n");
- break;
- case 8:
- led4 = 0;
- UART_Send_String("led4_open OK\r\n\r\n");
- break;
- case 9:
- led4 = 1;
- UART_Send_String("led4_close OK\r\n\r\n");
- break;
- case 10:
- led5 = 0;
- UART_Send_String("led5_open OK\r\n\r\n");
- break;
- case 11:
- led5 = 1;
- UART_Send_String("led5_close OK\r\n\r\n");
- break;
- case 12:
- led6 = 0;
- UART_Send_String("led6_open OK\r\n\r\n");
- break;
- case 13:
- led6 = 1;
- UART_Send_String("led6_close OK\r\n\r\n");
- break;
- case 14:
- led7 = 0;
- UART_Send_String("led7_open OK\r\n\r\n");
- break;
- case 15:
- led7 = 1;
- UART_Send_String("led7_close OK\r\n\r\n");
- break;
- case 255:
- UART_Send_String("Error:-999 --> Command error\r\n\r\n");
- break;
- default:
- break;
- }
- }
- void main(void)
- {
- unsigned char i;
- P0=0xff;
- init();
- for (i = 0; i < 19; i++)
- {
- UART_Send_String(com_face[i]);
- }
- UART_Send_Enter();
- UART_Send_String("初始化......... OK!\r\n");
- while(1)
- {
- if(UART_Flag==1) //接收標志位表示接收完成
- {
- Get_command_ID(str); //查檢所收命令與命令數組所對應的導數
- Command_function(); //執行功能
- length=0; //長度清0
- // memset(str,'\0',50); //清空str命令緩存數組(memset函數須包含“string.h”頭文件)
- UART_Flag=0; //標志位清0
- }
- }
- }
復制代碼
所有資料51hei提供下載:
51 串口通信程序.7z
(660.33 KB, 下載次數: 91)
2018-3-2 09:52 上傳
點擊文件名下載附件
工程文件
|