Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Cómo envía STM32 datos al host a través de printf?

¿Cómo envía STM32 datos al host a través de printf?

Esto requiere pasar el puerto serie STM32.

① Si el host es una computadora, necesita un puerto serie USB a TTL o TTL a STM32.

②Escriba un controlador de puerto serie STM32 (esto es muy simple, solo configure los pines y el puerto serie)

③Utilice el printf de la biblioteca estándar o escriba su propio printf y línea de puerto serie acoplamiento del conductor del puerto.

MFD SP!{R1-R3, LR}; en

LDR R1,=Cur_ Usart

LDR R1, [R1];

LDR R2, [R1, #SROS]

TST R2, #0X80

BEQ SEND_STR; Espera a que se complete la última transferencia

LDRB R3, [R0], #1; Leer los caracteres del puntero (R0) en R3

STRB R3, [R1, #DROS]; Escribir

CMP R3; , #0

BNE SEND_STR ; Bucle hasta el terminador '\0'

LDMFD SP! , {R1-R3, PC}; Fuera de la pila

; ***printStr, end.***printStr, end

; : código de dispositivo usart (1=usart1, no 1=usart2)

printNum

STMFD SP!{R1-R5, LR}; R1, .=10; El divisor es 10 y el divisor ya está en R0

LDR R3, =Num_Buffer La primera dirección del buffer de carga

LDR R4, =0<; /p>

LDR R5, =0; indicador negativo, 1=negativo

TST R0, #0x80000000

BEQ STR_ NUM; EOR R0, #0xFFFFFFFF; número negativo, inverso

ADD R0, #1

LDR R5, =1

STR_NUM

BL Div_U32

AGREGAR R2, R2, #0x30; Convertir a carácter

STRB R2, [R3], #1; Almacenar el resto en el búfer

AGREGAR R4, R4 , #1 ; cuenta 1

CMP R0, #0

BNE STR_NUM; hasta que el cociente sea 0

CMP R5, #1

LDR R1, =Cur_Usart

LDR R1, [R1] ; Cargar dirección Usart

BNE SEND_NUM ; ='-'

STRB R2, [R3], #1; el número '-' se almacena en el búfer

ADD R4, R4, #1;

ENVIAR _NUM

¡LDRB R0, [R3, #-1]!

SEND_WAIT

LDR R2, [R1, #SROS]; leer registro de estado

TST R2, #0X80

BEQ SEND_WAIT; espere a que se complete la última transmisión

STRB R0, [R1, #DROS] escriba

SUBS R4, R4, #1

BNE SEND_NUM

LDMFD SP!{R1-R

5, PC}; fuera de la pila

; printNum, end END

usart.h/****************** **************************

USART2{TX=PA2, Rx=PA3}, USART1{TX=PA9 , Rx=PA10}

*************************************** **** *******

#ifndef?USART_H_

#define?USART_H_

#include?"Common.h"

#include?"I2C.h"

#include?"SG90.h"

#include?"SG90.h"

#include?" Common.h"

#include?"SG90.h"

#include?"SRF05.h"

#define?USART_RECV_BUFF_SIZE? 15

#define?Pclk1_36MHz?36000000?//otros USART

#define?Pclk2_72MHz?72000000?//USART1

#define?USART_PSC?// ¿Preescalador? ¿valor? Preescalador de reloj

//#define?CrLf?{0x0D, 0x0A, 0x00}

void?usart_init(void);

u32?calcBRRDiv (u32? BaudRate, u32?Pclk);

extern?void?SelectUsart(u32?Usart); //Usart es el nombre clave de usart? 1 significa usart1, no-1 significa usart2

extern?void?printChar(char?ch); //implementado por ensamblaje

extern?void?printStr(char?*?str ) ;

extern?void?printNum(s32?num);

#ifdef?DEBUG

void?printf(char*?s,... ) ;

#endif

#endif

usart.c#include?"usart.h"

#include?"stdarg h"void?printf(char*?formato,...)

{

va_list?args;

va_start(args, formato);

p>

while(*formato)

{

if(*formato=='')

{

cambiar (* formato)

{

case?'c':

printChar((char)va_arg(args, int));

descanso;

caso?'s:

printStr(va_arg( args, char*));

romper;

caso? 'd':

printNum((s32)va_arg(args, s32));

romper; >

caso?'':

printChar(''

descanso

}

}

else

{

printChar(*formato);

}

formato; }

va_end(args);

}

#endif

//----------- -------------------------------------------------- -----

//Nombre de la función: void?USART2_IRQHandler( void)

//Parámetros de entrada: vacío

/Parámetros de retorno: vacío

/Descripción: Servicio de interrupción de recepción del puerto serie

//-------------------------- -- -------------------------------- ------

const?uchar? BTCtrl_DataFrameHeader [5]={0xa5, 0x5a, 0x11, 0xf5, 0}; //Encabezado del marco de datos de control de Bluetooth

uchar?ser_dat[USART_RECV_BUFF_SIZE] //Búfer de datos

bool? bProcessCompleted=true; //Determina si se procesa la trama Cuando se recibe la trama, la variable se establece en false

enum?BTProcessingFlag/*Modo de recepción de datos Bluetooth**

{

CheckingFrameHeader, //Comprobando el encabezado del marco de datos

ReceivingData//Recibiendo paquete de datos

};

void?USART2_IRQHandler(void)

{

static?uchar?ser_x=0;

static?uchar?mat_x=0;//match?x

static?uchar ?sum =0;

estático?Después de completar el procesamiento de datos del último cuadro

{

if?(USART2-gt;SR?amp;?1lt ;es; 5)//! Determine si el registro de lectura no está vacío

{

if?(dflag===CheckingFrameHeader)

{

if? ( USART2-gt;DR==BTCtrl_DataFrameHeader[mat_x])

{

mat_x;

}

else

{

mat_x=0;

}

si?(BTCtrl_DataFrameHeader[mat_x]==0)//! El encabezado de datos finaliza, cambia el modo y prepárate para recibir datos

{

dflag=ReceivingData;

ser_x=0;<

/p>

mat_x=0;

suma=0;

}

}

else?if?( dflag ==RecibiendoDatos)

{

ser_dat[ser_x]=USART2-gt;DR;

if?(ser_x==USART_RECV_BUFF_SIZE-1)//! Sólo se reciben USART_RECV_BUFF_SIZE bytes

{

sum =BTCtrl_DataFrameHeader[2];

sum =BTCtrl_DataFrameHeader[3];

dflag= Comprobación de encabezado de marco; //! Cambiar modo de recepción

if?(ser_dat[USART_RECV_BUFF_SIZE-1]==sum)//! Verificación de datos

{

bProcessCompleted=false; Los datos son correctos, configure el indicador de finalización de recepción

USART2-gt;CR1?amp;=?~(1lt;lt;13); //! Deja de usart2

}

}

sum =ser_dat[ser_x] //! Validación de datos

ser_x;

}

}

}

}

//------------------------------------------------ ------------------

//Nombre de la función: u32?calcBRRDiv(u32?BaudRate, u32?Pclk)

/ /Parámetro de entrada: BaudRate=BaudRate, Pclk=frecuencia de reloj RCC

//Parámetro de retorno: el valor que debe colocarse en el registro

//Descripción: Calcula la suma de la velocidad en baudios del registro BRRDiv Frecuencia de reloj: ver método de cálculo (generación de velocidad de baudios fraccionaria)

//------------------------- - ---------------------------------------

u32?calcBRRDiv ( u32?BaudRate,u32?Pclk)

{

u32?div_mant;

u32?div_frac;

flotador?frac;

div_mant=Pclk/(USART_PSC*BaudRate);

frac=(float)Pclk/(USART_PSC*BaudRate);

frac-=div_mant; /p>

frac=(float)Pclk/(USART_PSC*BaudRate);

frac-=div_mant

p>

frac*=USART_PSC

p>

div_frac=(u32 )frac;

div_frac =(frac-div_frac)gt;=0.5?1:0; //redondear hacia arriba

if?(div_frac) ==USART_PSC)//redondeo USART_PSC completo

{

div_frac=0;

div_mant;

}

div_mantlt;lt;=4;

div_mant|=div_frac;

¿regresar?