当前位置:文档之家› 单片机串口通信C程序及应用实例

单片机串口通信C程序及应用实例

一、程序代码#include<STC12C5A.h>//该头文件可到网站下载#define uint unsigned int#define uchar unsigned charuchar indata[4];uchar outdata[4];uchar flag;static uchar temp1,temp2,temp3,temp;static uchar R_counter,T_counter;void system_initial(void);void initial_comm(void);void delay(uchar x);void uart_send(void);void read_Instatus(void);serial_contral(void);void main(){system_initial();initial_comm();while(1){if(flag==1){ES = 0;serial_contral();ES = 1;flag = 0;}elseread_Instatus();}}void uart_send(void){for(T_counter=0;T_counter<4;T_counter++){SBUF = outdata[T_counter];while(TI == 0);TI = 0;}T_counter = 0;}uart_receive(void) interrupt 4{if(RI){RI = 0;indata[R_counter] = SBUF;R_counter++;if(R_counter>=4){R_counter = 0;flag = 1;}}}void system_initial(void){P1M1 = 0x00;P1M0 = 0xff;P1 = 0xff; //初始化为全部关闭temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致temp = 0xf0;R_counter = 0;T_counter = 0;}void initial_comm(void){SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit ReloadPCON = 0x80; //波特率不加倍SMOD = 1TH1 = 0xfa; //baud: 9600;fosc = 11.0596IE = 0x90; // enable serial interruptTR1 = 1; // timer 1RI = 0;TI = 0;ES = 1;EA = 1;}void delay(uchar x){uchar i,j;for(i=0;i<x;i++)for(j=0;j<110;j++);}serial_contral(void){if(indata[3] == ((indata[0]^indata[1])^indata[2])){if(indata[1]== 0x01){P0 = 0xff;temp2 = P0; //读取四路输入// temp2 = temp2&0x0f;outdata[0] = 0xee;outdata[1] = 0x02;outdata[2] = temp2;outdata[3] = ((outdata[0]^outdata[1])^outdata[2]);uart_send();return;}if(indata[1]== 0x03){temp3 = indata[2];P1 = temp3; //控制六路输出return;}if(indata[1]==0x04){outdata[0] = 0xee;outdata[1] = 0x05;outdata[2] = temp3;outdata[3] = ((outdata[0]^outdata[1])^outdata[2]);uart_send();return;}}}void read_Instatus(void){P0 = 0xff;temp1 = P0; //读取四路输入if(temp1!=temp){delay(10);P0 = 0xff;temp1 = P0;if(temp1!=temp){temp = temp1;//P0 = 0xff;//temp = P0;//temp = temp&0x0f;outdata[0] = 0xee;outdata[1] = 0x06;outdata[2] = temp;outdata[3] = ((outdata[0]^outdata[1])^outdata[2]);uart_send();}}}//总结:原因在于串口中断接收一定要使用全局变量,并且这个变量R_counter和T_counter 要在主程序中初始化。

这样,当串口有数据进来时,系统进入中断接收程序,就不会出现数组混乱送出的问题。

二、原理图三、四路开关量输入/六路开关量输出通讯协议通信设置:波特率9600b/s8位数据位无校验位1位停止位命令格式:区别码(1字节)+ Command(1字节)+ Content(1字节)+ Xor(1字节)区别码:上位发送/单片机接收:0xff单片机发送/上位机接收:0xeeCommand = 0x01上位机命令单片机读取四路输入开关量的输入状态如:0xff + 0x01 + 0x00 + XorCommand = 0x02单片机返回四路输入状态给上位机此时,Content 的1字节中的低四位分别表示四路开关量的输入状态1表示输入高电平,0表示输入低电平第一路输入(第0位)第二位输入(第1位)第三路输入(第2位)第四路输入(第3位)如:假设某一时刻四路输入开关量的输入状态为0x03,上位机读取其状态为:0xee + 0x02 + 0x03 + XorCommand = 0x03上位机命令单片机控制六路输出的输出状态此时,Content 的1字节中的低六位分别表示六路开关量的输出状态1表示输出高电平,0表示输出低电平第一路输出(第0位)第二路输出(第1位)第三路输出(第2位)第四路输出(第3位)第五路输出(第4位)第六路输出(第5位)如:上位机欲设置某一时刻六路输出开关量的输出状态为0x01:0xff + 0x03 + 0x01 + XorCommand = 0x04上位机命令单片机读取六路输出开关量的输出状态如:0xff + 0x04 + 0x00 + XorCommand = 0x05 单片机返回六路输出状态给上位机此时,Content 的1字节中的低六位分别表示六路开关量的输出状态1表示输出高电平,0表示输出低电平第一路输出(第0位)第二路输出(第1位)第三路输出(第2位)第四路输出(第3位)第五路输出(第4位)第六路输出(第5位)如:某一时刻六路输出开关量的输出状态为0x01,上位机读取其状态为:0xee + 0x05 + 0x01 + XorCommand = 0x06四路输入状态发生变化时单片机读取其变化的状态并返回给上位机此时,Content 的1字节中的低四位分别表示四路开关量的输入状态1表示输入高电平,0表示输入低电平第一路输入(第0位)第二位输入(第1位)第三路输入(第2位)第四路输入(第3位)如:假设某一时刻四路输入开关量的输入状态为0x03,上位机读取其状态为:0xee + 0x06 + 0x03 + XorContent:表示四路输入开关量的输入状态(数据)或者六路输出开关量的输出状态(数据),在不使用它的命令格式中,它的值无意义,为通信方便,在不使用它的命令格式中,规定其值为0x00;Xor :从第一个字节开始到Xor的前一个字节(总共3个字节),做异或运算四、串口助手测试:读取四路输入开关量ff 01 00 fe控制六路输出的输出状态ff 03 XX Xor00 fc 全开01 fd 关闭右边第一个02 fe 关闭右边第二个04 f8 关闭右边第三个08 f4 关闭右边第四个10 ec 关闭右边第五个20 dc 关闭右边第六个3f c3 全关3e c2 开右边第一个3c c1 开右边第二个3b c7 开右边第三个37 cb 开右边第四个2f d3 开右边第五个1f e3 开右边第六个读取六路输出开关量的输出状态ff 04 00 fb简介:本文论述了一个简单的单片机串口通信作品,通过上位机和单片机通信,控制几路开关量的输入和输出。

只限于学习和参考之用,各部分均通过测试成功!是笔者工作和学习之总结,望大家多学习交流!2010-12-22 晚于上海难为。

相关主题