C#: 串口(定时)控制下位机开关
1. 下位机
/********************************************************************************************* 出品: 杜洋工作室 DoYoung Studio 程序名: DB1-011 电脑控制电源插座 编写人: 杜洋 编写时间: 2013年01月17日 硬件支持: DB1(PCB1) 修改日志: 1-2013011723 完成开发,4路开关控制+全局开关 2-2013011900 加入5到11路的扩展项目 /********************************************************************************************* 说明: 请使用DBC软件进行控制。 DB1端串口波特率4800,每次接收2个字节的数据(数据头码+控制项目序号) /*********************************************************************************************/ #include <reg52.h> //头文件 #define HEAD 0x00//数据头码 sbit J1 = P1 ^ 3;//控制器接口定义 sbit J2 = P3 ^ 2;// sbit J3 = P1 ^ 4;// sbit J4 = P1 ^ 5;// sbit J5 = P1 ^ 7;//5-11路没有使用(第12路用作了全局开关) sbit J6 = P1 ^ 7;// sbit J7 = P1 ^ 7;// sbit J8 = P1 ^ 7;// sbit J9 = P1 ^ 7;// sbit J10 = P1 ^ 7;// sbit J11 = P1 ^ 7;// /*********************************************************************************************/ void DELAY_MS (unsigned int a){//毫秒级延时 unsigned int i; while( a-- != 0){ for(i = 0; i < 600; i++); } } /*********************************************************************************************/ void UART_init (void){//UART串口初始化函数 TMOD = 0x20; //定时器T/C1工作方式2 SCON = 0x50; //串口工作方式1,允许串口接收(SCON = 0x40 时禁止串口接收) TH1 = 0xF3; //定时器初值高8位设置 TL1 = 0xF3; //定时器初值低8位设置 PCON = 0x80; //波特率倍频(屏蔽本句波特率为2400) TR1 = 1; //定时器启动 } /**********************************************************************************************/ void main (void){ unsigned char UART_data1,UART_data2; //定义串口接收数据变量 unsigned int s; // DELAY_MS(1000);//延时防止下载时死机 UART_init();//串口初始化(查寻) while(1){ if (RI == 1){ //接收中断标志位为1时//接受数据头码 UART_data1 = SBUF; //接收数据 SBUF 为单片机的接收发送缓冲寄存器 RI = 0; //令接收中断标志位为0(软件清零) s=0; while (s<2000&&UART_data1==HEAD){//判断头码是否正确,等待时间过长时跳出。 s++; if (RI == 1){//开始接受控制数据 UART_data2 = SBUF;// RI = 0; switch (UART_data2){ case 0x01:J1=0;break;//第1路开 case 0x81:J1=1;break;//第1路关 case 0x02:J2=0;break; case 0x82:J2=1;break; case 0x03:J3=0;break; case 0x83:J3=1;break; case 0x04:J4=0;break; case 0x84:J4=1;break; case 0x05:J5=0;break; case 0x85:J5=1;break; case 0x06:J6=0;break; case 0x86:J6=1;break; case 0x07:J7=0;break; case 0x87:J7=1;break; case 0x08:J8=0;break; case 0x88:J8=1;break; case 0x09:J9=0;break; case 0x89:J9=1;break; case 0x0A:J10=0;break; case 0x8A:J10=1;break; case 0x0B:J11=0;break; case 0x8B:J11=1;break; case 0x0C:J1=0;J2=0;J3=0;J4=0;J5=0;J6=0;J7=0;J8=0;J9=0;J10=0;J11=0;break;//全局开关 case 0x8C:J1=1;J2=1;J3=1;J4=1;J5=1;J6=1;J7=1;J8=1;J9=1;J10=1;J11=1;break; default://冗余语句 break; } } } } } } /**********************************************************************************************/ //杜洋工作室 DoYoung Studio /*********************************************************************************************/
2. 添加图片资源
3. 设计上位机界面
4. 编写代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; namespace serialPortControl { public partial class Form1 : Form { //device 1 const byte DeviceOpen1 = 0x01; const byte DeviceClose1 = 0x81; //device 2 const byte DeviceOpen2 = 0x02; const byte DeviceClose2 = 0x82; //device 3 const byte DeviceOpen3 = 0x03; const byte DeviceClose3 = 0x83; //SerialPort Write Buffer bool Button1Statue; byte[] SerialPortDataBuffer = new byte[1]; public Form1() { InitializeComponent(); //窗口构造 } private void button1_Click(object sender, EventArgs e) { if (serialPort1.IsOpen) //串口打开就关闭 { try { serialPort1.Close(); } catch { } //确保万无一失 button1.BackgroundImage = Properties.Resources.Image2; //灭 Button1Statue = false; //按钮状态 } else { try { serialPort1.PortName = comboBox1.Text; //端口号 serialPort1.Open(); //打开端口 button1.BackgroundImage = Properties.Resources.Image1;//亮 Button1Statue = true; //按钮状态 } catch { MessageBox.Show("串口打开失败","错误"); } } } private void Form1_Load(object sender, EventArgs e) { SearchAndAddSerialToComboBox(serialPort1, comboBox1); } private void WriteByteToSerialPort(byte data) //单字节写入串口 { byte[] Buffer = new byte [2]{0x00, data }; //定义数组 if (serialPort1.IsOpen) //传输数据的前提是端口已打开 { try { serialPort1.Write(Buffer, 0, 2); //写数据 } catch { MessageBox.Show("串口数据发送出错,请检查.","错误");//错误处理 } } } private void SearchAndAddSerialToComboBox(SerialPort MyPort,ComboBox MyBox) { //将可用端口号添加到ComboBox string[] MyString = new string[20]; //最多容纳20个,太多会影响调试效率 string Buffer; //缓存 MyBox.Items.Clear(); //清空ComboBox内容 for (int i = 1; i < 20; i++) //循环 { try //核心原理是依靠try和catch完成遍历 { Buffer = "COM" + i.ToString(); MyPort.PortName = Buffer; MyPort.Open(); //如果失败,后面的代码不会执行 MyString[i - 1] = Buffer; MyBox.Items.Add(Buffer); //打开成功,添加至下俩列表 MyPort.Close(); //关闭 } catch { } } MyBox.Text = MyString[0]; //初始化 } private void button2_Click(object sender, EventArgs e) { int i = 0; try { i = Convert.ToInt32(textBox1.Text.Substring(0, 2)); //先处理两位数,如果出错就处理一位数 } catch { try { i = Convert.ToInt32(textBox1.Text.Substring(0, 1));//处理一位数 } catch { MessageBox.Show("请输入正确的数字"); //错误提示 return; //退出函数 } } if (serialPort1.IsOpen) //避免定时器浪费时间和用户等待 { if (i == 0) //如果是0的话程序认为是定时模式关 { //MessageBox.Show("已关闭定时模式","提示"); WriteByteToSerialPort(DeviceOpen1); //器件一开 button2.Enabled = false; //开按钮不能按了… return; } else { WriteByteToSerialPort(DeviceOpen1); //器件一开 timer1.Interval = i * 1000; //可以这样写,不需要计数器 timer1.Start(); //开定时器 button2.Enabled = false; //开按钮不能按了… } } } private void button1_MouseHover(object sender, EventArgs e) { button1.BackgroundImage = Properties.Resources.Image3;//鼠标指上去则使用Image3 } private void button1_MouseLeave(object sender, EventArgs e) { if (Button1Statue) //鼠标移开,返回原来状态 { button1.BackgroundImage = Properties.Resources.Image1; } else { button1.BackgroundImage = Properties.Resources.Image2; } } private void button3_Click(object sender, EventArgs e) { try { timer1.Stop(); //如果定时器没开,则错误处理 } catch { } button2.Enabled = true; WriteByteToSerialPort(DeviceClose1); //器件一关 } private void button5_Click(object sender, EventArgs e) { WriteByteToSerialPort(DeviceOpen2); //器件二开 } private void button4_Click(object sender, EventArgs e) { WriteByteToSerialPort(DeviceClose2); //器件二关 } private void button7_Click(object sender, EventArgs e) { WriteByteToSerialPort(DeviceOpen3); //器件三开 } private void button6_Click(object sender, EventArgs e) { WriteByteToSerialPort(DeviceClose3); //器件三关 } private void button8_Click(object sender, EventArgs e) { SearchAndAddSerialToComboBox(serialPort1, comboBox1); //扫描并讲课用串口添加至下拉列表 }
// 当timer1终结时,此函式被调用 private void timer1_Tick(object sender, EventArgs e) { button2.Enabled = true; //开按钮可以按 timer1.Stop(); //一定要先关闭定时器 WriteByteToSerialPort(DeviceClose1); //器件一关 } } }