(七)stm32巡线小车首尝试 完整代码

#main.c

#include "stm32f10x.h"
#include "pwm_timer.h"
#include "car_driver.h"
#include "delay.h"
#include "bluetooth.h"
#include "infrared.h"
#include "timer.h"

volatile int P_control = 50;
volatile int I_control = 50;
volatile int D_control = 50;

#define infrared2_repeat 2
#define infrared3_repeat 3

void Myinit()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    CarDriverSet();
    delay_init();
    BluetoothUsartInit();
    INFRARED_Init(INFRARED1_init);
    INFRARED_Init(INFRARED2_init);
    INFRARED_Init(INFRARED3_init);
    INFRARED_Init(INFRARED4_init);
}

int main(void)
{
    int repeat_count = 30000, xun_flag = 0;
    Myinit();
    while(1)
    {
        if (data_out == xun_control)
        {
            if (INFRARED2_input == Meet_black)
            {
                CarControl(MOTORA, 2000);
                CarControl(MOTORB, 2000);
                while (repeat_count--)if (INFRARED1_input == Meet_black) xun_flag = 1;
                if (xun_flag == 0)
                {
                    CarControl(MOTORA, -2000);
                    CarControl(MOTORB, 2000);
                    delay_ms(120);
                }
                else 
                {
                    CarControl(MOTORA, -2000);
                    CarControl(MOTORB, 2000);
                    while(INFRARED3_input == None_black);
                    delay_ms(200);
                }
                xun_flag = 0;
                repeat_count = 30000;
            }
            else if (INFRARED3_input == Meet_black)
            {
                CarControl(MOTORA, 2000);
                CarControl(MOTORB, 2000);
                while (repeat_count--)if (INFRARED1_input == Meet_black) xun_flag = 1;
                if (xun_flag == 0)
                {
                    CarControl(MOTORA, 2000);
                    CarControl(MOTORB, -2000);
                    delay_ms(120);
                }
                else 
                {
                    CarControl(MOTORA, 2000);
                    CarControl(MOTORB, -2000);
                    while(INFRARED2_input == None_black);
                    delay_ms(200);
                }
                xun_flag = 0;
                repeat_count = 30000;
            }
            else
            {
                CarControl(MOTORA, 1300);
                CarControl(MOTORB, 1300);
            }
        }
    }
}


#pwm_timer.h
#ifndef __PWM_TIMER_H
#define __PWM_TIMER_H
#include "stm32f10x.h"

void PwmTIMER_BaseSet(TIM_TypeDef* base_input_TIMx, u16 arr, u16 psc);  // 基时设置
void PwmTIMER_Init(TIM_TypeDef* input_TIMx, int TIMER_OCx);  // pwm初始化函数

#if (!defined TIMER_reset_ENABLE) && (!defined TIMER_reset_DISABLE)
void TIMER_Stop(TIM_TypeDef* input_TIMx, int flag);
void TIMER_Start(TIM_TypeDef* input_TIMx);
#endif

#ifndef TIMER_reset_ENABLE
#define TIMER_reset_ENABLE 0
#endif

#ifndef TIMER_reset_DISABLE
#define TIMER_reset_DISABLE 1
#endif

#define PwmTIMER_Base_arr 7199
#define PwmTIMER_Base_psc 0
#define PwmTIMER_Base PwmTIMER_Base_arr, PwmTIMER_Base_psc    // 对应10kHz
#define TIMER_OC1 1
#define TIMER_OC2 2
#define TIMER_OC3 3
#define TIMER_OC4 4

#endif


#pwm_timer.c
#include "stm32f10x.h"
#include "pwm_timer.h"

void PwmTIMER_BaseSet(TIM_TypeDef* base_input_TIMx, u16 arr, u16 psc)
{
    // arr计时器初值,psc分频系数
    TIM_TimeBaseInitTypeDef TIM_base_init_set;

    TIM_base_init_set.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_base_init_set.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_base_init_set.TIM_Period = arr;
    TIM_base_init_set.TIM_Prescaler = psc;
	
	TIM_TimeBaseInit(base_input_TIMx, &TIM_base_init_set);
}

