51智能小车

用STC8A8K64A12S4单片机,智能小车主要是:电机控制部分、循迹、超声波避障、12864(并口)

采用类似arm的写法

.h文件

#ifndef __GPIO_H
#define __GPIO_H

#define PORT0 0
#define PORT1 1
#define PORT2 2
#define PORT3 3
#define PORT4 4
#define PORT5 5
#define PORT6 6
#define PORT7 7

#define PIN0 0
#define PIN1 1
#define PIN2 2
#define PIN3 3
#define PIN4 4
#define PIN5 5
#define PIN6 6
#define PIN7 7
#define PIN_ALL 8

#define PIN_MODE_STD 0x00 //准双向口
#define PIN_MODE_PP 0x01  //推挽输出
#define PIN_MODE_HR 0x02  //高阻输入
#define PIN_MODE_OD 0x03  //开漏输出
#define PIN_OUTPUT_HIGH 1
#define PIN_OUTPUT_LOW 0

void GPIO_DeInit();
void GPIO_Init(uint8_t PORT, uint8_t PIN, uint8_t MODE, uint8_t OUTPUT);

#endif

初始化管脚 

void GPIO_DeInit()
{
	//设置所有IO为高阻输入模式,进行初始化
	P0M0 = P1M0 = P2M0 = P3M0 = P4M0 = P5M0 = P6M0 = P7M0 = 0X00;
	P0M1 = P1M1 = P2M1 = P3M1 = P4M1 = P5M1 = P6M1 = P7M1 = 0XFF;
	P1 = P2 = P3 = P4 = P5 = P6 = P7 = 0X00;
}

void GPIO_Init(uint8_t PORT, uint8_t PIN, uint8_t MODE, uint8_t OUTPUT)
{
	uint8_t pinMode0 = 0, pinMode1 = 0, pinValue = 0;
	uint8_t PnM0 = 0X00, PnM1 = 0X00, Pn = 0X00;

	pinMode0 = (MODE & 0x01) >> 0;
	pinMode1 = (MODE & 0x02) >> 1;
	pinValue = OUTPUT;

	if (PIN == PIN_ALL)
	{
		PnM0 = pinMode0 == true ? 0xFF : 0x00;
		PnM1 = pinMode1 == true ? 0xFF : 0x00;
		Pn = pinValue == true ? 0xFF : 0x00;
	}
	else
	{
		switch (PORT)
		{
		case PORT0:
		{
			PnM0 = P0M0;
			PnM1 = P0M1;
			Pn = P0;
			break;
		}
		case PORT1:
		{
			PnM0 = P1M0;
			PnM1 = P1M1;
			Pn = P1;
			break;
		}
		case PORT2:
		{
			PnM0 = P2M0;
			PnM1 = P2M1;
			Pn = P2;
			break;
		}
		case PORT3:
		{
			PnM0 = P3M0;
			PnM1 = P3M1;
			Pn = P3;
			break;
		}
		case PORT4:
		{
			PnM0 = P4M0;
			PnM1 = P4M1;
			Pn = P4;
			break;
		}
		case PORT5:
		{
			PnM0 = P5M0;
			PnM1 = P5M1;
			Pn = P5;
			break;
		}
		case PORT6:
		{
			PnM0 = P6M0;
			PnM1 = P6M1;
			Pn = P6;
			break;
		}
		case PORT7:
		{
			PnM0 = P7M0;
			PnM1 = P7M1;
			Pn = P7;
			break;
		}
		}
		PnM0 = PnM0 & (~(0x01 << PIN));
		PnM0 = PnM0 | (pinMode0 << PIN);
		PnM1 = PnM1 & (~(0x01 << PIN));
		PnM1 = PnM1 | (pinMode1 << PIN);
		Pn = Pn & (~(0x01 << PIN));
		Pn = Pn | ((pinValue) << PIN);
	}

	switch (PORT)
	{
	case PORT0:
	{
		P0M0 = PnM0;
		P0M1 = PnM1;
		P0 = Pn;
		break;
	}
	case PORT1:
	{
		P1M0 = PnM0;
		P1M1 = PnM1;
		P1 = Pn;
		break;
	}
	case PORT2:
	{
		P2M0 = PnM0;
		P2M1 = PnM1;
		P2 = Pn;
		break;
	}
	case PORT3:
	{
		P3M0 = PnM0;
		P3M1 = PnM1;
		P3 = Pn;
		break;
	}
	case PORT4:
	{
		P4M0 = PnM0;
		P4M1 = PnM1;
		P4 = Pn;
		break;
	}
	case PORT5:
	{
		P5M0 = PnM0;
		P5M1 = PnM1;
		P5 = Pn;
		break;
	}
	case PORT6:
	{
		P6M0 = PnM0;
		P6M1 = PnM1;
		P6 = Pn;
		break;
	}
	case PORT7:
	{
		P7M0 = PnM0;
		P7M1 = PnM1;
		P7 = Pn;
		break;
	}
	}
}

