.
  • 作者:city7cc
  • 积分:4065
  • 等级:专家教授
  • 2019/10/10 10:46:50
  • 中国面包师贴吧-楼主(阅:3145/回:0)一种具有17路可调PWM直流电机的串口遥控机器人


    一种具有17路可调PWM直流电机的串口遥控机器人
    技术领域
        本实用新型涉及一种具有17路PWM直流电机的串口遥控机器人,尤其是一种可以用串口无线WIFI遥控的智能机器人。

    背景技术
    现有常规遥控机人按照无线电信号的遥控进行动作,也可以按照存储在寄存器里面的程序动作,但是动作电机较少,一般只有4路PWM直流电机,且PWM方波的频率,占空比保持固定,这对机器人的行动带来很大的不便。一种具有17路可调PWM直流电机的串口遥控机器人是一种具有17路可调PWM频率、占空比的直流电机的机器人,操作者可以使用计算机串口WIFI信号对它的17路直流电机进行遥控,它也可以按照其控制电路中的24C04铁电存储器里面的数据,读取ADC0832芯片采样的温度值,并通过串口WIFI信号发送到操作者的电脑。

    实用新型内容
    为了解决常规遥控机器人动作电机较少,动作单一的缺点,一种具有17路可调PWM直流电机的串口遥控机器人提供了一种具有17路可调PWM直流电机进行串口WIFI信号遥控动作的机器人。它可以按照电路中的24C04铁电存储器里面的数据,读取ADC0832芯片采样的温度值,在单片机STC12C5A60S2的控制下进行动作,也可以按照操作人员的计算机串口WIFI信号的遥控进行动作。由于它具有17路PWM直流电机,所以它可以进行行走,抬手,伸手等多种动作。操作人员可以将计算机的232串口单片机STC12C5A60S2的232串口连接起来,再通过COMMIX串口调试助手软件在计算机上面发送数据控制单片机STC12C5A60S2所产生的PWM波形的占空比,频率等参数,进而实现对直流电机的控制。操作人员在计算机上面的COMMIX串口调试助手软件发送十六进制数11,单片机STC12C5A60S2所产生的PWM波形的占空比,频率都减小,同时计算机上面的COMMIX串口调试助手软件收到单片机STC12C5A60S2返回的十六进制数11和ADC0832芯片所采集的十六进制温度数据。当温度热电阻发生变化时,ADC0832芯片所采集的温度数据也会发生变化。操作人员在计算机上面的COMMIX串口调试助手软件发送十六进制数AA,单片机STC12C5A60S2所产生的PWM波形的占空比,频率都增大。操作人员在计算机上面的COMMIX串口调试助手软件发送十六进制数FF,单片机STC12C5A60S2所产生的PWM波形的占空比,频率达到最大。
    本实用新型解决其技术问题所采用的技术方案是:一种具有17路可调PWM直流电机的串口遥控机器人是一种可以被WIFI串口信号遥控的机器人,它的17路PWM方波的频率和占空比都可以通过计算机WIFI串口信号进行调节。它依靠外壳下面装配的17路PWM直流电机在操作人员的计算机串口WIFI信号的遥控下进行转动,行走等各种动作。它可以在电机的转动下进行移动,行走,抬手等等动作。同时,它也可以按照控制电路中的24C04铁电存储器(5)里面的数据,在STC12C5A60S2单片机(4)的控制下进行电机的转动等动作,它可以将ADC0832芯片(6)采样得到的温度值通过WIFI串口发送到计算机。它的控制电路如图1所示。在图1中,STC12C5A60S2单片机(4)的P1中的P1.2, P1.3, P1.4, P1.5, P1.6,P1.7端口,P3 中的P3.2, P3.5, P3.6端口,P2中的P2.0,P2.1,P2.2,P2.3,P2.4,P2.5,P2.6,P2.7端口在定时器TIME0的控制下产生17路PWM方波,上面总共17路IO口,每个IO口产生一路PWM信号,总共17路PWM控制方波信号。操作人员通过遥控计算机的WIFI串口发送数据到STC12C5A60S2单片机(4),就可以改变上述端口的PWM方波信号的频率、占空比等。同时也可以得到ADC0832芯片(6)采样得到的温度值。WIFI模块连接在单片机STC12C5A60S2(4)的串口上面,它接收操作人员发出的数据,然后单片机STC12C5A60S2 (4)按照程序减少或增加PWM方波的占空比,增加或减少频率。同时单片机(4)按照铁电存储器24C04(5)中的数据控制上面的PWM方波信号。操作人员通过USB串口(1),经过芯片PL2303HX(3),给单片机下载程序。5V开关电源(2)给单片机提供5V直流电。ULN2003D驱动芯片(7)使单片机P1,P2,P3端口的PWM信号稳定保持不变
    操作人员通过计算机串口发送十六进制数01,单片机(4)的P0.0端口就是高电平,同时单片机将01发送给计算机,也将ADC0832芯片(6)采样得到的温度值发送给计算机。操作人员通过计算机串口发送十六进制数02,单片机(4)的P0.1端口就是高电平,同时单片机将02发送给计算机,也将ADC0832芯片(6)采样得到的温度值发送给计算机。操作人员通过计算机串口发送十六进制数04,单片机(4)的P0.2端口就是高电平,同时单片机将04发送给计算机,也将ADC0832芯片(6)采样得到的温度值发送给计算机。单片机的程序可以在百度网盘https://pan.baidu.com/s/14Uj9J_T1WzvOVJPuoOI-cw下载。
    单片机STC12C5A60S2(4)的控制程序是在keill4编译环境下,通过C语言编译并通过串口下载到单片机STC12C5A60S2(4)。程序代码如下:
    /******************************************************************************
    *程序思路说明:                                                              *
    *                                                                            *
    *关于频率和占空比的确定,对于12M晶振,假定PWM输出频率为1KHZ,这样定时中断次数 *
    *设定为C=10,即0.01MS中断一次,则TH0=FF,TL0=F6;由于设定中断时间为0.01ms,这样可以设定占空比
    可从1-100变化。即0.01ms*100=1ms                               *
    ******************************************************************************/
    #include <reg52.h>
    #include <INTRINS.H>
    #define uchar unsigned char  
         #include <intrins.h>
    #defineOP_READ0xa1// 器件地址以及读取操作
    #defineOP_WRITE 0xa0// 器件地址以及写入操作
    #defineMAX_ADDR 0x7f// AT24C02最大地址
    /*****************************************************************************
    * TH0和TL0是计数器0的高8位和低8位计数器,计算办法:TL0=(65536-C)%256;         *
    * TH0=(65536-C)/256,其中C为所要计数的次数即多长时间产生一次中断;TMOD是计数器*
    * 工作模式选择,0X01表示选用模式1,它有16位计数器,最大计数脉冲为65536,最长时 *
    * 间为1ms*65536=65.536ms                                                     *
    ******************************************************************************/
    #define V_TH0  0XFF                  
    #define V_TL0  0XF6                  
    #define V_TMOD 0X01                  
    #define V_TH1  0XFF                  
    #define V_TL1  0XF6                  
    #define V_TH2  0XFF                  
    #define V_TL2  0XF6  
    #define uint unsigned int
    #define uchar unsigned char
    #define nop _nop_()
    sbit adcs=P3^7;//P3.7连接ADC0832的CS使能端
    sbit adclk=P1^0; //P1.0连接ADC0832的时钟输入口
    sbit addin=P1^1;//ADC0832的D0,D1是分时工作的,所以这两个端口可以接在同一个IO口P1.1
    uchar addata;
    bit y;     //位数据,以0或1区倍两个通道的输入和输出
    unsigned char code dis_code[] = {0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff};
    // 写入到AT24C01的数据串
    sbit SDA = P3^4;
    sbit SCL = P3^3;
        void adread();
    void adstart();
    void start();
    void stop();
    unsigned char shin();
    bit shout(unsigned char write_data);
    unsigned char read_random(unsigned char random_addr);
    void write_byte( unsigned char addr, unsigned char write_data);
    void fill_byte(unsigned char fill_data);
    void delayms(unsigned char ms);
    void init_sys(void);            /*系统初始化函数*/
    void Delay5Ms(void);
    void delay1 (unsigned char m);
    unsigned char ZKB1,ZKB2,ZKB3,ZKB4,ZKB5,ZKB6,ZKB7,ZKB8,ZKB9,ZKB10,ZKB11,ZKB12,ZKB13,ZKB14,ZKB15,ZKB16,ZKB17,ZKB18;
    unsigned char ZKB19,ZKB20,ZKB21,ZKB22,ZKB23,ZKB24,ZKB25,ZKB26,ZKB27,ZKB28,ZKB29,ZKB30,ZKB31,ZKB32;
    unsigned char key_s, key_v, tmp,tmp1;
    char code str[]={0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff,0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff,0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff};
    void send_str();
    bitscan_key();
    void proc_key();
    void delayms(unsigned char ms);
      void delayms1(unsigned char a) ;
    void send_char(unsigned char txd);
       unsigned char i;
    unsigned char k,m;   //m为频率常数变量    
      unsigned char s=0;  
    unsigned char p;
    unsigned char p1=0x00,p2,p3,p4;
    //本例采用89C52, 晶振为12MHZ    
    //关于如何编制音乐代码, 其实十分简单,各位可以看以下代码.    
    //频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍;    
    //所以拿出谱子, 试探编吧!    
    //sbit Beep =  P3^7;
    sbit Beep1 =  P3^6;
    sbit Beep2 =  P3^5;
    //sbit Beep3 =  P3^4;
    // sbit Beep4 =  P3^3;
    sbit Beep5 =  P3^2;
    //sbit Beep6 =  P3^1;
    //sbit Beep7 =  P3^0;
    sbit Beep8 =  P1^7;
    sbit Beep9 =  P1^6;
    sbit Beep10 =  P1^5;
    sbit Beep11 =  P1^4;
    sbit Beep12 =  P1^3;
    sbit Beep13 =  P1^2;
    //sbit Beep14 =  P1^1;
    //sbit Beep15 =  P1^0;
    sbit Beep16 =  P2^7;
    sbit Beep17 =  P2^6;
    sbit Beep18 =  P2^5;
    sbit Beep19 =  P2^4;
    sbit Beep20 =  P2^3;
    sbit Beep21 =  P2^2;
    sbit Beep22 =  P2^1;
    sbit Beep23 =  P2^0;
    unsigned char n=0;  //n为节拍常数变量 歌曲为八月桂花香  
    unsigned char code music_tab[] ={  
    0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,    
    0x20, 0x40, 0x1C , 0x10,  
    0x18, 0x10, 0x20 , 0x10,  
    0x1C, 0x10, 0x18 , 0x40,  
    0x1C, 0x20, 0x20 , 0x20,  
    0x1C, 0x20, 0x18 , 0x20,  
    0x20, 0x80, 0xFF , 0x20,  
    0x30, 0x1C, 0x10 , 0x18,  
    0x20, 0x15, 0x20 , 0x1C,  
    0x20, 0x20, 0x20 , 0x26,  
    0x40, 0x20, 0x20 , 0x2B,  
    0x20, 0x26, 0x20 , 0x20,  
    0x20, 0x30, 0x80 , 0xFF,  
    0x20, 0x20, 0x1C , 0x10,  
    0x18, 0x10, 0x20 , 0x20,  
    0x26, 0x20, 0x2B , 0x20,  
    0x30, 0x20, 0x2B , 0x40,  
    0x20, 0x20, 0x1C , 0x10,  
    0x18, 0x10, 0x20 , 0x20,  
    0x26, 0x20, 0x2B , 0x20,  
    0x30, 0x20, 0x2B , 0x40,  
    0x20, 0x30, 0x1C , 0x10,  
    0x18, 0x20, 0x15 , 0x20,  
    0x1C, 0x20, 0x20 , 0x20,  
    0x26, 0x40, 0x20 , 0x20,  
    0x2B, 0x20, 0x26 , 0x20,  
    0x20, 0x20, 0x30 , 0x80,  
    0x20, 0x30, 0x1C , 0x10,  
    0x20, 0x10, 0x1C , 0x10,  
    0x20, 0x20, 0x26 , 0x20,  
    0x2B, 0x20, 0x30 , 0x20,  
    0x2B, 0x40, 0x20 , 0x15,  
    0x1F, 0x05, 0x20 , 0x10,  
    0x1C, 0x10, 0x20 , 0x20,  
    0x26, 0x20, 0x2B , 0x20,  
    0x30, 0x20, 0x2B , 0x40,  
    0x20, 0x30, 0x1C , 0x10,  
    0x18, 0x20, 0x15 , 0x20,  
    0x1C, 0x20, 0x20 , 0x20,  
    0x26, 0x40, 0x20 , 0x20,  
    0x2B, 0x20, 0x26 , 0x20,  
    0x20, 0x20, 0x30 , 0x30,  
    0x20, 0x30, 0x1C , 0x10,  
    0x18, 0x40, 0x1C , 0x20,  
    0x20, 0x20, 0x26 , 0x40,  
    0x13, 0x60, 0x18 , 0x20,  
    0x15, 0x40, 0x13 , 0x40,  
    0x18, 0x80, 0x00  
    };  
    unsigned char code music_tab1[] ={  
    0x1D, 2202, 0x1D , 2902, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数, 我从山中来歌曲  
    0x1D, 2902, 0x1D , 2902,  
    0x1D, 2906, 0x1D , 2702,  
    0x15, 2502, 0x16 , 2702,  
    0x00, 2502, 0x15 , 2402,  
    0x16, 2208, 0x19 , 0x20,  
    0x00, 0x80, 0x1C, 0x20,  
    0x00, 0x1C, 0x10 , 0x18,  
    0x20, 0x15, 0x20 , 0x1C,  
    0x20, 0x20, 0x20 , 0x26,  
    0x40, 0x20, 0x20 , 0x2B,  
    0x20, 0x26, 0x20 , 0x20,  
    0x20, 0x30, 0x80 , 0xFF,  
    0x20, 0x20, 0x1C , 0x10,  
    0x18, 0x10, 0x20 , 0x20,  
    0x26, 0x20, 0x2B , 0x20,  
    0x30, 0x20, 0x2B , 0x40,  
    0x20, 0x20, 0x1C , 0x10,  
    0x18, 0x10, 0x20 , 0x20,  
    0x26, 0x20, 0x2B , 0x20,  
    0x30, 0x20, 0x2B , 0x40,  
    0x20, 0x30, 0x1C , 0x10,  
    0x18, 0x20, 0x15 , 0x20,  
    0x1C, 0x20, 0x20 , 0x20,  
    0x26, 0x40, 0x20 , 0x20,  
    0x2B, 0x20, 0x26 , 0x20,  
    0x20, 0x20, 0x30 , 0x80,  
    0x20, 0x30, 0x1C , 0x10,  
    0x20, 0x10, 0x1C , 0x10,  
    0x20, 0x20, 0x26 , 0x20,  
    0x2B, 0x20, 0x30 , 0x20,  
    0x2B, 0x40, 0x20 , 0x15,  
    0x1F, 0x05, 0x20 , 0x10,  
    0x1C, 0x10, 0x20 , 0x20,  
    0x26, 0x20, 0x2B , 0x20,  
    0x30, 0x20, 0x2B , 0x40,  
    0x20, 0x30, 0x1C , 0x10,  
    0x18, 0x20, 0x15 , 0x20,  
    0x1C, 0x20, 0x20 , 0x20,  
    0x26, 0x40, 0x20 , 0x20,  
    0x2B, 0x20, 0x26 , 0x20,  
    0x20, 0x20, 0x30 , 0x30,  
    0x20, 0x30, 0x1C , 0x10,  
    0x18, 0x40, 0x1C , 0x20,  
    0x20, 0x20, 0x26 , 0x40,  
    0x13, 0x60, 0x18 , 0x20,  
    0x15, 0x40, 0x13 , 0x40,  
    0x18, 0x80, 0x00  
    };    
    void main (void)
    {
    init_sys();
    ZKB1=40;            /*占空比初始值设定*/
    SDA = 1;
    SCL = 1;
    //fill_byte(0x00);// 全部填充0xff
    //adstart();
    //  adread();
      play:  
      while(1)
      {
    //adstart();
    //  adread();
    if(RI)// 是否有数据到来
    {
    RI = 0;
    tmp = SBUF;// 暂存接收到的数据
    //tmp1=SBUF++;
    //  dis_code[i]=SBUF;
    // 数据传送到P0口
    // str[1]=SBUF;
       write_byte(0X00, tmp);
       //write_byte(0X01, tmp+4);
    write_byte(0X02, addata);
    //write_byte(0X00, str[1]);
    //write_byte(0X01, tmp1);
    P0 = read_random(0X00);// 循环读取24Cxx内容,并输出到P0口
    //P2=  read_random(0X02);
      // p1= read_random(0X00);
      //  p2= read_random(0X01);
    //delayms(250);
    send_char(tmp);// 回传接收到的数据
       send_char( addata);// 回传接收到的数据
    // send_str() ;
    }
       a: k=music_tab[s+tmp];  
           if(k==0x00)       { s=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍    
           else if(k==0xff)  { s=s+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符    
                else         {m=music_tab[s++], n=music_tab[s++];}  //取频率常数 和 节拍常数    
                 TR0=1;                                             //开定时器1    
               while(n!=0) Beep1=~Beep1,Beep2=~Beep2,Beep5=~Beep5,Beep8=~Beep8,Beep9=~Beep9,Beep10=~Beep10,Beep11=~Beep11,Beep12=~Beep12,Beep13=~Beep13,Beep16=~Beep16,Beep17=~Beep17,Beep18=~Beep18,Beep19=~Beep19,Beep20=~Beep20,Beep21=~Beep21,Beep22=~Beep22,Beep23=~Beep23,delay1(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)    
       TR0=0;                                           //关定时器1    
          b: k=music_tab1[s+tmp];  
           if(k==0x00)       { s=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍    
           else if(k==0xff)  { s=s+1;delayms(100),TR0=0; goto b;}  //若碰到休止符,延时100ms,继续取下一音符    
                else         {m=music_tab1[s++], n=music_tab1[s++];}  //取频率常数 和 节拍常数    
                 TR0=1;                                             //开定时器1    
               while(n!=0) Beep16=~Beep16,Beep17=~Beep17,Beep18=~Beep18,Beep19=~Beep19,Beep20=~Beep20,Beep21=~Beep21,Beep22=~Beep22,Beep23=~Beep23,delay1(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)    
       TR0=0;  
    //tmp1 = str[i];
    //write_byte(0X01, tmp1);
    //i++;// 下一个字符
    //P2 = read_random(0X01);// 循环读取24Cxx内容,并输出到P0口
          // if (!P0_0) //如果按了+键,增加占空比
          //{
          // Delay5Ms();
          // if (!P0_0)
          //   {
            // ZKB1--;
      //ZKB1=90;
            // }
          }      
    /*对占空比值限定范围*/
    //if (ZKB1>99) ZKB1=1;
    //if (ZKB1<1) ZKB1=99;
    }
    /******************************************************
    *函数功能:对系统进行初始化,包括定时器初始化和变量初始化*/
    void init_sys(void)            /*系统初始化函数*/
    {
      /*定时器TIME0初始化*/
      //TMOD=V_TMOD;
      TH0=V_TH0;
      TL0=V_TL0;
      TR0=1;
      ET0=1;
      EA=1;
        /*定时器TIME1初始化*/
    TMOD = 0x20;// 定时器1工作于8位自动重载模式, 用于产生波特率
    TH1 = 0xFD;// 波特率9600
    TL1 = 0xFD;
    SCON = 0x50;// 设定串行口工作方式
    PCON &= 0xef;// 波特率不倍增
    TR1 = 1;// 启动定时器1
      //TR2=1;
    // ET2=1;
    //TMOD&=0x0f;  
      //TMOD|=0x01;  
    TH0=0xd8;
    TL0=0xef;  
      IE=0x82;
    //IE = 0x0;// 禁止任何中断
    //  TH2=V_TH2;
    // TL2=V_TL2;
    // TR2=1;
    // ET2=1;
      //EA=1;
    }
    //延时
    void Delay5Ms(void)
    {
    unsigned int TempCyc = 1000;
    while(TempCyc--);
    }
    /*中断函数*/
    void timer0(void) interrupt 1 using 2
    {
    static uchar click=0;                  /*中断次数计数器变量*/
       adstart();
      adread();
    //TH0=V_TH0;                                    /*恢复定时器初始值*/
    //TL0=V_TL0;
        TH0=0xd8;  
       TL0=0xef;  
       n--;  
    //++click;
    //if (click>=100) click=0;
    //if (click<=ZKB1)      /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/
    // P1_0=0;
    //else
      //P1_0=1;
    //if (click<=ZKB2)                        
      //P1_1=0;
    //else
      //P1_1=1;
    //if (click<=ZKB3)      /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/
      //P1_2=0;
    //else
      //P1_2=1;
    }
    void send_char(unsigned char txd)
    // 传送一个字符
    {
    SBUF = txd;
    while(!TI);// 等特数据传送
    TI = 0;// 清除数据传送标志
    }
    void send_str()
    // 传送字串
    {
    unsigned char i = 0;
    while(str[i] != '\0')
    {
    SBUF = str[i];
    while(!TI);// 等特数据传送
    TI = 0;// 清除数据传送标志
    i++;// 下一个字符
    }
    }
    void start()
    // 开始位
    {
    SDA = 1;
    SCL = 1;
    _nop_();
    _nop_();
    SDA = 0;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SCL = 0;
    }
    void stop()
    // 停止位
    {
    SDA = 0;
    _nop_();
    _nop_();
    SCL = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA = 1;
    }
    unsigned char shin()
    // 从AT24Cxx移入数据到MCU
    {
    unsigned char i,read_data;
    for(i = 0; i < 8; i++)
    {
    SCL = 1;
    read_data <<= 1;
    read_data |= (unsigned char)SDA;
    SCL = 0;
    }
    return(read_data);
    }
    bit shout(unsigned char write_data)
    // 从MCU移出数据到AT24Cxx
    {
    unsigned char i;
    bit ack_bit;
    for(i = 0; i < 8; i++)// 循环移入8个位
    {
    SDA = (bit)(write_data & 0x80);
    _nop_();
    SCL = 1;
    _nop_();
    _nop_();
    SCL = 0;
    write_data <<= 1;
    }
    SDA = 1;// 读取应答
    _nop_();
    _nop_();
    SCL = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    ack_bit = SDA;
    SCL = 0;
    return ack_bit;// 返回AT24Cxx应答位
    }
    void write_byte(unsigned char addr, unsigned char write_data)
    // 在指定地址addr处写入数据write_data
    {
    start();
    shout(OP_WRITE);
    shout(addr);
    shout(write_data);
    stop();
    delayms(10);// 写入周期
    }
    void fill_byte(unsigned char fill_data)
    // 填充数据fill_data到EEPROM内
    {
    unsigned char i;
    for(i = 0; i < MAX_ADDR; i++)
    {
    write_byte(i, fill_data);
    }
    }
    unsigned char read_current()
    // 在当前地址读取
    {
    unsigned char read_data;
    start();
    shout(OP_READ);
    read_data = shin();
    stop();
    return read_data;
    }
    unsigned char read_random(unsigned char random_addr)
    // 在指定地址读取
    {
    start();
    shout(OP_WRITE);
    shout(random_addr);
    return(read_current());
    }
    void delayms(unsigned char ms)
    // 延时子程序
    {
    unsigned char i;
    while(ms--)
    {
    for(i = 0; i < 120; i++);
    }
    }
    void adstart()//ADC0832开始子函数
    {
    //、说明ADC0832芯片资料。CS使能=1.禁止,CLK和D0/D1随意
    // 需要转换时,宣讲CS=0使能,并保持到数据传输完成
    //单片机向CLK输出脉冲,前3个脉冲为启动和通道控制,脉冲上升沿有效;第一个脉冲前
    //使D1=1,启动信号传输,在第二个和第三个脉冲前分贝输入两位数字选择通道,10=CH0,11=CH1
    adcs=1;   // ;一个转换周期开始
    adclk=0;
    adcs=0; // CS置0,片选有效
    addin=1; //;DI置1,起始位
      adclk=1;// 第一个脉冲
    //nop;
    addin=0;  // 在负跳变之前加一个DI反转操作
      adclk=0;
    addin=1; //DI置1,设为单通道
      adclk=1; // 第二个脉冲
       addin=0;
      adclk=0;
    addin=0;  //DI置0,选择通道0
      adclk=1; //第三个脉冲
      addin=1;
      adclk=0;
    nop;
        adclk=1;  //第四个脉冲

    }
      void adread()   //adc0832的数据读取子函数
      {
    //根据芯片说明:从第4和脉冲ADC0832开始输出数据
    //4-19个脉冲分别从高到低输出(D7--D0)然后公用最低位D0,从低到高再(D0--D7)输出一次
    uchar h;
    //uchar dat0;   //dat0读取12--19脉冲作为数据效验,这里不要
    addata=0;
    for(h=0;h<8;h++)
    {
    adclk=1;
    nop;
    nop;
    adclk=0;
    nop;
    addata<<=1;   //必须选为以后读取。否则最高位会丢失
    addata|=addin;    //addata值同addin口的值进行或运算后赋值给addata
    nop;
    }
    //如果不要效验,12-19脉冲可以不再使用和读取,所以下面8位的循环可以去掉,直接将CS使能值1
    //for(h=0;h<8;h++)
    //{
    //dat0|=addin;  //因为上一组8位的末位是和这8位共用D0数据,所以这里需要选读取再脉冲
      //dat0=_cror_(dat0,1);   //这里需要使用的——coror_()循环位移
      //nop;
      //adclk=1;
      //nop;
      nop;
      //adclk=0;
      //nop;
      //nop;
      //}
      adcs=1;
      }
    //void timer2(void) interrupt 4 using 1
    //{
      //adstart();
      //adread();
    //}
    //void int0()  interrupt 1   //采用中断0 控制节拍    
    //{  //TH1=0xd8;  
      // TL1=0xef;  
      // n--;  
    //}  
    void delay1 (unsigned char m)   //控制频率延时    
    {  
    unsigned i=3*m;  
    while(--i);  
    }  
      
    void delayms1(unsigned char a)  //豪秒延时子程序    
    {  
      while(--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!    
    }  
    上述程序中,单片机STC12C5A60S2串口只能接收到一个字节的16进制数,所以每次必须发送一个字节的16进制数,这样单片机才能接收。程序中的下面内容:
    if(RI)// 是否有数据到来
    {
    RI = 0;
    tmp = SBUF;// 暂存接收到的数据
    //tmp1=SBUF++;
    //  dis_code[i]=SBUF;
    // 数据传送到P0口
    // str[1]=SBUF;
       write_byte(0X00, tmp);
       //write_byte(0X01, tmp+4);
    write_byte(0X02, addata);
    //write_byte(0X00, str[1]);
    //write_byte(0X01, tmp1);
    P0 = read_random(0X00);// 循环读取24Cxx内容,并输出到P0口
    //P2=  read_random(0X02);
      // p1= read_random(0X00);
      //  p2= read_random(0X01);
    //delayms(250);
    send_char(tmp);// 回传接收到的数据
       send_char( addata);// 回传接收到的数据
    // send_str() ;
    }
    这段代码实现的内容是将串口接收的一个字节数据存储到24C04中的0X00寄存器中,并输出到单片机的P0端口,并赋值给p1,最后有将接收到的数据从串口发送出去。
      a: k=music_tab[s+tmp];  
           if(k==0x00)       { s=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍    
           else if(k==0xff)  { s=s+1;delayms(100),TR0=0; goto a;}  //若碰到休止符,延时100ms,继续取下一音符    
                else         {m=music_tab[s++], n=music_tab[s++];}  //取频率常数 和 节拍常数    
                 TR0=1;                                             //开定时器1    
               while(n!=0) Beep1=~Beep1,Beep2=~Beep2,Beep5=~Beep5,Beep8=~Beep8,Beep9=~Beep9,Beep10=~Beep10,Beep11=~Beep11,Beep12=~Beep12,Beep13=~Beep13,Beep16=~Beep16,Beep17=~Beep17,Beep18=~Beep18,Beep19=~Beep19,Beep20=~Beep20,Beep21=~Beep21,Beep22=~Beep22,Beep23=~Beep23,delay1(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)    
       TR0=0;                                           //关定时器1    
          b: k=music_tab1[s+tmp];  
           if(k==0x00)       { s=0, delayms(1000); goto play;}     //如果碰到结束符,延时1秒,回到开始再来一遍    
           else if(k==0xff)  { s=s+1;delayms(100),TR0=0; goto b;}  //若碰到休止符,延时100ms,继续取下一音符    
                else         {m=music_tab1[s++], n=music_tab1[s++];}  //取频率常数 和 节拍常数    
                 TR0=1;                                             //开定时器1    
               while(n!=0) Beep16=~Beep16,Beep17=~Beep17,Beep18=~Beep18,Beep19=~Beep19,Beep20=~Beep20,Beep21=~Beep21,Beep22=~Beep22,Beep23=~Beep23,delay1(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)  
       TR0=0;  
    这段代码实现的功能是将music_tab[s+tmp],music_tab1[s+tmp]数组赋值给端口P0,P3,P2,使它们产生频率,占空比时时可变的PWM方波。
    /*中断函数*/
    void timer0(void) interrupt 1 using 2
    {
    static uchar click=0;                  /*中断次数计数器变量*/
       adstart();
      adread();
    //TH0=V_TH0;                                    /*恢复定时器初始值*/
    //TL0=V_TL0;
        TH0=0xd8;  
       TL0=0xef;  
       n--;  
    //++click;
    //if (click>=100) click=0;
    //if (click<=ZKB1)      /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/
    // P1_0=0;
    //else
      //P1_0=1;
    //if (click<=ZKB2)                        
      //P1_1=0;
    //else
      //P1_1=1;
    //if (click<=ZKB3)      /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/
      //P1_2=0;
    //else
      //P1_2=1;
    }
    这段代码的功能是利用定时器TIME0产生PWM方波。
    /******************************************************
    *函数功能:对系统进行初始化,包括定时器初始化和变量初始化*/
    void init_sys(void)            /*系统初始化函数*/
    {
      /*定时器TIME0初始化*/
      //TMOD=V_TMOD;
      TH0=V_TH0;
      TL0=V_TL0;
      TR0=1;
      ET0=1;
      EA=1;
        /*定时器TIME1初始化*/
    TMOD = 0x20;// 定时器1工作于8位自动重载模式, 用于产生波特率
    TH1 = 0xFD;// 波特率9600
    TL1 = 0xFD;
    SCON = 0x50;// 设定串行口工作方式
    PCON &= 0xef;// 波特率不倍增
    TR1 = 1;// 启动定时器1
      //TR2=1;
    // ET2=1;
    //TMOD&=0x0f;  
      //TMOD|=0x01;  
    TH0=0xd8;
    TL0=0xef;  
      IE=0x82;
    //IE = 0x0;// 禁止任何中断
    //  TH2=V_TH2;
    // TL2=V_TL2;
    // TR2=1;
    // ET2=1;
      //EA=1;
    }

    这段代码的功能是利用初始化定时器TIME1,进行串口数据接收或发送。
    上述的一种具有17路PWM直流电机的串口遥控机器人,所述的是一种具有17路可调PWM直流电机的串口WIFI遥控机器人。

    附图说明
    下面结合附图和实施例对本实用新型进一步说明。
    图1为本实用电路图。
    图1中,1.USB接口,2.5V开关电源,3.PL2303HX芯片,4.12C5A60S2单片机,5.24C04芯片,6.ADC0832芯片,7.ULN2003D。

    具体实施方式
    图1中,单片机STC12C5A60S2(4)的P3.0,P3.1端口连接WIFI模块,单片机STC12C5A60S2(4)的P3.3,P3.4端口连接24C04(5)存储器。单片机STC12C5A60S2(4)的P3.7端口连接ADC0832芯片(6)。STC12C5A60S2(4)的P2中的P2.0,P2.1,P2.2,P2.3,P2.4,P2.5,P2.6连接电源驱动芯片ULN2003(7)。STC12C5A60S2(4)的P3中的P3.0,P3.1连接芯片PL2303HX。ULN2003(3)的15脚,16脚连接USB端口(1)。5V直流电源(1)连接单片机STC12C5A60S2(4)的20脚,40脚。STC12C5A60S2(4)的P1中的 P1.2, P1.3, P1.4, P1.5, P1.6,P1.7端口,P3 中的P3.2, P3.5, P3.6端口,P2中的P2.0,P2.1,P2.2,P2.3,P2.4,P2.5,P2.6,P2.7上面总共17路IO口,每个IO口连接一路直流电机。
    图1中,单片机STC12C5A60S2(4)经过芯片PL2302HX(3)从串口接收或发送数据到USB端口(1),单片机STC12C5A60S2(4)从24C04(5)中读取或写入数据。单片机STC12C5A60S2(4)将芯片ADC0832(6)采集的到的温度数据通过串口发送给操作人员的计算机。ULN2003芯片(7)保持单片机P1,P2,P3端口上输出的PWM信号的稳定。5V开关电源(2)通过开关给单片机(4)供电。STC11F60单片机(1)的P1中的P1.2, P1.3, P1.4, P1.5, P1.6,P1.7端口,P3 中的P3.2, P3.5, P3.6端口,P2中的P2.0,P2.1,P2.2,P2.3,P2.4,P2.5,P2.6,P2.7上面总共17路IO口,每个IO口产生一路PWM信号,并连接一路直流电机。


    图片



    发帖须知:

    1,发帖请遵守《计算机信息网络国际联网安全保护管理办法》、《互联网信息服务管理办法》、 《互联网电子公告服务管理规定》、《维护互联网安全的决定》等法律法规。

    2,请对您的言论负责,我们将保留您的上网记录和发帖信息。

    3,在此发帖表示认同我们的条款,我们有权利对您的言论进行审核、删除或者采取其他在法律、地方法规等条款规定之内的管理操作。
    内容:
    验证: 验证码,看不清楚?请点击刷新验证码 * 匿名发表需要进行验证!
     
           
    中国面包师贴吧-中国烘焙师贴吧- 弹性深蓝色可爱版右侧悬浮qq在线客服代码
    在线咨询 x
    有什么可以帮到您
    点击咨询
    -粤ICP备13040473号-2