单片机PID控制电机程序

AVR 单片机PID 控制电机程序

2011-04-10 20:53

/*****************************************************

Project : PID_motor

Version : 第一版

Date : 2011-3-30

Author : 卢云

Company : 三峡大学电子设计创新实验室

Comments:

Chip type : ATmega16L

Program type : Application

Clock frequency : 4.000000 MHz

Memory model : Small

External SRAM size : 0

Data Stack size : 256

*****************************************************/

#include

#include

#include

#include

sfrw ICR1=0x26; //

义)

unsigned int icp_v1;

unsigned int icp_v2; 补充定义16位寄存器ICR1地址为0x26(mega16.h中未定

unsigned char icp_n;

unsigned char max_icp; //量程定义字

bit icp_ok;

bit time_4ms_ok;

bit freq_ok;

bit begin_m; //

bit full_ok; //

long fv;

struct PID

{

unsigned int SetPoint; //

unsigned int Proportion; //

unsigned int Integral; //

unsigned int Derivative; //

unsigned int LastError; // Error[-1]

unsigned int PrevError; // Error[-2]

unsigned int SumError; // Sums of Errors

};

struct PID spid; // PID Control Structure

long rout; // PID Response (Output)

long rin; // PID Feedback (Input)

void PID_Init(struct PID *pp)

{

memset ( pp,0,sizeof(struct PID)); //定时器1溢出,重新测量标志字 定时器1溢出 设定目标 Desired Value 比例常数 ProportionalConst 积分常数 Integral Const 微分常数 Derivative Const 全部初始化为0

}

unsigned int PID_Calc( struct PID *pp, unsigned int NextPoint )

{

unsigned int dError,Error;

Error = pp->SetPoint - NextPoint; // 偏差

pp->SumError += Error; // 积分

dError = pp->LastError - pp->PrevError; // 当前微分

pp->PrevError = pp->LastError;

pp->LastError = Error;

return (pp->Proportion * Error // 比例项

+ pp->Integral * pp->SumError // 积分项

+ pp->Derivative * dError); // 微分项

}

// Timer 2 比较匹配中断服务,4ms 定时

interrupt [TIM2_COMP] void timer2_comp_isr(void)

{

#asm("sei") // 开放全局中断, 允许中断嵌套

time_4ms_ok = 1;

}

// Timer 1 溢出中断服务

interrupt [TIM1_OVF] void timer1_ovf_isr(void)

{

full_ok = 1;

}

// Timer 1 输入捕捉中断服务

interrupt [TIM1_CAPT] void timer1_capt_isr(void)

{

if (icp_n >= max_icp) // 第N 个上升沿到

{

icp_v2 = ICR1; // 记录第N 个上升沿时间

TIMSK = 0x80; // 禁止T/CI输入捕捉和溢出中断

icp_ok = 1;

}

else if (icp_n == 0)

{

icp_v1 = ICR1; // 记录第1个上升沿时间

}

icp_n++;

}

void main(void)

{

unsigned int icp_1,icp_2;

PORTB=0x00;

DDRB=0x08;

PORTD=0x40; // PD6(icp)输入方式,上拉有效

// T/C0 定时初始化

TCCR0=0x79; // Mode: Fast PWM top=FFh

TCNT0=0x00; // OC0 output: Non-Inverted PWM

OCR0=0xff;

// T/C1 计数初始化

TCCR1B = 0x41; // T/C1正常计数方式,上升沿触发输入捕捉,4M/1计数时钟

TIMSK = 0xA4; // 允许T/C2比较匹配中断,允许T/C1输入捕捉、溢出中断

// T/C2 定时初始化

TCCR2=0x0C; // 内部时钟,64分频(4M/64=62.5KHz),CTC 模式

OCR2=0xff; // OCR2 = 0xf9(249),(249+1)/62.5=4ms

icp_n = 0;

max_icp =1; //定义上升沿的位序

#asm("sei") // 开放全局中断

INIT_FYD();

Show_Text(3,0,chinese); //(列,行,显示字)

PID_Init(&spid); // Initialize Structure

spid.SetPoint = 168; //设定目标 Desired Value

spid.Proportion = 6; //比例常数 Proportional Const

spid.Integral =5; //积分常数 Integral Const

spid.Derivative =2; //微分常数 Derivative Const

FM_Num(0,1,spid.Proportion);

FM_Num(3,1,spid.Integral);

FM_Num(6,1,spid.Derivative);

FM_Num(0,2,spid.SetPoint);

while (1)

{

if (icp_ok == 1) // 完成一次测量

{

if (icp_v2 >= icp_v1) // 计算N 个上升沿的时钟脉冲个数, icp_2 = icp_v2 - icp_v1; //两次连续的ICR1的差值

else

icp_2 = 65536 - icp_v1 + icp_v2; //定时器1溢出,加上65535 if (!(icp_v2 >= icp_v1 && full_ok)) // 有溢出,数据无效

{

//if (icp_2 == icp_1) // 两次个数相等,测量有效 {

fv = 1000000 * (long)max_icp / icp_2; // 换算成频率值

freq_ok = 1; //频率换算完成

if (fv > 4000)

{

max_icp = 20; // 如果频率大于4Khz ,N=64 }

else

{

max_icp = 1; // N=1

}

}

}

else

max_icp = 1; // 有溢出,N=1 icp_1 = icp_2;

icp_ok = 0;

begin_m = 1;

}

if (time_4ms_ok) //定时器2,定时到 {

if(freq_ok) //判断频率是否换算完成 {

rin=fv;

FM_Num(0,3,rin);

rout = PID_Calc ( &spid,rin );

rout=rout/100;

FM_Num(3,3,rout);

if(rout>100&&rout

OCR0=rout;

freq_ok = 0;

}

else if(begin_m)

{

icp_n = 0; // 开始新的一次测量,

full_ok = 0; // 清除溢出标志

TIFR = 0x24; // 清除可能存在的输入捕捉、溢出中断标志位

TIMSK = 0xa4; // 开启T/C1输入捕捉、溢出中断允许

begin_m = 0;

}

time_4ms_ok = 0;

}

} }


