2017-01-26 6 views
0

Я пытаюсь отправить данные с микроконтроллера cortrx m4 на компьютер через USB. Существует программа, написанная на языке C++ в кодовых блоках ide. В основном программа устанавливает параметры последовательной связи и считывает данные с помощью функции ReadFile. Проблема в том, что я получаю значения мусора на выходе, даже если скорость передачи в poc proogram и микроконтроллере одинакова.последовательная связь с консольным микроконтроллером

Как я могу решить эту проблему?

Программа для ПК показана ниже.

#include <Windows.h> 
#include <stdio.h> 

int main(void) 
{ 
HANDLE hComm;       // Handle to the Serial port 
char ComPortName[] = "\\\\.\\COM51"; // Name of the Serial port to be opened, 
BOOL Status;       // Status of the various operations 
DWORD dwEventMask;      // Event mask to trigger 
char TempChar;      // Temperory Character 
char SerialBuffer[26];    // Buffer Containing Rxed Data 
DWORD NoBytesRead;      // Bytes read by ReadFile() 
int i = 0; 

printf("\n\n +==========================================+"); 
printf("\n | Serial Port Reception (Win32 API) |"); 
printf("\n +==========================================+\n"); 
/*---------------------------------- Opening the Serial Port -----------*/ 

hComm = CreateFile(ComPortName,   // Name of the Port to be Opened 
        GENERIC_READ | GENERIC_WRITE, // Read/Write Access 
        0,       // No Sharing 
        NULL,       // No Security 
        OPEN_EXISTING,    // Open existing port only 
        0,       // Non Overlapped I/O 
        NULL);      // Null for Comm Devices 

if (hComm == INVALID_HANDLE_VALUE) 
    printf("\n Error! - Port %s can't be opened\n", ComPortName); 
else 
printf("\n Port %s Opened\n ", ComPortName); 


DCB dcbSerialParams = { 0 };    // Initializing DCB structure 
dcbSerialParams.DCBlength = sizeof(dcbSerialParams); 

Status = GetCommState(hComm, &dcbSerialParams); //retreives the current settings 

if (Status == FALSE) 
    printf("\n Error! in GetCommState()"); 

     dcbSerialParams.BaudRate = 115200;  // Setting BaudRate = 115200 
     dcbSerialParams.ByteSize = 8;    // Setting ByteSize = 8 
     dcbSerialParams.StopBits = ONE5STOPBITS; // Setting StopBits = 1 
     dcbSerialParams.Parity = NOPARITY;  // Setting Parity = None 

Status = SetCommState(hComm, &dcbSerialParams); //Configuring the port according to settings in DCB 

     if (Status == FALSE) 
      { 
       printf("\n Error! in Setting DCB Structure"); 
      } 
     else //If Successfull display the contents of the DCB Structure 
      { 
       printf("\n\n Setting DCB Structure Successfull\n"); 
       printf("\n  Baudrate = %ld", dcbSerialParams.BaudRate); 
       printf("\n  ByteSize = %d", dcbSerialParams.ByteSize); 
       printf("\n  StopBits = %d", dcbSerialParams.StopBits); 
       printf("\n  Parity = %d", dcbSerialParams.Parity); 
      } 

     //----------------- Setting Timeouts ---------------------------- 

     COMMTIMEOUTS timeouts = { 0 }; 
     timeouts.ReadIntervalTimeout   = 50; 
     timeouts.ReadTotalTimeoutConstant = 50; 
     timeouts.ReadTotalTimeoutMultiplier = 10; 
     timeouts.WriteTotalTimeoutConstant = 50; 
     timeouts.WriteTotalTimeoutMultiplier = 10; 

     if (SetCommTimeouts(hComm, &timeouts) == FALSE) 
      printf("\n\n Error! in Setting Time Outs"); 
     else 
      printf("\n\n Setting Serial Port Timeouts Successfull"); 

//-------------- Setting Receive Mask ------------------------------- 


if (!SetCommMask(hComm, EV_RXCHAR)) 
    printf("\n\n Error! in Setting CommMask");  // Error setting communications event mask 
else 
    printf("\n\n Setting CommMask successfull"); 


    i = 0; 
    printf("\n\n Waiting for Data Reception"); 

    if (WaitCommEvent(hComm, &dwEventMask, NULL)) 
    { 
     printf("\n\n Characters Received\n"); 
     do 
     { 
        if (ReadFile(hComm, &TempChar, 1, &NoBytesRead, NULL)) 
        { 
         // A byte has been read; process it. 
         SerialBuffer[i] = TempChar; 
         //printf("\n%c\n", TempChar); 
         if(TempChar == 's') 
          printf("\ndone\n"); 
         i++; 

        } 
        else 
        { 
         // An error occurred in the ReadFile call. 
         break; 
        } 
       } while (NoBytesRead); 
      } 

int j =0; 
for (j = 0; j < i-1; j++)  // j < i-1 to remove the dupliated last character 
printf("%c", SerialBuffer[j]); 

CloseHandle(hComm);//Closing the Serial Port 
printf("\n +==========================================+\n"); 

} 

