历史上的今天
返回首页

历史上的今天

今天是:2025年08月12日(星期二)

正在发生

2019年08月12日 | STM32-(10):Printf

2019-08-12 来源:eefocus

学C语言的时候我们经常将printf作为打印输出,可以加格式转换符,比如十进制,十六进制,浮点输出,功能十分强大。在硬件进行调试的时候,也希望能输出这样一个结果,能够看到内部的ARM工作在什么状态,或者运行的结果,一般会用到数码管、液晶屏,但是控制起来麻烦,如果也能用到printf,那肯定很方便!

此时我们只需将printf重定向,原来是输出到屏幕,我们只需要重定向输出到串口。 串口只需要一个串口助手就能看到打印。


printf 是 标准的输入输出库 stdio.lib 内实现的, 这个 lib 库赖以支持的基础是一个文件流 FILE,文件流内有很多的底层函数,比如:_sys_exit _sys_open ,其中有一个底层函数是 int fputc(int ch,FILE*f),我们只需要修改 fputc 函数进行重定向就能将打印输出到串口。



//----------------头文件声明--------------------

#include"stm32f10x_lib.h" //包含所有的头文件

#include

//----------------函数声明--------------------

void Delay_MS(u16 dly);

void RCC_Configuration(void);

void GPIO_Configuration(void);

void USART_Configuration(u32 BaudRate);


/*******************************************************************************

* Function Name  : fputc

* Description    : 重定向这个C库(stdio)printf函数  文件流——》串口USART1

* Input          : ch,*f

* Output         : None

* Return         : None

*******************************************************************************/ 

int fputc(int ch,FILE *f)

{

//ch送给USART1

USART_SendData(USART1, ch);

//等待发送完毕

while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET) ;

//返回ch

return(ch);

}


/*******************************************************************************

* Function Name  : main

* Description    : Main program.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/ 

int main(void)

{

u8 i,data;


RCC_Configuration();

GPIO_Configuration();

USART_Configuration(19600);


data='A';

for(i=0;i<30;i++)

{

USART_SendData(USART1, data);

data++;

while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET) ;

}

printf("ntwww.yxarm.net");

printf("nti value is   %d",i);

printf("nti value is   %o",i);

printf("nti value is   %d,  %d",i+i,i*i);

printf("nt-----------------------------");

}


/*******************************************************************************

* Function Name  : Delay_Ms

* Description    : delay 1 ms.

* Input          : dly (ms)

* Output         : None

* Return         : None

*******************************************************************************/

void Delay_MS(u16 dly)

{

u16 i,j;

for(i=0;i for(j=1000;j>0;j--);

}


/*******************************************************************************

* Function Name  : RCC_Configuration

* Description    : Configures the different system clocks.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void RCC_Configuration(void)

{

//----------使用外部RC晶振-----------

RCC_DeInit(); //初始化为缺省值

RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟 

while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪

//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer

//FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state

RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK

RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 =  HCLK

RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ

RCC_PLLCmd(ENABLE); //Enable PLLCLK


while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock

while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source

//---------打开相应外设时钟--------------------

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能APB2外设的GPIOA的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能APB2外设的GPIOC的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);  

 

}


/*******************************************************************************

* Function Name  : GPIO_Configuration

* Description    : 初始化GPIO外设

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/ 

void GPIO_Configuration(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;


  /* Configure USARTx_Tx as alternate function push-pull */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* Configure USARTx_Rx as input floating */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(GPIOA, &GPIO_InitStructure);


}


void USART_Configuration(u32 BaudRate)

{

USART_InitTypeDef USART_InitStructure; 

USART_InitStructure.USART_BaudRate = BaudRate; 

USART_InitStructure.USART_WordLength = USART_WordLength_8b; 

USART_InitStructure.USART_StopBits = USART_StopBits_1; 

USART_InitStructure.USART_Parity = USART_Parity_No; 

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 

USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;  

USART_Init(USART1, &USART_InitStructure);

USART_Cmd(USART1, ENABLE);

}


推荐阅读

史海拾趣

Franel Corp公司的发展小趣事

为了更好地服务中国市场,法勒公司不断优化其供应链和生产布局。近年来,法勒加大了在国内的投资力度,建设了现代化的生产基地和研发中心。通过本土化生产,法勒不仅降低了产品成本,还缩短了交货周期,提高了市场响应速度。同时,法勒还积极与本土供应商建立紧密的合作关系,共同构建了一个高效、稳定的供应链体系。

BVLED公司的发展小趣事