相关文章

  • 基于STC89C52的步进电机调速系统
  • 目录 摘 要.............................................................................................................................. 3 一 课程设计目的....... ...

  • 基于51单片机的直流电机转速测量与控制
  • 单片机原理与应用 课程设计 院 系 信息工程学院 班 级 自动化121 学生姓名 张晓峰 学 号 [1**********]2 日 期 2015/7/9 任务要求 基于51单片机的直流电机转速测量与控制 一.设计目的 1.通过本次课程设计加深对单片机课程的全面认识复习和掌握,对单片机课程的应用有进一 ...

  • 机的交流伺服电机转速控制系统研究
  • -匿E譬E墨一壑重量:量王望丘垫笪銮速鱼8垦皇熟整逢壁劁丞筮亟窒 基于单片机的交流伺服电机转速控制系统研究 赵磊1,王哈力1,何绪锋2,周永勤1 (1.哈尔滨理工大学黑龙江哈尔滨 150040:2.淄博牵引电机集团公司 山东淄博255100) 摘要:介绍基于STC89C52RC单片机实现非标准交流伺 ...

  • 计算机控制课程设计:直流电机调速系统
  • 计算机控制课程设计 直流电机调速系统 一. 实验要求 (1) 使用PID 算法实现直流电机的调速控制. (2) 利用光电开关测量直流电机转速,通过控制加在直流电机两端的电压调节 其转速,使之达到所设置的转速. (3) 通过键盘设置期望转速,要求有两组转速显示值,一组为期望转速:一组 为电机的实时转速 ...

  • 第十一届智能车技术报告_天津大学
  • 1 第十一届"恩智浦"杯全国大学生 智能汽车竞赛 技 术 报 告 学 校:天津大学 队伍名称:凌宇智控光电队 参赛队员:杨 明 杨炎龙 吴岳峰 带队教师:王建荣 1 摘要 本文以第十一届全国大学生智能车竞赛为背景,介绍了智能赛车控制系统的软硬件结构和开发流程.该比赛采用大赛组委会 ...

  • 高频电刀的设计与实现
  • 嵌入式系统应用 文章编号:1008-0570(2010)04-2-0050-03 (嵌入式与SOC)2010年第26卷第4-2期<微计算机信息> 高频电刀的设计与实现 DesignandrealizationofHFelectrosurgicalunit (华北科技学院) 曹智文于家城 ...

  • 摄像头循迹智能平衡小车
  • 摄像头循迹智能平衡小车 付国栋,胡健军,王杰 (哈尔滨工程大学自动化学院 哈尔滨 黑龙江 150001) 摘要: 摄像头循迹智能平衡小车是使用MK60DN512ZVLQ10微处理器和CCD 摄像头配合来实现在跑道上的自动循迹,识别黑白线,直道和弯道的加减速行驶.小车是机械系统与硬件系统配合软件系统实 ...

  • 智能小车设计方案
  • 智能小车设计方案 总体设计 硬件部分: 设计制作思路:本车采用MC9S12DG128单片机为核心,附加外围接口电路, 将光电传感器采集的到的道路信息进行综合判别和处理,并通过速度传感器获得当前小车速度,然后发出指令给电机驱动器(包括舵机和驱动电机)控制小车,从而控制小车速度,准确的根据道路特定路线行 ...

  • 太阳能热水器的设计
  • 摘要 针对现在的太阳能加热,我们的系统分为三部分:信号输入部分,加热控制控制部分以及电机控制出水温度部分.信号输入部分我们采用便于现场控制的键盘输入和便于用户控制的红外输入,加热部分采用的是温度和容量可调的加热系统,而电机控制采用的是发展较为成熟的PID控制以及定位准确的步进电机控制.三个系统相互联 ...

© 2024 范文中心 | 联系我们 webmaster# onjobs.com.cn