小弟最近在学PIC单片机,弄了个小程序,希望高手给点建议!呵呵

2020-02-08 12:21发布

//PIC18F458单片机 北京时代超群57系列步进电机以及配套驱动器
// 开发环境 MPALB8.40 ,CCSC
//设计思想:用串口调试助手控制电机转动的角度以及方向
#include <18F458.h>
#include<string.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=10000000)
#use rs232(baud=19200, parity=N,xmit=PIN_C6, rcv=PIN_C7,stream=MYPC,bits=8)
void  Turn_ange(int16 Set_Angel);
void chose();

int8 order=0; // 命令
// float tmp;//电机转的角度
int1 a=0;  //电机正反转
int8 xorder;

void main()
{   
  float Deg;//电机转的角度   
int8 f=0;   // 数位的标志位
int16 data1,data2,data3,data4,data5,data6,data7;  //依次百十个
output_high(PIN_D1);//开始时,电机处于脱机状态
while(1)
{
   if(kbhit()!=0)
   {
    xorder=getc(MYPC);

   if(xorder>0x42) //判断是否是命令
          {
            order=xorder;
            delay_ms(1);
            chose();
           }
   if(xorder<=0x39)
     {
        if(f==0)
         {
            data1=xorder;
           Deg=(data1-48)*100;  //ASCII转换成十进制
           f=1;
         }  //end  if(f==0)
            if(f==1)
             {
                   data2=getc(MYPC);
               Deg+=(data2-48)*10;   //ASCII转换成十进制
               f=2;
             }  //end if(f==1)
            if(f==2)
             {
                   data3=getc(MYPC);
               Deg+=(data3-48);  //ASCII转换成十进制
               f=3;
             }  //end if(f==2)
            if(f==3)
             {
                   data4=getc(MYPC);
               //tmp=tmp+(data4-48)*10;  //ASCII转换成十进制
               f=4;
             }  //end if(f==3)
            if(f==4)
             {
                   data5=getc(MYPC);
               Deg+=(float)(data5-48)/10;  //ASCII转换成十进制
               f=5;
             }  //end if(f==4)
            if(f==5)
             {
                   data6=getc(MYPC);
               Deg+=(float)(data6-48)/100;  //ASCII转换成十进制
               f=6;
             }  //end if(f==5)
            if(f==6)
             {
                   data7=getc(MYPC);
               Deg+=(float)(data7-48)/1000;  //ASCII转换成十进制
               f=7;
             }  //end if(f==4)

       if(f==7)
         {   
            int16 tmp;
           f=0;            
           printf("Turn %6.3f Deg ", Deg);//打印转的角度
            tmp= (unsigned int16)(Deg/0.028125);//转换转多少步
           Turn_ange(tmp);  //转换转多少步  
         }
      }  //end if(xorder<=65)
   }    //end  if(kbhit()!=0)
   
  }  //end while(1)

} //end main
/////////////////设定角度/////////////////////////////////////////
void  Turn_ange(unsigned int16 Set_Angel)
{
   int16 i;
   for(i=0;i<Set_Angel;i++)
   {
      output_low(PIN_C2);//输出高电平
      delay_us(100);
      output_high(PIN_C2);//输出低电平
      delay_us(100);
     if(kbhit()!=0)
{
     xorder=getc(MYPC);
        if(xorder=='e'||xorder=='E') //判断是否是命令
          {
            order=xorder;
            delay_ms(1);
            chose(); break;
           }
        
}

   }
}
/////////////////选择命令//////////////////////////////////////
void chose()
{
      switch(order)       //选择命令
                {
                        case 'S':      //大写S
                        case 's':      //发的数据是S吗?
                             printf( "S:StartMotor " );  //在串口助手
                                        //上打印“S:StartMotor"
                             printf( "delay_ms(500) " );
                             delay_ms(500);
                 output_low(PIN_D1);//
                             break;
           case 'D':
           case 'd':
                printf("change direction ");
                a=!a;
                output_bit(PIN_D3,a);
                break;
                        case 'E':
                        case 'e':
                         printf( "E:End_Motor " );    //在串口助手上打印"Q:EndADC"
                             printf( "delay_ms(500) " );
                             delay_ms(500);
                     output_high(PIN_D1);//
                         break;
                        default :             // rs232 get other char
            delay_ms(100);
            puts( "ERROR " );
                        break;
           }//end switch(tmp)
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
surf_131
1楼-- · 2020-02-08 13:07
本不是高手,不宜置喙。特别是对那个编译器不熟悉。但是看不到串口中断驱动,却见printf()这样的东西,对执行效率难免生疑。还有那个kbhit(),若是标准函数,它怎么获得232口对端的动作,又怎样传递给本机,不甚了了。
其它条件分支可采用switch语句处也不很清楚。
headwolf_83
2楼-- · 2020-02-08 13:51
大陆用CCS的很少,建议趁早改用MCC18或者PICC18。
piccode
3楼-- · 2020-02-08 16:05
没有用到串口中断驱动,是查讯

串口中断的写法是这样:
#INT_RDA
  void RDA_isr(){
  
  }
--------------------------------------------------------------------------------

kbhit( )是CCSC的标准函数  它的说明文档和例子很详细

Syntax:
value = kbhit()
value = kbhit (stream)
Parameters:
stream is the stream id assigned to an available RS232 port. If the stream parameter is not included, the function uses the primary stream used by getc().

Returns:
0 (or FALSE) if getc() will need to wait for a character to come in, 1 (or TRUE) if a character is ready for getc()
Function:
If the RS232 is under software control this function returns TRUE if the start bit of a character is being sent on the RS232 RCV pin. If the RS232 is hardware this function returns TRUE if a character has been received and is waiting in the hardware buffer for getc() to read. This function may be used to poll for data without stopping and waiting for the data to appear. Note that in the case of software RS232 this function should be called at least 10 times the bit rate to ensure incoming data is not lost.
springsky
4楼-- · 2020-02-08 21:35
 精彩回答 2  元偷偷看……
springsky
5楼-- · 2020-02-08 22:58
回复【1楼】surf_131
-----------------------------------------------------------------------

小弟用的是CCSC编译器,现在大陆用的人很少,HI-TECH PICC 很盛行。
springsky
6楼-- · 2020-02-09 03:53
回复【3楼】piccode
-----------------------------------------------------------------------

谢谢~~~!

一周热门 更多>