打印
[51单片机]

上位机控制单片机控制步进电机

[复制链接]
2054|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fhyxihuan1314|  楼主 | 2017-5-25 13:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近用上位机发一串数据控制单片机,主要是控制步进电机的起停,转向,脉冲数,频率,输入的数据如A1000C1000D1E1.2F1,第一个1000为脉冲数,第二个1000为频率,D后面的1代表转向,E后面的1.2代表占空比,F后面的1代表起停,程序写好后用串口助手发过去,数据能发送,没问题,但是步进电机不能运行,求解,求解。
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
//#include<stdio.h>
typedef unsigned int u16;         
typedef unsigned char u8;
unsigned char timer1;
void timerint(void);
int T;
int c;
int z;
int i;
double aa;int cc;double dd;float ee;         double ff;
sbit DIR=P1^0; //换向DIR为P1.0口
sbit ENA=P1^1; //使能ENA为P1.1口
sbit CP=P1^2; //脉冲CP为P1.2口
sbit K1=P1^3;//外部控制正转
sbit K3=P1^4;//外部控制反转
sbit K2=P1^5; //外部停止
sbit CP1=P1^6; //控制电压脉冲为P1.6口
sbit p1=P2^1;
char receiveData[18];
/*******************************************************************************
* 函数名         :UsartInit()
* 函数功能                   :设置串口
* 输入           : 无
* 输出                  : 无
*******************************************************************************/
void UsartInit()
{
        SCON=0X50;                        //设置为工作方式1
        TMOD=0X20;                        //设置计数器工作方式2
        PCON=0X80;                        //波特率加倍
        TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
        TL1=0XF3;
        ES=1;                                                //打开接收中断
        EA=1;                                                //打开总中断
        TR1=1;                                        //打开计数器
}
void system_Ini()                 //T0
{
    TMOD=0X01;
    TH0 =0XFF;                         //0.05ms定时
    TL0 =0XCE;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}
// void delay(u16 j)
//{
//        while(j--);       
//}
/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{       
        UsartInit();  //        串口初始化       
        ENA=0;
        if(i>17)
                    i=0;
                if(receiveData[0]=='A')
                {
                 if(receiveData[1]<='0'||receiveData[1]>='9')
                        {receiveData[1]='0';}
                    if(receiveData[2]<='0'||receiveData[2]>='9')
                        {receiveData[2]='0';}
                        if(receiveData[3]<='0'||receiveData[3]>='9')
                        {receiveData[3]='0';}
                        aa=1000*(receiveData[1]-'0')+100*(receiveData[2]-'0')+10*(receiveData[3]-'0')+(receiveData[4]-'0');
                        if(receiveData[6]<='0'||receiveData[6]>='9')
                        {receiveData[6]='0';}
                    if(receiveData[7]<='0'||receiveData[7]>='9')
                        {receiveData[7]='0';}
                        if(receiveData[8]<='0'||receiveData[8]>='9')
                        {receiveData[8]='0';}
                        cc=1000*(receiveData[6]-'0')+100*(receiveData[7]-'0')+10*(receiveData[8]-'0')+(receiveData[9]-'0');
                   dd=receiveData[11]-'0';
                   ee=(receiveData[13]-'0')+(receiveData[15]-'0')*0.1;
                   ff=receiveData[17]-'0';         }
        system_Ini();//初始化定时器T0                        
         while(1)       
         {         if(10*T<aa)
         {
                if(K1==0||dd==1&&K3==1)
                                {ENA=1;
                                DIR=1;
                                dd=0;}
                                if(K2==0||ff==0)
                                {ENA=0;}
                                if(K3==0||dd==0&&K1==1)
                                {ENA=1;
                                DIR=0;
                                dd=1;}                                                               
                                if(timer1>20000/cc)
                                {
                                        timer1=0; //输出占空比0.7的脉冲
                                }
                                if(timer1<10000/cc)
                                {
                                        CP=0;
                                }
                                else
                                {
                                        CP=1;
                                }
                                if(timer1<ee*5) //占空比可变的脉冲,控制电压
                                {CP1=1;}
                                else
                                {CP1=0;}
                                if(p1==0)
                                 {c++;}       
                                 }       
         }                 
}
/*******************************************************************************
* 函数名         : Usart() interrupt 4
* 函数功能                  : 串口通信中断函数
* 输入           : 无
* 输出                  : 无
*******************************************************************************/
void Usart() interrupt 4
{
         while (!RI); //等待接收数据
        receiveData[i]=SBUF;//出去接收到的数据
         if(receiveData[i]=='A'         )
        { i=0;
         receiveData[0]='A';       
        }
        i++;
        RI = 0;//清除接收中断标志位
//if(i==18)
//   {SBUF=c;//将接收到的数据放入到发送寄存器
//        while(!TI);                         //等待发送数据完成
//        TI=0;}                                                 //清除发送完成标志位
}
void T0zd() interrupt 1 //3 为定时器1的中断号; (1 定时器0的中断号; 0 外部中断1; 2 外部中断2; 4 串口中断),脉冲中断
{       
    TH0 =0XFF;
    TL0 =0XCE;
    timer1++; //计数+1
        T++;//计周期
}

相关帖子

沙发
xuyaqi| | 2017-5-25 14:05 | 只看该作者
串口中断里不能有这个“while (!RI); //等待接收数据”。

使用特权

