本帖最后由 baixichi 于 2011-11-18 11:52 编辑
在上一个帖子中就说到过,因为并未调用JTAG_Wait()函数,又将JTAG所在引脚配置为IO口使用,我的811板子被锁住了。
于是借来同学的一块6911继续M3的学习。准备过几天再去买一块片子换上。
言归正传,用PWM波驱动直流电机。我用的驱动芯片是L298N,是一个带光耦的模块,之前做比赛的时候留下来的。该芯片内部采用高效的恒压恒流桥式PWM电路,
好像是四个三极管还是mos管,由于模电没有学好,弄不大明白。处理器可以通过IO口输出电平信号,
精确地控制两个2相直流电机转动方向,由PWM引脚输出的占空比控制转速。
电机是普通的直流减速电机。减速电机有直流电机转速快的优点,且力矩大,反向快。由于6911没有专门的PWM引脚,所以我用定时器
模拟PWM输出,以控制直流电机。
下边是L298N模块的电路图:
这里仅写了一个测试程序,让电机正转10s,反转10s。PA0和PA1引脚控制电机的正反转。
#include "hw_memmap.h"
#include "hw_types.h"
#include "sysctl.h"
#include "gpio.h"
#include "timer.h"
unsigned long TheSysClock=0;
void PWM_Init()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); // 使能Timer模块
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // 使能CCP2所在的GPIO端口
GPIOPinTypeTimer(GPIO_PORTB_BASE,GPIO_PIN_1); // 配置CCP2管脚为PWM输出
TimerConfigure(TIMER1_BASE, TIMER_CFG_16_BIT_PAIR| // 配置Timer为双16位PWM
TIMER_CFG_A_PWM);
TimerControlLevel(TIMER1_BASE,TIMER_A,true); // 控制PWM输出反相,即低电平有效
TimerLoadSet(TIMER1_BASE, TIMER_A,20000); // 周期设置
TimerMatchSet(TIMER1_BASE, TIMER_A,20000*1/2); // 占空比设置
TimerEnable(TIMER1_BASE, TIMER_A); // 使能Timer计数,PWM开始输出
}
int main(void)
{
SysCtlClockSet(SYSCTL_XTAL_8MHZ
|SYSCTL_OSC_MAIN
|SYSCTL_USE_PLL
|SYSCTL_SYSDIV_4);
TheSysClock=SysCtlClockGet();
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);
PWM_Init();
while(1)
{
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_0,0xff);//正转
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_1,0x00);
SysCtlDelay(TheSysClock/3*10);//延时10s
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_0,0x00);//反转
GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_1,0xff);
SysCtlDelay(TheSysClock/3*10);
}
}
6911使用的是8MHz晶振,所以SYSCTL_XTAL_8MHZ。
值得注意的是在配置周期的时候,数值不能大于65535,因为PWM是16位的。
如果想要得到精确的周期,最好先调用函数SysCtlPWMClockSet()分频,以为50MHz的PWM频率可以会导致数据溢出。
过一段时间,准备做一个小车跑一下。嘿嘿 |