小弟最近在学习编码器,看了论坛关于编码器的帖子,写出了程序
但是屏幕一直显示0。。调试的时候,一直无法进入中断。。。现在把程序发上来,求助各位高手。。
编码器程序
[mw_shl_code=c,true]/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_encoder.h"
#include "lcd.h"
#include <stdio.h>
extern u16 v_counter;
extern float v;
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ENCODER_TIMER TIM3 // Encoder unit connected to TIM3
#define ENCODER_PPR (u16)(400) // number of pulses per revolution
#define SPEED_BUFFER_SIZE 8
#define COUNTER_RESET (u16)0
#define ICx_FILTER (u8) 6 // 6<-> 670nsec //设定滤波值
/*******************************************************************************
正交编码器接口的初始化,Timer3驱动编码器
* Function Name : ENC_Init
* Description : General Purpose Timer x set-up for encoder speed/position
* sensors
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void Encoder_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
/* Encoder unit connected to TIM3, 4X mode */
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock source enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);;//使能TIM3时钟
/* Enable GPIOA, clock */ //串口时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
GPIO_StructInit(&GPIO_InitStructure);
/* Configure PA.06,07 as encoder input */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//PA6 PA7浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化 PA6 PA7
/* Enable the TIM3 Update Interrupt */
/*设置编码器溢出中断*/
/*中断频道*/
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
/*中断一级优先级设置*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
/*中断二级优先级设置*/
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
/*中断使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
/*设置赋值*/
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
/* Timer configuration in Encoder mode */
TIM_DeInit(ENCODER_TIMER);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
/*不需要任何预分频*/ //Tout=(arr+1)*(psc+1)/Tclk;
TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // No prescaling
TIM_TimeBaseStructure.TIM_Period = (4*ENCODER_PPR)-1; //设定计数器重装值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割 T_dts = T_ck_int
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数
TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);
/*设置为编码器模式*/
TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12,
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3
TIM_ICStructInit(&TIM_ICInitStructure);
/*filter设置*/
TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER; //选择输入比较滤波器 /*TIM_ICFilter选择输入比较滤波器。该参数取值在0x0和0xF之间*/
TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);
/*清楚中断标志位*/
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);
/*开启编码器溢出中断*/
TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE);
//Reset counter
/*复位编码器*/
ENCODER_TIMER->CNT = COUNTER_RESET;
/*使能编码器*/ //允许TIM3工作,也就是使能TIM3
TIM_Cmd(ENCODER_TIMER, ENABLE); //使能TIMx
}
/*******************************************************************************
Timer3的Update中断处理程序
* Function Name : TIM3_IRQHandler
* Description : This function handles TIMx Update interrupt request.
Encoder unit connected to TIM2
* Input : None
* Output : None
* Return : None
*******************************************************************************/
/*中断溢出处理(测速)*/
void TIM3_IRQHandler(void) //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
v_counter=TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
v=(float)v_counter*120/400; //定时为0.5s
v_counter=v;
}
}[/mw_shl_code]
主程序
[mw_shl_code=c,true]u16 v=0;
u16 v_counter=0;
int main(void)
{
delay_init(72); //延时函数初始化
uart_init(9600); //串口初始化为9600
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
SystemInit();
Encoder_Init();
LCD_Init(); //初始化LCD屏
delay_ms(100);
while(1)
{
LCD_ShowxNum(20,40, v,2,16,0);
}
}[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>