void PwmTIMER_Init(TIM_TypeDef* input_TIMx, int TIMER_OCx)
{
    TIM_OCInitTypeDef TIMER_pwm_init_set;

    // 使能定时器时钟
    if (input_TIMx == TIM2)
	    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    else if (input_TIMx == TIM3)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    else if (input_TIMx == TIM4)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    if (input_TIMx -> ARR == 0 || input_TIMx->PSC == 0)PwmTIMER_BaseSet(input_TIMx, PwmTIMER_Base);

    TIMER_pwm_init_set.TIM_OCMode = TIM_OCMode_PWM1;    // 小于为有效电平
    TIMER_pwm_init_set.TIM_OutputState = TIM_OutputState_Enable;    // pwm输出开启
    TIMER_pwm_init_set.TIM_OCPolarity = TIM_OCPolarity_High;    // 有效时高电平
    
    if (TIMER_OCx == TIMER_OC1)
    {
        TIM_OC1Init(input_TIMx, &TIMER_pwm_init_set);
        TIM_OC1PreloadConfig(input_TIMx, TIM_OCPreload_Enable);
    }   
    else if (TIMER_OCx == TIMER_OC2)
    {
        TIM_OC2Init(input_TIMx, &TIMER_pwm_init_set);
        TIM_OC2PreloadConfig(input_TIMx, TIM_OCPreload_Enable);
    }
    else if (TIMER_OCx == TIMER_OC3)
    {
        TIM_OC3Init(input_TIMx, &TIMER_pwm_init_set);
        TIM_OC3PreloadConfig(input_TIMx, TIM_OCPreload_Enable);
    }
    else if (TIMER_OCx == TIMER_OC4)
    {
        TIM_OC4Init(input_TIMx, &TIMER_pwm_init_set);
        TIM_OC4PreloadConfig(input_TIMx, TIM_OCPreload_Enable);
    }

    TIM_Cmd(input_TIMx, ENABLE);
}

void TIMER_Stop(TIM_TypeDef* input_TIMx, int flag)
{
    TIM_Cmd(input_TIMx, DISABLE);
    if (flag == TIMER_reset_ENABLE)TIM_SetCounter(input_TIMx, 0);
}

void TIMER_Start(TIM_TypeDef* input_TIMx)
{
    TIM_Cmd(input_TIMx, ENABLE);
}


#car_driver.h
#ifndef CAR_DRIVER_H
#define CAR_DRIVER_H
#include "stm32f10x.h"
#include "pwm_timer.h"


// 参数:GPIOx,Pin,Mode
// 对应MyGPIO_Set函数
#define PWMA_GPIO GPIOB
#define PWMA_Pin GPIO_Pin_0
#define PWMA_init PWMA_GPIO, PWMA_Pin, GPIO_Mode_AF_PP

#define PWMB_GPIO GPIOB
#define PWMB_Pin GPIO_Pin_1
#define PWMB_init PWMB_GPIO, PWMB_Pin, GPIO_Mode_AF_PP

#define AIN1_GPIO GPIOB
#define AIN1_Pin GPIO_Pin_7
#define AIN1_init AIN1_GPIO, AIN1_Pin, GPIO_Mode_Out_PP

#define AIN2_GPIO GPIOB
#define AIN2_Pin GPIO_Pin_8
#define AIN2_init AIN2_GPIO, AIN2_Pin, GPIO_Mode_Out_PP

#define BIN1_GPIO GPIOB
#define BIN1_Pin GPIO_Pin_5
#define BIN1_init BIN1_GPIO, BIN1_Pin, GPIO_Mode_Out_PP

#define BIN2_GPIO GPIOB
#define BIN2_Pin GPIO_Pin_6
#define BIN2_init BIN2_GPIO, BIN2_Pin, GPIO_Mode_Out_PP



#define PWM_timer TIM3
#define PWMA_OC TIMER_OC3  // 即TIMx_CH3
#define PWMB_OC TIMER_OC4  // 即TIMx_CH4

void CarDriverSet(void);
void CarControl(int which_motor, int input_motor_speed);

#define MOTORA 1
#define MOTORB 2

#endif


#car_driver.c
#include "stm32f10x.h"
#include "car_driver.h"

// 初始化相应引脚
void MyGPIO_Set(GPIO_TypeDef* input_GPIOx, uint16_t input_Pin, GPIOMode_TypeDef input_Mode)
{
    GPIO_InitTypeDef GPIO_init_set;

    if (input_GPIOx == GPIOA)
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	else if (input_GPIOx == GPIOB)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	else if (input_GPIOx == GPIOC)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

	else if (input_GPIOx == GPIOD)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

    GPIO_init_set.GPIO_Mode = input_Mode;
    GPIO_init_set.GPIO_Pin = input_Pin;
    GPIO_init_set.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(input_GPIOx, &GPIO_init_set);
}

