用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();
}
}
|