C#未完成----串口通信

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        SerialPort sp = new SerialPort(SerialPort.GetPortNames()[0].ToString(), 115200, Parity.None, 8, StopBits.One);
        bool isOpen = false;
        //bool isSetPorperty = false;     //是否设置串口的属性
        byte[] sendData = new byte[8];
        byte[] receiveData = new byte[8];

        char[] ch = new char[8];
        //ch[0]=(char)0xffff;
        
        //构造函数
        public Form1()
        {
            InitializeComponent();
            //sp = new SerialPort("COM1");
            sendData[0] = 0x20;   //命令标志,上位机请求命令
            sendData[1] = 0x24;  //命令信息,设置定时
            //数据位
            sendData[2] = 0x05;   //设置年为11年
            sendData[3] = 0x09;    //设置月份为9月
            sendData[4] = 0x15;     //设置天为21号
            sendData[5] = 0x00;        //第四位数据位没有用到置为0
            sendData[6] = 0x01;        //设置校验位为1
            sendData[7] = 0x0A;     //设置结束位。暂定0x00s表示
            SetPortProperty();
            sp = new SerialPort("COM1", 115200, Parity.None, 8, StopBits.One);

            ch[0] = (char)0xff;
            //Open_Com();
            

            //Receive_sendData();
        }

        //窗体加载时的初始化函数
        private void Form1_Load(object sender, EventArgs e)
        {
            this.MaximumSize = this.Size;   //设置窗体的大小不变
            this.MinimumSize = this.Size;
            this.MaximizeBox = false;       //关闭最大化窗口选项
            PC_Set_PortProperty();          //初始化串口COM1
        }







        //串口初始化函数
        private void PC_Set_PortProperty()
        {
            serialPort1.PortName = "COM1";      //设置串口名称
            serialPort1.BaudRate = 115200;         //设置串口的波特率

            //设置停止位//float f = 1;
            serialPort1.StopBits = StopBits.One;

            //设置数据位
            serialPort1.DataBits = 8;

            //设置为偶校验位
            serialPort1.Parity = Parity.None;

            //设置超时读取时间
            serialPort1.ReadTimeout = -1;

            //sp.sendDataReceived += new SerialsendDataReceivedEventHandler(sp.sendDataReceived);

            //打开串口
            Open_Com();
        }

        //打开串口
        private void Open_Com()
        {
            try 
	        {
                serialPort1.Open();
                //sp.Close();
        		//sp.Open();
                isOpen=true;
                lblStatus.Text = "打开串口成功!";
	        }
	        catch (Exception)
	        {
                lblStatus.Text = "打开串口时发生错误!";
	        }
        }

        //关闭串口
        private void Close_Com()
        {
            try
            {
                serialPort1.Close();
                isOpen = false;
                lblStatus.Text = "关闭串口成功!";
            }
            catch (Exception)
            {
                lblStatus.Text = "关闭串口时发生错误!";
            }
        }
        
        //数据发送方法
        public int Send_Data(byte[] sendDatas)
        {
            //检查sendDatas是否为空

            //检查串口的属性是否设置
            //if (!isSetPorperty)
            //{
            //    SetPortProperty();      //重新设置串口
            //    isSetPorperty = true;   //标志位置为true
            //}

            sendDatas[6] =Convert.ToByte(PC_Calculate_Parity(sendDatas));          //填充校验位
            MessageBox.Show(sendDatas[6].ToString());
            //写串口数据
            if (isOpen)
            {
                try
                {
                    for (int i = 0; i < 8; i++)
			        {
                        serialPort1.WriteLine(sendDatas[i].ToString());
			        }
                    MessageBox.Show("发送成功!");
                    return 1;
                }
                catch (Exception)
                {
                    lblStatus.Text = "发送数据时发生错误!";
                    return 0;
                }    
            }
            return 0;
        }

        //接收串口数据
        public int Receive_Data()
        {
           
                if (isOpen)
                {
                    try
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            //if (sp.ReadLine()!="")
                            //{
                                //tbxRecvData.Text += sp.ReadLine() + "\n";
                            //tbxRecvData.Text += serialPort1.ReadLine()+ "\n";
                            receiveData[i] = Convert.ToByte(serialPort1.ReadLine());
                            //serialPort1.Read(receiveData, 0, 8);
                            //serialPort1.Read(receiveData, 1, 8);
                            tbxRecvData.Text += receiveData[i] + "\r\n" + Environment.NewLine;
                            //}
                            //else
                            //{
                            //    lblStatus.Text = "数据流为空!";
                            //}
                            
                        }
                        PC_Check_Data(receiveData);         //检验数据是否正确
                        return 1;
                    }
                    catch (Exception)
                    {
                        lblStatus.Text = "读取串口1时发生错误!";
                        return 0;
                    }
                }
                else
                {
                    MessageBox.Show("串口未打开!", "错误提示");
                    //SetPortProperty();
                    try
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            tbxRecvData.Text += serialPort1.ReadLine() + "\n";
                        }
                        return 1;
                    }
                    catch (Exception)
                    {
                        lblStatus.Text = "读取串口2时发生错误!";
                        return 0;
                    }
                }
            
            return 0;
        }

        //上位机偶校验函数
        private int PC_Calculate_Parity(byte[] Datas)
        {
            int[] check = new int[6];
            int sum=0;
            int num = 0xAA,count=0;
            char a = (char)0xAf;
            //while (num > 0)
            //{
            //    //一个数的二进制表示中1的个数算法为:此数减1,再与自身相与,以此循环,直至该数小于等于0为止。循环的次数即为1的个数
            //    num = (num - 1) & num;
            //    count++;
            //}
            //MessageBox.Show(count.ToString());
            for (int i = 0; i < 6; i++)
            {
                //for (int j = 0; j < 8; j++)
                //{
                //    int s = (a & (0x01 << j));
                //    MessageBox.Show(s.ToString());
                //    if ((Datas[i] & (1 << j)) == 1)
                //    {
                //        check[i] += 1;
                //    }

                //}



                check[i] = Convert.ToInt32(Convert.ToString(Datas[i], 16)) + 0x00;

                //check[i] = 0xf0;
                while (check[i] > 0)
                {
                    //一个数的二进制表示中1的个数算法为:此数减1,再与自身相与,以此循环,直至该数小于等于0为止。循环的次数即为1的个数
                    check[i] = (check[i] - 1) & check[i];
                    sum++;
                }
                MessageBox.Show(sum.ToString());
            }

            if (sum % 2 == 1)
                return 1;
            else
                return 0;
        }

        //检测偶校验
        private int PC_Check_Data(byte[] Datas)
        {
            int[] check = new int[6];       //存储每个字节1的个数
            int sum = 0;                    //存储前6个字节1的个数
            
            for (int i = 0; i < 6; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    
                    if ((Datas[i] & (1 << j)) == 1)
                    {
                        check[i] += 1;
                    }
                }
                sum += check[i];
            }

            sum +=Convert.ToInt32(Datas[6]);        //加上奇偶校验位
            if (sum % 2 == 0)                   //偶校验,说明数据正确
            {
                lblStatus.Text = "数据正确!";
                return 1;
            }
            else
            {
                lblStatus.Text = "数据失败!";
                return 0;
            }
                
        }







        //接收数据时触发次方法
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Receive_Data();
        }


        //发送按钮
        private void btnSend_Click(object sender, EventArgs e)
        {
            Send_Data(sendData);
        }

        //退出按钮
        private void btnExit_Click(object sender, EventArgs e)
        {
            Close_Com();
            this.Close();
        }

    }
}




