设计思路:stm32 用TIM2实现外部脉冲计数,按键4充当外部脉冲。预期实验现象:LED3灭,串口输出脉冲个数(即按下的按键次数),延时,LED3亮,延时,LED3灭,输出脉冲个数,如此循环。
问题:真实现象是LED3闪一下就再也不亮了,串口没有任何输出。是我串口设置的问题吗?请各位大神指教。拜托。
程序如下:
/*脉冲量测量*/
#include "stm32f10x.h"
#include <stdio.h>
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
", 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--);
}
此帖出自
小平头技术问答
或者不看程序,请问,TIM可以对松开、按下按键产生的脉冲计数吗?涉及到TIM哪部分的设置,只需要设置ETR管脚,还是需要设置输入捕获?
一周热门 更多>