打印
[STM32F1]

学习F103,碰到一个不科学的,有关printf的问题

[复制链接]
2251|28
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
dai410257573|  楼主 | 2016-11-28 22:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dai410257573 于 2016-11-29 09:26 编辑

学习中碰到一个问题,觉得有点不科学。问题点在于,如果我在初始化的情况下不初始化C口(红色),printf打印不出来,什么都没有。初始化B/C/D/E/F口都行,下面的打印都打印正常,有点纳闷。代码如下,求大神分析下。

/*******************************************************************************
*                 
*                  
--------------------------------------------------------------------------------
* 实 验 名         : 串口实验
* 实验说明       : 在串口助手上选择波特率为9600,选择HEX发送和HEX显示,发送数据
                    在串口上加1进行显示,参考里面图片设置
* 连接方式       :
* 注    意         :     所用函数在头文件.c文件内
*******************************************************************************/

#include "public.h"
#include "usart.h"
#include "systick.h"
#include "stdio.h"

//配置系统时钟,使能各外设时钟

void RCC_Configuration()
{
    ErrorStatus HSEStartUpStatus;                           //定义枚举类型变量HSEStartUpStatus
    RCC_DeInit();                                           //复位系统时钟
    RCC_HSEConfig(RCC_HSE_ON);                              //开启HSE
    HSEStartUpStatus = RCC_WaitForHSEStartUp();             //等待HSE起振
    if(HSEStartUpStatus == SUCCESS)
    {
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        FLASH_SetLatency(FLASH_Latency_2);
        RCC_HCLKConfig(RCC_SYSCLK_Div1);                      //选择HCLK时钟源为SYSCLK1分频
        RCC_PCLK2Config(RCC_HCLK_Div1);                       //选择PCLK2的时钟源为HCLK1分频
        RCC_PCLK1Config(RCC_HCLK_Div2);                       //选择PCLK1的时钟源为HCLK2分频
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);    //选择PLL时钟源为HSE1分频,9倍频
        RCC_PLLCmd(ENABLE);                                   //使能PLL
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);   //等待PLL输出稳定
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);            //系统时钟为PLL
        while(RCC_GetSYSCLKSource() != 0x08);                 //等待PLL为系统时钟源
    }
}
/****************************************************************************
* Function Name  : usart_io_init
* Description    : IO init program.
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/
void usart_io_init()
{
    GPIO_InitTypeDef GPIO_InitStructure;                //声明一个结构体变量,用来初始化GPIO

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能IO口的时钟   
    GPIO_InitStructure.GPIO_Pin= LED;            
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;   
    GPIO_Init(GPIOC,&GPIO_InitStructure);                 /* 初始化GPIO */        


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能IO口的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;            //TX               //串口输出PA9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;            //RX             //串口输入PA10
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;    //模拟输入
    GPIO_Init(GPIOA,&GPIO_InitStructure);                 /* 初始化GPIO */        

   
}

void Usart_mode_init()
{
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
   

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    USART_InitStructure.USART_BaudRate = 9600;                            //设置波特率9600        
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;            //设置数据长度8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                //设置停止位1位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;

    USART_Init(USART1,&USART_InitStructure);                                /* 初始化USART1 */
   
    USART_Cmd(USART1,ENABLE);                                            //使能usart1
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);                        //中断开启
    USART_ClearFlag(USART1,USART_FLAG_TC);                                //清楚中断标志   

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);   
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;        //打开USART1的全局中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;      //抢占优先级为0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;             //响应优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;              //使能
    NVIC_Init(&NVIC_InitStructure);
}

/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Init_NVIC
** 功能描述: 系统中断配置
** 参数描述:无
** 作   者: Dream
** 日   期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Init_NVIC(void)
{     
    #ifdef  VECT_TAB_RAM                                      //向量表基地址选择

      NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);              //将0x20000000地址作为向量表基地址(RAM)
    #else  

      NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);         //将0x08000000地址作为向量表基地址(FLASH)  
    #endif
}

int fputc(int ch,FILE *p)  //函数默认的,在使用printf函数时自动调用
{
    USART_SendData(USART1,(u8)ch);   
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
    return ch;
}


int GetKey (void)
{

      while (!(USART1->SR & USART_FLAG_RXNE));

      return ((int)(USART1->DR & 0x1FF));

}