/*******************************************************************************
*File: UART.C
*功能: 串口驱动程序(中断方式接收)
*说明: 使用外部晶振,Fpclk=Fcclk/4
*波特率除数计算:UxDLM,UxDLL=Fpclk/16*波特率
*******************************************************************************/

#include   "config.h"
#include "lcd12864.h"

#define  LED1CON    0x00000800          //P0.11引脚控制LED1,低电平点亮    

uint8  sCount=0;       //用于接收时计数,为当前所赋值的结构体成员,结构体总共有八个成员

//数据结构体
struct receiveData
{
    unsigned  char cmd;            //命令标志
    unsigned  char cmd_info;        //命令信息
    unsigned  char option_first;        //可选择的信息1
    unsigned  char option_second;    //可选择的信息2
    unsigned  char option_third;        //可选择的信息1
    unsigned  char option_four;    //可选择的信息2
    unsigned  char check;            //校验
    unsigned  char end;            //结束标志  暂时定位  0A 表示回车    
}receData={'h','e','l','l','o','g','o','d'};

struct receiveData *stu=&receData;

void UART_SendByte(uint8 data,uint8 num);
//void UART_SendStr(uint8 *str,uint8 num);
void LPC_Send_Str(struct receiveData *str,uint8 num);
char LPC_Check_Data(struct receiveData *str);

/*******************************************************************************
*名称:LPC_Open_Com()
*功能:下位机打开串口
*******************************************************************************/

