STM32F103串口1 printf函数的实现

发布者:Yuexiang最新更新时间:2022-01-29 来源: eefocus关键字:STM32F103  串口1  printf函数 手机看文章 扫描二维码
随时随地手机看文章

  在单片机中使用最多的通信接口基本就是串口了,说起串口就不得不提串口中最常用的一个函数就是打印函数printf()函数,在上位机上中这个函数直接从库函数中调用就可以了,那么在单片机中这个函数要怎么使用呢?能不能将这个函数和串口1对应起来,当然是有方法的。


  下面就通过代码来演示一下如何在串口1上使用printf()函数的功能。


void uart_init(u32 bound)

{

    //GPIO端口设置

    GPIO_InitTypeDef GPIO_InitStructure;

    USART_InitTypeDef USART_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟


    //USART1_TX   GPIOA.9

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出

    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9


    //USART1_RX   GPIOA.10初始化

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入

    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10


    //Usart1 NVIC 配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ; //抢占优先级3

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能

    NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器


    //USART 初始化设置


    USART_InitStructure.USART_BaudRate = bound;//串口波特率

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式

    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_Rx | USART_Mode_Tx; //收发模式


    USART_Init(USART1, &USART_InitStructure); //初始化串口1

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断

    USART_Cmd(USART1, ENABLE);                    //使能串口1

}


  首先初始化串口1所使用到的端口,将发送引脚设置为推挽输出模式,将接收引脚设置为浮空输入模式。这里串口使用中断来接收数据,所以还需要设置中断优先级,通过NVIC(嵌套向量中断控制器)来设置串口中断的优先级,接下来设置串口的波特率,字长为8位,1位停止位,无奇偶校验位,无硬件数据流控制端口,串口模式设置为收发模式。最后使能串口,并开启中断功能。


  下面编写串口中断函数,用来接收数据


u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.

//接收状态

//bit15, 接收完成标志

//bit14, 接收到0x0d

//bit13~0, 接收到的有效字节数目

u16 USART_RX_STA = 0;     //接收状态标记


void USART1_IRQHandler(void)                //串口1中断服务程序

{

    u8 Res;

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)

    {

        Res = USART_ReceiveData(USART1); //读取接收到的数据


        if((USART_RX_STA & 0x8000) == 0) //接收未完成

        {

            if(USART_RX_STA & 0x4000) //接收到了0x0d

            {

                if(Res != 0x0a)USART_RX_STA = 0; //接收错误,重新开始

                else USART_RX_STA |= 0x8000; //接收完成了

            }

            else //还没收到0X0D

            {

                if(Res == 0x0d)USART_RX_STA |= 0x4000;

                else

                {

                    USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res ;

                    USART_RX_STA++;

                    if(USART_RX_STA > (USART_REC_LEN - 1))USART_RX_STA = 0; //接收数据错误,重新开始接收

                }

            }

        }

    }

}


  接收数据时通过USART_RX_STA变量的最高两位表示接收数据的状态,接收数据以回车换行作为结束位,回车换行对应的数据为0x0D、0x0A,只有这两个数据挨着接收到之后才表示一组数据成功的接收到了,这里使用USART_RX_STA最高两位表示是否接收到了这两个结束标志。


  串口设置好之后,接下来给串口1添加支持printf()函数的代码。


#if 1

#pragma import(__use_no_semihosting)

//标准库需要的支持函数

struct __FILE

{

    int handle;

};

FILE __stdout;

//定义_sys_exit()以避免使用半主机模式

_sys_exit(int x)

{

    x = x;

}

//重定义fputc函数

int fputc(int ch, FILE *f)

{

    while((USART1->SR & 0X40) == 0); //循环发送,直到发送完毕

    USART1->DR = (u8) ch;

    return ch;

}

#endif


  上面的两个函数是固定模式不需要修改,自己需要修改的是fputc()函数,在这个函数中将寄存器设置为串口1的寄存器,这样printf()函数在打印数据的时候,就会通过串口1将数据发送出去,如何这里的寄存器设置为了其他串口的寄存器,那么使用printf()函数打印的时候就会通过其他串口打印出去。重定义函数fputc()设置好之后,就可在程序中直接使用printf()函数打印了。


int main(void)

