.
  • 作者:city7cc
  • 积分:4065
  • 等级:专家教授
  • 2022/6/11 9:41:01
  • 中国面包师贴吧-楼主(阅:2412/回: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

    链接:https://pan.baidu.com/s/19ILdGWllusCQG74J93ZZkw ;

    提取码:5b25

    链接: https://pan.baidu.com/s/1xAZzwzAHQSPZ6OUJjYV3Mw?pwd=rwdk 提取码: rwdk 复制这段内容后打开百度网盘手机App,操作更方便哦

    下载。微云文件分享:20PWM机器人下载地址:

    https://share.weiyun.com/5rR1CYe

    单片机STC12C5A60S2(4)的控制程序是在keill4编译环境下,通过C语言编译并通过串口下载到单片机STC12C5A60S2(4)。程序代码如下:

    /******************************************************************************

    *程序思路说明: *

    *关于频率和占空比的确定,对于12M晶振,假定PWM输出频率为1KHZ,这样定时中断次数 *

    设定为C=10,即0.01MS中断一次,则TH0=FF,TL0=F6;由于设定中断时间为0.01ms,这样可以设定占空比

    可从1-100变化。即0.01ms100=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(k0x00) { s=0, delayms(1000); goto play;} //如果碰到结束符,延时1秒,回到开始再来一遍

    else if(k0xff) { 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;// 第一个脉冲

    /p;

    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_()循环位移

    /p;

    //adclk=1;

    /p;

    nop;

    //adclk=0;

    /p;

    /p;

    //}

    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(k0x00) { s=0, delayms(1000); goto play;} //如果碰到结束符,延时1秒,回到开始再来一遍

    else if(k0xff) { 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(k0x00) { s=0, delayms(1000); goto play;} //如果碰到结束符,延时1秒,回到开始再来一遍

    else if(k0xff) { 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信号,并连接一路直流电机。

    ————————————————

    版权声明:本文为CSDN博主「中国数学和矩阵研究员」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/zhangluan2019/article/details/120798137



    发帖须知:

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

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

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