首页 > 其他分享 >基于51单片机的蓝牙循迹小车 代码方案分享

基于51单片机的蓝牙循迹小车 代码方案分享

时间:2024-11-09 22:45:52浏览次数:5  
标签:------------------------------------------------ 定时器 循迹 sfr 51 Timer 单片机 sbit de

一、硬件

        包括:

                STC89C52RC 单片机

                sg90舵机(阿克曼转向)

                TCRT5000红外模块(黑白线检测)

                小车用电机x2(使用L298N电机驱动板驱动)

                HC-06蓝牙模块

                L2596M降稳压模块

        各硬件之间的连接非常简单,无非就是信号线连IO口,正极连正极负极连负极,在此不作描述。(可以参考其他教程的连线,最后修改自己的IO口定义就好了)

二、代码结构

        为每个部件都写了单独的头文件,具体如下:

        主函数

        basic部分的头文件是基础头文件,包括寄存器定义(regx52.h)延时(其实整个程序基本没用到, delay.h),定时器(timer.h)

        functional部分则是每个部件的头文件,包括舵机(servo.h)电机(motor.h)红外循迹(ir.h)以及蓝牙(bluetooth.h)

        主函数内只有每个部件的初始化函数和蓝牙/循迹函数的循环。

//basic
#include <regx52.h>
#include <delay.h>
#include <timer.h>

//functional
#include <servo.h>
#include <motor.h>
#include <ir.h>
#include <bluetooth.h>

void main() {
    motorInit();
    servoInit();
    bluetoothInit();
    while (1) {
        if (mode == 0) {
            ES = 0;				    //关闭蓝牙中断
            detectLine();
            ES = 1;				    //重新打开蓝牙中断
        } else if (mode == 1) {
            ES = 1;				    //打开蓝牙中断
        }
    }
}

        头文件

        如之前所说,共有7个头文件(虽多,但是能使之后的更新和维护变得简单)。

        头文件之间的关系如下图所示:

        (等一下。。。。等我拿到平板就传上来)

        下面依次附上代码和注释:

        (1)寄存器定义(regx52.h)

                对原始的REGX52头文件做了少许修改,如把P0^1改为P01,这样更符合我的习惯

#ifndef __AT89X52_H__
#define __AT89X52_H__

/*------------------------------------------------
Byte Registers
------------------------------------------------*/
sfr P0      = 0x80;
sfr SP      = 0x81;
sfr DPL     = 0x82;
sfr DPH     = 0x83;
sfr PCON    = 0x87;
sfr TCON    = 0x88;
sfr TMOD    = 0x89;
sfr TL0     = 0x8A;
sfr TL1     = 0x8B;
sfr TH0     = 0x8C;
sfr TH1     = 0x8D;
sfr P1      = 0x90;
sfr SCON    = 0x98;
sfr SBUF    = 0x99;
sfr P2      = 0xA0;
sfr IE      = 0xA8;
sfr P3      = 0xB0;
sfr IP      = 0xB8;
sfr T2CON   = 0xC8;
sfr T2MOD   = 0xC9;
sfr RCAP2L  = 0xCA;
sfr RCAP2H  = 0xCB;
sfr TL2     = 0xCC;
sfr TH2     = 0xCD;
sfr PSW     = 0xD0;
sfr ACC     = 0xE0;
sfr B       = 0xF0;

/*------------------------------------------------
P0 Bit Registers
------------------------------------------------*/
sbit P00 = 0x80;
sbit P01 = 0x81;
sbit P02 = 0x82;
sbit P03 = 0x83;
sbit P04 = 0x84;
sbit P05 = 0x85;
sbit P06 = 0x86;
sbit P07 = 0x87;

/*------------------------------------------------
PCON Bit Values
------------------------------------------------*/
#define IDL_    0x01

#define STOP_   0x02
#define PD_     0x02    /* Alternate definition */

#define GF0_    0x04
#define GF1_    0x08
#define SMOD_   0x80

/*------------------------------------------------
TCON Bit Registers
------------------------------------------------*/
sbit IT0  = 0x88;
sbit IE0  = 0x89;
sbit IT1  = 0x8A;
sbit IE1  = 0x8B;
sbit TR0  = 0x8C;
sbit TF0  = 0x8D;
sbit TR1  = 0x8E;
sbit TF1  = 0x8F;

