[应用相关]

关于光电编码器测速问题

[复制链接]
2856|28
手机看帖
扫描二维码
随时随地手机跟帖
Rangar|  楼主 | 2018-5-20 16:40 | 显示全部楼层 |阅读模式
基于STM32单片机,利用光电编码器测速,光电编码器转动但是串口上显示脉冲数一直是0.
代码如下:
#include "stm32f10x.h"
#include <stdio.h>


void delay(uint32_t);
void COM_Config(void);
void GPIO_Configuration(void);
void TIM2_Configuration(void);

int fputc(int ch, FILE *f);
int fgetc( FILE *f);

int ActualSpeed=0;
int Times=1;

int main(void)
{
        COM_Config();
        GPIO_Configuration();
        TIM2_Configuration();
        
    while (1)
    {        
             delay(10000000);                 
                 ActualSpeed=TIM_GetCounter(TIM2);
                 printf(" 实际转速=%d  %d \n\r",ActualSpeed,Times++);
    }   
}

void COM_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;  
    USART_InitTypeDef USART_InitStructure;

        /*使能GPIOD端口时钟、复用功能时钟*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
        /*使能USART2时钟*/
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);   

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;  
    GPIO_Init(GPIOD, &GPIO_InitStructure);  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;  
    GPIO_Init(GPIOD, &GPIO_InitStructure);  

        /*串口2重映射*/
        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(USART2, &USART_InitStructure);  

    USART_Cmd(USART2, ENABLE);  
}

/*外部脉冲输入管脚         PC6 */
void GPIO_Configuration(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;           
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}


/*TIM2对脉冲计数*/
void  TIM2_Configuration(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , 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);
}

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


#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;
}

不知道哪里出错了,请各位大神指教。
Stannis| | 2018-5-20 17:14 | 显示全部楼层
用示波器看看编码器的输出

使用特权

评论回复
Brand2| | 2018-5-20 17:23 | 显示全部楼层
用示波器看编码器输出,编码器需要与电机连接吗?

使用特权

评论回复
Soraka| | 2018-5-20 17:36 | 显示全部楼层
用手转动编码器即可,速度低更容易观察

使用特权

评论回复
Garen2| | 2018-5-20 17:50 | 显示全部楼层
能够显示脉冲波形就证明编码器是正常的对吗?

使用特权

评论回复
Ryze| | 2018-5-20 17:58 | 显示全部楼层
参照器件手册看波形,波形正常则编码器就没问题

使用特权

评论回复
Varus| | 2018-5-20 18:22 | 显示全部楼层
可能要上拉电阻

使用特权

评论回复
Snow7| | 2018-5-20 18:31 | 显示全部楼层
你这个编码器应该是正交编码器的吧

使用特权

评论回复
android2| | 2018-5-20 18:39 | 显示全部楼层
一般电机的测速都用到带光栅的正交编码器哦

使用特权

评论回复
kkzz| | 2018-5-20 22:29 | 显示全部楼层
是串口的问题吗?

使用特权

评论回复
hudi008| | 2018-5-20 22:29 | 显示全部楼层
光电编码器有信号吗?

使用特权

评论回复
lzmm| | 2018-5-20 22:30 | 显示全部楼层
光电编码器的分辨率为?

使用特权

评论回复
minzisc| | 2018-5-20 22:30 | 显示全部楼层
有干扰了

使用特权

评论回复
selongli| | 2018-5-20 22:30 | 显示全部楼层
采用定时中断读取是最合理的

使用特权

评论回复
fentianyou| | 2018-5-20 22:31 | 显示全部楼层
有数据信号吗?

使用特权

评论回复
xiaoyaodz| | 2018-5-20 22:31 | 显示全部楼层
反转计数异常?

使用特权

评论回复
febgxu| | 2018-5-20 22:32 | 显示全部楼层
查看一下光电脉冲编码器的结构和工作原理

使用特权

评论回复
sdlls| | 2018-5-20 22:32 | 显示全部楼层
先查看一下硬件吧。

使用特权

评论回复
pixhw| | 2018-5-20 22:33 | 显示全部楼层
你的代码发送呢?》

使用特权

评论回复
selongli| | 2018-5-20 22:33 | 显示全部楼层
议使用定时中断去读.

使用特权

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

本版积分规则

154

主题

763

帖子

0

粉丝