C++ 与arm单片机的串行通信
我试图通过usb将数据从arm cortrx m4微控制器发送到pc。在C++代码块中有一个用C++语言编写的程序。基本上,程序设置串行通信设置,并使用ReadFile功能读取数据。 问题是,即使pc程序和微控制器中的波特率相同,我也会在输出端得到垃圾值 我怎样才能解决这个问题 pc程序如下所示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;
#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 */
}