美文网首页C++计算机杂谈互联网科技
“单片机双机通讯控制直流电机调速”系统设计方案

“单片机双机通讯控制直流电机调速”系统设计方案

作者: 张照博 | 来源:发表于2018-03-06 13:05 被阅读93次

正文之前

感觉自己老老实实的写技术类文章还是上个世纪了。本学期开学了,每天沉迷于课设和写小说的节奏中,有点不可自拔。今天待会还要去发大四的补考证。真是忧伤。实在想不明白,挂科这么难的事情,怎么那么多人一门都能挂两次呢???百思不得其解!

正文

一、系统要实现的功能

  • 主机从机串口通讯

    • 主机向从机发送指定的速度差值
      • 数据差值由 预设速度-实际速度 获得
      • 差值在一定范围内的时候就算稳定,不传输
    • 从机负责接收来自主机的速度差值,并且通过PWM转化为占空比的变化量
  • 光电门测速

    • 通过光电门获取直流电机的转速,传入主机之后加以利用
  • 按键

    • 设置两个功能按钮,一个加速一个减速
  • 显示屏

    • 四块七段LED显示屏,两块显示预设速度,两块显示实际速度!
  • 直流电机

    • 与从机连接,根据从机给定的占空比实现不同的转速

二、 硬件准备

内容如下图,就不转化为文字了。从PPT复制过来直接就是图片了,不知道咋消除格式~

三、流程设计

四、系统架构

五、系统设计

其实系统设计跟系统架构接近,就是一个是硬件的架构,一个是软件的模块分析,不同的软件模块对应不同的硬件设备。

六、模块关系设计

这个是我准备用来当流程图用的东西,但是答辩的时候没想到这茬,结果就瞎鸡儿一说了。瞎了我画的这张好图!

七、电路图设计

这图对于电气这方面的同学来说肯定弱的一屁。但是我们毕竟是机械,没学那么多电学,而且也不是大头。所以担待下啦!还有不少没写的呢

八、细节电路设计

光电门因为仿真软件上没有合适的型号,所以我室友用的按键代替高低电平信号输入单片机

九、系统软件设计

代码上一波(这一波我是主力):

#include<reg51.h>
#include<intrins.h>
// #define TIMS=3306
#define FOSC 18432000L //当前主时钟频率
#define BAUD 115200  //声明当前波特率常数
#define uchar unsigned char
#define uint unsigned int
#define sdint signed int
//从0~9 的晶体管显示方式 
uchar table[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x71};
uint times=0;
uint sendtimes=0;
sbit P31=P3^1;  //串口通信口 RXD1(主机)  注意主机的RXD1要接从机的TXD1
sbit P30=P3^0;  //串口通信口 TXD1(主机) 
sbit P32=P3^2;  //用于接受按键的外部输入 增速指令 设置于主循环中,不另外设置外部中断了
sbit P33=P3^3;  //用于接受按键的外部输入 降速指令
sbit P34=P3^4;
sbit P35=P3^5;
sbit P36=P3^6;
sbit P37=P3^7;

sdint Speed_Want=0;  //根据键盘的输入,确定预设速度 初始值为0 
sdint Speed_Now=0;  // 根据光电门获得的速度存储地
uint Pulse=0; //Pulse 是脉冲的意思!这里用这个全局变量来接受光电门的脉冲信号,采用外部中断计数。
//发送数据函数,用于主机,查询TI(发送中断请求标志位) 
void SendDate(uchar date)
{
    SBUF=date; //将数据写入串口缓存区
    while(!TI); 
    TI=0; //此处应该由软件清零
}

//接受数据函数,用于从机,查询RI(接收中断请求标志位)
uchar ReciveDate(void )
{
    RI=0;
    while(!RI);
    RI=0;
    return SBUF;
}

//延时子程序,常用的
void delay(uint z)
{
    uint x,y;
    for(x=z;x>0;--x)
        for(y=110;y>0;y--);
}