void CarDriverSet(void)
{
    MyGPIO_Set(PWMA_init);
    MyGPIO_Set(PWMB_init);
    MyGPIO_Set(AIN1_init);
    MyGPIO_Set(AIN2_init);
    MyGPIO_Set(BIN1_init);
    MyGPIO_Set(BIN2_init);

    PwmTIMER_Init(PWM_timer, PWMA_OC);
    PwmTIMER_Init(PWM_timer, PWMB_OC);

    TIM_SetCompare3(PWM_timer, 0);
    TIM_SetCompare4(PWM_timer, 0);

    // 默认电机1停止
    GPIO_ResetBits(AIN1_GPIO, AIN1_Pin);
    GPIO_ResetBits(AIN2_GPIO, AIN2_Pin);

    // 默认电机2停止
    GPIO_ResetBits(BIN1_GPIO, BIN1_Pin);
    GPIO_ResetBits(BIN2_GPIO, BIN2_Pin);
}

void CarControl(int which_motor, int input_motor_speed)
{
    // 速度输入合理性判断
    if (input_motor_speed < -PwmTIMER_Base_arr)
    {
        input_motor_speed = -PwmTIMER_Base_arr;
    }
    else if (input_motor_speed > PwmTIMER_Base_arr)
    {
        input_motor_speed = PwmTIMER_Base_arr;
    }

    if (input_motor_speed == 0)
    {
        if (which_motor == MOTORA)
        {
            GPIO_ResetBits(AIN1_GPIO, AIN1_Pin);
            GPIO_ResetBits(AIN2_GPIO, AIN2_Pin);
        }
        else if (which_motor == MOTORB)
        {
            GPIO_ResetBits(BIN1_GPIO, BIN1_Pin);
            GPIO_ResetBits(BIN2_GPIO, BIN2_Pin);
        }
    }
    else if (input_motor_speed > 0)
    {
        if (which_motor == MOTORA)
        {
            GPIO_SetBits(AIN1_GPIO, AIN1_Pin);
            GPIO_ResetBits(AIN2_GPIO, AIN2_Pin);
            if (PWMA_OC == TIMER_OC1)TIM_SetCompare1(PWM_timer, input_motor_speed);
            else if (PWMA_OC == TIMER_OC2)TIM_SetCompare2(PWM_timer, input_motor_speed);
            else if (PWMA_OC == TIMER_OC3)TIM_SetCompare3(PWM_timer, input_motor_speed);
            else if (PWMA_OC == TIMER_OC4)TIM_SetCompare4(PWM_timer, input_motor_speed);
        }
        else if (which_motor == MOTORB)
        {
            GPIO_SetBits(BIN1_GPIO, BIN1_Pin);
            GPIO_ResetBits(BIN2_GPIO, BIN2_Pin);
            if (PWMB_OC == TIMER_OC1)TIM_SetCompare1(PWM_timer, input_motor_speed);
            else if (PWMB_OC == TIMER_OC2)TIM_SetCompare2(PWM_timer, input_motor_speed);
            else if (PWMB_OC == TIMER_OC3)TIM_SetCompare3(PWM_timer, input_motor_speed);
            else if (PWMB_OC == TIMER_OC4)TIM_SetCompare4(PWM_timer, input_motor_speed);
        }
       
    }
    else if (input_motor_speed < 0)
    {
        if (which_motor == MOTORA)
        {
            GPIO_ResetBits(AIN1_GPIO, AIN1_Pin);
            GPIO_SetBits(AIN2_GPIO, AIN2_Pin);
            if (PWMA_OC == TIMER_OC1)TIM_SetCompare1(PWM_timer, -input_motor_speed);
            else if (PWMA_OC == TIMER_OC2)TIM_SetCompare2(PWM_timer, -input_motor_speed);
            else if (PWMA_OC == TIMER_OC3)TIM_SetCompare3(PWM_timer, -input_motor_speed);
            else if (PWMA_OC == TIMER_OC4)TIM_SetCompare4(PWM_timer, -input_motor_speed);
        }
        else if (which_motor == MOTORB)
        {
            GPIO_ResetBits(BIN1_GPIO, BIN1_Pin);
            GPIO_SetBits(BIN2_GPIO, BIN2_Pin);
            if (PWMB_OC == TIMER_OC1)TIM_SetCompare1(PWM_timer, -input_motor_speed);
            else if (PWMB_OC == TIMER_OC2)TIM_SetCompare2(PWM_timer, -input_motor_speed);
            else if (PWMB_OC == TIMER_OC3)TIM_SetCompare3(PWM_timer, -input_motor_speed);
            else if (PWMB_OC == TIMER_OC4)TIM_SetCompare4(PWM_timer, -input_motor_speed);
        }

    }
}


