本文介绍了与臂微控制器的串行通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我正在尝试通过usb从arm cortrx m4微控制器发送数据。有一个用C ++语言编写的代码块中的程序。基本上该程序设置串行通信设置并使用ReadFile功能读取数据。 问题是,即使pc程序和微控制器中的波特率相同,我也会在输出中获取垃圾值。I am trying to send data from the arm cortrx m4 microcontroller to pc through usb. There is a program written in C++ language in codeblocks ide. Basically the program sets the serial communication settings and read data using ReadFile function.The problem is I am getting garbage values at the output even if the baud rate in pc proogram and microcontroller is same.我如何解决这个问题?How can I solve this problem? pc程序如下所示。#include <Windows.h>#include <stdio.h>int main(void){HANDLE hComm; // Handle to the Serial portchar ComPortName[] = "\\\\.\\COM51"; // Name of the Serial port to be opened,BOOL Status; // Status of the various operationsDWORD dwEventMask; // Event mask to triggerchar TempChar; // Temperory Characterchar SerialBuffer[26]; // Buffer Containing Rxed DataDWORD 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 Devicesif (hComm == INVALID_HANDLE_VALUE) printf("\n Error! - Port %s can't be opened\n", ComPortName);elseprintf("\n Port %s Opened\n ", ComPortName);DCB dcbSerialParams = { 0 }; // Initializing DCB structuredcbSerialParams.DCBlength = sizeof(dcbSerialParams);Status = GetCommState(hComm, &dcbSerialParams); //retreives the current settingsif (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 = NoneStatus = 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 maskelse 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 characterprintf("%c", SerialBuffer[j]);CloseHandle(hComm);//Closing the Serial Portprintf("\n +==========================================+\n");}这里显示当char为连续发送在港口。Here image showing the garbage value printed when the char s is continuosly sent on the port.微控制器代码在下面。#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 delayvoid delay(int value){ while(value){ value--;}}//debug codeint 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 tx缓冲区,很久以前UART才有机会发送任何东西。This code is not correct. I suspect you keep overwriting the UART tx buffer over and over, long before the UART is given a chance to send anything at all.首先,你不能写这样的延迟函数。编译器可以自由地优化它,因为它不能发现任何副作用。一般来说,你应该将烧伤时间循环作为穷人的延误,但如果由于某种原因必须使用它们,则必须这样写:First of all, you can't write the delay function like that. The compiler is free to optimize it all away, as it can't spot any side-effects. Generally, you should away "burn-away time" loops as poor man's delays, but if you for some reason must use them, they have to be written like this:void delay(int value){ for(volatile int i=0; i<value; i++) {}} volatile关键字可防止编译器优化整个功能。The volatile keyword prevents the compiler from optimizing away the whole function.正确的方法是,不要使用这样的钝器延迟,而是观察UART硬件的发送器忙标志。在UART状态寄存器中找到,无论是为特定的微控制器调用哪一个。The correct way to do this though, is not to use such blunt delays at all, but instead watch the transmitter busy flag of your UART hardware. It is found in the UART status register, whatever that one is called for your specific microcontroller.伪代码:n = 0;while(n < 10){ if((UART_SR & TX_BUSY) == 0) { UART_OutChar('s'); n++; } /* can do other things here in the meantime */} 这篇关于与臂微控制器的串行通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-29 05:43