C#串口通信求助
pc与mcu通信,每帧为7byte 帧格式为起始位0x80--上位机地址---下位机地址---传感器编号---命令---数据1----数据0mcu端处理流程如下:(中断接收)
(1)接收帧头,如接收正确,状态机跳到(2),否则状态机停留(1)
(2)接收上位机地址,其余据上类推....
当一帧数据接收完成后,rx_receive_finished_flag置1代码如下:
void USART1_IRQHandler(void)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_RXNE);
rx_temp=USART_ReceiveData(USART1);
switch(rx_state)
{
case FRAME_HEAD_STATE:
if(rx_temp==0x80)
rx_state=UP_ADDR_STATE;
break;
case UP_ADDR_STATE:
if(up_addr==0x00)
{
up_addr=rx_temp;
rx_state=LOW_ADDR_STATE;
}
else if(rx_temp==up_addr)
rx_state=LOW_ADDR_STATE;
else
rx_state=FRAME_HEAD_STATE;
break;
case LOW_ADDR_STATE:
if(rx_temp==low_addr)
rx_state=SENSOR_ADDR_STATE;
else
rx_state=FRAME_HEAD_STATE;
break;
case SENSOR_ADDR_STATE:
curr_sensor_addr=rx_temp;
rx_state=CMD_DATA_STATE;
rx_cnt=2;
break;
case CMD_DATA_STATE:
rx_data=rx_temp;
if(rx_cnt>0)
rx_cnt--;
else
{
rx_cnt=0;
rx_receive_finished_flag=1;
rx_state=FRAME_HEAD_STATE;
}
break;
default:
rx_state=FRAME_HEAD_STATE;
break;
}
}
}
由于不熟悉上位机软件,故将上述方法借鉴与C#的串口编程中。(上位机发送一帧数据,下位机收到后即返回收到的那帧数据)
自认为下面上位机接收是基于中断方式,当一帧数据接收完成后 rx_receive_finished_flag = true;
(定时器在发送数据时启动,200ms后检测rx_receive_finished_flag == true? 并输出相应消息,用以提示下位机是否
正确收到数据帧)
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) -----------##1
{
byte rx_temp = 0;
rx_temp = (byte)serialPort1.ReadByte();
serialPort1.DiscardInBuffer();
switch (rx_state)
{
case FRAME_HEAD_STATE:
if (rx_temp == 0x80)
rx_state = UP_ADDR_STATE;
break;
case UP_ADDR_STATE:
if (rx_temp == frame)
rx_state = LOW_ADDR_STATE;
else
rx_state = FRAME_HEAD_STATE;
break;
case LOW_ADDR_STATE:
if (rx_temp == frame)
{
rx_state = CMD_DATA_STATE;
rx_data_cnt = 2;
}
else
rx_state = FRAME_HEAD_STATE;
break;
case CMD_DATA_STATE:
buffer = rx_temp;
if (rx_data_cnt > 0)
rx_data_cnt--;
else
{
rx_data_cnt = 0;
rx_receive_finished_flag = true;
rx_state = FRAME_HEAD_STATE;
}
break;
}
}
很遗憾,每次发送后定时器弹出的消息都是“ERROR”,而下位机显示屏上显示的数据却是正确的接收数据----显然上位机接收处理部分出了问题,在哪里?
该怎么修正??
将上位机接收部分改为
//=========================================================================================
//接收数据
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) ----------##2
{
int bytes = serialPort1.BytesToRead;
byte[] buffer = new byte;
serialPort1.Read(buffer, 0, buffer.Length);
string str = ByteArrayToHexString(buffer).Trim();
if (textBox2.Text == "")
textBox2.Text = str;
else
textBox2.Text = textBox2.Text + " " + str;
}
文本显示数据和发送数据是一致的。
糊涂了,不清楚##1为什么不对,serialPort1_DataReceived是每有一byte进入接收缓冲区就触发一次还是....? 上位机一般是消息循环机制,这个和中断不一样,不会一个字符就产生一个消息的,所以上位机一定是##2的办法,看看缓冲区里边有多少字节,然后一起取走处理。 看着楼主的代码有点抓狂,感觉好乱啊 可现场上位机和下位机是通过无线模块连接的,可能会有几台上下位同时工作,如果上位机不能及时的抛除非本机寻址的下位机返回数据,那结果....
页:
[1]