#bluetooth.h
#ifndef __BLUETOOTH_H
#define __BLUETOOTH_H

#define BLUETOOTH_GPIO GPIOA
#define BLUETOOTH_TX_Pin GPIO_Pin_2
#define BLUETOOTH_RX_Pin GPIO_Pin_3
#define BLUETOOTH_Usart USART2
#define BLUETOOTH_IRQ USART2_IRQn

extern volatile uint16_t data_in;
extern volatile uint16_t data_out;
extern volatile uint16_t data_in_flag;
extern volatile uint16_t data_out_flag;

void BluetoothUsartInit(void);


#define BLUETOOTH_baud_rate 115200

// 运动与巡线
#define move_forward '2'
#define move_back '3'
#define move_right '4'
#define move_left '5'
#define move_stop '6'
#define xunxian '7'

// pid控制
#define change_p '['
#define change_I ']'
#define change_d '{'

// 红外
#define infrared1 '@'
#define infrared2 '#'
#define infrared3 '$'
#define infrared4 '%'

// 速度
#define BL_speed_test1 '^'
#define BL_speed_test2 '&'
#define BL_speed_test3 '*'
#define BL_speed_test4 '('

#define start_transmit '|'
#define stop_transmit '~'

// 模式选择
#define Mode_move 'm'
#define Mode_xun 'x'
#define move_control 0
#define xun_control 1

#endif


#bluetooth.c

#include "stm32f10x.h"
#include "bluetooth.h"
#include "car_driver.h"
#include "infrared.h"

volatile uint16_t data_in = 0;
volatile uint16_t data_out = move_control;
volatile uint16_t data_in_flag = 0;
volatile uint16_t data_in_flag1 = 0;
volatile uint16_t data_out_flag = 0;

extern volatile int P_control;
extern volatile int I_control;
extern volatile int D_control;

int receive_data[5] = {0};
int receive_count = 0;
int temp_data = 0;

void BluetoothUsartInit(void)
{
	GPIO_InitTypeDef GPIO_init_set;
	USART_InitTypeDef USART_init_set;
	NVIC_InitTypeDef NVIC_init_set;
	
	// 使能GPIOA与usart时钟
	// 由于io复用,需要使能GPIOA时钟
    if (BLUETOOTH_IRQ == USART1_IRQn)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    else if (BLUETOOTH_IRQ == USART2_IRQn)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    else if (BLUETOOTH_IRQ == USART3_IRQn)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    
	if (BLUETOOTH_GPIO == GPIOA)
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	else if (BLUETOOTH_GPIO == GPIOB)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	else if (BLUETOOTH_GPIO == GPIOC)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

	else if (BLUETOOTH_GPIO == GPIOD)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

	// 串口复位
	USART_DeInit(BLUETOOTH_Usart);
    
	// GPIO端口模式设置
	GPIO_init_set.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_init_set.GPIO_Pin = BLUETOOTH_TX_Pin;
	GPIO_init_set.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(BLUETOOTH_GPIO, &GPIO_init_set);

	GPIO_init_set.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_init_set.GPIO_Pin = BLUETOOTH_RX_Pin;
	GPIO_Init(BLUETOOTH_GPIO, &GPIO_init_set);


	// USART Rx|Tx init
	USART_init_set.USART_BaudRate = BLUETOOTH_baud_rate;
	USART_init_set.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_init_set.USART_Parity = USART_Parity_No;
	USART_init_set.USART_StopBits = USART_StopBits_1;
	USART_init_set.USART_WordLength = USART_WordLength_8b;
	USART_init_set.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init(BLUETOOTH_Usart, &USART_init_set);


	// 串口使能
	USART_Cmd(BLUETOOTH_Usart, ENABLE);
	
	// USART1中断设置
	USART_ITConfig(BLUETOOTH_Usart, USART_IT_RXNE, ENABLE);


	// 中断设置
	NVIC_init_set.NVIC_IRQChannel = BLUETOOTH_IRQ;
	NVIC_init_set.NVIC_IRQChannelCmd = ENABLE;
	NVIC_init_set.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_init_set.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_init_set);

	USART_SendData(BLUETOOTH_Usart, 123);
}


void USART2_IRQHandler(void)
{
	if (USART_GetITStatus(BLUETOOTH_Usart, USART_IT_RXNE))
	{
		if (data_in_flag1 != start_transmit)
			data_in_flag = USART_ReceiveData(BLUETOOTH_Usart);

		if (data_in_flag == move_forward)
		{
			CarControl(MOTORA, 2000);
			CarControl(MOTORB, 2000);
		}
		else if (data_in_flag == move_left)
		{
			CarControl(MOTORA, 0);
			CarControl(MOTORB, 3000);
		}
		else if (data_in_flag == move_right)
		{
			CarControl(MOTORA, 3000);
			CarControl(MOTORB, 0);
		}
		else if (data_in_flag == move_back)
		{
			CarControl(MOTORA, -2000);
			CarControl(MOTORB, -2000);
		}
		else if (data_in_flag == move_stop)
		{
			CarControl(MOTORA, 0);
			CarControl(MOTORB, 0);
		}
		else if (data_in_flag == infrared1)
		{
			USART_SendData(BLUETOOTH_Usart, INFRARED1_input);
		}
		else if (data_in_flag == infrared2)
		{
			USART_SendData(BLUETOOTH_Usart, INFRARED2_input);
		}
		else if (data_in_flag == infrared3)
		{
			USART_SendData(BLUETOOTH_Usart, INFRARED3_input);
		}
		else if (data_in_flag == infrared4)
		{
			USART_SendData(BLUETOOTH_Usart, INFRARED4_input);
		}
		else if (data_in_flag == change_p)
		{
			if (data_in_flag1 == start_transmit)temp_data = USART_ReceiveData(BLUETOOTH_Usart);
			data_in_flag1 = start_transmit;
			if (temp_data != stop_transmit)
			{
				receive_data[receive_count] = temp_data;
				receive_count++;
				if (receive_count >= 5)receive_count = 5;
			}
			else
			{
				data_in_flag1 = 0;
				receive_count--;
				temp_data = 0;
				for (; receive_count > 0; receive_count--)
				{
					temp_data = receive_data[receive_count] + temp_data*10;
				}
				P_control = temp_data;
				temp_data = 0;
				receive_count = 0;
			}
		}
		else if (data_in_flag == change_I)
		{
			if (data_in_flag1 == start_transmit)temp_data = USART_ReceiveData(BLUETOOTH_Usart);
			data_in_flag1 = start_transmit;
			if (temp_data != stop_transmit)
			{
				receive_data[receive_count] = temp_data;
				receive_count++;
				if (receive_count >= 5)receive_count = 5;
			}
			else
			{
				data_in_flag1 = 0;
				receive_count--;
				temp_data = 0;
				for (; receive_count > 0; receive_count--)
				{
					temp_data = receive_data[receive_count] + temp_data*10;
				}
				I_control = temp_data;
				temp_data = 0;
				receive_count = 0;
			}
		}
		else if (data_in_flag == change_d)
		{
			if (data_in_flag1 == start_transmit)temp_data = USART_ReceiveData(BLUETOOTH_Usart);
			data_in_flag1 = start_transmit;
			if (temp_data != stop_transmit)
			{
				receive_data[receive_count] = temp_data;
				receive_count++;
				if (receive_count >= 5)receive_count = 5;
			}
			else
			{
				data_in_flag1 = 0;
				receive_count--;
				temp_data = 0;
				for (; receive_count > 0; receive_count--)
				{
					temp_data = receive_data[receive_count] + temp_data*10;
				}
				D_control = temp_data;
				temp_data = 0;
				receive_count = 0;
			}
		}
		else if (data_in_flag == Mode_xun)
		{
			data_out = xun_control;
		}
		else if (data_in_flag == Mode_move)
		{
			data_out = move_control;
		}
	}
}


#infrared.h
// 红外传感器,接收到信号时低电平,被遮挡时高电平

#ifndef __INFRARED_H
#define __INFRARED_H

#include "stm32f10x.h"

void INFRARED_Init(GPIO_TypeDef* input_GPIOx, uint16_t Pin);

