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);
}
C#未完成----串口通信
最新推荐文章于 2020-10-11 14:53:03 发布