这是我在大一上学期做的一个通过蓝牙遥控 控制车前两个舵机搬运物体的小车程序。
使用L298N电机驱动
#include <STC8.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uint x,y,z;
sbit PA1=P1^5; //定义左舵机PWM输出的IO口
sbit PA2=P1^6; //定义右舵机PWM输出的IO口
#define SYSMCLK 27000000
/*电机驱动IO定义*/
sbit IN1 = P1^0; //为1 左电机反转
sbit IN2 = P1^1; //为1 左电机正转
sbit IN3 = P1^2; //为1 右电机正转
sbit IN4 = P1^3; //为1 右电机反转
unsigned int time=0;
int pwm=1;
#define left_motor_en EN1 = 1 //左电机使能
#define left_motor_stops EN1 = 0 //左电机停止
#define right_motor_en EN2 = 1 //右电机使能
#define right_motor_stops EN2 = 0 //右电机停止
#define left_motor_back IN1 = 0, IN2 = 1//左电机反转
#define left_motor_go IN1 = 1, IN2 = 0//左电机正转
#define right_motor_back IN3 = 1, IN4 = 0//右电机反转
#define right_motor_go IN3 = 0, IN4 = 1//右电机正转
//int Sensor_PwmL = 20,Sensor_PwmR=22;//舵机控制 关闭位置
int Sensor_PwmL = 22,Sensor_PwmR=20;//舵机控制 张开位置
typedef unsigned char uint8; // 8 bits
typedef unsigned int uint16; // 16 bits
void OSCInit(void)//使能外部晶振
{
P_SW2 = 0x80;
XOSCCR = 0xC0;
while (!(XOSCCR & 1));
CLKDIV = 0x00;
CKSEL = 0x01;
P_SW2 = 0x00;
}
void UartInit(void) //115200bps@24.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xCC; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES=1;
}
void PWMInit() //增强型pwm初始化(STC增强版8051单片机片上外设)
{
P_SW2 = 0x80;
PWMCKS = 0x00; // PWM时钟为系统时钟
PWMC = (SYSMCLK/30000); //设置PWM周期(30000Hz@27Mhz)
PWM0T1= 0;
PWM0T2= 0;
PWM0CR= 0x80; //使能PWM0输出(P20)
PWM3T1= 0;
PWM3T2= 0;
PWM3CR= 0x80; //使能PWM3输出(P23)
P_SW2 = 0x00;
PWMCR = 0x80; //启动PWM模块
P2M0 = 0X02;
}
void PWM0Set(uint16 Val) //PWM0占空比赋值
{
P_SW2 = 0x80;
PWM0T2= (uint16)(900-Val); //PWM计数器计数到PWM0T2翻转为低电平
P_SW2 = 0x00;
}
void PWM3Set(uint16 Val) //PWM3占空比赋值
{
P_SW2 = 0x80;
PWM3T2= (uint16)(900-Val); //PWM计数器计数到PWM3T2翻转为低电平
P_SW2 = 0x00;
}
void Timer0Init(void) //100微秒@24.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xA0; //设置定时初值
TH0 = 0xF6; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}
//小车前进
void forward()
{
PWM0Set(800);
PWM3Set(800);
left_motor_go; //左电机前进
right_motor_go; //右电机前进
}
void left_go() //左转
{
PWM0Set(325);
PWM3Set(750);
left_motor_back;
right_motor_go;
delay(1000);
forward();
}
//右转
void right_go()
{
PWM0Set(700);
PWM3Set(325);
delay(50);
right_motor_back;
left_motor_go;
delay(1000);
forward();
}
//小车后退
void back()
{
PWM0Set(800);
PWM3Set(800);
left_motor_back;
right_motor_back;
}
void left_left()//左转转
{
PWM0Set(500);
PWM3Set(700);
left_motor_back;
right_motor_go;
}
void right_right()//右转转
{
PWM0Set(700);
PWM3Set(500);
left_motor_go;
right_motor_back;
}
//小车停止
void stop()
{
PWM0Set(0);
PWM3Set(0);
}
void TM0_Isr() interrupt 1
{
static int time;
time++;
if(time>200)
time=0;
if(time<Sensor_PwmL)
PA1=1;
else
PA1=0;
if(time<Sensor_PwmR)
PA2=1;
else
PA2=0;
}
//串口中断
void UART_SER() interrupt 4
{
if(RI)
{
RI = 0;//清除接收标志
switch(SBUF)
{
case 0x0f: forward(); break;//前进
case 0xfe: back(); break;//后退
case 0xff: stop(); break;//停止
case 0xaf: left_go(); break;//左转
case 0xa0: right_go(); break;//右转
case 0xa1: Sensor_PwmL = 22,Sensor_PwmR=20; break;//臂张开
case 0xa2: Sensor_PwmL = 20,Sensor_PwmR=22; break;//臂关闭
case 0xa5: left_left(); break;//左转转
case 0xa6: right_right(); break;//右转转
}
}
}
void main()
{
UartInit(); //串口初始化
Timer0Init();
PWMInit();//增强型PWM初始化
ET0=1;
EA=1;
while(1)
{
}
}
?当时写的很水 但是基本思路就是 等待串口发送的数据 然后进去中断判定接下来的指令 PWM控制电机与舵机
|