标题:
STC12C5410AD单片机智能小车代码与原理图资料
[打印本页]
作者:
zbjllq
时间:
2021-9-23 09:15
标题:
STC12C5410AD单片机智能小车代码与原理图资料
单片机源程序如下:
// 注:以下文档的 TAB 为 2 个字符!
/*------------------------------------------------------------------------
此项目为“寻迹小车”的升级,在结构上作了改进,码盘从10(20)个/圈提高到 50(100)个圈;
同时,改进了电机的驱动防护逻辑,既能实现电机的四个状态,保证不短路,还可以使PWM控制的
软件耗费大大减少,而且一个电机只需使用3个I/O口(原来为 4个)。
其余没做大的改动,所以程序只要要修改的是电机驱动部分。
为了能使用PCA硬件实现PWM,以便于使用RTOS,暂时取消PWM的频率修改功能,日后有更好的方案再考虑。
因为程序要支持寻迹的所有功能,所以将程序分成模块化,便于阅读和调试。
程序分为:
1) 主控程序 —— 调度所有消息,初始化系统
2) 电机驱动模块 —— 包含所有与电机驱动有关的函数,接受不同的控制命令,并付诸实施;
3) 轨迹采样模块 —— 包含所有与轨迹采样有关的处理,结果为与处理后的轨迹状态;
4) 走轨迹控制模块 —— 读取轨迹采样所获取的信息,根据需求和策略输出相应的电机控制命令;将调试的相关功能也纳入此模块。
资源分配:
Timer 0 —— 系统时基, 1ms
Timer 1 —— 串口波特率
------------------------------------------------------------------------*/
#pragma PR
#pragma OT(5,size)
#pragma Listinclude
#pragma code
#include <E:\dingqi\keilc51\inc\math.h>
#include <STC12C5410AD.h> /* STC12C5410AD 的头文件*/
#include <Port_Def.H>
#include <ComConst.H>
#include <CM_Const.H>
#include <CM_Var.H>
void init_hardware(void); // 硬件初始化函数
void init_var(void); // 初始化变量
void feed_watchdog(void); // 清看门狗计数器
extern void init_LineCtrl_Hardware(void); // 初始化轨迹控制模块用硬件
extern void init_LineCtrl_Var(void); // 初始化轨迹控制模块用变量
extern void lineCtrl_proc(unsigned char ucMessage); // 轨迹控制部分处理入口函数
extern void init_MotorDrv_Hardware(void); // 初始化电机驱动模块用硬件
extern void init_MotorDrv_Var(void); // 初始化电机驱动模块用变量
extern void calOutValue(unsigned char No); // 计算电机控制输出值
extern void calSpeed(void); // 计算转速
extern void proc_Stop(unsigned char No); // 处理行走脉冲计数
extern void proc_PID_Ctrl(unsigned char No); // 处理PID控制
extern void init_LineSamp_Hardware(void); // 初始化轨迹采样模块用硬件
extern void init_LineSamp_Var(void); // 初始化轨迹采样模块用变量
extern void lineSamp_proc(void); // 轨迹采样处理
/******** 主程序 *************/
void main(void)
{
init_hardware();
init_var();
EA = TRUE; // 启动中断,开始正常工作
while(1)
{
if(gb_CheckM1StopCnt)
{
gb_CheckM1StopCnt = FALSE;
proc_Stop(MOTOR1); // 处理行走脉冲计数
}
if(gb_M1CalOutValue == TRUE)
{
gb_M1CalOutValue = FALSE;
calOutValue(MOTOR1); // 根据变化后的参数计算电机输出控制数据
}
if(gb_CheckM2StopCnt)
{
gb_CheckM2StopCnt = FALSE;
proc_Stop(MOTOR2); // 处理行走脉冲计数
}
if(gb_M2CalOutValue == TRUE)
{
gb_M2CalOutValue = FALSE;
calOutValue(MOTOR2); // 根据变化后的参数计算电机输出控制数据
}
if(gb_calSpeed)
{
gb_calSpeed = FALSE;
calSpeed(); // 计算速度
}
if(gb_SpeedOk)
{
gb_SpeedOk = FALSE;
if(gb_EnablePID)
{
proc_PID_Ctrl(MOTOR1); // 根据速度值计算PID控制值
proc_PID_Ctrl(MOTOR2); // 根据速度值计算PID控制值
}
}
if(gb_NewData)
{
gb_NewData = FALSE;
lineCtrl_proc(NEW_RCV_DATA); // 处理数据接收
}
if(gb_SampleStart)
{
union
{
unsigned int all;
unsigned char b[2];
}uiTemp;
uiTemp.b[0] = TH0;
uiTemp.b[1] = TL0;
if(uiTemp.all > (TIME1ms_C + SAMP_LED_ONTIME))
{
gb_SampleStart = FALSE;
lineSamp_proc(); // 处理轨迹采样
}
}
if(gb_NewSampData)
{
gb_NewSampData = FALSE;
lineCtrl_proc(NEW_SAMP_DATA); // 处理轨迹采样数据
}
if (gb_1msFlag==TRUE)
{
gb_1msFlag=FALSE;
gc_LED_Time_Cnt--;
if(gc_LED_Time_Cnt ==0)
{
gc_LED_Time_Cnt = LED_ON_OFF_TIME;
gb_WorkDisp = ~gb_WorkDisp;
}
gc_ui1msCnt--;
if(gc_ui1msCnt==0)
{
gc_ui1msCnt=WDTTIME_C;
feed_watchdog();
}
gc_ucMeaSpeedTimeCnt--;
if(gc_ucMeaSpeedTimeCnt ==0)
{
gc_ucMeaSpeedTimeCnt = MEA_SPEED_PERIOD;
gb_calSpeed = TRUE;
}
}
}
}
/********** 模块自用函数 **************/
// 以下函数只由模块自身使用,别的模块不用声明。
/********************************************/
/*名称: init_hardware */
/*用途: 硬件初始化函数 */
/*说明: 初始化所有相关的硬件状态 */
/********************************************/
void init_hardware(void)
{
/* 初始化系统时钟 */
CLK_DIV = CLKDIV1_C;
/* 初始化I/O口*/
P1M0 = P1M0_C;
P1M1 = P1M1_C;
P2M0 = P2M0_C;
P2M1 = P2M1_C;
P3M0 = P3M0_C;
P3M1 = P3M1_C;
/* 初始化定时器 */
TMOD = T0MODE1|T1MODE2; // Timer0工作在模式1 ,16位定时,Timer1 工作在模式 2 ,8位重加载,作为波特率发生器;
AUXR = AUXR&CLR_T0X12_C; // Timer0 工作在12分频
TCON = 0; /* 未使用外部中断,所以不用定义中断的触发方式 */
TH0 = TIME1msH_C;
TL0 = TIME1msH_C;
TR0 = TRUE;
/* 初始化中断 */
IE = EnT0_C; // 此处只允许 Timer0 中断,其它由各模块自身决定
IPH = NOIP_C; // 此处不设优先级,有各功能模块自身设定
IP = NOIP_C;
/* 初始化轨迹采样模块所需硬件 */
init_LineSamp_Hardware();
/* 初始化轨迹控制所需硬件 */
init_LineCtrl_Hardware();
/* 初始化电机驱动所需硬件 */
init_MotorDrv_Hardware();
/* 看门狗初始化程序 */
WDT_CONTR = Watchdog_C; // 设置 WDT 分频
}
/********************************************/
/*名称: init_var */
/*用途: 变量初始化 */
/*说明: 初始化全局变量 */
/********************************************/
void init_var(void)
{
// WDT参数初始化
gb_1msFlag=FALSE;
gc_ui1msCnt=WDTTIME_C;
gc_LED_Time_Cnt = LED_ON_OFF_TIME;
/* 初始化轨迹采样模块用变量 */
init_LineSamp_Var();
/* 初始化轨迹控制所用变量 */
init_LineCtrl_Var();
/* 初始化电机驱动所用变量 */
init_MotorDrv_Var();
}
/********************************************/
/*名称: feed_watchdog */
/*用途: 喂狗程序 */
/*说明: 请参照STC12C5410的喂狗方法说明 */
/********************************************/
void feed_watchdog(void)
{
WDT_CONTR = CLRWDT_C;
}
// ------------- 中断处理程序 ---------------------
/********************************************/
/* 定时器 0 中断服务 */
/* 说明: 1ms 中断一次, */
/********************************************/
void Timer0_Int(void) interrupt 1 using 1
{
TH0 = TIME1msH_C;
TL0 = TIME1msL_C;
gb_1msFlag = TRUE;
gb_EnSample = ~gb_EnSample;
if(gb_EnSample)
{
gb_Sample = EN_Sample; // 打开采样LED
gb_SampleStart = TRUE;
}
}
\032
复制代码
51hei.png
(12.68 KB, 下载次数: 91)
下载附件
2021-9-23 21:58 上传
代码和原理图资料51hei附件下载:
智能小车详细资料.rar
(238.93 KB, 下载次数: 68)
2021-9-23 09:15 上传
点击文件名下载附件
智能小车详细资料
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1