评论回复
板凳
fhyxihuan1314|  楼主 | 2017-5-28 17:48 | 只看该作者
这两天又改了下,发现TMOD不一样,所以改了下TMOD设置,然后稍微变动了下,结果是用串口助手输入数据后,小灯过4秒左右才亮,而且步进电机也没动。。。。请问为啥啊,下面上代码
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
//#include<stdio.h>
typedef unsigned int u16;         
typedef unsigned char u8;
unsigned char timer1;
void timerint(void);
int T;
int c;
int z;
int i;
double aa;double cc;double dd;double ee;         double ff;
sbit DIR=P1^0; //换向DIR为P1.0口
sbit ENA=P1^1; //使能ENA为P1.1口
sbit CP=P1^2; //脉冲CP为P1.2口
sbit K1=P1^3;//外部控制正转
sbit K3=P1^4;//外部控制反转
sbit K2=P1^5; //外部停止
sbit CP1=P1^6; //控制电压脉冲为P1.6口
sbit p1=P2^1;
char receiveData[18];
  sbit led=P2^2;
/*******************************************************************************
* 函数名         :UsartInit()
* 函数功能                   :设置串口
* 输入           : 无
* 输出                  : 无
*******************************************************************************/
void UsartInit()
{
        SCON=0X50;                        //设置为工作方式1
        TMOD=0X21;                        //设置计数器工作方式2
        PCON=0X80;                        //波特率加倍
        TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
        TL1=0XF3;
        ES=1;                                                //打开接收中断
        EA=1;                                                //打开总中断
        TR1=1;                                        //打开计数器
}
void system_Ini()                 //T0
{
    TMOD=0X21;
    TH0 =0XFF;                         //0.05ms定时
    TL0 =0XCE;
    EA = 1;
    ET0 = 1;
   
}
// void delay(u16 j)
//{
//        while(j--);       
//}
/*******************************************************************************
* 函 数 名       : main
* 函数功能                 : 主函数
* 输    入       : 无
* 输    出             : 无
*******************************************************************************/
void main()
{       
        IP=0X10;
        UsartInit();  //        串口初始化
        system_Ini();//初始化定时器T0        
        ENA=0;
        while(1)       
         {
        if(i>17)
                    i=0;
                if(receiveData[0]=='A')
                {
                 if(receiveData[1]<='0'||receiveData[1]>='9')
                        {receiveData[1]='0';}
                    if(receiveData[2]<='0'||receiveData[2]>='9')
                        {receiveData[2]='0';}
                        if(receiveData[3]<='0'||receiveData[3]>='9')
                        {receiveData[3]='0';}
                        aa=1000*(receiveData[1]-'0')+100*(receiveData[2]-'0')+10*(receiveData[3]-'0')+(receiveData[4]-'0');
                        if(receiveData[6]<='0'||receiveData[6]>='9')
                        {receiveData[6]='0';}
                    if(receiveData[7]<='0'||receiveData[7]>='9')
                        {receiveData[7]='0';}
                        if(receiveData[8]<='0'||receiveData[8]>='9')
                        {receiveData[8]='0';}
                        cc=1000*(receiveData[6]-'0')+100*(receiveData[7]-'0')+10*(receiveData[8]-'0')+(receiveData[9]-'0');
                   dd=receiveData[11]-'0';
                   ee=(receiveData[13]-'0')+(receiveData[15]-'0')*0.1;
                   ff=receiveData[17]-'0';         }
        T=0;
        if(aa==1000&&cc==1000&&dd==1&&ee==1.2&&ff==1)//灯作为测试用       
        {
           led=1;
        }
        else
        {led=0;}                                                               
                  if(20000*T/cc<=aa)
                 {
                        if(dd==1)
                                {ENA=1;
                                DIR=1;
                                 TR0 = 1;}
                                if(K2==0||ff==0)
                                {ENA=0;}
                                if(dd==0)
                                {ENA=1;
                                DIR=0;
                                 TR0 = 1;}                                                               
                                if(timer1>20000/cc)
                                {
                                        timer1=0; //输出占空比0.7的脉冲
                                }
                                if(timer1<10000/cc)
                                {
                                        CP=0;
                                }
                                else
                                {
                                        CP=1;
                                }
                                if(timer1<ee*10000/cc) //占空比可变的脉冲,控制电压
                                {CP1=1;}
                                else
                                {CP1=0;}
                                if(p1==0)
                                 {c++;}       
                }
                        else
                        {TR0=0;
                        T=0;}//计周期       
         }                 
}
/*******************************************************************************
* 函数名         : Usart() interrupt 4
* 函数功能                  : 串口通信中断函数
* 输入           : 无
* 输出                  : 无
*******************************************************************************/
void Usart() interrupt 4
{
         while (!RI); //等待接收数据
        receiveData[i]=SBUF;//出去接收到的数据
         if(receiveData[i]=='A'         )
        { i=0;
         receiveData[0]='A';       
        }
        i++;
        RI = 0;//清除接收中断标志位
//if(i==18)
//   {SBUF=c;//将接收到的数据放入到发送寄存器
//        while(!TI);                         //等待发送数据完成
//        TI=0;}                                                 //清除发送完成标志位
}
void T0zd() interrupt 1 // 1 定时器0的中断号; 0 外部中断1; 2 外部中断2; 4 串口中断),脉冲中断
{       
    TH0 =0XFF;
    TL0 =0XCE;
    timer1++; //计数+1
        if(20000*T/cc<=aa)
        {T++;}       
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

7

帖子

0

粉丝