Здесь изображение, показывающее значение мусора, напечатанное при непрерывном отправлении символа на порт.

serial-read output

код микроконтроллера опускается ниже.

#include "PLL.h" 
#include "UART.h" 

#define GPIO_PORTF_DATA_R  (*((volatile unsigned long *)0x400253FC)) 
#define GPIO_PORTF_DIR_R  (*((volatile unsigned long *)0x40025400)) 
#define GPIO_PORTF_AFSEL_R  (*((volatile unsigned long *)0x40025420)) 
#define GPIO_PORTF_PUR_R  (*((volatile unsigned long *)0x40025510)) 
#define GPIO_PORTF_DEN_R  (*((volatile unsigned long *)0x4002551C)) 
#define GPIO_PORTF_LOCK_R  (*((volatile unsigned long *)0x40025520)) 
#define GPIO_PORTF_CR_R   (*((volatile unsigned long *)0x40025524)) 
#define GPIO_PORTF_AMSEL_R  (*((volatile unsigned long *)0x40025528)) 
#define GPIO_PORTF_PCTL_R  (*((volatile unsigned long *)0x4002552C)) 
#define SYSCTL_RCGC2_R   (*((volatile unsigned long *)0x400FE108)) 

unsigned long In; // input from PF4 


// time delay 
void delay(int value) 
{ 
    while(value){ 
    value--;} 
} 
//debug code 
int main(void) 
{ 
    unsigned char i; 
    char string[20];   // global to assist in debugging 
    unsigned long n; 
    unsigned char c; 
    char text[10] = "Hello!"; 
    unsigned long count; 


    SYSCTL_RCGC2_R |= 0x00000020;  // 1) F clock 
    //delay = SYSCTL_RCGC2_R;   // delay 
    GPIO_PORTF_LOCK_R = 0x4C4F434B; // 2) unlock PortF PF0 
    GPIO_PORTF_CR_R = 0x1F;   // allow changes to PF4-0  
    GPIO_PORTF_AMSEL_R = 0x00;  // 3) disable analog function 
    GPIO_PORTF_PCTL_R = 0x00000000; // 4) GPIO clear bit PCTL 
    GPIO_PORTF_DIR_R = 0x0E;   // 5) PF4,PF0 input, PF3,PF2,PF1 output 
    GPIO_PORTF_AFSEL_R = 0x00;  // 6) no alternate function 
    GPIO_PORTF_PUR_R = 0x11;   // enable pullup resistors on PF4,PF0  
    GPIO_PORTF_DEN_R = 0x1F;   // 7) enable digital pins PF4-PF0   


    PLL_Init(); 
    UART_Init();    // initialize UART 


     n = 0; 
     while(n < 10) 
     { 
      UART_OutChar('s'); 
      delay(10000); 
      n++; 
     } 
} 
+7

Первое использование некоторых стандартная программа терминала как 'PuTTY' вместо вашего окна приложения, и посмотреть, какой выход вы получите. Это поможет определить, какую сторону отлаживать. –

+0

Что @EugeneSh. сказал, тогда, если это показывает тот же мусор, вы знаете, что это результат встроенной цели, а не кода ПК. Затем вы должны проверить синхронизацию бит и кадрирование с помощью осциллографа. В коде не указано, где вы устанавливаете скорость передачи и кадрирование. – Clifford

+0

в какой-то момент вы можете в конечном итоге «взглянуть на него с областью действия», и, возможно, у вас нет другого, иначе вы бы уже пробовали это? разделите проблему наполовину, как говорит Юджин. используйте известную рабочую туманную терминальную программу, если проблема исчезнет, ​​это ваш хост-код, если не тогда, возможно, сторона mcu. cortex-m4 не говорит нам ничего важного здесь, насколько ваш чип и периферия периферии go ... –

ответ

1
UART_OutChar('s'); 
delay(10000); 

Этот код не является правильным. Я подозреваю, что вы продолжаете перезаписывать буфер UT tx снова и снова, задолго до того, как UART получит шанс отправить что-нибудь вообще.

Прежде всего, вы не можете написать такую ​​функцию задержки. Компилятор может свободно оптимизировать все это, так как не может обнаружить никаких побочных эффектов. Как правило, вы должны прочь «выгорание прочь время» петли задержки, как бедный человек, но если вы по какой-то причине необходимо использовать их, они должны быть написаны так:

void delay(int value) 
{ 
    for(volatile int i=0; i<value; i++) 
    {} 
} 

Летучие ключевое слово позволяет компилятору оптимизировать всю функцию.

Правильный способ сделать это, однако, не использовать такие тупые задержки вообще, а вместо этого наблюдать флаг занятости передатчика вашего оборудования UART. Он находится в регистре состояния UART, независимо от того, что вы вызываете для вашего конкретного микроконтроллера.

Псевдо код:

n = 0; 
while(n < 10) 
{ 
    if((UART_SR & TX_BUSY) == 0) 
    { 
    UART_OutChar('s'); 
    n++; 
    } 

    /* can do other things here in the meantime */ 
} 
+0

после изменений, которые вы предложили, я получаю такую ​​же ошибку. – Ashish