您好!
通过 UART0发送数据时、微控制器的 UART 传输存在问题
在白蚁端子中观察它时、一些数据串会被切成一半(图像1)
、或者字符串中有空格(图像2)、您能给我任何建议来解决这个问题吗? :)
梅拉
图1.
图2.
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
通过 UART0发送数据时、微控制器的 UART 传输存在问题
在白蚁端子中观察它时、一些数据串会被切成一半(图像1)
、或者字符串中有空格(图像2)、您能给我任何建议来解决这个问题吗? :)
梅拉
图1.
图2.
您好、Mayra、
您能否发送您正在使用的代码以便我可以在我的板上运行它? 如果我可以这样调试它、这对我来说将是最简单的。
此致、
Ralph Jacobi
#include <stdint.h> #include <stdbool.h> #include <string.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "inc/hw_gpio.h" #include "driverlib/sysctl.h" #include "driverlib/pin_map.h" #include "driverlib/gpio.h" #include "driverlib/adc.h" #include "driverlib/debug.h" #include <driverlib/uart.h> #include <driverlib/interrupt.h> #include "inc/hw_ints.h" //librería para interrupciones #include <stdbool.h> #define NORM_MSG_LEN 26 #define ERR_MSG_LEN 8 uint32_t g_ui32SysClock; //variable para configurar el reloj del microcontrolador uint32_t ui32Status; uint32_t buffer_ADC[24]; // arreglo para guardar datos entrantes del ADC //uint32_t pui32ADC0Value[20]; volatile int i_rx=0; volatile bool flag_rx=false; char BUFFER_UART[27]; char BUFFER[27]; int i_Rx=0,lim=0; int i_y=0; int flagUART_P=0; int coincidencia=0; int impedimenta=0; int lumos=0, t=0; char S_P1 [] = "?V913\r\n";//solicitud de respuesta al Edwards para el sensor de presion 1 char S_P2 [] = "?V914\r\n";//solicitud de respuesta al Edwards para el sensor de presion 2 char S_P4 [] = "!S925 5\r\n";//Instrucción para subir o bajar el contraste a la pantalla del edwards int recepcion=0; int contadordeborrado=0; int flag_UART=0; //bandera para detectar coincidencia entre las posiciones del arreglo float a,b,c,d,e,E,F,G,H,p1,p=0; int bandera=0,banderanum; float arregloP[2]; //arreglo para guardar los datos de presion float arreglo[12]; //arreglo para guardar los datos de los termistores float vol_T=0.0; //guarda el dato de voltaje float RT=0.0;//guarda el dato de resistencia del termistor float mu_T; //guarda el promedio de muestreo del adc float T=0.0;//guarda el dato de temperatura //----------------------------------------------------------------------------------------------------------------- // ADC //------------------------------------------------------------------------------------------------------------------ //función de autoria propia void INIT_ADC() //inicializa el ADC { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //habilita el periferico para ADC0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)); GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3); //PINES PARA ENTRADA ADC0 //ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR,0); } //Función copiada void TEMP_TERMISTOR() //configura la secuencia de muestreo del adc y procesa los datos entrantes del adc { int i_adc; for(i_adc=0; i_adc<12; i_adc++) { ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR,0); ADCSequenceStepConfigure(ADC0_BASE, 0,0, i_adc);//(paso 1) ADCSequenceStepConfigure(ADC0_BASE, 0,1, i_adc);//(paso 2) ADCSequenceStepConfigure(ADC0_BASE, 0,2, i_adc);//(paso 3) ADCSequenceStepConfigure(ADC0_BASE, 0,3, i_adc);//(paso 4) ADCSequenceStepConfigure(ADC0_BASE, 0,4, i_adc);//(paso 5) ADCSequenceStepConfigure(ADC0_BASE, 0,5, i_adc);//(paso 6) ADCSequenceStepConfigure(ADC0_BASE, 0,6, i_adc);//(paso 7) ADCSequenceStepConfigure(ADC0_BASE, 0,7, i_adc|ADC_CTL_IE|ADC_CTL_END);//(paso 8) ADCSequenceEnable(ADC0_BASE,0); ADCIntClear(ADC0_BASE,0); //limpia las banderas de interrupción del ADC ADCProcessorTrigger(ADC0_BASE,0); //Causa un trigger para una secuencia de muestreo while(!ADCIntStatus(ADC0_BASE,0,false)) //indica el estado de las interrupciones { } ADCSequenceDataGet(ADC0_BASE,0,buffer_ADC);//obtiene los datos capturados por el adc mu_T=(buffer_ADC[0]+buffer_ADC[1]+buffer_ADC[2]+buffer_ADC[3]+buffer_ADC[4]+buffer_ADC[5]+buffer_ADC[6]+buffer_ADC[7])/8; vol_T=mu_T*3.3/4096; //aqui hubo breakpoint RT=((3900*(3.3-vol_T))/vol_T); T=(1/(0.000634544+(0.000321866*log(RT))+(-0.000000306*pow(log(RT),3))))-273.15;//aqui hubo breakpoint arreglo[i_adc]=T; //aqui hubo breakpoint } } //--------------------------------------------------------------------------------------------------------------- // UART //---------------------------------------------------------------------------------------------------------------- void INIT_UART() //HABILITA LOS MÓDULOS UART0 Y UART1 { SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);//Habilitación del módulo UART2 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);//Habilitación del módulo UART1 (Recepción y transmisión de datos de presión) SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);//Habilitación del módulo UART0 (conexión USB) SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART1)); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7); //Configurar los pines a usar en UART0 GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1); //Configurar los pines a usar en UART1 GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); //Configurar los pines a usar en UART0 } void CONFIG_UART() { //ASIGNACIÓN DE PINES? RX y TX GPIOPinConfigure(GPIO_PA6_U2RX); //Configurar terminal de RX UART2 GPIOPinConfigure(GPIO_PA7_U2TX); //Configurar terminal de TX UART2 GPIOPinConfigure(GPIO_PB0_U1RX); //Configurar terminal de RX UART1 GPIOPinConfigure(GPIO_PB1_U1TX); //Configurar terminal de TX UART1 GPIOPinConfigure(GPIO_PA0_U0RX); //Configurar terminal de RX UART0 GPIOPinConfigure(GPIO_PA1_U0TX); //Configurar terminal de TX UART0 //configuración de dirección del puerto UART, reloj del modulo, baudrate, tamaño de bit y bit de paridad UARTConfigSetExpClk(UART2_BASE,g_ui32SysClock,9600,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); //configuración de dirección del puerto UART1 UARTConfigSetExpClk(UART1_BASE,g_ui32SysClock,9600,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); //configuración de dirección del puerto UART1 UARTConfigSetExpClk(UART0_BASE,g_ui32SysClock,9600,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); //configuración de dirección del puerto UART0 IntEnable(INT_UART2); //habilitación de interrupción por UART1 UARTIntEnable(UART2_BASE,UART_INT_RX); //habilitar interrupción por recepción y transmision UART1 IntEnable(INT_UART1); //habilitación de interrupción por UART1 UARTIntEnable(UART1_BASE,UART_INT_RX); //habilitar interrupción por recepción y transmision UART1 IntEnable(INT_UART0); //habilitación de interrupción por UART0 UARTIntEnable(UART0_BASE,UART_INT_RX|UART_INT_RT); //habilitar interrupción por recepción y transmision UART0 IntMasterEnable(); //Habilita las interrupciones globales } void sendDataUART1(uint32_t c) //envia la petición de respuesta al sensor de presión por UART1 al Edwards dato por dato { UARTCharPut(UART1_BASE, c); } void sendStringUART1(char* txt) //envia la petición de respuesta al sensor de presión por UART1 al Edwards dato en arreglo { while(*txt!=0x00) { sendDataUART1(*txt); txt++; } } void sendDataUART0(uint32_t c) //envia la petición de respuesta al sensor de presión por UART0 al Edwards dato por dato { UARTCharPut(UART0_BASE, c); } void sendStringUART0(char* txt) //envia la petición de respuesta al sensor de presión por UART0 al Edwards en arreglo { while(*txt!=NULL) { sendDataUART0(*txt); txt++; } } //función de autoria propia void convertir_hexadecimal(uint32_t ui32Base, float number) { int32_t entero; // uint32_t entero; float auxiliar; uint32_t decimal; //char digito; char ad; char ad2; if(number>0) //coloca el signo (si es mayor o menor a cero) a la temperatura { UARTCharPut(ui32Base,0x2B);//+ } else { UARTCharPut(ui32Base,0x2D);//- number=number*-1; } auxiliar=number; entero=number; decimal=(auxiliar-entero)*100; //AQUI VA LA CONVERSIÓN DE LA PARTE ENTERA A HEXADECIMAL UARTCharPut(ui32Base,(char)(entero)); ad=(char)(entero); UARTCharPut(ui32Base,0x2E);//. //AQUI VA LA CONVERSIÓN DE LA PARTE DECIMAL A HEXADECIMAL UARTCharPut(ui32Base,(char)(decimal)); ad2=(char)(decimal); } //funcion de autoria propia void cabecera(uint32_t ui32Base, char letra) //envía los datos en formato hexadecimal T+0x32.0x87 { int y=0, z=0; switch(letra) { case 'I': UARTCharPut(ui32Base,0x49);//cabecera para corriente (I) break; case 'P': if(arregloP[0]!=0x00 && arregloP[1]!=0x00) { UARTCharPut(ui32Base,0x50);//cabecera para presion (P) for(z=0;z<2;z++)//envia los datos de temperatura { convertir_hexadecimal(UART0_BASE,arregloP[z]);//manda a llamar a la funcion convertir_hexadecimal2 } UARTCharPut(UART0_BASE,0x0A);//salto de linea } break; case 'R': UARTCharPut(ui32Base,0x52);//cabecera para el RTD (R) break; case 'T': UARTCharPut(UART0_BASE,0x0A);//salto de linea UARTCharPut(ui32Base,0x54);//cabecera para el termistor(T) for(y=0;y<12;y++)//envia los datos de temperatura { convertir_hexadecimal(UART0_BASE,arreglo[y]);//manda a llamar a la funcion convertir_hexadecimal } UARTCharPut(UART0_BASE,0x0D);//retorno de carro break; case'V': UARTCharPut(ui32Base,0x56);//V para el volaje break; default: break; //default, que no haga algo } } //----------------------------------------------------------------------------------------------------------------- // TERMISTOR //----------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------ // RTD //------------------------------------------------------------------------------------------------------------------ //----------------------------------------------------------------------------------------------------------------- // PRESION //----------------------------------------------------------------------------------------------------------------- //función para limpiar los buffer y el contador de UART void clear_variables() { i_rx=0; //pone en cero el contador lumos=0; impedimenta=0; for(i_Rx=0;i_Rx<=25;i_Rx++) { BUFFER_UART[i_Rx]=0; //Limpia el buffer de UART breakpoint BUFFER[i_Rx]=0; //Limpia el buffer de proceso } } //Procesa los datos de presión void calculo() { if ( BUFFER[6]>=0x30 && BUFFER[6] <= 0x39 ) banderanum=1; //verifica que el dato en la posición [6] sea un numero t=8; do { if(BUFFER[t]>=0x30 && BUFFER[t] <= 0x39)////verifica que los datos desde la posición [8] a [11] sean numeros { banderanum=1;// bandera se pone en 1 } else { banderanum=0; // bandera se pone en 0 } t++; }while(t<=11); if(banderanum==1) //si los datos son mumeros { if(BUFFER[15] >=0x30 && BUFFER[15] <= 0x39 ) bandera=1;// verifica que el dato en la posición [15] sea un numero } if(banderanum==1) { if(bandera==1) { //resta 48 a los datos del arreglo para convertir los caracteres en numeros a=1*(BUFFER[6]-48);// numero*1=numero b=0.1*(BUFFER[8]-48); //numero*0.1=0.numero c=0.01*(BUFFER[9]-48);//numero*0.01=0.0numero d=0.001*(BUFFER[10]-48);//numero*0.001=0.00numero e=0.0001*(BUFFER[11]-48);//numero*0.0001=0.000numero G=BUFFER[15]-48; // exponente de la presion E=a+b+c+d+e; //suma los numeros //G=ver[15]-48; F=pow(10,G);//eleva el 10 al exponente de la presion if(BUFFER[13]==0x2D) //breakpoint (posición [13] del arreglo) si el signo de la presión es negativo { p1=E/F; //breakpoint presion en el sensor 1 = suma de los numeros dividido entre el exponente de la presion p=p1/1000;//breakpoint // convertir_hexadecimal(UART0_BASE, p1); } else if (BUFFER[13]==0x2B) //(posición [13] del arreglo) si el signo de la presión es positivo { p1=E*F; //presion en el sensor 2 = suma de los numeros multiplicado por el exponente de la presion p=p1/1000;//breakpoint } } if(contadordeborrado==0) { arregloP[0]=p; } else if(contadordeborrado==1) { arregloP[1]=p; } } } //Guarda los datos procedentes del UART en un nuevo arreglo y vacía los buffer void GUARDA_ARREGLO() { if(lumos==1) { if(BUFFER_UART[0]==0x3D && BUFFER_UART[18]==0x39)//compara si la posicion 0 del arreglo es = y la posición 19 es ; { coincidencia=1; //breakpoint pone en uno la bandera de coincidencia flag_UART=1; //pone en uno la bandera de flag_UART i_rx=0; //reinicia el contador } else { clear_variables(); //limpia los buffer y reinicia el contador i_rx } } if(flag_UART==1) { flag_UART=0; //breakpoint if(coincidencia==1)//si la posición 0 y 25 del arreglo entrante son iguales { coincidencia=0; i_rx=0; //reinicia el contador for(i_y=0;i_y<=25;i_y++)//Guarda el contenido del buffer de uart en un buffer para procesar los datos { BUFFER[i_y]=BUFFER_UART[i_y]; } calculo(); } else { clear_variables(); //limpia los buffer y reinicia el contador i_rx } contadordeborrado++; if(contadordeborrado==2) contadordeborrado=0;//lleva el conteo de las posiciones del arreglo de presion } clear_variables(); //Limpia los buffer y el contador cuando la trama es erronea o está cortada. if(BUFFER_UART[0]==0x2A) //compara si la posicion 0 del arreglo es igual a "*" { clear_variables(); //limpia los buffer y reinicia el contador i_rx } } //---------------------------------------------------------------------------------------------------------------------------- // MAIN //---------------------------------------------------------------------------------------------------------------------------- int main(void) { //configurar el reloj del microcontrolador g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN |SYSCTL_USE_PLL |SYSCTL_CFG_VCO_240), 120000000);//120 MHz INIT_ADC(); //inicializa el ADC INIT_UART(); CONFIG_UART(); //sendStringUART1(S_P4); while(1) { TEMP_TERMISTOR();//configura las caracteristicas de las funciones de ADC del micro y procesa los datos entrantes a temperatura SysCtlDelay(10000); sendStringUART1(S_P1); SysCtlDelay(21000000);//514ms GUARDA_ARREGLO(); SysCtlDelay(10000000);//514ms sendStringUART1(S_P2); SysCtlDelay(21000000);//514ms GUARDA_ARREGLO(); SysCtlDelay(17000000);//514ms cabecera(UART0_BASE,0x54);// Manda a llamar a la funcion "cabecera" cabecera(UART0_BASE,0x50); } } //------------------------------------------------------------------------------------------------------------------------------ // ISR //------------------------------------------------------------------------------------------------------------------------------ //i_rx=0; //int variable=0; void ISR_UART0(void) { } void ISR_UART1(void) { ui32Status = UARTIntStatus(UART1_BASE,true); UARTIntClear(UART1_BASE, ui32Status); //limpia las banderas de interrupción? if (UARTCharsAvail(UART1_BASE)) { char rxData = UARTCharGetNonBlocking(UART1_BASE); //recibe el dato UART entrante if (flag_rx) { if (rxData == 0x0D) { flag_rx = false; } BUFFER_UART[i_rx++]=rxData;// Guarda el dato recibido en un arreglo } else { if (rxData == '=') { flag_rx = true; i_rx = 0; BUFFER_UART[i_rx++]=rxData;// Guarda el dato recibido en un arreglo } } impedimenta=1; //breakpoint }//cierra if(charsAvail) lumos=1; //breakpoint } void ISR_UART2(void) { } //
你好!
这是我的代码!
梅拉
Mayra、您好!
谢谢、我希望能够轻松地运行代码并进行复制、但我不确定这在这里会很简单。 如果我正在正确读取代码、您有时会收到指示 UART 输出的 UART 消息?
如果是、我将无法完全复制您的系统设置。
尽管知道这一点之后会带来一个不同的问题、即您看到的错误输出区域是否与通过 UART 接收的内容、与热敏电阻读数相关的内容或与器件中存储的静态消息相关的内容?
此致、
Ralph Jacobi
您好!
是的、使用 UART1的微控制器向外部器件(S_P1)发送响应请求、
该器件是一个压力控制器、需要500毫秒的时间进行响应、因此是微控制器
等待500毫秒,并调用函数 Guarda_arreglo()来处理从接收到的数据
外部器件。 然后它发送另一个响应请求(S_P2),等待500毫秒并调用 Guarda_arreglo()
这是因为它从两个不同的传感器请求压力。 来自两个压力传感器的数据是
由 UART0作为以字母"P"开头的字符串发送。
有一个温度传感器(热敏电阻)、其值由微控制器通过 ADC 接收、
总共有12个热敏电阻、但目前我只使用1进行测试。 处理的温度数据
通过 UART0以字母"T"开头的数据串发送程序、
压力和温度数据串从 UART0发出、以在 LabVIEW 接口中显示数据。
我希望我已经正确地解释了自己、
此致、
Mayra
Mayra、您好!
是的、这基本上是合理的-足以让我对应用有足够的了解。
因此、查看源代码并了解其基于测量结果等、我认为现在发生的情况是、由于您只是通过 UART 发送原始字符、 有时、数据最终会成为一个字符、终端会显示为空格或 换行符 、而不是输出十六进制值。
我想、如果您使用 UARTprintf 这样的函数 来指定希望如何输出字符串、则可以避免这种问题的发生。
您可以做的一件事是检查一下、运行一个计数器、该计数器发送多少次类似'0x20'(Space)的数据、然后查看您是否运行它并看到4条带空格的消息、计数器读取4次... 这将解释您看到的输出、然后您可以尝试并解决该问题?
这是我在这一点上的主要猜测、因为代码似乎使用正确的初始化编写得很好、我认为没有任何缓冲区溢出或数据损坏问题。 我认为这只是原始字符打印的一个例子、它导致终端获取一些数据、而不是将其输出为原始十六进制值、而是将其解释为其他值。
此致、
Ralph Jacobi
Mayra、您好!
实际上、我认为发生的情况是、您收到的数据值有时为0x20。
当您将0x20发送到带有 UARTCharPut 的 Termite 时、它只打印一个空格、而不显示数据值。
因此、我建议检查您是否以数据的形式发送0x20、例如在发送数据之前查看数据、并使计数器递增、即数据值等于0x20。 如果是、这将解释问题。
然后、您可以使用 UARTprintf 解决该问题。
此致、
Ralph Jacobi
您好、Mayra、
您需要以不同的方式初始化 UART、然后才能使用该调用。 需要调用 UARTStdioConfig 以使 UART stdio 函数知道要使用哪个 UART。 请参阅以下代码片段。
void prvConfigureUART(void) { /* Enable GPIO port A which is used for UART0 pins. * TODO: change this to whichever GPIO port you are using. */ SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); /* Configure the pin muxing for UART0 functions on port A0 and A1. * This step is not necessary if your part does not support pin muxing. * TODO: change this to select the port/pin you are using. */ GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); /* Enable UART0 so that we can configure the clock. */ SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); /* Use the internal 16MHz oscillator as the UART clock source. */ UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); /* Select the alternate (UART) function for these pins. * TODO: change this to select the port/pin you are using. */ GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); /* Initialize the UART for console I/O. */ UARTStdioConfig(0, 115200, 16000000); }
此致、
Ralph Jacobi
您好!
我在 CONFIG_UART()中添加了 UARTStdioConfig()函数
用于配置 UART 功能的函数、我还替换了 UARTCharPut ()
在"cabecera"和"convertir_Hexadeciment"函数中使用 UARTPrintf()的函数。
void CONFIG_UART()
{
//ASIGNACIÓN DE PINES? RX y TX
GPIOPinConfigure(GPIO_PA6_U2RX); //Configurar terminal de RX UART2
GPIOPinConfigure(GPIO_PA7_U2TX); //Configurar terminal de TX UART2
GPIOPinConfigure(GPIO_PB0_U1RX); //Configurar terminal de RX UART1
GPIOPinConfigure(GPIO_PB1_U1TX); //Configurar terminal de TX UART1
GPIOPinConfigure(GPIO_PA0_U0RX); //Configurar terminal de RX UART0
GPIOPinConfigure(GPIO_PA1_U0TX); //Configurar terminal de TX UART0
//configuración de dirección del puerto UART, reloj del modulo, baudrate, tamaño de bit y bit de paridad
UARTConfigSetExpClk(UART2_BASE,g_ui32SysClock,9600,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); //configuración de dirección del puerto UART1
UARTConfigSetExpClk(UART1_BASE,g_ui32SysClock,9600,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); //configuración de dirección del puerto UART1
UARTConfigSetExpClk(UART0_BASE,g_ui32SysClock,9600,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE)); //configuración de dirección del puerto UART0
IntEnable(INT_UART2); //habilitación de interrupción por UART1
UARTIntEnable(UART2_BASE,UART_INT_RX); //habilitar interrupción por recepción y transmision UART1
IntEnable(INT_UART1); //habilitación de interrupción por UART1
UARTIntEnable(UART1_BASE,UART_INT_RX); //habilitar interrupción por recepción y transmision UART1
IntEnable(INT_UART0); //habilitación de interrupción por UART0
UARTIntEnable(UART0_BASE,UART_INT_RX|UART_INT_RT); //habilitar interrupción por recepción y transmision UART0
IntMasterEnable(); //Habilita las interrupciones globales
UARTStdioConfig(0,9600,120000000);
}
void convertir_hexadecimal(float number)
{
int32_t entero;
// uint32_t entero;
float auxiliar;
uint32_t decimal;
//char digito;
char ad;
char ad2;
if(number>0) //coloca el signo (si es mayor o menor a cero) a la temperatura
{
//+
UARTprintf("\%c",0x2B);
}
else
{
//-
UARTprintf("\%c",0x2D);
number=number*-1;
}
auxiliar=number;
entero=number;
decimal=(auxiliar-entero)*100;
//AQUI VA LA CONVERSIÓN DE LA PARTE ENTERA A HEXADECIMAL
// UARTCharPut(ui32Base,(char)(entero));
UARTprintf("\%c",(char)(entero));
ad=(char)(entero);
// UARTCharPut(ui32Base,0x2E);//.
UARTprintf("\%c",0x2E);
//AQUI VA LA CONVERSIÓN DE LA PARTE DECIMAL A HEXADECIMAL
// UARTCharPut(ui32Base,(char)(decimal));
UARTprintf("\%c",(char)(decimal));
ad2=(char)(decimal);
}
void cabecera(char letra) //envía los datos en formato hexadecimal T+0x32.0x87
{
int y=0, z=0;
switch(letra)
{
case 'I':
//cabecera para corriente (I)
UARTprintf("\%c",0x49);
break;
case 'P':
if(arregloP[0]!=0x00 && arregloP[1]!=0x00)
{
//cabecera para presion (P)
UARTprintf("\%c",0x50);
for(z=0;z<2;z++)//envia los datos de temperatura
{
convertir_hexadecimal(arregloP[z]);//manda a llamar a la funcion convertir_hexadecimal2
}
//salto de linea
UARTprintf("\%c",0x0A);
}
break;
case 'R':
//cabecera para el RTD (R)
UARTprintf("\%c",0x52);
break;
case 'T':
//salto de linea
UARTprintf("\%c",0x0A);
//cabecera para el termistor(T)
UARTprintf("\%c",0x54);
for(y=0;y<3;y++)//envia los datos de temperatura
{
convertir_hexadecimal(arreglo[y]);//manda a llamar a la funcion convertir_hexadecimal
}
//retorno de carro
UARTprintf("\%c",0x0D);
break;
case'V':
//V para el volaje
UARTprintf("\%c",0x56);
break;
default:
break;
//default, que no haga algo
}
}
int main(void)
{
//configurar el reloj del microcontrolador
g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN |SYSCTL_USE_PLL |SYSCTL_CFG_VCO_240), 120000000);//120 MHz
INIT_ADC(); //inicializa el ADC
INIT_UART();
CONFIG_UART();
//sendStringUART1(S_P4);
// int holaa=3;
while(1)
{
TEMP_TERMISTOR();//configura las caracteristicas de las funciones de ADC del micro y procesa los datos entrantes a temperatura
SysCtlDelay(10000);
sendStringUART1(S_P1);
SysCtlDelay(21000000);//514ms
GUARDA_ARREGLO();
SysCtlDelay(10000000);//514ms
sendStringUART1(S_P2);
SysCtlDelay(21000000);//514ms
GUARDA_ARREGLO();
SysCtlDelay(17000000);//514ms
cabecera(0x54);//Manda a llamar a la funcion "cabecera" (T)
cabecera(0x50);//Manda a llamar a la funcion "cabecera" (P)
}
}
Mayra、您好!
好的、这就是我希望在 UARTprintf 调用时看到的结果。 遗憾的是、您的设置方式与以前的设置方式没有什么不同。 如果通过 UART 发送某些字符、打印字符将提示终端中断显示。
为了演示这一点、我用"data"填充了一个50字节的缓冲区、该缓冲区从0x00开始、到0x49结束。
然后、我以两种方式输出该缓冲器。 第一个是使用%c 发送字符:
for(ui32LoopCount=0; ui32LoopCount<50; ui32LoopCount++) { UARTprintf("[ 0x%c ]", ui32DataBuffer[ui32LoopCount]); }
数据的输出结果如下:
[ 0x ][ 0x[01]][ 0x[02]][ 0x[03]][ 0x[04]][ 0x[05]][ 0x[06]][ 0x[07]][ 0x[08]][ 0x ][ 0x
][ 0x[0B]][ 0x[0C]][ 0x
][ 0x[0E]][ 0x[0F]][ 0x[10]][ 0x[11]][ 0x[12]][ 0x[13]][ 0x[14]][ 0x[15]][ 0x[16]][ 0x[17]][0x[18]][0x119]][0x1A]][0x1A]][0x1Q][0x1C][0x1]][0x1C][0x1]][0x1]][0x1C][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x1]][0x][0x ][ 0x"][ 0x#][ 0x$][ 0x%][ 0x&][ 0x'][ 0x (][ 0x)][ 0x*][ 0x+][ 0x、][ 0x-][ 0x。 ][ 0x/][ 0x0 ][ 0x1 ]
您可以看到两条断裂的线、它不会显示在 E2E 上、但那里也有一个从制表符中明显可见的空间(我之前指出、我以为空间是0x20、但我错了、它是0x09、而是制表符执行此操作)。
然后、我执行相同的操作、但输出十进制值-即原始数据值。
for(ui32LoopCount=0; ui32LoopCount<50; ui32LoopCount++) { UARTprintf("[ 0x%d ]", ui32DataBuffer[ui32LoopCount]); }
数据的结果输出现在为:
[ 0x0 ][ 0x1][ 0x2][ 0x3][ 0x4][ 0x5][ 0x6][ 0x7][ 0x8][ 0x9][ 0x10][ 0x11][ 0x12][ 0x13][ 0x14][ 0x15][ 0x16][ 0x18][ 0x19][ 0x21][ 0x21][ 0x21][ 0x21][ 0x21][ 0x23][ 0x21][ 0x21][ 0x21][ 0x21][ 0x21] ][ 0x25 ][ 0x26 ][ 0x27 ][ 0x28 ][ 0x29 ][ 0x30 ][ 0x31 ][ 0x32 ][ 0x33 ][ 0x34 ][ 0x35 ][ 0x36 ][ 0x37 ][ 0x38 ][ 0x39 ][ 0x40 ][ 0x41 ][ 0x42 ][ 0x43 ][ 0x44 ][ 0x47 ][ 0x46 ][ 0x48 ][ 0x46 ][ 0x48 ] ]
因此、您必须为 UARTprintf 使用正确的输出格式、以避免出现换行符等
以下是两个输出后的 Termite:
此致、
Ralph Jacobi
您好、Mayra、
当然。 原始数据通常指未处理/分析的任何数据。 由于您提到过您正在读取热敏电阻、这意味着您尝试获取温度数据-但您显示的输出都是十六进制字符、问题似乎存在(现在已确认为) 源自非典型 ASCII 数字/字母的输出字符。 因此、在我看来 、数据似乎尚未经过处理、无法将传感器读数转换为"35摄氏度"等实际温度。 这方面我可能会错、但这正是我所期望的。
此致、
Ralph Jacobi