【问题标题】:Embedded C code to control a DC motor with a PIC microcontroller使用 PIC 微控制器控制直流电机的嵌入式 C 代码
【发布时间】:2016-02-17 21:52:35
【问题描述】:

我正在尝试创建一个嵌入式 c 代码来使用 PIC32MX460F512L 微控制器控制直流电机。我将系统时钟配置为 80MHz,外围时钟配置为 10MHz,我使用定时器 1 以给定的占空比为 PWM 提供脉冲,定时器 2 用于测量电机运行时间。我有一个头文件(includes.h),其中包含系统配置信息,例如时钟。我已经创建了大部分功能,但有些功能有点挑战性。例如,初始化 LED 以及前进、后退和停止功能,我希望直流电机在 70% 占空比下正向运行 4 秒,然后停止 1 秒,然后在 50% 占空比下反转 3 秒循环,然后停止 1 秒,然后以 40% 占空比再次前进 3 秒,停止 1 秒,最后以 20% 占空比前进 5 秒。关于前进、停止和反转功能的任何建议

#include <stdio.h>
#include <stdlib.h>
#include <includes.h>

void main()
{
    // Setting up PIC modules such as Timers, IOs OCs,Interrupts, ...
    InitializeIO();
    InitializeLEDs();
    InitializeTimers();

    while(1) {
        WaitOnBtn1();
        Forward(4.0,70);
        Stop(1.0);
        Backward(3.0,50);
        Stop(2);
        Forward(3.0,40);
        Stop(1.0);
        Backward(2.0,20);
        LEDsOFF();
    }
    return;
}

void InitializeIO(){
    TRISAbits.TRISA6 = 1;
    TRISAbits.TRISA7 = 1;
    TRISGbits.TRISG12 = 0;
    TRISGbits.TRISB13 = 0;
    LATGbits.LATB12 = 0;
    LATGbits.LATB13 = 0;
    return;
}

void InitializeLEDs(){
    //code to initialize LEDS
}

void InitializeTimers(){
    // Initialize Timer1
    T1CON = 0x0000; // Set Timer1 Control to zeros
    T1CONbits.TCKPS=3; // prescale by 256
    T1CONbits.ON = 1; // Turn on Timer
    PR1= 0xFFFF; // Period of Timer1 to be full
    TMR1 = 0; // Initialize Timer1 to zero
    // Initialize Timer2
    T2CON = 0;
    T2CONbits.TCKPS = 7; // prescale by 256
    T2CONbits.T32 = 1; // use 32 bits timer
    T2CONbits.ON = 1;
    PR2 = 0xFFFFFFFF; // Period is set for 32 bits
    TMR2 = 0;
}

void WaitOnBtn1(){
    // wait on Btn1 indefinitely
    while(PORTAbits.RA6 == 0);

    // Turn On LED1 indicating it is Btn1 is Pushed
    LATBbits.LATB10 = 1;
    return;
}

void Forward(float Sec, int D){
    int RunTime = (int)(Sec*39000); // convert the total
    time to number of Tics
    TMR2 = 0;
    //LEDs
    LATGbits.LATG12 = 1; // forward Direction
    LATBbits.LATB12 = 0;
    LATBbits.LATB13 = 0;
    LATBbits.LATB11 = 1;
    // Keep on firing the PWM as long as Run time is not
    elapsed
    while (TMR2 < RunTime){
        PWM(D);
    }
    return;
}

void PWM(int D){
    TMR1 = 0;
    int Period = 400;
    while (TMR1< Period) {
        if (TMR1 < Period*D/100){
            LATGbits.LATG13 = 1;
        }
        else{
        LATGbits.LATG13 = 0;
    }
}

【问题讨论】:

  • 建议?先问一个问题。
  • 1) C 不支持方法。 2) 学习How to Ask 3) 正确格式化和缩进你的代码。 4) 使用原型风格的函数声明器。
  • 对不起,我指的是函数;将来我会尝试更好地格式化我的代码,但同时有任何建议
  • 没有原理图就无法说明任何事情。有了原理图,它将更适合SE EE
  • 我其实是在做计算机科学的,代码是在mplab x ide和proteus中模拟的

标签: c embedded pic


【解决方案1】:

确切地说是函数,而不是方法。

那么问题到底是什么?

快速浏览源代码可以说:

应该像在 InitializeIO() 函数中那样完成 LED 初始化。只需将适当的 TRISx 位设置为 0 即可将 LED 引脚配置为输出。

对于 PWM 和电机控制功能,您应该花一些时间尝试了解内置 PWM 外设的工作原理。它是 OC(输出比较)的一部分,非常易于使用。请看下面的链接http://ww1.microchip.com/downloads/en/DeviceDoc/61111E.pdf

这是使用内置外围库https://electronics.stackexchange.com/questions/69232/pic32-pwm-minimal-example的最小实现@

基本上,您需要设置 OC 寄存器来“使”OC 模块像 PWM 一样工作。您需要分配其中一个定时器来使用 OC 模块(它将用于基本 PWM 频率),仅此而已。

之后您只需要通过设置定时器 PRx 寄存器来设置 PWM 占空比值,您不需要像在 PWM 例程中那样交换位。

要停止它简单停止它只需禁用计时器。

要再次运行它,请运行计时器。

要改变方向(这取决于你的电机驱动器)我猜你只需要切换方向销。

希望对你有帮助……

【讨论】:

  • 抱歉混淆了方法和函数;我沉迷于java。无论如何感谢您的信息。让我详细研究一下,看看会发生什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多