[求助] 基于STM32单片机,光电编码器测速,接收不到信号

shrxh   2018-3-24 18:16 楼主
基于STM32单片机,利用光电编码器测速,光电编码器转动但是串口上显示脉冲数一直是0.
代码如下:
#include "stm32f10x.h"
#include


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

不知道哪里出错了,请各位大神指教。


回复评论 (11)

实物图如下
  • IMG_20180324_205008.jpg
点赞  2018-3-24 20:51
用示波器看看编码器的输出。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2018-3-24 23:54
引用: chunyang 发表于 2018-3-24 23:54
用示波器看看编码器的输出。

好的。
用示波器看编码器输出,编码器需要与电机连接吗?能够显示脉冲波形就证明编码器是正常的对吗?
点赞  2018-3-25 10:10
引用: shrxh 发表于 2018-3-25 10:10
好的。
用示波器看编码器输出,编码器需要与电机连接吗?能够显示脉冲波形就证明编码器是正常的对吗?

用手转动编码器即可,速度低更容易观察。参照器件手册看波形,波形正常则编码器就没问题。
上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
点赞  2018-3-25 16:11
天哪,你怎么设计的,绿白接一起从哪儿学来的呀
点赞  2018-3-25 21:11
可能要上拉电阻
点赞  2018-3-25 21:19
引用: huo_hu 发表于 2018-3-25 21:11
天哪,你怎么设计的,绿白接一起从哪儿学来的呀

和绿线接在一起的那根白线只是单纯的导线,不是光电编码器上带的那根。。。
点赞  2018-3-26 09:36
引用: chunyang 发表于 2018-3-25 16:11
用手转动编码器即可,速度低更容易观察。参照器件手册看波形,波形正常则编码器就没问题。

蟹蟹
点赞  2018-3-26 09:37
你这个编码器应该是正交编码器的吧。。。。。。一般电机的测速都用到带光栅的正交编码器哦。
点赞  2018-3-26 11:12

没看见电路图。有很多编码器输出是OC方式,如果不加上拉是没有输出的;
另外,编码器需要供电,你电源是多大的;

其次,A、B、Z你用了那个,程序很乱,看不出逻辑来,你到底用了测周期法还是计数法,关键地方的注释不能反映你的意图,所以很难帮到你。

主程序重又用了一个10秒的延时,不知道什么意图。

چوآن شـين
点赞  2021-4-2 16:43

有次我发现没读数,后来发现是编码器没接电源。

点赞 (1) 2021-4-6 18:35
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复