main.c 

#include "user_config.h"
#include "gpio.h"
#include "12864.h"
#include "tank_drive.h"

void main()
{
  uint8_t i;                                                                //降压启动自增变量

  GPIO_DeInit();                                                            //GPIO初始化

  //serial 1
  GPIO_Init(PORT3, PIN0, PIN_MODE_STD, PIN_OUTPUT_HIGH);                    //等于P3M0=0X00
  GPIO_Init(PORT3, PIN1, PIN_MODE_STD, PIN_OUTPUT_HIGH);

  //serial 3
  GPIO_Init(PORT0, PIN0, PIN_MODE_STD, PIN_OUTPUT_HIGH);                    //蓝牙io口初始化
  GPIO_Init(PORT0, PIN1, PIN_MODE_STD, PIN_OUTPUT_HIGH);

  //12864
  GPIO_Init(PORT4, PIN4, PIN_MODE_PP, PIN_OUTPUT_LOW);                      //12864初始化管脚
  GPIO_Init(PORT4, PIN0, PIN_MODE_PP, PIN_OUTPUT_HIGH);
  GPIO_Init(PORT4, PIN1, PIN_MODE_PP, PIN_OUTPUT_HIGH);
  GPIO_Init(PORT4, PIN2, PIN_MODE_PP, PIN_OUTPUT_HIGH);
  GPIO_Init(PORT4, PIN3, PIN_MODE_PP, PIN_OUTPUT_HIGH);
  GPIO_Init(PORT2, PIN_ALL, PIN_MODE_PP, PIN_OUTPUT_LOW);

  //PWM
  GPIO_Init(PORT1, PIN0, PIN_MODE_PP, PIN_OUTPUT_LOW);                        //L298N两个EN端io口初始化
  GPIO_Init(PORT1, PIN1, PIN_MODE_PP, PIN_OUTPUT_LOW);

  //PWM signal
  GPIO_Init(PORT0, PIN2, PIN_MODE_PP, PIN_OUTPUT_LOW);                      //L298N四个IN端io口初始化
  GPIO_Init(PORT0, PIN3, PIN_MODE_PP, PIN_OUTPUT_HIGH);
  GPIO_Init(PORT0, PIN4, PIN_MODE_PP, PIN_OUTPUT_HIGH);
  GPIO_Init(PORT0, PIN5, PIN_MODE_PP, PIN_OUTPUT_LOW);

  // ultrasonic wave sensor
  GPIO_Init(PORT3, PIN2, PIN_MODE_HR, PIN_OUTPUT_LOW);                     //超声波传感器io口初始化
  GPIO_Init(PORT3, PIN3, PIN_MODE_PP, PIN_OUTPUT_LOW);

  //infrared sensor
  GPIO_Init(PORT1, PIN2, PIN_MODE_HR, PIN_OUTPUT_LOW);                      //红外io口初始化
  GPIO_Init(PORT1, PIN3, PIN_MODE_HR, PIN_OUTPUT_LOW);
  GPIO_Init(PORT1, PIN4, PIN_MODE_HR, PIN_OUTPUT_LOW);
  GPIO_Init(PORT1, PIN5, PIN_MODE_HR, PIN_OUTPUT_LOW);
  GPIO_Init(PORT1, PIN6, PIN_MODE_HR, PIN_OUTPUT_LOW);

  LCD12864_Init();                                                          //12864初始化
  LCD12864_DisplayChars(0, 3, "障碍距离");                                  //两行为12864显示函数的调用(在第3行的第0位显示"障碍距离")
  LCD12864_DisplayChars(14, 3, "mm");                                       //在第3行的第14位显示mm(毫米为测量单位)

  start();                                                                  //电机启动

  for (i = 2; i <= 4; i++)                                                  //for用来减压启动直流电机
  {
    Delay1ms(40);                                                           //减压启动延时40毫秒

    k[Motor_RF] = i << 4;                                                   //(右电机)减压启动为i*16倍
    k[Motor_LF] = i << 4;                                                   //(左电机)

    wide(Motor_RF, k[Motor_RF]);                                            //占空比调节(1通道,占空比)
    wide(Motor_LF, k[Motor_LF]);                                            //占空比调节(2通道,占空比)
  }

  forward();                                                                //电机启动

  status_UrtralSoundSensor = uSSS_Idle;                                     //超声波进入闲置状态

  while (true)                                                              //定义了true==1
  {
    tracking();                                                             //开启循迹
    LCD12864_DisplayChars(6, 0, _display);
    uSS_StateMachine(&status_UrtralSoundSensor, true);                      //超声波初始状态为闲置状态,状态为1
    Delay1ms(10);
    
    if (distance_i > 50 && distance_i < 3000)                               //有效工作范围:30mm到3000mm
    {
      sprintf(distance_c, "%4d", distance_i);                               //将距离显示出来
      LCD12864_DisplayChars(8, 3, distance_c);                              //在第3行第8位
    }
    else
    {
      LCD12864_DisplayChars(8, 3, "溢出");                                  //当不在有效工作范围显示"溢出"(第3行第8位)
    }
  }
}

