0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

PID运算程序和初始化程序的实现

GReq_mcu168 来源:搜狐网 作者:搜狐网 2020-10-09 12:01 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

设计中采用了专门的芯片组成了PWM信号的发生系统并且对PWM信号的原理、产生方法以及如何通过软件编程对PWM信号占空比进行调节从而控制其输入信号波形等均作了详细的阐述。另外本系统中使用了红外对管对直流电机的转速进行测量,经过整形电路后将测量值送到单片机,并且最终作为反馈值输入到单片机进行PID运算从而实现了对直流电机速度的控制。在软件方面,文章中详细介绍了PID运算程序初始化程序等的编写思路和具体的程序实现。

1 单片机最小系统:单片机最小系统由51单片机,晶振电路,复位电路,电源组成。大家都比较熟悉,这里不再赘述。

2 四位数码管显示:在应用系统中,设计要求不同,使用的LED显示器的位数也不同,因此就生产了位数,尺寸,型号不同的LED显示器供选择,在本设计中,选择4位一体的数码型LED显示器,简称“4-LED”。本系统中前三位显示电压的整数位,最后一位显示转速的小数位。4-LED显示器引脚如图2所示,是一个共阴极接法的4位LED数码显示管,其中a,b,c,e,f,g为4位LED各段的公共输出端,1、2、3、4分别是每一位的位数选端,dp是小数点引出端,4位一体LED数码显示管的内部结构是由4个单独的LED组成,每个LED的段输出引脚在内部都并联后,引出到器件的外部。

3 电机驱动电路:电机驱动电中是采用ULN2003来驱动。ULN2003是高耐压、大电流达林顿陈列,由七个硅NPN达林顿管组成。该电路的特点:ULN2003的每一对达林顿都串联一个2.7K的基极电阻,在5V的工作电压下它能与TTL和CMOS电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据,输入5VTTL电平,输出可达500mA/50V。ULN2003的引脚图,其中IN1~IN7为输入控制端;OUT1~OUT7为输出端;8脚为芯片的接地端;9脚为公共端,该脚是内部7个续流二极管负极的公共端,各二极管的正极分别接各达林顿管的集电极。用于感性负载时,该脚接负载电源正极,实现续流作用。如果该脚接地,实际上就是达林顿管的集电极对地接通。

当P1.0中为高电平时,其内部三极管导通,使电机转动。当P1.0为低电平时,内部三极管截止,电路断开,电机停止转动。所以在程序中可以利用P1.0口输出PWM波来控制电机的转速。

4 红外测速电路:发射管工作时发出红外线,当接收管收到红外信号时,其电阻变小(本设计相当于从无穷大变到1k左右)。利用其电阻变化,改变接收管分压情况。挡片是利用圆盘上剪四个孔,当挡片随电机转动时,接收管两端电平发生变化,产生脉冲。

5 整形电路:本设计的整形电路是用555定时器接成的施密特触发器。

6 源程序:

#include "reg52.h"

#define uchar unsigned char

#define uint unsigned int