#define INFRARED1_init GPIOA, GPIO_Pin_1
#define INFRARED1_input GPIO_ReadInputDataBit(INFRARED1_init)

#define INFRARED2_init GPIOA, GPIO_Pin_4
#define INFRARED2_input GPIO_ReadInputDataBit(INFRARED2_init)

#define INFRARED3_init GPIOA, GPIO_Pin_5
#define INFRARED3_input GPIO_ReadInputDataBit(INFRARED3_init)

#define INFRARED4_init GPIOA, GPIO_Pin_6
#define INFRARED4_input GPIO_ReadInputDataBit(INFRARED4_init)

#define None_black 0
#define Meet_black 1

#endif


#infrared.c
#include "infrared.h"
#include "stm32f10x.h"

void INFRARED_Init(GPIO_TypeDef* input_GPIOx, uint16_t Pin)
{
    GPIO_InitTypeDef GPIO_init_set;

	if (input_GPIOx == GPIOA)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    else if (input_GPIOx == GPIOB)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    else if (input_GPIOx == GPIOC)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    else if (input_GPIOx == GPIOD)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    
    GPIO_init_set.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_init_set.GPIO_Pin = Pin;
    GPIO_init_set.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(input_GPIOx, &GPIO_init_set);
}


#timer.h
#ifndef __TIMER_H
#define __TIMER_H

#include "stm32f10x.h"

#define Time_control_timer TIM2

#define TIMER_base 719, 99  // 分别是arr和psc,即计数器初值和预分频系数,1ms溢出一次
#define TIMER_reset_ENABLE 0    // 定时器重置为0
#define TIMER_reset_DISABLE 1   // 定时器不重置

// 向上计数
void TIMER_Init(TIM_TypeDef* input_TIMx);
int TIME_calculate(void);   // 若arr或psc更改,该函数必须更改
void TIMER_Stop(TIM_TypeDef* input_TIMx, int flag);   // 时钟停止,flag决定是否重置
void TIMER_Start(TIM_TypeDef* input_TIMx);

#endif


#timer.c
#include "timer.h"
#include "stm32f10x.h"
volatile unsigned int timer2_counter = 0;   // 防止编译器优化导致进入中断后造成错误

void TIME_BaseInit(TIM_TypeDef* base_input_TIMx, u16 arr, u16 psc)
{
    // arr计时器初值,psc分频系数
    TIM_TimeBaseInitTypeDef TIM_base_init_set;

    TIM_base_init_set.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_base_init_set.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_base_init_set.TIM_Period = arr;
    TIM_base_init_set.TIM_Prescaler = psc;
	
	TIM_TimeBaseInit(base_input_TIMx, &TIM_base_init_set);
}

void TIMER_Init(TIM_TypeDef* input_TIMx)
{
    NVIC_InitTypeDef NVIC_init_set;

    if (input_TIMx == TIM2)
	    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    else if (input_TIMx == TIM3)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    else if (input_TIMx == TIM4)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    TIME_BaseInit(input_TIMx, TIMER_base);  // 基准设置

    TIM_ITConfig(input_TIMx, TIM_IT_Update, ENABLE);    // 使能计时器中断

    NVIC_init_set.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_init_set.NVIC_IRQChannelSubPriority = 1;
    NVIC_init_set.NVIC_IRQChannelCmd = ENABLE;

    if (input_TIMx == TIM2)
	    NVIC_init_set.NVIC_IRQChannel = TIM2_IRQn;

    else if (input_TIMx == TIM3)
        NVIC_init_set.NVIC_IRQChannel = TIM3_IRQn;

    else if (input_TIMx == TIM4)
        NVIC_init_set.NVIC_IRQChannel = TIM4_IRQn;
    
    NVIC_Init(&NVIC_init_set);
    
    TIM_Cmd(input_TIMx, ENABLE);
}

int TIME_calculate(void)
{
    // 如果大于1ms的溢出时间可能会出错
    return timer2_counter;
}

void TotalTIMER_Stop(TIM_TypeDef* input_TIMx, int flag)
{
    TIM_Cmd(input_TIMx, DISABLE);
    if (flag == TIMER_reset_ENABLE)TIM_SetCounter(input_TIMx, 0);
}

void TotalTIMER_Start(TIM_TypeDef* input_TIMx)
{
    TIM_Cmd(input_TIMx, ENABLE);
}

