一个用电脑的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)
|