📄 main.c
字号:
//========================================================
// The information contained herein is the exclusive property of
// Sunnnorth Technology Co. And shall not be distributed, reproduced,
// or disclosed in whole in part without prior written permission.
// (C) COPYRIGHT 2003 SUNNORTH TECHNOLOGY CO.
// ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorized copies.
//========================================================
//========================================================
// 工程名称: DC_SpeedCtrl
// 功能描述: 直流电机速度测量与调节
// 涉及的库: CMacro1016.lib
// 组成文件: main.c
// isr.asm, Dig.asm, Key.asm, DCMotor.asm
// Dig.inc, Key.inc, DCMotor.inc, SPCE061A.inc
// Dig.h,Key.h, DCMotor.h, SPCE061A.h
// 硬件连接: 61板IOB高8位与电机模组J1连接
// 61板IOA高8位与电机模组J2连接
// 61板IOB低8位与电机模组J3连接
// 维护记录: 2005-12-2 v1.0
//========================================================
//========================================================
// 文件名称: main.c
// 功能描述: 数码管显示
// 维护记录: 2005-09-12 v1.0
//========================================================
#include "SPCE061A.h"
#include "DCMotor.h"
#include "Dig.h"
#include "Key.h"
#define SPEED_MAX 60 // 最高设定速度
#define SPEED_MIN 30 // 最低设定速度
#define SPEED_STEP 2 // 速度设定步进值
#define CP 8 // 比例常数 Proportional Const
#define CI 3 // 积分常数 Integral Const
#define CD 1 // 微分常数 Derivative Const
unsigned int g_Direction, g_Speed; // 全局变量,保存设定的转动方向和速度
//========================================================================
// 语法格式: void System_Init(void)
// 实现功能: 系统初始化(时钟、变量等)
// 参数: 无
// 返回值: 无
//========================================================================
void System_Init(void)
{
*P_SystemClock = C_Fosc_49M|C_StrongMode; // 系统时钟
DCMotor_Init();
Key_Init();
DIG_Init();
g_Direction = 1; // 初始设置为正转
g_Speed = 40;
}
//========================================================================
// 语法格式: void DispNum(unsigned int Num)
// 实现功能: 在4位数码管上显示整数
// 参数: Num - 要显示的数值,范围0~9999
// 返回值: 无
//========================================================================
const unsigned int DigNum[]={ // 0~9十个数字对应的数码管显示编码
0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x27,0x7f,0x6f
};
void DispNum(unsigned int Num)
{
unsigned int TempNum = Num, k;
DIG_Clear(); // 清除数码管显示
if(Num>=1000) // 千位
{
k = TempNum/1000;
DIG_Set(1,DigNum[k]);
TempNum = TempNum - k * 1000;
}
if(Num>=100) // 百位
{
k = TempNum/100;
DIG_Set(2,DigNum[k]);
TempNum = TempNum - k * 100;
}
if(Num>=10) // 十位
{
k = TempNum/10;
DIG_Set(3,DigNum[k]);
TempNum = TempNum - k * 10;
}
DIG_Set(4,DigNum[TempNum]); // 个位
}
//========================================================================
// 语法格式: void DelayMS(unsigned ms)
// 实现功能: 延时若干毫秒(不精确)
// 参数: ms - 毫秒数@49MHz
// 返回值: 无
//========================================================================
void DelayMS(unsigned ms)
{
unsigned i;
while(ms--)
{
for(i = 0; i < 1044; i++)
*P_Watchdog_Clear = 1;
}
}
//========================================================================
// 语法格式: int DCMotor_Speed_PID(int SetSpeed, int CurSpeed)
// 实现功能: 增量式PID计算: u0 = u1 + CP*(e0-e1) + CI*e0 + CD*(e0-2*e1+e2)
// 参数: SetSpeed: 设定的转速
// CurSpeed: 实际测得转速
// 返回值: 直流电机速度等级(PWM占空比)
//========================================================================
int DCMotor_Speed_PID(int SetSpeed, int CurSpeed)
{
int e0, u0;
static int u1 = 0; // 前一次输出值(为避免浮点运算将该值扩大16倍)
static int e1 = 0, e2 = 0;
e0 = SetSpeed - CurSpeed; // 当前速度偏差
u0 = u1
+ CP * (e0 - e1) // 比例项
+ CI * e0 // 积分项
+ CD * (e0 - e1 - e1 + e2); // 微分项
if(u0 > 1023) u0 = 1023; // 输出值应小于64(扩大16倍)
if(u0 < 16) u0 = 16; // 输出值应不小于1(扩大16倍)
u1 = u0; // 更新u1、e1和e2
e2 = e1;
e1 = e0;
return u0>>4; // 返回u0/16
}
//========================================================================
// 语法格式: void SetSpeed(void)
// 实现功能: 设定转速
// 参数: 无
// 返回值: 无
//========================================================================
void SetSpeed(void)
{
unsigned int KeyCode;
while(1)
{
DispNum(g_Speed); // 闪烁显示当前设定的转速
DelayMS(300);
DIG_Clear();
DelayMS(300);
KeyCode = Key_Get();
switch(KeyCode)
{
case KEY_1: // Key1, 设定值增加
g_Speed += SPEED_STEP;
if(g_Speed > SPEED_MAX)g_Speed = SPEED_MIN;
break;
case KEY_2: // Key2, 设定值减小
g_Speed -= SPEED_STEP;
if(g_Speed < SPEED_MIN)g_Speed = SPEED_MAX;
break;
case KEY_3: // Key3, 确定
return;
default:
}
}
}
//========================================================================
// 语法格式: void SetDirection(void)
// 实现功能: 设定转动方向
// 参数: 无
// 返回值: 无
//========================================================================
void SetDirection(void)
{
unsigned int KeyCode;
unsigned int i;
i = 1;
while(1)
{
/// 在数码管上显示滚动的"-",表示电机转动方向
DIG_Clear(); // 清除显示
DIG_Set(i,0x40);
DelayMS(200);
i += g_Direction;
if(i>4)i=1;
if(i<1)i=4;
KeyCode = Key_Get();
switch(KeyCode)
{
case KEY_1: // Key1, 正转
g_Direction = 1;
break;
case KEY_2: // Key2, 反转
g_Direction = -1;
break;
case KEY_3: // Key3, 确定
return;
default:
break;
}
}
}
//========================================================================
// 语法格式: void StartMotor(void)
// 实现功能: 直流电机转动控制
// 参数: 无
// 返回值: 无
//========================================================================
void StartMotor(void)
{
unsigned int KeyCode;
unsigned int SpeedLevel, CurSpeed=0, PreSpeed=0;
if(g_Direction==1) // 确定转动方向
DCMotor_Forward(MOTOR_1+MOTOR_2);
else
DCMotor_Backward(MOTOR_1+MOTOR_2);
DispNum(CurSpeed);
while(1)
{
if(CurSpeed != PreSpeed) // 如果转速改变则更新显示
{
DispNum(CurSpeed); // 显示当前转速
PreSpeed = CurSpeed;
}
if(DCMotor_IsSpeedRdy()) // 如果已完成一次测速
{
CurSpeed = DCMotor_GetSpeed(); // 获取转速
SpeedLevel = DCMotor_Speed_PID(g_Speed, CurSpeed); // PID计算,得到新的PWM占空比
DCMotor_SetSpeed(MOTOR_1+MOTOR_2, SpeedLevel); // 更新PWM占空比,调节转速
}
KeyCode = Key_Get();
switch(KeyCode)
{
case KEY_1: // Key1,速度增加
g_Speed += SPEED_STEP;
if(g_Speed > SPEED_MAX)g_Speed = SPEED_MIN;
break;
case KEY_2: // Key2,速度减小
g_Speed -= SPEED_STEP;
if(g_Speed < SPEED_MIN)g_Speed = SPEED_MAX;
break;
case KEY_3: // Key3,停止
DCMotor_Stop(MOTOR_1+MOTOR_2);
return;
default:
break;
}
}
}
//========================================================================
// 语法格式: int main(void)
// 实现功能: 主函数,通过按键选择不同功能
// 参数: 无
// 返回值: 无
//========================================================================
int main(void)
{
unsigned int KeyCode, Flag_KeyEvent;
System_Init(); // 系统初始化
Flag_KeyEvent = 1;
while(1)
{
if(Flag_KeyEvent==1)
{
DispNum(g_Speed); // 显示当前设定的转速
Flag_KeyEvent = 0;
}
KeyCode = Key_Get();
switch(KeyCode)
{
case KEY_1: // Key1, 转速设定
SetSpeed();
Flag_KeyEvent = 1;
break;
case KEY_2: // Key2, 方向设定
SetDirection();
Flag_KeyEvent = 1;
break;
case KEY_3: // Key3, 启动电机
StartMotor();
Flag_KeyEvent = 1;
break;
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -