#include<reg52.h>;
#include<math.h>;
#include<intrins.h>;
#defineucharunsignedchar;
#defineuintunsignedint;
ucharBuffer=0;//从串口接收的数据;uintURTAReceivedCount=0,;uchardataT
#include<reg52.h>
#include<math.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar Buffer =0; //从串口接收的数据
uint URTAReceivedCount=0,n=1;
uchar data Tempdatatable[5],CommandDatatable[5];//数据包
uchar serVal[2];
uint pwm[]={1120,1190,1382,1382,1382,1382,1382,1382}; //初始90度,(实际是1382.4,取整得1382)
uchar pwm_flag=0;
uint code ms0_5Con=461; //0.5ms计数 (实际是460.8,取整得461)
uint code ms2_5Con=2304; //2.5ms计数
bit key_stime_ok;
sbit StatusLight=P2^0; //状态灯
sbit MainLight=P2^1; //主大灯
sbit servo0=P0^0; //舵机控制
sbit servo1=P0^1;
sbit servo2=P0^2;
sbit servo3=P0^3;
sbit servo4=P0^4;
sbit servo5=P0^5;
sbit servo6=P0^6;
sbit servo7=P0^7;
//定义智能小车驱动模块输入IO
sbit IN1 = P1^0; // 高电平1 后退(反转)
sbit IN2 = P1^1; // 高电平1 前进(正转)
sbit IN3 = P1^2; // 高电平1 前进(正转)
sbit IN4 = P1^3; // 高电平1 后退(反转)
sbit EN1 = P1^4; // 高电平使能
sbit EN2 = P1^5; // 高电平使能
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/ void Delay_1ms(uint i)//1ms延时
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++);
}
void TurnOnStatusLight()
{
StatusLight=0;
}
/********************************************************************
* 名称 : Send_Data()
* 功能 : 向上位机传送字符
* 输入 : 无
* 输出 : 无
***********************************************************************/ void Send_Data(uchar type,uchar cmd,uchar dat)
{
uchar data Buffer[5];//构建数据包
uchar *p;
uint Send_Count=0;
p = Buffer;
Buffer[0]=0XFF;
Buffer[1]=type;
Buffer[2]=cmd;
Buffer[3]=dat;
Buffer[4]=0XFF;
while(1)
{
if(*p==0XFF)
{
Send_Count++; //0XFF标志统计位
}
SBUF = *p; //发送
while(!TI) //如果发送完毕,硬件会置位TI,等待发送完毕
{
_nop_();
}
p++;
TI = 0;
if(Send_Count == 2) //当统计到两次出现0XFF,则认为一个数据包发送完毕,跳出循环
{
TI = 0;
break;
}
}
}
/********************************************************************
协议规定:
包头 类型位 数据位 数据位 结束位
0XFF 0X** OX** 0X** 0XFF
各命令说明:
类型位 数据位 数据位 功能
0X00 0X02 0X00 前进
0X00 0X01 0X00 后退
0X00 0X03 0X00 左转
0X00 0X04 0X00 右转
0X00 0X00 0X00 停止
0X01 0X01 角度 舵机1
0X01 0X02 . 舵机2
0X01 0X01 . 舵机3
0X01 0X02 . 舵机4
0X01 0X01 . 舵机5
0X01 0X02 . 舵机6
0X01 0X01 . 舵机7
0X01 0X02 数据 舵机8
0X02 0X01 车灯亮
0X02 0X02 车灯灭
0X03 雷达数据 发送雷达数据
***********************************************************************/ /********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
***********************************************************************/ void Com_Int(void) interrupt 4
{
uchar temp;
ES=0; //关串口中断
RI=0; //软件清除接收中断
temp=SBUF;
if(temp==0XFF && URTAReceivedCount<3)
{
Tempdatatable[0]==0XFF; //包头
URTAReceivedCount++;
}
else
{
Tempdatatable[n]=temp;
n++;
if(URTAReceivedCount==0&&n==2)
n=1;
}
if(URTAReceivedCount==2)//包尾
{
Tempdatatable[0]=0XFF;
Tempdatatable[4]=0XFF;
n=1;
URTAReceivedCount=0; //组包完毕
temp="";
// Send_Data(Tempdatatable[1],Tempdatatable[2],Tempdatatable[3]); //发送组成的数据包回去
}
CommandDatatable[0]=Tempdatatable[0];
CommandDatatable[1]=Tempdatatable[1];
CommandDatatable[2]=Tempdatatable[2];
CommandDatatable[3]=Tempdatatable[3];
CommandDatatable[4]=Tempdatatable[4];
ES=1;//开串口中断
}
/********************************************************************
* 名称 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
***********************************************************************/ void Com_Init(void)
{
TMOD = 0x21;
PCON = 0x00;
SCON = 0x50;
TH1 = 0xFd; //设置波特率 9600
TL1 = 0xFd;
TR1 = 1; //启动定时器1
ES = 1; //开串口中断
EA = 1; //开总中断
IT0=0;
EX0=1;
}
/******************************************************************** * 名称 :Moto_Forward()
* 功能 : 电机1、2启动,都是前进,整车表现为前进。
***********************************************************************/ void Moto_Forward()
{
IN1=0; //左电机
IN2=1;
IN3=1; //右电机
IN4=0;
EN1=1;
EN2=1;
Delay_1ms(100);
}
/******************************************************************** * 名称 :Moto_Backward()
* 功能 : 电机1、2启动,都是后退,整车表现为后退。
***********************************************************************/ void Moto_Backward()
{
IN1=1; //左电机
IN2=0;
IN3=0; //右电机
IN4=1;
EN1=1;
EN2=1;
Delay_1ms(100);
}
/******************************************************************** * 名称 :Moto_TurnLeft()
* 功能 : 电机1后退,电机2前进,整车表现为左转。
***********************************************************************/ void Moto_TurnLeft()
{
IN1=0;//左电机;IN2=0;;IN3=1;//右电机;IN4=0;;EN1=1;;EN2=1;;Delay_1ms(100);;/***********************;*名称:Moto_TurnRight();*功能:电机1前进,电机2后退,整车表现为右转;************************;voidMoto_TurnRigh
IN1=0; //左电机
IN2=0;
IN3=1; //右电机
IN4=0;
EN1=1;
EN2=1;
Delay_1ms(100);
}
/********************************************************************
* 名称 :Moto_TurnRight()
* 功能 : 电机1前进,电机2后退,整车表现为右转。
***********************************************************************/
void Moto_TurnRight()
{
IN1=0; //左电机
IN2=1;
IN3=0; //右电机
IN4=0;
EN1=1;
EN2=1;
Delay_1ms(100);
}
/********************************************************************
* 名称 :Moto_Stop()
* 功能 : 电机1停止,电机2停止,整车表现为停止。
***********************************************************************/
void Moto_Stop()
{
IN1=0; //左电机
IN2=0;
IN3=0; //右电机
IN4=0;
EN1=1;
EN2=1;
Delay_1ms(100);
}
/********************************************************************
* 功能 : 舵机PWM中断初始化
***********************************************************************/
void Timer0Init()
{
/*0度=0.5ms, 45度=1ms, 90度=1.5ms, 135度=2ms, 180度=2.5ms
/.5 ms初始值 F700, (12n/11059200=2.5/1000, n=2304, X=65536-2304=63232 > F700)*/
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=-ms2_5Con>>8; //给定初值,17ms中断
TL0=-ms2_5Con;
EA=1; //总中断打开
ET0=1; //定时器0中断打开
TR0=1; //定时器0开关打开 }
/********************************************************************
* 功能 : 舵机PWM中断, //舵机控制函数 周期为20ms 一个循环20MS = 8*2.5ms ***********************************************************************/
void SteeringGear() interrupt 1
{
switch(pwm_flag)
{
case 1: servo0=1; TH0=-pwm[0]>>8; TL0=-pwm[0]; break;
case 2: servo0=0; TH0=-(ms2_5Con-pwm[0])>>8; TL0=-(ms2_5Con-pwm[0]); break; case 3: servo1=1; TH0=-pwm[1]>>8; TL0=-pwm[1]; break;
case 4: servo1=0; TH0=-(ms2_5Con-pwm[1])>>8; TL0=-(ms2_5Con-pwm[1]); break; case 5: servo2=1; TH0=-pwm[2]>>8; TL0=-pwm[2]; break;
case 6: servo2=0; TH0=-(ms2_5Con-pwm[2])>>8; TL0=-(ms2_5Con-pwm[2]); break; case 7: servo3=1; TH0=-pwm[3]>>8; TL0=-pwm[3]; break;
case 8: servo3=0; TH0=-(ms2_5Con-pwm[3])>>8; TL0=-(ms2_5Con-pwm[3]); break; case 9: servo4=1; TH0=-pwm[4]>>8; TL0=-pwm[4]; break;
case 10: servo4=0; TH0=-(ms2_5Con-pwm[4])>>8; TL0=-(ms2_5Con-pwm[4]); break; case 11: servo5=1; TH0=-pwm[5]>>8; TL0=-pwm[5]; break;
case 12: servo5=0; TH0=-(ms2_5Con-pwm[5])>>8; TL0=-(ms2_5Con-pwm[5]); break; case 13: servo6=1;TH0=-pwm[6]>>8; TL0=-pwm[6]; break;
case 14: servo6=0;TH0=-(ms2_5Con-pwm[6])>>8; TL0=-(ms2_5Con-pwm[6]); break; case 15: servo7=1;TH0=-pwm[7]>>8; TL0=-pwm[7]; break;
case 16: servo7=0;TH0=-(ms2_5Con-pwm[7])>>8; TL0=-(ms2_5Con-pwm[7]); break; default: TH0=0xff; TL0=0x80; pwm_flag=0;
}
pwm_flag++;
}
void SetSteeringGear(uchar i, uchar val)
{
uint a = (val+46)*10;
if(a<ms0_5Con)
a=ms0_5Con;
if(a>ms2_5Con)
a=ms2_5Con;
pwm[i]=a;
CommandDatatable[2]=0xff; //清除缓存
}
/******************************************************************** * 功能 : 串口中断接收数据
***********************************************************************/
/*********************************************************************************
** 函数功能 : 主函数
*********************************************************************************/
void main()
{
MainLight=0;
Delay_1ms(200);
Com_Init();//串口初始化
Timer0Init();//舵机PWM中断初始化
while(1)
{
if(CommandDatatable[0]==0XFF && CommandDatatable[4]==0XFF)
{
switch (CommandDatatable[1]) //根据键值不同,执行不同的内容 {
case 0X00: //类型位0X00,表明是控制数据包,进入控制数据case
switch(CommandDatatable[2]) //根据数据位的值来进行选择执行不同的动作
{
case 0X00:Moto_Stop();break;
case 0X01:Moto_Forward();break;
case 0X02:Moto_Backward();break;
case 0X03:Moto_TurnLeft();break;
case 0X04:Moto_TurnRight();break;
default : break;
}
break;
case 0X01: //类型位0X01,表明是舵机数据包,进入舵机case switch(CommandDatatable[2])
{
case 0x01:SetSteeringGear(0,CommandDatatable[3]);break;
case 0x02:SetSteeringGear(1,CommandDatatable[3]);break; case 0x03:SetSteeringGear(2,CommandDatatable[3]);break; case 0x04:SetSteeringGear(3,CommandDatatable[3]);break;
case 0x05:SetSteeringGear(4,CommandDatatable[3]);break; case 0x06:SetSteeringGear(5,CommandDatatable[3]);break; case 0x07:SetSteeringGear(6,CommandDatatable[3]);break;
case 0x08:SetSteeringGear(7,CommandDatatable[3]);break; default : break;
}
}
}
} break; case 0X02: //类型位0X02,表明是大灯数据包,进入大灯case switch(CommandDatatable[2]) { case 0X01:MainLight=1;break; case 0X02:MainLight=0;break; default : break; } break default : break; }
|