3908|9

42

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

stm32 用TIM2实现外部脉冲计数,串口无法输出 [复制链接]

    设计思路:stm32 用TIM2实现外部脉冲计数,按键4充当外部脉冲。预期实验现象:LED3灭,串口输出脉冲个数(即按下的按键次数),延时,LED3亮,延时,LED3灭,输出脉冲个数,如此循环。
   问题:真实现象是LED3闪一下就再也不亮了,串口没有任何输出。是我串口设置的问题吗?请各位大神指教。拜托。
   程序如下:

/*脉冲量测量*/
#include "stm32f10x.h"
#include
void delay(uint32_t);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM2_Configuration(void);
void COM_DMA_Config(void);
void LED_Config(void);
int fputc(int ch, FILE *f);
int fgetc( FILE *f);
uint8_t buff[5200];
uint32_t count=0;


int main(void)
{
        RCC_Configuration();
    GPIO_Configuration();
    TIM2_Configuration();
        COM_DMA_Config() ;
        LED_Config() ;   

    while (1)
    {
          delay(6000000);
          GPIO_SetBits(GPIOD,GPIO_Pin_4);       
          printf("计数=%dr/min \n\r", count);
          delay(6000000);
          GPIO_ResetBits(GPIOD,GPIO_Pin_4);
    }   
}



void RCC_Configuration(void)
{
    SystemInit();
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}

void LED_Config(void)
{
           GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;          
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       
    GPIO_Init(GPIOD, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;          
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

//外部脉冲输入管脚
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;           //TIM2_CH1
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       
    GPIO_Init(GPIOA, &GPIO_InitStructure);


}
void  TIM2_Configuration(void)
{
    DMA_InitTypeDef  DMA_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        DMA_DeInit(DMA1_Channel5);
        /*外设地址为TIM2的CNT(计数器寄存器)*/
        DMA_InitStructure.DMA_PeripheralBaseAddr= (u32)&TIM2->CNT;
        /*内存地址*/
        DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&count;
        /*外设至内存模式*/
        DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize=1;
        /*外设地址不自动加1*/
        DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;
        DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;
        DMA_InitStructure.DMA_Priority=DMA_Priority_High;
        DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
        DMA_Init(DMA1_Channel5,&DMA_InitStructure);
        DMA_Cmd(DMA1_Channel5, ENABLE);



  TIM_DeInit(TIM2);
  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;      //?自动重装载值,值越小频率越大,值越大频率越小
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;      
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;  
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式

  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);      
  TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);          //外部时钟模式2,计数器在选定输入端的每个上升沿计数
  TIM_SetCounter(TIM2, 0);           //设置寄存器寄存值
  TIM_Cmd(TIM2, ENABLE);
  TIM_DMACmd(TIM2,TIM_DMA_COM,ENABLE);                 //TIM_DMA_Update: TIM update Interrupt source
                                             //TIM_DMA_CC1: TIM Capture Compare 1 DMA source
                                             //TIM_DMA_CC2: TIM Capture Compare 2 DMA source
                                             //TIM_DMA_CC3: TIM Capture Compare 3 DMA source
                                             //TIM_DMA_CC4: TIM Capture Compare 4 DMA source
                                             //TIM_DMA_COM: TIM Commutation DMA source
                                             //TIM_DMA_Trigger: TIM Trigger DMA source

}

void COM_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);          
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);          
       
        /*设置TX*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  
    GPIO_Init(GPIOD, &GPIO_InitStructure);
        /*设置RX*/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;   
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;                  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                  
    GPIO_Init(GPIOD, &GPIO_InitStructure);
        /*重映射*/
        GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);

   USART_InitStructure.USART_BaudRate=115200;
   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_Rx|USART_Mode_Tx;
   USART_Init(USART1,&USART_InitStructure);
   USART_Cmd(USART2,ENABLE);
}

//用DMA将脉冲数转至内存
void COM_DMA_Config(void)
{
                   DMA_InitTypeDef DMA_InitStructure;

        /*使能DMA时钟*/
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);       
       
        /*设置DMA传输的外设地址*/
        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART2->DR;  
       
        /*设置DMA传输内存地址(要传输的变量的指针)*/
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buff;
       
        /*DMA传输方向:从内存到外设*/       
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
       
        /*DMA传输的数据量*/
        DMA_InitStructure.DMA_BufferSize = 5200;  

        /*外设地址不增*/
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
       
        /*内存地址递增*/
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

        /*外设数据单位 8位*/
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  
       
        /*内存数据单位 8位*/
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
       
        /*DMA模式:一次传输*/
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在正常缓存模式
       
        /*优先级:中*/
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
       
        /*禁止内存到内存的传输        */
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输

        /*配置DMA1的17通道*/       
        DMA_Init(DMA1_Channel7, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
       
        DMA_Cmd(DMA1_Channel7, ENABLE);  //使能USART1 TX DMA1 所指示的通道           
}





#ifndef MicroLIB
//#pragma import(__use_no_semihosting)             //没有实现fgetc时需要声明该参数   
/* 标准库需要的支持函数 使用printf()调试打印不需要实现该函数 */               
struct __FILE
{
        int handle;
    /* Whatever you require here. If the only file you are using is */   
    /* standard output using printf() for debugging, no file handling */   
    /* is required. */
};

FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
/* 重定义fputc函数 如果使用MicroLIB只需要重定义fputc函数即可 */  
int fputc(int ch, FILE *f)
{
    /* Place your implementation of fputc here */

         /* e.g. write a character to the USART */
    USART_SendData(USART2, (uint8_t) ch);

    /* Loop until the end of transmission */
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
    {}

    return ch;
}
/*
可以直接使用putchar
不需要再定义 int putchar(int ch),因为stdio.h中有如下定义
#define putchar(c) putc(c, stdout)
*/

int ferror(FILE *f) {  
    /* Your implementation of ferror */  
    return EOF;  
}
#endif

FILE __stdin;

int fgetc(FILE *fp)
{
        int ch = 0;
       
    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
    {
    }

    ch = (int)USART2->DR & 0xFF;
       
    putchar(ch); //回显
       
        return ch;
}

void delay(__IO uint32_t nCount)
{
    for (; nCount != 0; nCount--);
}




此帖出自stm32/stm8论坛

最新回复

你就没调用串口初始化的函数,你只调用串口DMA初始化的函数了,个人感觉,串口作为调试口打印调试信息时,没有大量数据要发送,没必要使用DMA,那样纯粹是给自己找麻烦。写程序一定要仔细,该调用什么函数一定要清楚  详情 回复 发表于 2018-1-4 20:39
点赞 关注
 

回复
举报

4005

帖子

0

TA的资源

版主

沙发
 
太长了
此帖出自stm32/stm8论坛

点评

或者不看程序,请问,TIM可以对松开、按下按键产生的脉冲计数吗?涉及到TIM哪部分的设置,只需要设置ETR管脚,还是需要设置输入捕获?  详情 回复 发表于 2018-1-4 15:37
 
 

回复

42

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

拜托大神耐心看一下,它看着长一部分是因为我的注释太多,拜托拜托
此帖出自stm32/stm8论坛
 
 

回复

42

帖子

0

TA的资源

一粒金砂(中级)

4
 

或者不看程序,请问,TIM可以对松开、按下按键产生的脉冲计数吗?涉及到TIM哪部分的设置,只需要设置ETR管脚,还是需要设置输入捕获?
此帖出自stm32/stm8论坛
 
 
 

回复

3471

帖子

11

TA的资源

五彩晶圆(高级)

5
 
把串口输出。部分屏蔽掉。看看灯的运行状态。若正常。就检查串口配置方面,可以看看例程的初始化和调用。
此帖出自stm32/stm8论坛

点评

好的,请问,TIM可以对松开、按下按键产生的脉冲计数吗?涉及到TIM哪部分的设置,只需要设置ETR管脚,还是需要设置输入捕获?  详情 回复 发表于 2018-1-4 17:33
 
 
 

回复

42

帖子

0

TA的资源

一粒金砂(中级)

6
 
ienglgge 发表于 2018-1-4 17:26
把串口输出。部分屏蔽掉。看看灯的运行状态。若正常。就检查串口配置方面,可以看看例程的初始化和调用。

好的,请问,TIM可以对松开、按下按键产生的脉冲计数吗?涉及到TIM哪部分的设置,只需要设置ETR管脚,还是需要设置输入捕获?
此帖出自stm32/stm8论坛

点评

可以,就是输入捕获功能  详情 回复 发表于 2018-1-4 17:48
 
 
 

回复

1万

帖子

16

TA的资源

版主

7
 
本帖最后由 ddllxxrr 于 2018-1-4 17:50 编辑
shrxh 发表于 2018-1-4 17:33
好的,请问,TIM可以对松开、按下按键产生的脉冲计数吗?涉及到TIM哪部分的设置,只需要设置ETR管脚,还 ...

可以,就是定义定时器 输入捕获功能,及相应的通道。
此帖出自stm32/stm8论坛

点评

问题已解决,谢谢  详情 回复 发表于 2018-1-4 20:58
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复

373

帖子

0

TA的资源

纯净的硅(中级)

8
 
你就没调用串口初始化的函数,你只调用串口DMA初始化的函数了,个人感觉,串口作为调试口打印调试信息时,没有大量数据要发送,没必要使用DMA,那样纯粹是给自己找麻烦。写程序一定要仔细,该调用什么函数一定要清楚
此帖出自stm32/stm8论坛

点评

嗯嗯,知道啦。  详情 回复 发表于 2018-1-7 21:36
 
 
 

回复

42

帖子

0

TA的资源

一粒金砂(中级)

9
 
ddllxxrr 发表于 2018-1-4 17:48
可以,就是定义定时器 输入捕获功能,及相应的通道。

问题已解决,谢谢
此帖出自stm32/stm8论坛
 
 
 

回复

42

帖子

0

TA的资源

一粒金砂(中级)

10
 
wudayongnb 发表于 2018-1-4 20:39
你就没调用串口初始化的函数,你只调用串口DMA初始化的函数了,个人感觉,串口作为调试口打印调试信息时, ...

嗯嗯,知道啦。
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

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