// 直流电机速率控制与测量实验程序解析
//头文件
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include "utils/ustdlib.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "driverlib/gpio.h"
#include "driverlib/fpu.h"
#include "driverlib/pin_map.h"
#include "driverlib/pwm.h"
#include "grlib/grlib.h"
#include "drivers/buttons.h"
#include "drivers/cfal96x64x16.h"
//宏定义以及静态变量定义
//一个PWM脉冲时间所占的时钟周期数
#define PWM_MAX 400
#define PWM_MIN 0
//每秒systick的次数,对应于计算电机速度的次数//
#define TICKS_PER_SECOND 2
static volatile ui32 TickCount = 0; //用于计数systick
static char cText[10]; //OLED显示内容
static ui32 motor_signal = 0; //电机计数信号
//主程序
int main (void)
{
FPUEnable();
FPULazyStackingEnable();
//系统时钟设置
SysCtlClockSet(SYSCTL_SYSDIV_6 |SYSCTL_USE_PLL \
|SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);
//外围设备初始化
ButtonsInit(); //按键初始化
CFAL96x64x16Init(); //OLED显示初始化
GrContextInit(&sContext, &g_sCFAL96x64x16);
……
//GPIO口PN0作为脉冲1信号的输入
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
ROM_GPIOPinTypeGPIOInput(GPIO_PORTN_BASE,GPIO_PIN_0);
//设置systick为每秒两次,即每半秒脉冲1计数清0,更新电机速度。
ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND);
ROM_SysTickEnable();
ROM_SysTickIntEnable();
//PWM设置
//使能GPIO口PORT G
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
//使能PWM
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM);
// PWM时钟配置:不分频
ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
//设置PG7为PWM模式0,信号PWM7
ROM_GPIOPinConfigure(GPIO_PG7_M0PWM7);
//设置PWM发生器3,减计数,非同步
ROM_GPIOPinTypePWM(GPIO_PORTG_BASE,GPIO_PIN_7);
ROM_PWMGenConfigure(PWM_BASE, PWM_GEN_3,
//设置PWM脉冲占时钟的周期数
PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
//设置占空比,初始为250/400=62.5%
ROM_PWMGenPeriodSet(PWM_BASE, PWM_GEN_3, PWM_MAX);
ROM_PWMPulseWidthSet(PWM_BASE, PWM_OUT_7, PWM_Width);
//使能PWM发生器3
ROM_PWMGenEnable(PWM_BASE, PWM_GEN_3);
//产生PWM波
ROM_PWMOutputState(PWM_BASE, PWM_OUT_7_BIT, true);
//码盘计数以及速度按键控制
while(1)
{
//等待下一次tick
while(LastTickCount == TickCount)
{
ui8 ucButtonState;
ui8 ucButtonChanged;
ucButtonState = ButtonsPoll(&ucButtonChanged, 0);
//如果按键UP,增加PWM的占空比
if(BUTTON_PRESSED(UP_BUTTON, ucButtonState, ucButtonChanged))
{
PWM_Width = PWM_Width+5;
if(PWM_Width > PWM_MAX)
PWM_Width = PWM_MAX;
ROM_PWMPulseWidthSet(PWM_BASE, PWM_OUT_7, PWM_Width);
}
//如果按键DOWN,减小PWM的占空比
if(BUTTON_PRESSED(DOWN_BUTTON, ucButtonState, ucButtonChanged))
{
PWM_Width = PWM_Width-5;
if(PWM_Width < PWM_MIN)
PWM_Width = PWM_MIN;
ROM_PWMPulseWidthSet(PWM_BASE, PWM_OUT_7,
PWM_Width);
}
//当读入的计数脉冲信号没有翻转时,始终读取该信号
while(motor_signal!=status)
{
motor_signal=
ROM_GPIOPinRead(GPIO_PORTN_BASE,GPIO_PIN_0);
}
//若信号翻转,则计数加1,同时改变status为当前状态值,等待下
//一次翻转,这样得以保证每一个上升沿和下降沿都被计数。
cnt = cnt+1;
status = 1-status;
}
//每半秒钟计数清0
cnt = 0 ;
//更新TickCount
LastTickCount = TickCount;
//速度计算和显示
ROM_SysTickDisable();
cnt = cnt*60/334; //计算每分钟转速
usprintf(cText,"%10d",cnt); //送OLED显示
GrContextForegroundSet(&sContext, ClrWhite);
GrStringDrawCentered(&sContext,cText, -1,
GrContextDpyWidthGet(&sContext) / 3*2,
((GrContextDpyHeightGet(&sContext) - 24) / 2) + 24, 1);
GrFlush(&sContext);
//计算占空比并显示
unsigned int rate = 100*PWM_Width/PWM_MAX;
usprintf(cText,"%4u%%",rate);
GrContextForegroundSet(&sContext, ClrWhite);
GrStringDrawCentered(&sContext,cText, -1,
GrContextDpyWidthGet(&sContext) /3,
((GrContextDpyHeightGet(&sContext) - 24) / 2) + 24, 1);
GrFlush(&sContext);
ROM_SysTickEnable();
//为了使得脉冲计数更准确,此处屏蔽了SysTick,以避免由于处理该段程
//序对实际计数时间造成的影响