void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
    {
        // 注意可能会溢出,虽然溢出时间很长,但终归有可能溢出
        timer2_counter++;
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}


#以下是未使用代码
#speed.h
// 速度传感器,接收到信号时高电平,被遮挡时低电平

#ifndef __SPEED_H
#define __SPEED_H

#include "stm32f10x.h"

typedef struct
{
	GPIO_TypeDef* input_GPIOx;	// 光电传感器传入数据GPIO
	uint16_t Pin;	// 光电传感器具体引脚
	uint32_t EXTI_Line_set;		// 中断线设置,与Pin对应
	uint8_t GPIO_port_source;	// 设置中断线对应GPIOx, EXTI_Init
	uint8_t GPIO_pin_source;	// 设置中断线GPIO_pin, EXTI_Tnit
} MySPEED_InitTypeDef;


void SPEED_Set(MySPEED_InitTypeDef* input_speed_set);


#endif


#speed.c
// 光电传感器基础配置服务
#include "speed.h"
#include "stm32f10x.h"

void SPEED_Set(MySPEED_InitTypeDef* input_speed_set)
{
	GPIO_InitTypeDef GPIO_init_set;
	EXTI_InitTypeDef EXTI_init_set;
	NVIC_InitTypeDef NVIC_init_set;

	if (input_speed_set->input_GPIOx == GPIOA)
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

	else if (input_speed_set->input_GPIOx == GPIOB)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	else if (input_speed_set->input_GPIOx == GPIOC)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

	else if (input_speed_set->input_GPIOx == GPIOD)
	    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);

	// 光电传感器所需gpio配置
	GPIO_init_set.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_init_set.GPIO_Pin = input_speed_set->Pin;
	GPIO_init_set.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(input_speed_set->input_GPIOx, &GPIO_init_set);

	GPIO_EXTILineConfig(input_speed_set->GPIO_port_source, input_speed_set->GPIO_pin_source);  // io与中断线映射

	// 初始化,设置触发方式等
	EXTI_init_set.EXTI_Line = input_speed_set->EXTI_Line_set; // 中断线设置
	EXTI_init_set.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_init_set.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_init_set.EXTI_LineCmd = ENABLE;
	
	
	// 中断使能
    NVIC_init_set.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_init_set.NVIC_IRQChannelSubPriority = 1;
    NVIC_init_set.NVIC_IRQChannelCmd = ENABLE;
	if (input_speed_set->EXTI_Line_set == EXTI_Line0)
    	NVIC_init_set.NVIC_IRQChannel = EXTI0_IRQn;

	else if (input_speed_set->EXTI_Line_set == EXTI_Line1)
		NVIC_init_set.NVIC_IRQChannel = EXTI1_IRQn;

	else if (input_speed_set->EXTI_Line_set == EXTI_Line2)
		NVIC_init_set.NVIC_IRQChannel = EXTI2_IRQn;

	else if (input_speed_set->EXTI_Line_set == EXTI_Line3)
		NVIC_init_set.NVIC_IRQChannel = EXTI3_IRQn;
	
	else if (input_speed_set->EXTI_Line_set == EXTI_Line4)
		NVIC_init_set.NVIC_IRQChannel = EXTI4_IRQn;
    NVIC_Init(&NVIC_init_set);

	EXTI_Init(&EXTI_init_set);
}

很抱歉,我无法提供完整的stm32巡线小车pid控制代码。然而,根据引用\[2\]中提到的功能,你可以使用陀螺仪来根据俯仰角变化在下坡后停车,并通过三路电感实现小车巡线。此外,你还可以使用红外光电开关来判断小车的启停,并启动舵机。根据引用\[3\]中的子函数.h文件,你可以在代码中包含这些函数来实现相应的功能。请注意,PID控制是一种常用的控制算法,可以用于巡线小车的精确控制,但具体的PID控制代码需要根据你的具体需求和硬件配置进行编写。你可以参考PID控制算法的原理和实现方法,根据你的巡线小车的具体情况进行代码编写。 #### 引用[.reference_title] - *1* *3* [基于stm32巡线(白线)小车(依据光敏板传感器测线)比赛,直角转弯等赛道分析与局部到整体代码实现](https://blog.csdn.net/yinyoushiren_wb/article/details/126684078)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [stm32 电磁巡线小车](https://blog.csdn.net/m0_52396087/article/details/120479776)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值