void LPC_Open_Com()
{
    PINSEL0|=0xFFF5FFFF;                         //设置IO连接到UART1
}

/*******************************************************************************
*名称:LPC_Close_Com()
*功能:下位机关闭串口
*******************************************************************************/

void LPC_Close_Com()
{
    PINSEL0|=0xFFF0FFFF;                         //设置IO连接到UART1
}


/*******************************************************************************
*名称: LPC_Receive_Str(void)
*功能: UART1接收中断
*******************************************************************************/

__irq void LPC_Receive_Str(void)
{
    uint32 i;
    
    i=IOSET;
    if((i & LED1CON)==0)  
        IOSET=LED1CON;
    else
        IOCLR=LED1CON;

    //if((U1IIR & 0x0F)==0x04)        //接收数据可用
    
    switch(sCount)
    {
        case 0: (*stu).cmd=U1RBR;sCount++;UART_SendByte((*stu).cmd,1);while((U1LSR&0x20)==0);break; 
        case 1:    (*stu).cmd_info=U1LSR;sCount++;UART_SendByte((*stu).cmd_info,1);while((U1LSR&0x20)==0);break;
        case 2:    (*stu).option_first=U1LSR;sCount++;UART_SendByte((*stu).option_first,1);while((U1LSR&0x20)==0);break;
        case 3:    (*stu).option_second=U1LSR;sCount++;UART_SendByte((*stu).option_second,1);while((U1LSR&0x20)==0);break;
        case 4:    (*stu).option_third=U1LSR;sCount++;UART_SendByte((*stu).option_third,1);while((U1LSR&0x20)==0);break;
        case 5:    (*stu).option_four=U1LSR;sCount++;UART_SendByte((*stu).option_four,1);while((U1LSR&0x20)==0);break;
        case 6:    (*stu).check=U1LSR;sCount++;UART_SendByte((*stu).check,1);while((U1LSR&0x20)==0);break;
        case 7:    (*stu).end=U1LSR;sCount=0;UART_SendByte((*stu).end,1);while((U1LSR&0x20)==0);break;          //最后一位接收完成后,将sCount清零
        default  :break;
    }
    

    LPC_Check_Data(stu);
   
    VICVectAddr=0x00;
}

/*******************************************************************************
*名称: LPC_UART_Init()
*功能: 初始化串口0、1.设置为8位数据位,1位停止位,无奇偶校验,波特率为115200,
*      Fcclk=Fosc*4=11.0592*4MHz,Fpclk=Fcclk/4=11.0592MHz/4=11.0592MHz
*******************************************************************************/

void LPC_UART_Init(void)
{  
    U1LCR=0x83;                       //设置为8位数据位,1位停止位,无奇偶校验
    U1DLL=6;                          //除数锁存寄存器低8位,波特率为115200
    U1DLM=0x00;                       //除数锁存寄存器高8位
    U1LCR=0x03;                       //禁止访问除数锁存寄存器

    U0LCR=0x83;                       
    U0DLL=6;
    U0DLM=0x00;
    U0LCR=0x03;
}

/*******************************************************************************
*名称: UART_SendByte()
*功能: 向串口发送字节数据,并等待发送完毕
*******************************************************************************/

void UART_SendByte(uint8 data,uint8 num)
{   
    if(num==0)
    {
        U0THR=data;                      //发送保持寄存器
        while((U0LSR&0x20)==0);          //等待数据发送完毕    
    }

    if(num==1)
    {
        U1THR=data;                      //发送保持寄存器
        while((U1LSR&0x20)==0);          //等待数据发送完毕    
    }    
}


/*******************************************************************************
*名称:LPC_Calculate_Parity()
*功能:偶校验函数  返回1表示stu中有奇数个1;返回0则表示stu中正好有偶数个1
*******************************************************************************/
char LPC_Calculate_Parity(struct receiveData *str)
{
    char i=0,j=0,sum=0,check[6];

    for(i=0;i<6;i++)
    {
        
        switch(i)
        {
            case 0:for(j=0;j<8;j++){if(((*str).cmd<<j)==1)check[i]++;};break;
            case 1:for(j=0;j<8;j++){if(((*str).cmd_info<<j)==1)check[i]++;};break;
            case 2:for(j=0;j<8;j++){if(((*str).option_first<<j)==1)check[i]++;};break;
            case 3:for(j=0;j<8;j++){if(((*str).option_second<<j)==1)check[i]++;};break;
            case 4:for(j=0;j<8;j++){if(((*str).option_third<<j)==1)check[i]++;};break;
            case 5:for(j=0;j<8;j++){if(((*str).option_four<<j)==1)check[i]++;};break;
        }
        sum+=check[i];
    }
    
    if(sum%2==1)
        return 1;
    else
        return 0;
}

