Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与arm单片机的串行通信_C++_C_Embedded_Codeblocks_Keil - Fatal编程技术网

C++ 与arm单片机的串行通信

C++ 与arm单片机的串行通信,c++,c,embedded,codeblocks,keil,C++,C,Embedded,Codeblocks,Keil,我试图通过usb将数据从arm cortrx m4微控制器发送到pc。在C++代码块中有一个用C++语言编写的程序。基本上,程序设置串行通信设置,并使用ReadFile功能读取数据。 问题是,即使pc程序和微控制器中的波特率相同,我也会在输出端得到垃圾值 我怎样才能解决这个问题 pc程序如下所示 #include <Windows.h> #include <stdio.h> int main(void) { HANDLE hComm;

我试图通过usb将数据从arm cortrx m4微控制器发送到pc。在C++代码块中有一个用C++语言编写的程序。基本上,程序设置串行通信设置,并使用ReadFile功能读取数据。 问题是,即使pc程序和微控制器中的波特率相同,我也会在输出端得到垃圾值

我怎样才能解决这个问题

pc程序如下所示

#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");

}
这里的图像显示了在端口上连续发送字符时打印的垃圾值

微控制器代码如下

#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++;
      }
}
此代码不正确。我怀疑在UART有机会发送任何东西之前,您一直在一次又一次地覆盖UART tx缓冲区

首先,你不能这样写延迟函数。编译器可以完全自由地对其进行优化,因为它不能发现任何副作用。一般来说,你应该把时间循环作为穷人的延迟来消磨掉,但如果你出于某种原因必须使用它们,它们必须这样写:

void delay(int value)
{
  for(volatile int i=0; i<value; i++)
  {}
}
volatile关键字防止编译器优化整个函数

但是,正确的方法是根本不使用这种迟钝的延迟,而是观察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 */
}

首先使用一些标准的终端程序,比如PuTTY,而不是windows应用程序,然后看看你得到了什么样的输出。这将有助于确定调试哪一方。What@EugeneSh。也就是说,如果显示的是相同的垃圾,那么您知道它是来自嵌入式目标的输出,而不是PC代码。然后,应使用示波器检查位定时和帧。从您设置波特率和帧的代码中看不出这一点。在某个时候,您可能会用一个范围来查看它,也许您没有范围,否则您现在会尝试吗?正如尤金所说,把问题一分为二。使用一个已知的可工作的哑终端程序,如果问题消失,它是您的主机代码,如果不是,那么可能是mcu端。cortex-m4没有告诉我们任何与芯片和uart外围设备相关的信息……我想说的是,您的波特率并不是您想象的那样。首先两次和三次检查您的寄存器设置,然后使用范围。我使用了具有相同波特率115200的putty,它运行良好。在您建议的更改之后,我得到了相同的错误。
n = 0;
while(n < 10)
{
  if((UART_SR & TX_BUSY) == 0)
  {
    UART_OutChar('s');
    n++;
  }

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