/*------------------------------------------------
TMOD Bit Values
------------------------------------------------*/
#define T0_M0_   0x01
#define T0_M1_   0x02
#define T0_CT_   0x04
#define T0_GATE_ 0x08
#define T1_M0_   0x10
#define T1_M1_   0x20
#define T1_CT_   0x40
#define T1_GATE_ 0x80

#define T1_MASK_ 0xF0
#define T0_MASK_ 0x0F

/*------------------------------------------------
P1 Bit Registers
------------------------------------------------*/
sbit P10 = 0x90;
sbit P11 = 0x91;
sbit P12 = 0x92;
sbit P13 = 0x93;
sbit P14 = 0x94;
sbit P15 = 0x95;
sbit P16 = 0x96;
sbit P17 = 0x97;

sbit T2   = 0x90;       /* External input to Timer/Counter 2, clock out */
sbit T2EX = 0x91;       /* Timer/Counter 2 capture/reload trigger & dir ctl */

/*------------------------------------------------
SCON Bit Registers
------------------------------------------------*/
sbit RI   = 0x98;
sbit TI   = 0x99;
sbit RB8  = 0x9A;
sbit TB8  = 0x9B;
sbit REN  = 0x9C;
sbit SM2  = 0x9D;
sbit SM1  = 0x9E;
sbit SM0  = 0x9F;

/*------------------------------------------------
P2 Bit Registers
------------------------------------------------*/
sbit P20 = 0xA0;
sbit P21 = 0xA1;
sbit P22 = 0xA2;
sbit P23 = 0xA3;
sbit P24 = 0xA4;
sbit P25 = 0xA5;
sbit P26 = 0xA6;
sbit P27 = 0xA7;

/*------------------------------------------------
IE Bit Registers
------------------------------------------------*/
sbit EX0  = 0xA8;       /* 1=Enable External interrupt 0 */
sbit ET0  = 0xA9;       /* 1=Enable Timer 0 interrupt */
sbit EX1  = 0xAA;       /* 1=Enable External interrupt 1 */
sbit ET1  = 0xAB;       /* 1=Enable Timer 1 interrupt */
sbit ES   = 0xAC;       /* 1=Enable Serial port interrupt */
sbit ET2  = 0xAD;       /* 1=Enable Timer 2 interrupt */

sbit EA   = 0xAF;       /* 0=Disable all interrupts */

/*------------------------------------------------
P3 Bit Registers (Mnemonics & Ports)
------------------------------------------------*/
sbit P30 = 0xB0;
sbit P31 = 0xB1;
sbit P32 = 0xB2;
sbit P33 = 0xB3;
sbit P34 = 0xB4;
sbit P35 = 0xB5;
sbit P36 = 0xB6;
sbit P37 = 0xB7;

sbit RXD  = 0xB0;       /* Serial data input */
sbit TXD  = 0xB1;       /* Serial data output */
sbit INT0 = 0xB2;       /* External interrupt 0 */
sbit INT1 = 0xB3;       /* External interrupt 1 */
sbit T0   = 0xB4;       /* Timer 0 external input */
sbit T1   = 0xB5;       /* Timer 1 external input */
sbit WR   = 0xB6;       /* External data memory write strobe */
sbit RD   = 0xB7;       /* External data memory read strobe */

/*------------------------------------------------
IP Bit Registers
------------------------------------------------*/
sbit PX0  = 0xB8;
sbit PT0  = 0xB9;
sbit PX1  = 0xBA;
sbit PT1  = 0xBB;
sbit PS   = 0xBC;
sbit PT2  = 0xBD;

/*------------------------------------------------
T2CON Bit Registers
------------------------------------------------*/
sbit CP_RL2= 0xC8;      /* 0=Reload, 1=Capture select */
sbit C_T2 = 0xC9;       /* 0=Timer, 1=Counter */
sbit TR2  = 0xCA;       /* 0=Stop timer, 1=Start timer */
sbit EXEN2= 0xCB;       /* Timer 2 external enable */
sbit TCLK = 0xCC;       /* 0=Serial clock uses Timer 1 overflow, 1=Timer 2 */
sbit RCLK = 0xCD;       /* 0=Serial clock uses Timer 1 overflow, 1=Timer 2 */
sbit EXF2 = 0xCE;       /* Timer 2 external flag */
sbit TF2  = 0xCF;       /* Timer 2 overflow flag */