uchar code table[10]={0x3f,0x06,0x5b,

0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管显示码(0-9)

sbit xiaoshudian=P0^7;

sbit wei1=P2^4; //数码管位选定义

sbit wei2=P2^5;

sbit wei3=P2^6;

sbit wei4=P2^7;

sbit beep=P2^3; //蜂鸣器控制端

sbit motor = P1^0; //电机控制

sbit s1_jiasu = P1^4; //加速按键

sbit s2_jiansu= P1^5; //减速按键

sbit s3_jiting=P1^6; //停止/开始按键

uint pulse_count; //INT0接收到的脉冲数

uint num=0; //num相当于占空比调节的精度

uchar speed[3]; //四位速度值存储

float bianhuasudu; //当前速度(理论计算值)

float reallyspeed; //实际测得的速度

float vv_min=0.0;vv_max=250.0;

float vi_Ref=60.0; //给定值

float vi_PreError,vi_PreDerror;

uint pwm=100; //相当于占空比标志变量

int sample_time=0; //采样标志

float v_kp=1.2,v_ki=0.6,v_kd=0.2; //比例,积分,微分常数

void delay (uint z)

{

uint x,y;

for(x=z;x>0;x--)

for (y=20;y>0;y--);

}

void time_init()

{

ET1=1; //允许定时器T1中断

ET0=1; //允许定时器T0中断

TMOD = 0x15; //定时器0计数,模式1;定时器1定时,模式1

TH1 = (65536-100)/256; //定时器1值,负责PID中断 ,0.1ms定时

TL1 = (65536-100)%6;

TR0 = 1; //开定时器

TR1 = 1;

IP=0X08; //定时器1为高优级

EA=1; //开总中断

}

void keyscan()

{

float j;

if(s1_jiasu==0) //加速

{

delay(20);

if(s1_jiasu==0)

vi_Ref+=10;

j=vi_Ref;

}

while(s1_jiasu==0);

if(s2_jiansu==0) //减速

{

delay(20);

if(s2_jiansu==0)

vi_Ref-=10;

j=vi_Ref;

}

while(s2_jiansu==0);

if(s3_jiting==0)

{

delay(20);

motor=0;

P1=0X00;

P3=0X00;

P0=0x00;

}

while(s3_jiting==0);

}

float v_PIDCalc(float vi_Ref,float vi_SpeedBack)

{

register float error1,d_error,dd_error;

error1=vi_Ref-vi_SpeedBack; //偏差的计算

d_error=error1-vi_PreError; //误差的偏差

dd_error=d_error-vi_PreDerror; //误差变化率

vi_PreError=error1; //存储当前偏差

vi_PreDerror=d_error;

bianhuasudu=(v_kp*d_error+v_ki*vi_PreError+v_kd*dd_error);

return (bianhuasudu);

}

void v_Display()

{

uint sudu;

sudu=(int)(reallyspeed*10); //乘以10之后强制转化成整型

speed[3]=sudu/1000; //百位

speed[2]=(sudu00)/100; //十位

speed[1]=(sudu0)/10; //个位

speed[0]=sudu; //小数点后一位

wei1=0; //第一位打开

P0=table[speed[3]];

delay(5);

wei1=1; //第一位关闭

wei2=0;

P0=table[speed[2]];

delay(5);

wei2=1;

wei3=0;

P0=table[speed[1]];

xiaoshudian=1;

delay(5);

wei3=1;

wei4=0;

P0=table[speed[0]];

delay(5);

wei4=1;

}

void BEEP()

{

if((reallyspeed)>=vi_Ref+5||(reallyspeed

{

beep=~beep;

delay(4);

}

}

void main()

{

time_init();

motor=0;

while(1)

{

v_Display();

BEEP();

}

if(s3_jiting==0) //对按键3进行扫描,增强急停效果

{

delay(20);

motor=0;

P1=0X00;

P3=0X00;

P0=0x00;

}

while(s3_jiting==0);

}

void timer0() interrupt 1

{

}

void timer1() interrupt 3

{

TH1 = (65536-100)/256; //1ms定时

TL1 = (65536-100)%6;

sample_time++;

if(sample_time==5000) //采样时间0.1ms*5000=0.5s

{

TR0=0; //关闭定时器0

sample_time=0;

pulse_count=TH0*255+TL0; //保存当前脉冲数

keyscan(); //扫描按键

reallyspeed=pulse_count/(4*0.6); //计算速度

pwm=pwm+v_PIDCalc(vi_Ref,reallyspeed);

if(pwm

if(pwm>100)pwm=100;

TH0=TL0=0;

TR0=1; //开启定时器0

}

num++;

if(num==pwm) //此处的num值,就是占空比

{

motor=0;

}

if(num==100) //100相当于占空比调节的精度

{

num=0;

motor=1;

}

}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PID
    PID
    +关注

    关注

    37

    文章

    1489

    浏览量

    90101
  • 初始化程序
    +关注

    关注

    1

    文章

    4

    浏览量

    6855

原文标题:厉害了我的单片机!看它如何控制PWM信号实现直流电机转速控制~

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    串口通信基石:Air8000下Modbus RTU串口初始化详解!

    串口初始化是Modbus RTU通信稳定可靠的关键起点。本篇深入剖析Air8000开发板串口参数配置、初始化代码实现及调试要点,结合master_rtu示例,分享实际操作中的经验与避坑指南,让您
    的头像 发表于 10-28 16:33 1450次阅读
    串口通信基石:Air8000下Modbus RTU串口<b class='flag-5'>初始化</b>详解!

    使用 ICP 编程工具编程时,用户在启用后是否需要在程序初始化看门狗?

    使用ICP编程工具进行编程时,用户在配置位设置中启用“看门狗”选项后,是否需要在程序初始化看门狗?用户是否需要清除超时标志?
    发表于 08-28 06:48

    GraniStudio:IO初始化以及IO资源配置例程

    IO资源配置.gsp文件,点击打开,完成导入。 2.功能说明 实现连接格拉尼控制器IO块以及配置输入输出IO点。 2.1通过初始化IO算子连接格拉尼控制器IO块,导入工程自动进行连接。 2.2 通过IO配置算子输出配置的IO表。 第一次使用GS软件时操作步骤如下: (1)
    的头像 发表于 08-22 17:34 752次阅读
    GraniStudio:IO<b class='flag-5'>初始化</b>以及IO资源配置例程

    GraniStudio:初始化例程

    1.文件运行 导入工程 双击运行桌面GraniStudio.exe。 通过引导界面导入初始化例程,点击导入按钮。 打开初始化例程所在路径,选中初始化.gsp文件,点击打开,完成导入。 2.功能
    的头像 发表于 08-22 16:45 713次阅读
    GraniStudio:<b class='flag-5'>初始化</b>例程

    zephyr设备驱动程序模型

        1:Zephyr 内核支持多种设备驱动程序。驱动程序是否可用取决于board 和驱动程序。 Zephyr 设备模型为配置作为系统一部分的驱动程序提供了一致的设备模型。设备型号负
    的头像 发表于 07-29 10:34 493次阅读
    zephyr设备驱动<b class='flag-5'>程序</b>模型

    定义IO初始化结构体

    由上述IOPORT相关功能的枚举类型我们可以知道,在对IOPORT模块进行初始化时需要根据情况配置它们。因此我们定义一个IOPORT初始化的结构体类型IOPORT_Init_t,它的成员包括了由上述所有枚举类型所声明的变量,因此该结构体类型的变量可以包含IOPORT的相关
    的头像 发表于 07-16 16:26 1120次阅读

    IM系列设备过载故障:界面初始化终止的诊断流程与修复指南

    当 IM 系列设备出现过载故障导致界面初始化终止时,通常表现为设备启动后操作界面无显示、指示灯异常闪烁或初始化进度条停滞不前,同时可能伴随设备运行异响或异常发热。初步判断时,可观察设备是否有错
    的头像 发表于 06-28 09:47 948次阅读

    IM 系列设备过载保护机制下界面初始化中断的底层逻辑与解决方案

    一、过载保护机制与界面初始化的关联基础 IM 系列设备的过载保护机制是保障设备安全运行的核心功能,其通过传感器实时采集设备运行参数,如电流、电压、温度、系统资源占用率等。一旦这些参数超出预设阈值
    的头像 发表于 06-27 09:58 374次阅读

    请问init_ipc_shm() 是否只初始化一次?

    通过在 S32G A 核上使用 C(或 C)创建多个项目来开发 IPCF 功能时,是init_ipc_shm()允许初始化已配置的共享资源的函数仅一次在运行时?如果是,系统级别的最佳架构建议是什么?我的想法是实现一个自启动服务程序
    发表于 03-25 08:05

    ads1252的初始化程序是什么?

    我想问下ads1252的初始化程序是什么?我整了半天也没整明白?有更多关于ads1252的资料吗
    发表于 02-13 06:45

    EE-359:ADSP-CM40x启动时间优化和器件初始化

    电子发烧友网站提供《EE-359:ADSP-CM40x启动时间优化和器件初始化.pdf》资料免费下载
    发表于 01-13 16:33 0次下载
    EE-359:ADSP-CM40x启动时间优化和器件<b class='flag-5'>初始化</b>

    EE-88:使用21xx编译器在C中初始化变量

    电子发烧友网站提供《EE-88:使用21xx编译器在C中初始化变量.pdf》资料免费下载
    发表于 01-13 15:54 0次下载
    EE-88:使用21xx编译器在C中<b class='flag-5'>初始化</b>变量

    ADS1259初始化程序必须执行两次才能够初始化成功,为什么?

    最近在调试ADS1259这个片子,发现初始化程序必须执行两次才能够初始化成功,然后读出来的CONFIG0寄存器的最高位是“0”(官方文档上是“1”),不知道是什么原因,求TI工程师解答呀!
    发表于 01-10 12:41

    OMAP5912多媒体处理器初始化参考指南

    电子发烧友网站提供《OMAP5912多媒体处理器初始化参考指南.pdf》资料免费下载
    发表于 12-17 16:20 0次下载
    OMAP5912多媒体处理器<b class='flag-5'>初始化</b>参考指南

    STM32F407 MCU使用SD NAND 不断电初始化失效解决方案

    STM32F407微控制器单元(MCU)与SD NAND的结合提供了强大的存储解决方案。然而,不断电初始化失效问题可能会导致系统稳定性和数据完整性受损。我们将STM32F407与SD NAND集成时可能遇到的初始化问题,并提供专业的解决方案。
    的头像 发表于 12-11 10:51 1495次阅读
    STM32F407 MCU使用SD NAND 不断电<b class='flag-5'>初始化</b>失效解决方案