与arm微控制器串行通信

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

我怎么解决这个问题?

电脑程序如下所示。

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

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

串行读取输出

微控制器代码如下。

 #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_OutChar('s'); delay(10000); 

此代码不正确。 我怀疑你在UART有机会发送任何东西之前很久就会反复覆盖UART tx缓冲区。

首先,你不能写那样的延迟函数。 编译器可以自由地优化它,因为它无法发现任何副作用。 一般来说,你应该把“倦怠时间”循环当作穷人的延迟,但如果你出于某种原因必须使用它们,那么它们必须像这样写:

 void delay(int value) { for(volatile int i=0; 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 */ }