{

    u8 t;

    u8 len;

    u16 times=0;

    delay_init();       //延时函数初始化

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

    uart_init(115200);

    LED_Init();

    while(1)

    {

if(USART_RX_STA&0x8000)

{

    LED1=!LED1;

len=USART_RX_STA&0x3fff; //获取本次接收数据长度

printf("rn您发送的消息为:rn");

for(t=0;t {

USART_SendData(USART1,USART_RX_BUF[t]);//向串口1发送数据

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送完成 

}

printf("rn");

USART_RX_STA=0;

}

else

{

times++;

if(times%5000==0)

{

printf("串口实验rn");

}

if(times%300==0)

printf("请输入数据,以回车键结束rn");

if(times%30==0)

LED0=!LED0;

delay_ms(10);

}

    }

}


  在主函数中通过printf()打印提示语句,提示用户输入数据。当用户输入数据并以回车换行结束后,串口接收到数据就会将接收到的数据直接打印出来。

image.png

  这样在单片机中,通过串口1就可以输出printf()函数打印的数据了。

关键字:STM32F103  串口1  printf函数 引用地址:STM32F103串口1 printf函数的实现

上一篇:STM32单片机一个定时器输出不同频率PWM波
下一篇:STM32F103自定义的printf函数的实现

推荐阅读最新更新时间:2024-11-10 10:26

STM32F103ZET6 — IWDG
简介 首先简单介绍一下看门狗的作用。 看门狗用来防止系统在运行过程中遇到的各种异常情况,而导致程序不能继续运行。可以理解为,看门狗是一种可以挽救系统进入异常进而系统无法继续工作的保障。当系统启动看门狗功能后,计数器开始计数,在计数器完成计数的时刻之前,系统程序必须“喂狗”,使得让看门狗知道系统依然“活着”。如果到了指定时间,系统没有去“喂狗”,则看门狗产生一个复位信号,系统从 Reset 重新运行。 从系统实现的角度上来看,看门狗其实就是一个计数器而已,当计数的个数达到终点时刻,产生复位信号。若计数未到达终点,软件干涉,进行喂狗的行为,则计数器重新计数,不会产生复位。 STM32 拥有两种类型的看门狗:独立看门狗(IW
[单片机]
<font color='red'>STM32F103</font>ZET6 — IWDG
STC15F2K60S2串口1程序
此程序为才写的串口1,工作模式1程序,自己测试没问题 //本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译 //假定测试芯片的工作频率为18.432MHz #include reg51.h sfr P4 = 0xc0; sfr P5 = 0xc8; sfr AUXR = 0x8e ; unsigned char temp ; bit flag = 0 ; void UartInit(void) //9600bps@11.0592MHz { SCON = 0x50; //8位数据,可变波特率 AUXR |= 0x40; //定时器1时钟为Fosc,即1T AUXR &=
[单片机]
基于STM32F103——DS18B20温度采集+串口打印
DS18B20相关介绍 DS18B20特性 1.独特的单总线接口,就需一条线则可实现双向通信(测温) 2.测温范围:-55℃~+125℃,可通过编程设定9—12位分辨率,对应分辨温度分别为0.5、0.25、0.125、0.0625℃。 3.支持多点组网(可连接多个DS18B20温度传感器),多个DS18B20可以并联(3或2线)实现多个组网测温,但注意超过8个要解决好供电问题,否则电压过低会导致传输不稳定,从而数据不准确。 4.工作电压:3.0~5.5V (寄生电源方式下可由数据线供电) 5.在使用过程中不需要外围电路,全部传感元件及转换电路都在芯片内了。(上拉电阻) 6.测温结果直接是数字量输出,单总线串行传送方式,同时可传送C
[单片机]
基于<font color='red'>STM32F103</font>——DS18B20温度采集+<font color='red'>串口</font>打印
STM32F103学习笔记 (十一) USMART调试组件
usmart组件简直就是调试神奇,利用它,则只需要在串口调试助手里面输入函数及参数,然后直接串口发送给单片机,就执行了一次参数调整,不满意的话,你在串口调试助手修改参数在发送就可以了,直到你满意为止。 支持的类型有: 10 或者 16 进制数字、字符串指针(如果该参数是用作参数返回的话,可能会有问题!)、函数指针等。 使用USMART 调用的函数,必须将文件添加到usmart_config.c: 只要把函数所在头文件添加进来,并把函数名按上图所示的方,增加即可。 主函数很简单,就是在屏幕上显示一些内容: int main(void) { delay_init(); //延时函数初始化 NVIC_C
[单片机]
<font color='red'>STM32F103</font>学习笔记 (十一) USMART调试组件
STM32F103标准库开发---Uart串口通信实验---printf()函数重定向
一、printf()函数重定向 方法一:使用MicroLIB库 1. 勾选 Use MicroLIB 具体如下图所示: 2. 重定向 fputc 函数 具体代码如下: #include stdio.h //需要调用stdio.h文件 /**********************printf重定向****************************/ int fputc(int ch, FILE *f) { USART_SendData(USART1, ch); //发送数据 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等待发送完
[单片机]
<font color='red'>STM32F103</font>标准库开发---Uart<font color='red'>串口</font>通信实验---<font color='red'>printf</font>()<font color='red'>函数</font>重定向
STM32F103之Timer2PWM输出
一、简介 本文以STM32F103编程为例,介绍STM32F103Timer2 PWM输出。 二、实验平台 电脑平台:Windows7 64位旗舰 编译软件:IAR 硬件平台:STM32F103CB 三、版权声明 四、实验前提 1、在进行本文步骤前,请先安装IAR Embedded Workbench 5.4版本;准备好STM32F103CB硬件平台。 五、基础知识 暂无 六、源码地址 暂无 七、关联文章 暂无 八、实验内容 1.初始化Timer2,初始化时需先开起相关时钟 void Hal_Init_Pwm(uint16 period,uint16 Presca
[单片机]
STM32F103 STM32F407 引脚配置 方法对比
先说STM32F407引脚的配置方法 1. 首先以 UART4 为例,先把引脚配置成 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; 2. 就是 Alternate function功能 3. 把 UATR4 映射到对应的引脚,看下图,UART4 属于AF8,代码是 GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_UART4); 4. 看下面的代码,其实 GPIO_AF_UART4 就是 AF8,从 M4 开始,意法半导体把外围模块分成了AF0-AF15,其实是一个多路复用器。 /** * @brief AF 7 se
[单片机]
<font color='red'>STM32F103</font> STM32F407 引脚配置 方法对比
STM32f103 串口接收不定长数据
方法1:串口接受数据,定时器来判断超时是否接受数据完成。 方法2:DMA接受+IDLE中断 实现思路:采用STM32F103的串口1,并配置成空闲中断IDLE模式且使能DMA接收,并同时设置接收缓冲区和初始化DMA。那么初始化完成之后,当外部给单片机发送数据的时候,假设这帧数据长度是200个字节,那么在单片机接收到一个字节的时候并不会产生串口中断,而是DMA在后台把数据默默地搬运到你指定的缓冲区里面。当整帧数据发送完毕之后串口才会产生一次中断,此时可以利用DMA_GetCurrDataCounter();函数计算出本次的数据接受长度,从而进行数据处理。 应用对象:适用于各种串口相关的通信协议,如:MODBUS,PPI
[单片机]
<font color='red'>STM32f103</font> <font color='red'>串口</font>接收不定长数据

推荐帖子

嵌入式软件开发工程师
汉王科技股份有限公司嵌入式软件开发工程师-OCR软件部电子邮箱:yinsg@hanwang.com.cn发布日期:2007-03-21工作地点:北京市招聘人数:1工作年限:二年以上外语要求:英语薪水范围:面议学历:本科接受简历语言:中文或英文职位描述:职责描述:1、windows平台,应用软件开发;2、嵌入式平
yangsiyan 嵌入式系统
TI store购买开发板攻略
经常在TIstore买板子的你可能早就熟悉了整个购买过程,最近听说有了一点小变化,在这儿给大家分享下。如果你曾在TIstore购买板子的时候遇到过一些问题或疑问,欢迎跟帖分享有TI账号直接登录即可,没有的话需要先注册TI帐号,并登陆,然后在TIstore搜索你要购买的产品型号,如:CC3200-LAUNCHXL(以此板为例)点此查看我搜索到这块开发板的链接点击Buy加入购物车
eric_wang TI技术论坛
关于触摸屏的触摸声音
我把WINCE600\\PUBLIC\\COMMON\\OAK\\DRIVERS\\WAVEUI目录下的四个文件替换掉了,为了保险起见,把找来的文件都转成了8bitPCM,1mono,11Khz。放进去后build-c然后sysgen,发现声音播不出来。开机音乐我也给替换了,16bitPCM,22Khz2stereo,可以播。那位兄弟晓得怎么回事?或者有不错的触摸屏声音送我一个,谢拉!QQ:18271320关于触摸屏的触摸声音MARK,学习下,帮顶下。在
zoling 嵌入式系统
模拟电路与数字电路及其应用复习资料
数字电路及其应用复习资料2005-6-10(尽管其本非是专业课,但与专业“数字电路的模拟电路”相关当今时代,数字电路已广泛地应用于各个领域。本报将在“电路与制作”栏里,刊登系列文章介绍数字电路的基本知识和应用实例。    在介绍基本知识时,我们将以集成数字电路为主,该电路又分TTL和CMOS两种类型,这里又以CMOS集成数字电路为主,因它功耗低、工作电压范围宽、扇出能力强和售价低等,很适合电子爱好者选用。    介绍应用时,以实用为主,特别介绍一些家电产品和娱乐产品中的数字电
fighting 模拟电子
WINCE电源管理的问题
各位好友,我的系统进入SLEEP时会调用驱动里面的IOCTL_SET_POWER_STATE,但为何退出SLEEP时没有进入驱动里面的IOCTL_SET_POWER_STATE呢?谢谢了!WINCE电源管理的问题说明你的调用可能有问题呗Wince还是WindowsMobile?唤醒后可以正常工作吗?你的退出Sleep是什么意思,唤醒吗PM里有个函数叫updatdevicestate,PM在这个函数设备电源状态的更改,把调试信息打出来,看看PM有没有更改设备的状态wince4.2怎
hjkl645 WindowsCE
晶体谐振器的工作原理
晶体谐振器的工作原理什么是石英石英的化学成分为SiO2,晶体属六方晶系的氧化物矿物,即低温石英(a-石英),是石英族矿物中分布最广的一个矿物种。广义的石英还包括高温石英(b-石英)。受压或受热能产生压电效应。石英晶体振荡器是利用石英晶体的压电效应制成的一种谐振器件,它的基本构成大致是:从一块石英晶体上按一定方位角切下薄片(常用晶片切型分为两种:AT切和BT切),在它的两个对应面上镀银作为电极,在每个电极上各焊一根引线接到管脚上,再加上封
YXC扬兴晶振 分立器件
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved