Thắc mắc UART

Nguyễn Hữu Sang

Thành Viên PIF
Mấy anh cho em hỏi là mình dùng cờ ngắt nào để biết rằng việc truyền dữ liệu bằng UART đã kết thúc (truyền 1 chuỗi bất kỳ không quy định số ký tự), hay cụ thể là biết có stop bit đc truyền???
Tình hình là em làm cái GUI truyền 1 chuỗi xuống MCU, MCU hiện nó ra LCD rồi echo lại cho máy tính. Vì chưa trả lời đc câu hỏi trên nên em tạm nghĩ ra giải pháp là truyền thêm ký tự '~' (ASCII 126) làm dấu. Nhưng mà MCU không bắt được dấu '~' đó!!!
Code win form:
Code:
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 GUI_Controling_DC_motor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
       
        }
 
        int listLength = 0;
        string uartData = "";
        bool isNewData = false;
        int dataThres = 0;
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            if (listLength != ports.Length)
            {
                listLength = ports.Length;
                comList.Items.Clear();
                if (listLength == 0)
                {
                    return;
                }
                for (int i = 0; i < listLength; i++)
                {
                    comList.Items.Add(ports[i]);
                }
                if (ports.Length != 0)
                {
                    comList.Text = ports[0];
                }
            }
        }
 
        private void cbSwitch_Click(object sender, EventArgs e)
        {
            if (cbStatus.Text == "Disconnect")
            {
                Com.PortName = comList.Text;
                Com.Open();
                cbSwitch.Text = "Disconnect";
                cbStatus.Text = "Connect";
            }
            else
            {
                Com.Close();
                cbSwitch.Text = "Connect";
                cbStatus.Text = "Disconnect";
            }
        }
 
        private void Send_Click(object sender, EventArgs e)
        {
            string dataSend;
            if (cbStatus.Text == "Connect")
            {
                dataThres = dataTX.Text.Length;
                dataSend = dataTX.Text + "~";
                Com.WriteLine(dataSend);
                dataTX.Clear();
            }
        }
 
        private void dataRX_ISR(object sender, SerialDataReceivedEventArgs e)
        {
            //string uartData;
            uartData = uartData + Com.ReadExisting();
            if (uartData.Length == dataThres)
            {
                isNewData = true;
            }
            //Display(uartData);
        }
 
        private void timer2_Tick(object sender, EventArgs e)
        {
            if (isNewData)
            {
                dataRX.Text = uartData;
                uartData = "";
                isNewData = false;
            }
        }
    }
}
Untitled.png

dataRX_ISR là event khi nhận data, ngắt là 1 byte
uartData là string chứa data
dataTX, dataRX là 2 textbox truyền nhận
timer2 để canh nhận đủ dữ liệu echo thì hiện lên dataRX

Code MCU g2553: (LCD đã sửa thành port2)
Code:
#include <msp430.h>
#include "STE2007.h"
 
unsigned char data[100];
int dataLength;
 
int main(void)
{
  int i;
  WDTCTL = WDTPW + WDTHOLD;                // Stop WDT
  DCOCTL = 0;                              // Select lowest DCOx and MODx settings
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2 ;                    // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2 ;                    // P1.1 = RXD, P1.2=TXD
  UCA0CTL1 |= UCSSEL_2;                    // SMCLK
  UCA0BR0 = 104;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                    // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt
 
  lcd_init();
 
  while(1){
      __bis_SR_register(LPM0_bits + GIE);      // Enter LPM0, interrupts enabled
      lcd_clear();
      lcd_gotoxy(6,2);
 
      for(i=0 ; i<dataLength ; i++){
          lcd_putc(data[i]);
      }
 
        for(i=0 ; i<dataLength ; i++){
            while (!(IFG2&UCA0TXIFG));
            UCA0TXBUF = data[i];
        }
        dataLength = 0;
 
  }
}
 
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    unsigned char temp;
    temp = UCA0RXBUF;
    if(temp == 126){
        __bic_SR_register_on_exit(CPUOFF);
        return;
    }
    data[dataLength] = temp;
    dataLength++;
}
chỗ if(tem == 126) đổi thành temp=='~' hay temp=="~" gì thì cũng zậy.
Nhưng mà nếu nó không bắt được '~' thì đáng lẽ nó phải tiếp tục nhận, zậy mà truyền tiếp lần 2 là treo chương trình lun, không hiểu. Chứ lúc đầu em cho quy định chung số byte thì chạy tốt rồi. Mong các anh chị cứu giúp :((.
 
Top