![]() |
中国面包师贴吧-楼主(阅:3182/回:0)12路PWM直流电机的串口遥控机器人技术领域一种具有12路PWM直流电机的串口遥控机器人 本实用新型涉及一种一种具有12路PWM直流电机的串口遥控机器人,尤其是一种可以用串口无线WIFI遥控的智能机器人。 背景技术 现有常规遥控机人按照无线电信号的遥控进行动作,也可以按照存储在寄存器里面的程序动作,但是动作电机较少,一般只有4路PWM直流电机,这对机器人的行动带来很大的不便。一种具有12路PWM直流电机的串口遥控机器人是一种具有12路PWM直流电机的机器人,操作者可以使用计算机串口WIFI信号对它的12路直流电机进行遥控,它也可以按照其控制电路中的24C04铁电存储器里面的数据,在STC11F60单片机的控制下进行动作。 实用新型内容 为了解决常规遥控机器人动作电机较少的缺点,一种具有12路PWM直流电机的串口遥控机器人提供了一种具有12路PWM直流电机进行串口WIFI信号遥控动作的机器人。它可以按照电路中的24C04铁电存储器里面的数据,在STC11F60单片机的控制下进行动作,也可以按照操作人员计算机串口WIFI信号的遥控进行动作。由于它具有12路PWM直流电机,所以它可以进行行走,抬手,伸手等多种动作。 本实用新型解决其技术问题所采用的技术方案是:一种具有12路PWM直流电机的串口遥控机器人是一种可以被WIFI串口信号遥控的机器人。它依靠外壳下面装配的12路PWN直流电机在操作人员的计算机串口WIFI信号的遥控下进行的转动进行各种动作,它可以在电机的转动下进行移动,行走,抬手等等动作。同时,它也可以按照控制电路中的24C04铁电存储器里面的数据,在STC11F60单片机(1)的控制下进行电机的转动等动作。它的控制电路如图1所示。在图1中,STC11F60单片机(1)的P1中的P1.0, P1.1, P1.2, P1.3, P1.4, P1.5, P1.6,P1.7端口,P3 中的P3.2, P3.5, P3.6, P3.7端口在定时器TIME0产生12路PWM方波,上面总共12路IO口,每个IO口产生一路PWM信号,总共12路PWM控制方波信号。WIFI模块(2)连接在单片机STC11F60(1)的串口上面,它接收操作人员发出的数据,然后单片机STC11F60 (1)按照程序减少或增加PWM方波的占空比。同时单片机(1)按照铁电存储器24C04(3)中的数据控制上面的PWM方波信号。微云文件分享:12PWM机器人下载地址: https://share.weiyun.com/51DCGVd:-|^|-:https://share.weiyun.com/51DCGVd:-|^|-: 单片机STC11F60的控制程序是在keill4编译环境下,通过C语言编译并通过串口下载到单片机STC11F60。程序代码如下: /****************************************************************************** *程序思路说明: * * * *关于频率和占空比的确定,对于12M晶振,假定PWM输出频率为1KHZ,这样定时中断次数 * *设定为C=10,即0.01MS中断一次,则TH0=FF,TL0=F6;由于设定中断时间为0.01ms,这样可以设定占空比 可从1-100变化。即0.01ms*100=1ms * ******************************************************************************/ #include <regx51.h> #include <INTRINS.H> #define uchar unsigned char #include <intrins.h> #define OP_READ 0xa1 // 器件地址以及读取操作 #define OP_WRITE 0xa0 // 器件地址以及写入操作 #define MAX_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 unsigned char code dis_code[] = {0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff}; // 写入到AT24C01的数据串 sbit SDA = P3^4; sbit SCL = P3^3; 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); 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(); bit scan_key(); void proc_key(); void delayms(unsigned char ms); void send_char(unsigned char txd); unsigned char i; unsigned char p; unsigned char p1=0x00,p2,p3,p4; void main (void) { init_sys(); ZKB1=40; /*占空比初始值设定*/ ZKB2=70; /*占空比初始值设定*/ ZKB3=20; /*占空比初始值设定*/ ZKB4=70; /*占空比初始值设定*/ ZKB5=30; /*占空比初始值设定*/ ZKB6=70; /*占空比初始值设定*/ ZKB7=80; /*占空比初始值设定*/ ZKB8=70; /*占空比初始值设定*/ ZKB9=50; /*占空比初始值设定*/ ZKB10=70; /*占空比初始值设定*/ ZKB11=40; /*占空比初始值设定*/ ZKB12=40; /*占空比初始值设定*/ ZKB13=40; /*占空比初始值设定*/ ZKB14=70; /*占空比初始值设定*/ ZKB15=60; /*占空比初始值设定*/ ZKB16=70; /*占空比初始值设定*/ ZKB17=40; /*占空比初始值设定*/ ZKB18=70; /*占空比初始值设定*/ ZKB19=20; /*占空比初始值设定*/ ZKB20=70; /*占空比初始值设定*/ ZKB21=30; /*占空比初始值设定*/ ZKB22=70; /*占空比初始值设定*/ ZKB23=80; /*占空比初始值设定*/ ZKB24=70; /*占空比初始值设定*/ ZKB25=50; /*占空比初始值设定*/ ZKB26=70; /*占空比初始值设定*/ ZKB27=40; /*占空比初始值设定*/ ZKB28=40; /*占空比初始值设定*/ ZKB29=40; /*占空比初始值设定*/ ZKB30=70; /*占空比初始值设定*/ ZKB31=60; /*占空比初始值设定*/ ZKB32=70; /*占空比初始值设定*/ SDA = 1; SCL = 1; // fill_byte(0x00); // 全部填充0xff while(1) { if(RI) // 是否有数据到来 { RI = 0; tmp = SBUF; // 暂存接收到的数据 // tmp1=SBUF++; // dis_code[i]=SBUF; // 数据传送到P0口 // str[1]=SBUF; write_byte(0X00, tmp); // write_byte(0X00, str[1]); // write_byte(0X01, tmp1); P0 = read_random(0X00); // 循环读取24Cxx内容,并输出到P0口 // P2= read_random(0X01); p1= read_random(0X00); // p2= read_random(0X01); //delayms(250); send_char(tmp); // 回传接收到的数据 // send_str() ; } 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 (!P0_1) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_1) { ZKB1++; // ZKB1=20; } } if (!P0_2) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_2) { ZKB2--; // ZKB1=90; } } if (!P0_3) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_3) { ZKB2++; // ZKB1=20; } } if (!P0_4) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_4) { ZKB3--; // ZKB1=90; } } if (!P0_5) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_5) { ZKB3++; // ZKB1=20; } } if (!P0_6) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_6) { ZKB4--; // ZKB1=90; } } if (!P0_7) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_7) { ZKB4++; // ZKB1=20; } } if (!P2_0) //如果按了+键,增加占空比 { Delay5Ms(); if (!P2_0) { ZKB5--; // ZKB1=90; } } if (!P2_1) //如果按了+键,增加占空比 { Delay5Ms(); if (!P2_1) { ZKB5++; // ZKB1=20; } } // if (!SBUF) //如果按了-键,减少占空比 // { // Delay5Ms(); // if (SBUF=0x02) // { // ZKB1--; // } // } /*对占空比值限定范围*/ //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 // 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; /*中断次数计数器变量*/ TH0=V_TH0; /*恢复定时器初始值*/ TL0=V_TL0; ++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; if (click<=ZKB4) P1_3=0; else P1_3=1; if (click<=ZKB5) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ P1_4=0; else P1_4=1; if (click<=ZKB6) P1_5=0; else P1_5=1; if (click<=ZKB7) /*当小于占空比值时输出低电平,高于时是高电平,从而实 现占空比的调整*/ P1_6=0; else P1_6=1; if (click<=ZKB8) P1_7=0; else P1_7=1; // if (click<=ZKB9) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ //P2_0=0; //else // P2_0=1; //if (click<=ZKB10) //P2_1=0; //else //P2_1=1; //if (click<=ZKB11) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ // P2_2=0; //else // P2_2=1; //if (click<=ZKB12) //P2_3=0; //else //P2_3=1; // if (click<=ZKB13) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ //P2_4=0; //else // P2_4=1; //if (click<=ZKB14) // P2_5=0; //else //P2_5=1; //if (click<=ZKB15) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ // P2_6=0; //else //P2_6=1; //if (click<=ZKB16) //P2_7=0; //else // P2_7=1; //if (click<=ZKB17) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ // P3_0=0; //else //P3_0=1; //if (click<=ZKB18) // P3_1=0; //else //P3_1=1; if (click<=ZKB19) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空 比的调整*/ P3_2=0; else P3_2=1; //if (click<=ZKB20) //P3_3=0; //else //P3_3=1; // if (click<=ZKB21) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ // P3_4=0; //else // P3_4=1; if (click<=ZKB22) P3_5=0; else P3_5=1; if (click<=ZKB23) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ P3_6=0; else P3_6=1; if (click<=ZKB24) P3_7=0; else P3_7=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++); } } 上述程序中,单片机STC11F60串口只能接收到一个字节的16进制数,所以每次必须发送一个字节的16进制数,这样单片机才能接收。程序中的下面内容: if(RI) // 是否有数据到来 { RI = 0; tmp = SBUF; // 暂存接收到的数据 // tmp1=SBUF++; // dis_code[i]=SBUF; // 数据传送到P0口 // str[1]=SBUF; write_byte(0X00, tmp); // write_byte(0X00, str[1]); // write_byte(0X01, tmp1); P0 = read_random(0X00); // 循环读取24Cxx内容,并输出到P0口 // P2= read_random(0X01); p1= read_random(0X00); // p2= read_random(0X01); //delayms(250); send_char(tmp); // 回传接收到的数据 // send_str() ; } 这段代码实现的内容是将串口接收的一个字节数据存储到24C04中的0X00寄存器中,并输出到单片机的P0端口,并赋值给p1,最后有将接收到的数据从串口发送出去。 tmp1 = str[i]; write_byte(0X01, tmp1); i++; // 下一个字符 P2 = read_random(0X01); // 循环读取24Cxx内容,并输出到P0口 这段代码实现的功能是将str[i]数组赋值给tmp1,并写入到24C04的0X01寄存器中,并输出到单片机的P2端口。 if (!P0_0) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_0) { ZKB1--; // ZKB1=90; } } if (!P0_1) //如果按了+键,增加占空比 { Delay5Ms(); if (!P0_1) { ZKB1++; // ZKB1=20; } } 这段代码实现的功能是将P1_0端口的PWM方波的占空比减小或增大。 void timer0(void) interrupt 1 using 2 { static uchar click=0; /*中断次数计数器变量*/ TH0=V_TH0; /*恢复定时器初始值*/ TL0=V_TL0; ++click; if (click>=100) click=0; if (click<=ZKB1) /*当小于占空比值时输出低电平,高于时是高电平,从而实现占空比的调整*/ P1_0=0; else P1_0=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 // IE = 0x0; // 禁止任何中断 // TH2=V_TH2; // TL2=V_TL2; // TR2=1; // ET2=1; //EA=1; } 这段代码的功能是利用初始化定时器TIME1,进行串口数据接收或发送。 上述的一种具有12路PWM直流电机的串口遥控机器人,所述的是一种具有12路PWM直流电机的串口WIFI遥控机器人。 附图说明 下面结合附图和实施例对本实用新型进一步说明。 图1为本实用电路图。 图1中,1.单片机STC11F60,2. WIFI模块,3.24C04存储器,4.12路PWM直流电机。 具体实施方式 图1中,单片机STC11F60(1)的P3.0,P3.1端口连接WIFI模块,单片机STC11F60(1)的P3.4,P3.4端口连接24C04存储器。STC11F60单片机(1)的P1中的P1.0, P1.1, P1.2, P1.3, P1.4, P1.5, P1.6,P1.7端口,P3 中的P3.2, P3.5, P3.6, P3.7端口,上面总共12路IO口,每个IO口连接一路直流电机。 图1中,单片机STC11F60(1)从串口接收或发送数据到WIFI模块(2),单片机STC11F60从24C04中读取或写入数据。STC11F60单片机(1)的P1中的P1.0, P1.1, P1.2, P1.3, P1.4, P1.5, P1.6, P1.7端口,P3 中的P3.2, P3.5, P3.6, P3.7端口,上面总共12路IO口,每个IO口产生一路PWM信号,并连接一路直流电机。 图1 |
| 发帖须知: 1,发帖请遵守《计算机信息网络国际联网安全保护管理办法》、《互联网信息服务管理办法》、 《互联网电子公告服务管理规定》、《维护互联网安全的决定》等法律法规。 2,请对您的言论负责,我们将保留您的上网记录和发帖信息。 3,在此发帖表示认同我们的条款,我们有权利对您的言论进行审核、删除或者采取其他在法律、地方法规等条款规定之内的管理操作。 |