为了进一步扩大市场份额和提升品牌影响力,BVLED公司开始积极拓展国内外市场。在国内,公司加强了与大型照明企业的合作,通过联合推广和定制服务等方式提高了产品知名度。在国外,公司积极参加国际展览和贸易洽谈会,与国际知名企业建立了合作关系,成功打开了国际市场的大门。

Crouzet公司的发展小趣事

随着市场竞争的加剧,Crouzet开始注重提供定制化的解决方案,以满足客户不断变化的需求。公司凭借强大的研发能力和丰富的行业经验,能够根据客户的具体需求,提供量身定制的产品和服务。这种以客户需求为导向的经营理念,使得Crouzet在市场上赢得了更多的客户和合作伙伴。

Formosa MS公司的发展小趣事

随着业务的不断发展,Crouzet公司于1989年和1992年分别成功兼并了法国Syreles公司及墨西哥Gordos公司。这一系列的兼并活动不仅增强了公司的实力,还进一步扩大了公司的业务范围。此后,Crouzet开始在全球范围内布局,陆续在美国、德国、英国、荷兰、比利时、瑞士、瑞典等国设立分公司,形成了一个覆盖全球的销售网络。

Delock公司的发展小趣事

Delock公司自创立之初,就致力于电子连接技术的研发。公司创始人李先生敏锐地洞察到市场对高性能、稳定可靠的电子连接设备的需求,于是带领团队投入大量资源进行技术研发。经过数年的努力,Delock公司成功开发出一种具有革命性意义的电子连接器,不仅传输速度快,而且耐用性高,迅速在市场上获得了认可。这一创新不仅为Delock公司带来了可观的利润,也为公司在电子行业树立了技术领先的形象。

FINTEK公司的发展小趣事

随着ASP芯片市场的成功,FINTEK公司意识到单一产品线的局限性。为了保持竞争优势并开拓新市场,公司开始多元化拓展产品线。经过市场调研和技术储备,FINTEK相继推出了数字信号处理器(DSP)、微控制器(MCU)以及射频前端模块(RF FEM)等一系列新产品。这些产品的推出不仅丰富了公司的产品线,也进一步巩固了FINTEK在半导体领域的市场地位。

问答坊 | AI 解惑

悬挂系统中的步进电机带动装置选择问题

本帖最后由 paulhyde 于 2014-9-15 09:25 编辑 步进电机带动滑轮,要用什么样的线比较好? 线要绕在步进电机上还是绕在哪里?绕在电机上的话线太长,步进电机齿轮太小,绕不上。 还有这些滑轮啦线啦齿轮啦要上哪买?五金店吗?  …

查看全部问答>

发个字符移动的程序(ZT)

本帖最后由 paulhyde 于 2014-9-15 09:38 编辑 前几天在公交站牌上看到那个led屏上字符移动的效果,看了之后回来想玩玩,就做了这个,发上来分享一下!!  …

查看全部问答>

请问无盘工作站是两个系统吗?

请问无盘工作站是两个系统吗?为什么有的是一个呢?它们有什么区别啊?》…

查看全部问答>

各位大虾帮忙,加密芯片ESPU0808有人用过吗?

最近我们公司有一个方案,要用到加密芯片。听说加密芯片ESPU0808芯片不错,上次去深圳的集成电路展也看到他们的公司了,有没有人用过这个芯片呢,有的话告诉我一下啊,谢谢了。急着了解中,…

查看全部问答>

ADS下全局变量赋值无效的问题

我用ADS1.2+JTAG调试程序的时候,定义的全局变量在赋值的时候赋不进去。当在初始化汇编代码init.s中加入存储寄存器初始化的代码,就可以赋值进去,这是什么原因呢 ? 加入的存储寄存器初始化代码如下: SMRDATA DATA ; Memory configuration sho ...…

查看全部问答>

如何将笔记本usb口虚拟成串口

本人想进行串口编程,但笔记本上只有usb口,故想将其虚拟成串口,但不知怎么做。希望个位帮帮忙,给分绝不吝惜!!!…

查看全部问答>

M2M-DMA的问题

  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SRC_Buffer;  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DST_Buffer;采用M2M模式,在本地RAM测试通过。即SRC_Buffer[x]={};  DST_ ...…

查看全部问答>

【转帖】MSP430是很有前途的单片机--转自老古论坛

对于ti推出的msp430低功耗的16位单片机,评论很多。在这个时候推出16位的单片机,是否能够占领市场? 我们知道8位单片机在中国是处于龙头地位的。要动摇51单片机的地位,确实在中国有一定的困难。在中国,特别要考虑的是中国的国情。 比 ...…

查看全部问答>