历史上的今天
返回首页

历史上的今天

今天是:2025年06月02日(星期一)

正在发生

2021年06月02日 | 实现STM32的串口数据发送和printf函数重定向

2021-06-02 来源:eefocus

简介:在调试电机驱动程序的时候,是不能随便利用中断来进行一些寄存器或数据的查看的,不然你在运行的时候突然来一下,如果占空比大的话那可能直接就把MOS管给烧了,所以我们很多情况下只能使用USART(串口)来进行程序的调试和数据的监控了。


对于STM32来说,由于很多内容都是有库来实现的,那就省了很多时间,直接看个例子就可以写了,大致有4步步骤:


1 1、RCC始终初始化,对端口和USARTX使能时钟

2 2、初始化端口功能,RX设置为输入悬空,TX设置为复用功能的推挽输出,注意GPIO_SPEED要设置下,我没设置弄了半天都没输出

3 3、设置USARTX寄存器,波特率、数据位、校验位、停止位等

4 4、看需要是否开中断,我这里没开


设置完后其实是可以发简单的数据了,不过如果要实现一些复杂的输出就需要自己去写相应的函数,还不一定能都实现,那该怎么才能跟好实现串口的数据输出呢?


这里就可以用到Printf函数,之前一直看个可以重定向这个函数来出现输出,就是以前片子资源少,就没想过用这个函数了,现在就有机会试试了。查了下,发现其实还是很简单的,就是重定向一个函数就好了。


 1 #include //标准的库函数

 2 

 3 //重写这个函数就可以了

 4 #ifdef _PRINTF_

 5 int fputc(int ch, FILE *f)

 6 {

 7    USART_SendData(USART3, (u8) ch);

 8 

 9    while(!(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == SET))

10    {

11    }

12 

13    return ch;

14 }

15 #endif

还有修改下IDE的设置,我的是用IAR,进到option->general option->library configuration下,把library从normal改为full,好了,下面使用printf输出数据就OK了,对于调试来说还是相当好用的。


初始化设置:


void Uart_RccInit(void)

{

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOBs);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);

}


void Uart_GpioInit(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    

    //PB10作为US1的TX端,打开复用,负责发送数据

    GPIO_StructInit(&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度设置,不设置可能导致无输出

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    

    //PB11作为US1的RX端,负责接收数据

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

}


void Uart_UartInit(void)

{

    USART_InitTypeDef USART_InitStructure;

    

    USART_StructInit(&USART_InitStructure);

    USART_InitStructure.USART_BaudRate = 9600;

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;

    USART_InitStructure.USART_StopBits = USART_StopBits_1;

    USART_InitStructure.USART_Parity = USART_Parity_No;

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_Init(USART3, &USART_InitStructure);

    

   // USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

    USART_Cmd(USART3, ENABLE);


}


推荐阅读

史海拾趣

问答坊 | AI 解惑

问个变压器问题~

1。变压器的电压比是5:4,但是应用时输出电压远远达不到这个值,实际输出电压比理论值要低差不多20V。比如说:我输入个AC 220V 50Hz的电压(量了,是正确的),输出电压理论值应该为 220*0.8=196V,但实际输出电压才173V。整个电路电流在15mA以内 ...…

查看全部问答>

xilinx usb 下载线

Xilinx platform cable usb(Xilinx 下载线) 1.目标器件VCC兼容 1.5V--5V 2.可配置所有Xilinx器件 3.支持iMPACT 和ChipScope 4.支持JTAG和Slave Serial配置模式 5.目标器件下载时钟可选,最高可达24 MHz 6.LED状态指示灯指示目标器件电 ...…

查看全部问答>

程序员人生:做CE的都进来谈谈,对于CE的未来你困惑吗?

这里有做CE很多年的,也有刚入行不久的朋友。入行很久的朋友说说你对CE未来的看法,对自己职业生涯的看法。刚入行的朋友谈谈入这行的动机吧。 背景:MS做了CE, Mobile很多年,这两个平台一直不温不火。最近android, iphone,还有新贵meego火得不 ...…

查看全部问答>

eboot中的main.c中的InitLDI_LTV350和Write_LDI_LTV350起什么作用的?

SMDK2450 FMD版的: InitDisplay里的代码: #elif (BSP_TYPE == BSP_SMDK2450) void Delay(void) {     volatile int i;     for(i=0 ; i < 1000 ; i++)     {     } } static void InitDisplay(void) ...…

查看全部问答>

ce 系统分区

Windows CE Firmware Init INFO: Initializing system interrupts... INFO: Initializing system clock(s)... INFO: Initializing driver globals area... SDMMC config set rGPGCON: fd96f5b6 OEMInit Done... Sp=ffffc7cc NandFlash FMD_I ...…

查看全部问答>

关于USB驱动的问题

想在PXA270板子上使用内置USB设备,涉及驱动结构 USBFNUSBD|HCD 如果我想用外接USB设备,就要涉及USB ROOT HUB的驱动, 请问USB ROOT HUB驱动是在上述结构的什么位置? USBFN里面对内置和外置USB设备处理有没有不同? 小弟初学,表述不周还请 ...…

查看全部问答>

简单但你却不一定能说得通的JTAG接口

JTAG接口        1JTAG(Joint Test Action Group;联合测试行动小组)是一种国际标准测试协议(IEEE 1149.1兼容),主要用于芯片内部测试。现在多数的高级器件都支持JTAG协议,如DSP、FPGA器件等。标准的JTAG接口是4 ...…

查看全部问答>

瑞嵌NXPLPC11XX文件详解

对NXPLPC11XX.H文件的解释…

查看全部问答>

关于STM32的JTAG口

请问如果把JTAG端口全部禁止后是不是就不能下载和仿真了呢? 如果JTAG口锁定了如何解除锁定呢?…

查看全部问答>

f2818中sprintf()函数可用吗?

char buff[40]; sprintf(buff, \\"%f\\", 5.252); 我想用sprintf()函数实现浮点数的显示,程序编译没问题,我单步调试中发现buff数组的值没有被更新!! 同时我也试了ltoa()函数,也同样不起作用!! 是不是库函数都可用??   &nb ...…

查看全部问答>