/****************************************************
功能描述:当发射脉冲后进入外部中断等待回波,在外部中断里面
判断溢出或计算距离
入口值:无
返回值:无
*****************************************************/
void INT0_Isr() interrupt 0
{
  if (status_UrtralSoundSensor == uSSS_SendingOut)                          //判断当前状态是否为为发射完成,没有接收到返回波
  {
    Timer0InitCounter();                                                    //启动定时器测量返回波
    INT0_Init();                                                            //中断初始化
    status_UrtralSoundSensor = uSSS_WaitingBack;                            //状态机改为等待回波状态测量距离
  }
  else if (status_UrtralSoundSensor == uSSS_WaitingBack)                     //如果当前状态是否为等待回波状态
  {
    TR0 = 0;                                                                  //先关断定时器
    
    distance_H = TH0;
    distance_L = TL0;                                                        //然后把定时器的值赋给distance_L
    
    Timer0Deinit();                                                          //反初始化 
    INT0_Deinit();
    
    status_UrtralSoundSensor = uSSS_GotData;
  }
}

/*******************************
功能描述:定时器中断
入口值:无
返回值:无
*******************************/
void Timer0_Isr() interrupt 1
{
  TR0 = 0;                                                                  //关断定时器
  
  if (status_UrtralSoundSensor == uSSS_SendingOut)                          //判断当前状态是否为发射完成
  {
    trig = PIN_OUTPUT_LOW;                                                  //如果发射完成则拉低trig管脚等待回波
  }
  else if (status_UrtralSoundSensor == uSSS_WaitingBack)                    //如果当前状态为等待回波状态
  {
    status_UrtralSoundSensor = uSSS_Overtime;                               //如果为溢出状态则进行反初始化
    Timer0Deinit();
    INT0_Deinit();
  }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅哥的小迷弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值