/*------------------------------------------------
T2MOD Bit Values
------------------------------------------------*/
#define DCEN_   0x01    /* 1=Timer 2 can be configured as up/down counter */
#define T2OE_   0x02    /* Timer 2 output enable */

/*------------------------------------------------
PSW Bit Registers
------------------------------------------------*/
sbit P    = 0xD0;
sbit F1   = 0xD1;
sbit OV   = 0xD2;
sbit RS0  = 0xD3;
sbit RS1  = 0xD4;
sbit F0   = 0xD5;
sbit AC   = 0xD6;
sbit CY   = 0xD7;

/*------------------------------------------------
Interrupt Vectors:
Interrupt Address = (Number * 8) + 3
------------------------------------------------*/
#define IE0_VECTOR	0  /* 0x03 External Interrupt 0 */
#define TF0_VECTOR	1  /* 0x0B Timer 0 */
#define IE1_VECTOR	2  /* 0x13 External Interrupt 1 */
#define TF1_VECTOR	3  /* 0x1B Timer 1 */
#define SIO_VECTOR	4  /* 0x23 Serial port */

#define TF2_VECTOR	5  /* 0x2B Timer 2 */
#define EX2_VECTOR	5  /* 0x2B External Interrupt 2 */

#endif

       

        (2)延时头文件(delay.h)

#ifndef __DELAY_H
#define __DELAY_H

#include <intrins.h>

/**
  * @brief  延时
  * @param  time 延时时间,单位ms
  * @retval None
  */
void delay(unsigned int time) {
	unsigned char data i, j;
    while (time) {
	    _nop_();
	    i = 2;
	    j = 199;
	    do
	    {
	    	while (--j);
	    } while (--i);
    	time--;
    }
}

/**
  * @brief  延时
  * @param  time 延时时间,单位10us
  * @retval None
  */
void delay10us(unsigned int time) {
	unsigned char data i;
	while (time) {
		i = 2;
		while (--i);
		time--;
	}
}