/*******************************************************************************
*名称:LPC_Check_Data()
*功能:偶校验验证函数  返回1表示数据str传送正确;返回0则表示数据str传送失败
*******************************************************************************/
char LPC_Check_Data(struct receiveData *str)
{
    char i=0,j=0,sum=0,check[6];

    for(i=0;i<6;i++)
    {
        
        switch(i)
        {
            case 0:for(j=0;j<8;j++){if(((*str).cmd<<j)==1)check[i]++;};break;
            case 1:for(j=0;j<8;j++){if(((*str).cmd_info<<j)==1)check[i]++;};break;
            case 2:for(j=0;j<8;j++){if(((*str).option_first<<j)==1)check[i]++;};break;
            case 3:for(j=0;j<8;j++){if(((*str).option_second<<j)==1)check[i]++;};break;
            case 4:for(j=0;j<8;j++){if(((*str).option_third<<j)==1)check[i]++;};break;
            case 5:for(j=0;j<8;j++){if(((*str).option_four<<j)==1)check[i]++;};break;
        }
        sum+=check[i];
    }
    
    sum+=(*str).check;
    
    if(sum%2==0)
        return 1;
    else
        return 0;
}



/*******************************************************************************
*名称:UART_SendStr()
*功能:向串口发送一字符串
*******************************************************************************/

/*void UART_SendStr(uint8 *str,uint8 num)
{  
    while(1)
    { 
        if(*str=='\0') 
        {
            if(num==0)
            {
                UART_SendByte('\r',0);
                UART_SendByte('\n',0);
            }
            if(num==1)
            {
                UART_SendByte('\r',1);
                UART_SendByte('\n',1);
            }
            break;
        } 
        if(num==0)
            UART_SendByte(*str++,0);           //发送数据
        if(num==1)
            UART_SendByte(*str++,1);           //发送数据
    }
}
*/

/*******************************************************************************
*名称:UART_SendStu()
*功能:向串口发送一结构体
*******************************************************************************/

void LPC_Send_Str(struct receiveData *str,uint8 num)
{  
            char i=0;           //用于循环计数的变量
            (*str).check=LPC_Calculate_Parity(str);            //设置偶校验位
            for(i=0;i<8;i++)
            {
                //UART_SendByte(*str++,1);           //发送数据
                switch(i)
                {
                    case 0:UART_SendByte((*str).cmd,1);    break;
                    case 1:UART_SendByte((*str).cmd_info,1);break;
                    case 2:UART_SendByte((*str).option_first,1);break;
                    case 3:UART_SendByte((*str).option_second,1);break;
                    case 4:UART_SendByte((*str).option_third,1);break;
                    case 5:UART_SendByte((*str).option_four,1);    break;
                    case 6:UART_SendByte((*str).check,1);break;
                    case 7:UART_SendByte((*str).end,1);    break;    //最后一位发送完成后,将sCount2清零
                    default  :break;
                }
            }
}

/*******************************************************************************
*名称: main()
*功能: 使用串口UART1接收上位机发送的数据,当接收到8个连续数据后,取反LED,并将数据原封不动的发送回去
*******************************************************************************/

int main(void)
{     
    //uint8 SEND_STRING[]="HELLO WORLD!\n";

    PINSEL0=0x00050005;                         //设置IO连接到UART0、UART1
    PINSEL1=0x00000000;
    IODIR=LED1CON;                              //设置LED控制口为输出
    IOSET=LED1CON;                                //关闭LED1
 
    LPC_UART_Init();
    U0FCR=0x81;                                 //使能FIFO,并设置触发点为8字节
    U1FCR=0x81;                                 //使能FIFO,并设置触发点为8字节
    U1IER=0x01;                                 //允许UART1的RBR接收中断

    IRQEnable();                                //使能中断
    
    VICIntSelect=0x00000000;                    //设置所有通道为IRQ中断
    VICVectCntl0=0x27;                          //UART1分配到IRQ Slot0,即优先级最高
    VICVectAddr0=(int)LPC_Receive_Str;
    VICIntEnable=0x00000080;                    //UART1中断VIC通道为7

    LPC_Send_Str(stu,1); 
    //UART_SendByte((*stu).cmd,1);  
    while(1);      
}                                 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值