/****************************************************************************
* Function Name  : main
* Description    : Main program.
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/
//u8 led_num = 0;

int main()
{   
    RCC_Configuration();
    Init_NVIC();
    usart_io_init();
    Usart_mode_init();

    while(1)
    {
        printf("学习\r\n");
        printf("STM32\r\n");
        delay_ms(1000);

    }
}




沙发
xyz549040622| | 2016-11-29 09:03 | 只看该作者
哪句代码呢》程序中没有特别指明的

使用特权

评论回复
板凳
dai410257573|  楼主 | 2016-11-29 09:33 | 只看该作者
xyz549040622 发表于 2016-11-29 09:03
哪句代码呢》程序中没有特别指明的

就是IO口的初始化函数里面。现在更新为红色字体,我有点奇怪,如果就这一套程序,如果不添加B/C/D/E/F的初始化函数,则打印什么都没有。如果加上了,则打印没有问题,我很纳闷。

使用特权

评论回复
地板
皈依| | 2016-11-29 11:37 | 只看该作者
楼主的意思是红色部分注释掉就不打印了?

使用特权

评论回复
5
dai410257573|  楼主 | 2016-11-29 11:51 | 只看该作者
皈依 发表于 2016-11-29 11:37
楼主的意思是红色部分注释掉就不打印了?

是的,很奇怪。

使用特权

评论回复
6
皈依| | 2016-11-29 11:53 | 只看该作者

写个最简单的函数循环打印试试,还没有的话测量一下波形

使用特权

评论回复
7
dai410257573|  楼主 | 2016-11-29 12:10 | 只看该作者
皈依 发表于 2016-11-29 11:53
写个最简单的函数循环打印试试,还没有的话测量一下波形

最开始的时候,没有初始化C口,一直没打印,想是不是while没进来还是怎么的,然后初始化了led的C口,发现就可以打印了。。。。
那我再弄个for试试,测试串口的波形吗?

使用特权

评论回复
8
皈依| | 2016-11-29 13:48 | 只看该作者
dai410257573 发表于 2016-11-29 12:10
最开始的时候,没有初始化C口,一直没打印,想是不是while没进来还是怎么的,然后初始化了led的C口,发现 ...

也有可能是没进去while
你看看程序跑没跑到printf

使用特权

评论回复
9
dai410257573|  楼主 | 2016-11-29 20:34 | 只看该作者
皈依 发表于 2016-11-29 13:48
也有可能是没进去while
你看看程序跑没跑到printf

PA9 示波器显示是没有数据。好像程序就没有跑起来一样。现在不初始化别的IO口,有没有方法测试程序是否跑起来了

使用特权

评论回复
10
李三狗| | 2016-11-29 20:35 | 只看该作者

使用特权

评论回复
11
dai410257573|  楼主 | 2016-11-29 21:00 | 只看该作者

使用特权

评论回复
12
皈依| | 2016-11-30 08:11 | 只看该作者
dai410257573 发表于 2016-11-29 20:34
PA9 示波器显示是没有数据。好像程序就没有跑起来一样。现在不初始化别的IO口,有没有方法测试程序是否跑 ...

最好的是硬件仿真一下,没条件的话在printf那里让灯闪烁,看灯会不会闪

使用特权

评论回复
13
dai410257573|  楼主 | 2016-11-30 09:48 | 只看该作者
皈依 发表于 2016-11-30 08:11
最好的是硬件仿真一下,没条件的话在printf那里让灯闪烁,看灯会不会闪

在查的时候,就是弄了个IO口驱动的LED在里面,发现可以打印。然而不加LED的IO口初始化,就打印不了。pa9也是没有电平变化的。

使用特权

评论回复
14
皈依| | 2016-11-30 10:03 | 只看该作者
dai410257573 发表于 2016-11-30 09:48
在查的时候,就是弄了个IO口驱动的LED在里面,发现可以打印。然而不加LED的IO口初始化,就打印不了。pa9 ...

那就仿真一下 程序一步步的跑试试

使用特权

评论回复
15
lenglx| | 2016-11-30 18:18 | 只看该作者
你的工程有没有提供USART的中断函数?

使用特权

评论回复
16
dai410257573|  楼主 | 2016-11-30 20:56 | 只看该作者
lenglx 发表于 2016-11-30 18:18
你的工程有没有提供USART的中断函数?
中断里面的函数如下
void USART1_IRQHandler(void)        //串口1中断函数
{
        static u8 usart1_data;
        USART_ClearFlag(USART1,USART_FLAG_TC);
        if(USART_GetITStatus(USART1,USART_IT_RXNE) != Bit_RESET) //检查指定的USART中断发生与否
        {
                usart1_data = USART_ReceiveData(USART1);
                USART_SendData(USART1,usart1_data);
                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == Bit_RESET);
        }
        
}

使用特权

评论回复
17
dai410257573|  楼主 | 2016-11-30 21:16 | 只看该作者
皈依 发表于 2016-11-30 10:03
那就仿真一下 程序一步步的跑试试

debug的时候,发现一直在中断函数里面出不来,并且一直在循环出不来,并且没有进入if的判断语句

使用特权

评论回复
18
皈依| | 2016-11-30 21:44 | 只看该作者
dai410257573 发表于 2016-11-30 21:16
debug的时候,发现一直在中断函数里面出不来,并且一直在循环出不来,并且没有进入if的判断语句 ...

那你看看是不停地进中断还是进去了卡在某一句卡死了

使用特权

评论回复
19
dai410257573|  楼主 | 2016-11-30 22:27 | 只看该作者
皈依 发表于 2016-11-30 21:44
那你看看是不停地进中断还是进去了卡在某一句卡死了

就是一直在里面执行清中断函数,if判断,但是if语句进不去里面。中断函数在我16L的回复里面

使用特权

评论回复
20
皈依| | 2016-11-30 22:33 | 只看该作者
dai410257573 发表于 2016-11-30 22:27
就是一直在里面执行清中断函数,if判断,但是if语句进不去里面。中断函数在我16L的回复里面 ...

把清楚中断标志位放在if里面就可以了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

312

帖子

5

粉丝