#endif

        (3)定时器(timer.h)

        整个程序共用到三个定时器( 属于榨干了((( ),舵机分配了定时器0,电机PWM是定时器2,蓝牙模块是定时器1(蓝牙模块并未使用下面的 t1Init() 函数,由于是串口的初始化)。

/*
Header Status: OK
*/

#ifndef TIMER_H_
#define TIMER_H_

#include <regx52.h>

void t0Init() {             //65微秒@11.0592MHz
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0xC4;				//设置定时初始值
	TH0 = 0xFF;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
    EA = 1;					//打开总中断
    ET0 = 1;				//打开定时器0中断
    PT0 = 0;				//设置定时器0中断优先级
}

//Not be used( replaced by bluetoothISR() )
void t1Init() {             //1毫秒@11.0592MHz
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0x18;				//设置定时初始值
	TH1 = 0xFC;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
    EA = 1;					//打开总中断
    ET1 = 1;				//打开定时器1中断
    PT0 = 0;				//设置定时器0中断优先级
}

void t2Init() {				//1毫秒@11.0592MHz	
	T2MOD = 0;				//初始化模式寄存器
	T2CON = 0;				//初始化控制寄存器
	TL2 = 0x18;				//设置定时初值
	TH2 = 0xFC;				//设置定时初值
	ET2 = 1;
	EA = 1;
	PT2 = 0;
	TR2 = 1;				//定时器2开始计时
}

#endif

        (4)舵机(servo.h)

/*
Header Status: OK
*/

#ifndef SERVO_H_
#define SERVO_H_

#include <regx52.h>

#define servoPin P00            //舵机引脚
unsigned int dutyServo = 16;    //舵机PWM的占空比变量

/**
  * @brief 初始化舵机
  * @param None
  * @retval None
  */
void servoInit() {
    t0Init();
}

void servoISR() interrupt 1 {
    static unsigned int counter = 0;

	TL0 = 0xC4;
	TH0 = 0xFF;

    counter++;
	counter %= 220;	//计数值变化范围限制在0~219
    if (counter < dutyServo) {
        servoPin = 1;
    } else {
        servoPin = 0;
    }
}

#endif

        (5)电机(motor.h)

/*
Header Status: OK
*/

#ifndef MOTOR_H_
#define MOTOR_H_

#include <regx52.h>
#include <timer.h>

#define motorL2 P13
#define motorL1 P12
#define motorR1 P11
#define motorR2 P10

unsigned char Lpwm, Rpwm;    //两电机的PWM占空比变量
unsigned char Ldir, Rdir;    //两电机的方向设置,0为倒转,1为正转

/**
  * @brief 初始化电机
  * @param None
  * @retval None
  */
void motorInit() {
    t2Init();
}

/**
  * @brief 设置左电机速度及方向
  * @param speed 速度值,范围0-10
  * @param direction 方向,0为反转,1为正转
  * @retval None
  */
void motorSetL(unsigned char speed, unsigned char direction) {

    if (speed > 10) {
        speed = 10;
    } else if (speed < 0) {
        speed = 0;
    }

    if (direction > 1) {
        direction = 1;
    } else if (direction < 0) {
        direction = 0;
    }

    Lpwm = speed;
    Ldir = direction;
}

/**
  * @brief 设置右电机速度及方向
  * @param speed 速度值,范围0-10
  * @param direction 方向,0为反转,1为正转
  * @retval None
  */
void motorSetR(unsigned char speed, unsigned char direction) {

    if (speed > 10) {
        speed = 10;
    } else if (speed < 0) {
        speed = 0;
    }

    if (direction > 1) {
        direction = 1;
    } else if (direction < 0) {
        direction = 0;
    }

    Rpwm = speed;
    Rdir = direction;
}

void motorISR() interrupt 5 {
    static unsigned int counter1 = 0;

    TF2 = 0;            //中断标志复位
    RCAP2L = 0x66;	    //设置低位定时初值
    RCAP2H = 0xFC;	    //设置高位定时初值

    counter1++;
    counter1 %= 10;     //计数值变化范围限制在0~9

    //左电机PWM及方向控制
    if (counter1 < Lpwm) {
        if (Ldir == 1) {
            motorL2 = 1;
            motorL1 = 0;
        } else if (Ldir == 0) {
            motorL2 = 0;
            motorL1 = 1;
        } else {
            motorL2 = 0;
            motorL1 = 0;
        }
    } else {
        motorL2 = 0;
        motorL1 = 0;
    }

    //右电机PWM及方向控制
    if (counter1 < Rpwm) {
        if (Rdir == 1) {
            motorR2 = 1;
            motorR1 = 0;
        } else if (Rdir == 0) {
            motorR2 = 0;
            motorR1 = 1;
        } else {
            motorR2 = 0;
            motorR1 = 0;
        }
    } else {
        motorR2 = 0;
        motorR1 = 0;
    }
}


#endif

        (6)红外循迹(ir.h)

        通过设置一个状态量,为不同的状态写了相应的反应程序。注意:此头文件不算完全完成,有些转向功能没达到我的预期,本人正在完善)

/*
Header Status: 80% Done
*/

#ifndef IR_H_
#define IR_H_

#include <regx52.h>
#include <delay.h>
#include <servo.h>

#define l2 P17
#define l1 P16
#define r1 P15
#define r2 P14

static unsigned char state = 1, lastState = 1;

/**
  * @brief  循迹函数
  * @param  None
  * @retval None
  */
void detectLine() {
    if (l2 == 0 && l1 == 1 && r1 == 1 && r2 == 0) {         //线轨迹为直线
        dutyServo = 16;
        motorSetL(4, 1);
        motorSetR(4, 1);
        state = 1;
    } else if (l2 == 0 && l1 == 0 && r1 == 1 && r2 == 0) {  //车稍右偏
        dutyServo = 13; 
        motorSetL(2, 1);
        motorSetR(3, 1);
        state = 2;
    } else if (l2 == 0 && l1 == 1 && r1 == 0 && r2 == 0) {  //车稍左偏
        dutyServo = 19;
        motorSetL(3, 1);
        motorSetR(2, 1);
        state = 5;
    } else if (l2 == 0 && l1 == 0 && r1 == 0 && r2 == 0) {
        if (lastState == 2) {                               //车右偏
            dutyServo = 11;
            motorSetL(1, 1);
            motorSetR(4, 1);
            state = 3;
        } else if (lastState == 5) {                        //车左偏
            dutyServo = 21;
            motorSetL(4, 1);
            motorSetR(1, 1);
            state = 6;
        }
    } else if (l2 == 0 && l1 == 0 && r1 == 0 && r2 == 1) {  //车急右转(未正常运行)
        if (lastState == 3) {
            dutyServo = 9;
            motorSetL(1, 1);
            motorSetR(4, 1);
            state = 4;
        }
    } else if (l2 == 1 && l1 == 0 && r1 == 0 && r2 == 0) {  //车急左转(未正常运行)
        if (lastState == 6) {
            dutyServo = 23;
            motorSetL(4, 1);
            motorSetR(1, 1);
            state = 7;0
        }
    }
    lastState = state;
}

#endif

        (7)蓝牙(bluetooth.h)

        蓝牙部分使用了一个大switch,对手机蓝牙调试器发来的指令做不同处理。

        手机端的软件就叫“蓝牙调试器”,是[email protected]的作品。其中有多个自定义按键用于发送不同指令。当然用其他带有自定义发送功能的软件也行

/*
Header Status: OK
*/

#ifndef __BLUETOOTH_H__
#define __BLUETOOTH_H__

#include <regx52.h>
#include <servo.h>
#include <motor.h>

static unsigned char mode = 1;
unsigned char Data;

/**
  * @brief  蓝牙初始化函数
  * @param  None
  * @retval None
  */
void bluetoothInit() {	    //[email protected]
	PCON &= 0x7F;		    //波特率不倍速
	SCON = 0x50;		    //8位数据,可变波特率
	TMOD &= 0x0F;		    //设置定时器模式
	TMOD |= 0x20;		    //设置定时器模式
	TL1 = 0xFD;			    //设置定时初始值
	TH1 = 0xFD;			    //设置定时重载值
	ET1 = 0;			    //禁止定时器中断
    EA = 1;				    //打开总中断
    TR1 = 1;			    //定时器1开始计时
}

/**
  * @brief  蓝牙接收数据处理函数
  * @param  Data 接收到的数据
  * @retval None
  */
void bluetoothRcv(unsigned char Data) {
    switch (Data) {

        case 'w':               //前直行
            dutyServo = 16;
            motorSetL(8, 1);
            motorSetR(8, 1);
            break;
        case 'q':               //前左转弯
            dutyServo = 12; 
            motorSetL(5, 1);
            motorSetR(7, 1);
            break;
        case 'e':               //前右转弯
            dutyServo = 20;
            motorSetL(7, 1);
            motorSetR(5, 1);
            break;
        case 's':               //后直行
            dutyServo = 16;
            motorSetL(5, 0);
            motorSetR(5, 0);
            break;
        case 'a':               //后左转弯
            dutyServo = 12;
            motorSetL(3, 0);
            motorSetR(5, 0);
            break;
        case 'd':               //后右转弯
            dutyServo = 20;
            motorSetL(5, 0);
            motorSetR(3, 0);
            break;
        
        case 'x':               //停止
            motorSetL(0, 1);
            motorSetR(0, 1);
            break;

        case '0':               //循迹模式
            mode = 0;
            break;
        case '1':               //遥控模式
            mode = 1;
            break;
    }
}

void bluetoothISR() interrupt 4 {
    RI = 0;                 //清除接收中断标志位
	Data = SBUF;            //读取串口数据
    bluetoothRcv(Data);     //处理串口数据
}

#endif

软件界面截图:

三、效果展示

51单片机是自己画的

        

视频传不上来,反正大概效果就是可循黑线,然后可以蓝牙遥控。这两个功能通过蓝牙发送不同指令来切换。

--END

标签:------------------------------------------------,定时器,循迹,sfr,51,Timer,单片机,sbit,de
From: https://blog.csdn.net/m0_59778421/article/details/143652114

相关文章

  • 发布 VectorTraits v3.0(支持 X86架构的Avx512系列指令集,支持 Wasm架构及PackedSimd指
    目录支持X86架构的Avx512系列指令集支持Avx512时的输出信息支持Wasm架构及PackedSimd指令集支持PackedSimd时的输出信息VectorTraits.Benchmarks.Wasm使用说明新增了向量方法支持.NET8.0新增的向量方法提供交织与解交织的向量方法YGroup3Unzip的范例代码提供重新构造组的向......
  • 51单片机实现数码管显示
    51单片机实现数码管显示本次的实现效果方式采用模拟进行,芯片为AT89C51,开发软件为keil5,proteus上代码代码如下:#include<reg51.h>voiddelay(unsignedinti);//延时函数unsignedinti=0;voidmain(){unsignedcharbutton=0,flag=0;unsignedchardigitC......
  • 51c大模型~合集20
    我自己的原文哦~ https://blog.51cto.com/whaosoft/11634780#Transformer大模型尺寸变化大模型尺寸正在重走CNN的老路;马斯克:在特斯拉也是这样, Transformer大模型尺寸变化,正在重走CNN的老路! Transformer大模型尺寸变化,正在重走CNN的老路!看到大家都被LLaMA3.1吸引了注......
  • 51c大模型~合集19
    我自己的原文哦~  https://blog.51cto.com/whaosoft/11622380#用苹果VisionPro隔空操控机器人黄仁勋表示:「AI的下一波浪潮是机器人,其中最令人兴奋的发展之一是人形机器人。」如今,ProjectGR00T又迈出了重要的一步。昨日,英伟达创始人黄仁勋在SIGGRAPH2024Keynote......
  • 51c嵌入式~单片机合集2
    我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395一、不同的电平信号的MCU怎么通信?下面这个“电平转换”电路,理解后令人心情愉快。电路设计其实也可以很有趣。    先说一说这个电路的用途:当两个MCU在不同的工作电压下工作(如MCU1工作电压5V;MCU2工作电压3.3V......
  • [lnsyoj1801/luoguP2051/AHOI2009] 中国象棋
    题意在\(n\timesm\)大小的棋盘上放无标号棋子,使得任何一行或一列都不多于\(2\)个棋子,求方案数sol计数题,优先考虑dp。由于每行每列棋子不多于两个,所以我们可以计\(f_{i,j,k}\)表示前\(i\)行中,\(j\)列恰好\(1\)个棋子,\(k\)列恰好\(2\)个棋子的方案数。状态转......
  • 25-018、基于STM32单片机智能行李箱设计-LED-BELL-KEY-指纹-LCD1602-GSM-GPS+HX711称
    本设计由STM32F103C8T6单片机核心板电路+LED指示灯电路+蜂鸣器报警电路+按键电路+指纹电路+LCD1602液晶显示电路+GSM模块电路+GPS模块电路组成。1、如果指纹错误。LED灯会闪,同时蜂鸣器发出滴滴声(3声即可)2、如果指纹输入三次失败后,禁止再用指纹解锁,如果指纹打不开,可以输入按键......
  • 浅谈单片机的gcc优化级别__以双音频信号发生器为例
    IDE:  CLionHOST: Windows11MinGW:x86_64-14.2.0-release-posix-seh-ucrt-rt_v12-rev0GCC: arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi一、简介        gcc有多种优化级别,一般不选择的情况下,IDE默认是按照-Og或这-O2优化的。        ......
  • 25-009、基于STM32单片机智能公交车自动报站系统RFID语音报站+液晶显示温度和烟雾值设
    本系统由STM32F103C8T6单片机核心板、2.4寸TFT彩屏、JR6001语音播报电路、ULN2003步进电机驱动电路、RC522-RFID刷卡识别电路、轻触开关检测电路、按键电路组成。【1】STM32单片机驱动2.4寸TFT彩屏实时显示所有站台信息、当前公交运行方向、当前到站的站点(并有图标显示);语音播......
  • 【51单片机】程序实验1——点亮LED
    由于博主还未学习数字电路和计算机组成原理,因此本系列先开展单片机软件编程的内容,硬件结构的内容简单带过,会考虑安排在后续学习计划中,编程入门部分不会深入涉及单片机电路结构原理。博主已有C语言基础,因此相关内容不会从零开始赘述主要参考学习资料:B站【普中官方】51单片......