//定时器0中断服务程序,用于累计时间,发送数据
void timer_0() interrupt 1
{
    ++sendtimes;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    if (sendtimes==4)
    {
        sendtimes=0;
        SendDate(0x7f+(Speed_Want-Speed_Now));
    }
}
//定时器1中断服务程序,用于定时去获取光电门的脉冲数据。
void timer_1() interrupt 3
{
    ++times;
    //计数重新赋值。每次定时器定时50ms
    TH1=(65536-50000)/256;
    TL1=(65536-50000)%256;
    if(times==4) //当定时4次的时候,时延0.2s,此时再次读取数据,并且计算电机速度。
    {
        times=0;
        Speed_Now=(Pulse)*5/4;
    }
}


// 键盘扫描函数,每次主循环中都要扫描一次,只检测两个独立按键即可。
uint kscan(void)
{
    uint keyboard;
    if (P36==0)
    {
        delay(2);
        if(P36==0)
        {
            keyboard=1;
        }
    }
    else if(P37==0) 
    {
        delay(2);
        if (P37==0)
        {
            keyboard=2;
        }
    }
    else
    {
        keyboard=0;
    }
    return keyboard;
}

void Change_Speed_Want(keyboard)
{
    if (keyboard==1)
    {
        Speed_Want+=10;
    }
    else if(keyboard==2)
    {
        if (Speed_Want>=10)
            Speed_Want-=10;
        else
            Speed_Want=0;
    }
}
// 7/8段LCD数码显示管显示程序。 P0负责个位数,P1负责十位数
void show(uint num)
{
    if (num<10 && num>=0)
    {
        P0=table[0];
        P1=table[num];
    }
    else if( num>=10 && num<100)
    {
        P0=table[num/10];
        P1=table[num%10];
    }
    else
    {
        //如果数值不合法,直接显示FF
        P0=table[10];
        P1=table[10];
    }
}


void main()
{
    P0=P1=0x00; //初始化显示器
    TMOD=0x11; //定时器工作方式寄存器设置
    SCON=0x50;  //设置串口1方式1工作,允许接收数据 SM0=0 SM1=1 REN=1
    TH1=(65536-50000)/256;
    TL1=(65536-50000)%256;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    while(1)
    {
        uint keyboard=0;
        delay(150);
        keyboard=kscan();
        Change_Speed_Want(keyboard);
        show(Speed_Want);
    }
}




//因为SBUF传递八位数据,而我们的速度定义是uint 也就是16位的无符号数,那么二者无法兼容。
// 所以我想了个办法,用C语言的隐式类型转换,通过16进制uchar类型的0x00与 10进制的uint数做加法
//强制转换为uchar之后,再在从机上进行解码!代码如下:
    // uint s=5;
    // uchar s1=0x09;
    // uchar s2=0x04;
    // if((s1-s2)==s)
    // {
    //  P0=table[1];
    // }
    // else
    //  P0=table[3];

// Output:1

// 又因为我们的差值可能是负数,所以特地定义了sdint这个类型
//事实证明,十六进制的加减后得到的也是sdsint
    // sdint s=25;
    // sdint xs=30;
    // uchar s1=0x7f;
    // uchar s2=0x84;
    // if((s1-s2)==(s-xs))
    // {
    //  P0=table[1];
    // }
    // else
    //  P0=table[3];
    
// Output: 1

十、欠缺部分

正文之后

其实今天老师说我们这个要实现的话定时器和中断可能不够用,而且串口通信的设计还不够。所以后面这些天可能就好好好地学一波通信协议 RS-232C这个东西了。然后再重新规划下我们的硬件设计

一犬得道现在居然在简书有个连载的东西了。但是我过几天估计就要跟起点签约了啊。。免费章节放到简书来会不会有版权问题?貌似签约就类似于卖版权??

相关文章

网友评论

本文标题:“单片机双机通讯控制直流电机调速”系统设计方案

本文链接:https://www.haomeiwen.com/subject/bcblfftx.html