#include "global.h" // Device heade sbit PWMB_PIN = P0^4; //¶¨ÒåPWMÊä³öÒý½Å¡£ sbit PWMA_PIN = P0^5; //¶¨ÒåPWMÊä³öÒý½Å¡£ static uint16_t PWM_high,PWM_low; //Öмä±äÁ¿£¬Óû§ÇëÎðÐ޸ġ£ /** * @brief Âí´ïGPIO³õʼ»¯ * @param None * @retval None */ static void Motor_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_OUT_PP; GPIO_InitStructure.GPIO_Pin = Left_MotoA_Pin | Left_MotoB_Pin | Right_MotoA_Pin | Right_MotoB_Pin | Right_MotoPWM_Pin | Left_MotoPWM_Pin; GPIO_Init(Motor_Port, &GPIO_InitStructure); GPIO_SetBits(Motor_Port, Left_MotoA_Pin | Left_MotoB_Pin | Right_MotoA_Pin | Right_MotoB_Pin | Right_MotoPWM_Pin | Left_MotoPWM_Pin); } void Motor_PWM_Init(void) { TIM_InitTypeDef TIM_InitStructure; //½á¹¹¶¨Òå TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //Ö¸¶¨¹¤×÷ģʽ, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask TIM_InitStructure.TIM_Polity = PolityLow; //Ö¸¶¨ÖжÏÓÅÏȼ¶, PolityHigh,PolityLow TIM_InitStructure.TIM_Interrupt = ENABLE; //ÖжÏÊÇ·ñÔÊÐí, ENABLE»òDISABLE TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //Ö¸¶¨Ê±ÖÓÔ´, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext TIM_InitStructure.TIM_ClkOut = DISABLE; //ÊÇ·ñÊä³ö¸ßËÙÂö³å, ENABLE»òDISABLE TIM_InitStructure.TIM_Value = 65536UL - PWM_DUTY; //³õÖµ, TIM_InitStructure.TIM_Run = ENABLE; //ÊÇ·ñ³õʼ»¯ºóÆô¶¯¶¨Ê±Æ÷, ENABLE»òDISABLE Timer_Inilize(Timer1,&TIM_InitStructure); //³õʼ»¯ Timer0,Timer1,Timer2 Motor_GPIO_Init(); } /**************** ¼ÆËãPWM֨װֵº¯Êý *******************/ static void LoadPWM(uint16_t i) { uint16_t j; j = 65536UL - PWM_DUTY + i; //¼ÆËãPWMµÍµçƽʱ¼ä i = 65536UL - i; //¼ÆËãPWM¸ßµçƽʱ¼ä EA = 0; PWM_high = i; //×°ÔØPWM¸ßµçƽʱ¼ä PWM_low = j; //×°ÔØPWMµÍµçƽʱ¼ä EA = 1; } /********************* Timer1ÖжϺ¯Êý************************/ void timer1_int (void) interrupt 3 { if(PWMB_PIN) { TH1 = (uint8_t)(PWM_high >> 8); //Èç¹ûÊÇÊä³öµÍµçƽ£¬Ôò×°ÔØ¸ßµçƽʱ¼ä¡£ TL1 = (uint8_t)PWM_high; PWMB_PIN = 0; PWMA_PIN = 0; } else { TH1 = (uint8_t)(PWM_low >> 8); //Èç¹ûÊÇÊä³ö¸ßµçƽ£¬Ôò×°ÔØµÍµçƽʱ¼ä¡£ TL1 = (uint8_t)PWM_low; PWMB_PIN = 1; PWMA_PIN = 1; } } /********************* Timer3ÖжϺ¯Êý************************/ /*STC15F2KûÓж¨Ê±Æ÷3*/ //void timer3_int (void) interrupt 19 //{ // // P1 = 0; // if(PWMA_PIN) // { // T3H = (uint8_t)(PWM_high >> 8); //Èç¹ûÊÇÊä³öµÍµçƽ£¬Ôò×°ÔØ¸ßµçƽʱ¼ä¡£ // T3L = (uint8_t)PWM_high; // PWMA_PIN = 0; // } // else // { // T3H = (uint8_t)(PWM_low >> 8); //Èç¹ûÊÇÊä³ö¸ßµçƽ£¬Ôò×°ÔØµÍµçƽʱ¼ä¡£ // T3L = (uint8_t)PWM_low; // PWMA_PIN = 1; // } //} void Motor_Run(uint8_t dir, uint16_t speed) { speed < PWM_HIGH_MIN ? speed = PWM_HIGH_MIN:speed; //Èç¹ûдÈëСÓÚ×îСռ¿Õ±ÈÊý¾Ý£¬ÔòÇ¿ÖÆÎª×îСռ¿Õ±È¡£ speed > PWM_HIGH_MAX ? speed = PWM_HIGH_MAX:speed; //Èç¹ûдÈë´óÓÚ×î´óÕ¼¿Õ±ÈÊý¾Ý£¬ÔòÇ¿ÖÆÎª×î´óÕ¼¿Õ±È¡£ switch (dir) { case FORWARD: LeftMotor_Go(); RightMotor_Go(); LoadPWM(speed); break; case BACKWARDS: LeftMotor_Back(); RightMotor_Back(); LoadPWM(speed); break; case TURNLEFT: LeftMotor_Stop(); RightMotor_Go(); LoadPWM(speed); break; case TURNRIGHT: LeftMotor_Go(); RightMotor_Stop(); LoadPWM(speed); break; case SPINTURNLEFT: LeftMotor_Back(); RightMotor_Go(); LoadPWM(speed); break; case SPINTURNRIGHT: LeftMotor_Go(); RightMotor_Back(); LoadPWM(speed); break; case STOP: LeftMotor_Stop(); RightMotor_Stop(); LoadPWM(speed); break; default: LeftMotor_Stop(); RightMotor_Stop(); break; } }
时间: 2025-06-18 07:56:26 浏览: 17
### STC15F2K系列51单片机智能小车避障程序PWM控制代码解析及功能说明
以下是一个基于STC15F2K系列51单片机的智能小车避障程序,其中使用了PWM(脉冲宽度调制)技术来控制电机的速度和方向。代码实现了通过超声波传感器检测障碍物,并根据检测结果调整小车的运动状态。
#### 代码实现
```c
#include <reg52.h>
// 定义超声波模块引脚
sbit TRIG = P3^0; // 超声波触发引脚
sbit ECHO = P3^1; // 超声波回响引脚
// 定义电机控制引脚
sbit PWM_L = P1^0; // 左电机PWM信号
sbit DIR_L = P1^1; // 左电机方向控制
sbit PWM_R = P1^2; // 右电机PWM信号
sbit DIR_R = P1^3; // 右电机方向控制
unsigned int distance;
void delay_us(unsigned int us) {
while (us--);
}
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 123; j++);
}
// 测量距离函数
unsigned int measure_distance() {
unsigned int time, distance;
TRIG = 0;
delay_us(2);
TRIG = 1;
delay_us(15);
TRIG = 0;
while (!ECHO);
time = 0;
while (ECHO) {
time++;
if (time > 5000) break; // 防止无限循环
}
distance = time / 58; // 距离计算公式
return distance;
}
// 初始化定时器0用于PWM生成
void timer0_init() {
TMOD |= 0x01; // 设置定时器0为模式1
TH0 = 0xFC; // 设置初值,对应20ms周期
TL0 = 0x18;
ET0 = 1; // 开启定时器0中断
EA = 1; // 全局中断使能
TR0 = 1; // 启动定时器0
}
// 定时器0中断服务程序
void timer0_ISR() interrupt 1 {
static unsigned char count = 0;
static unsigned char pwm_duty = 50; // 占空比设置为50%
TH0 = 0xFC; // 重载初值
TL0 = 0x18;
count++;
if (count <= pwm_duty) {
PWM_L = 1; // 左电机高电平
PWM_R = 1; // 右电机高电平
} else {
PWM_L = 0; // 左电机低电平
PWM_R = 0; // 右电机低电平
}
if (count >= 100) {
count = 0; // 每100次重置计数器
}
}
// 控制小车前进
void move_forward() {
DIR_L = 1; // 左电机正转
DIR_R = 1; // 右电机正转
}
// 控制小车后退
void move_backward() {
DIR_L = 0; // 左电机反转
DIR_R = 0; // 右电机反转
}
// 控制小车左转
void turn_left() {
DIR_L = 0; // 左电机反转
DIR_R = 1; // 右电机正转
}
// 控制小车右转
void turn_right() {
DIR_L = 1; // 左电机正转
DIR_R = 0; // 右电机反转
}
// 停止小车
void stop_car() {
DIR_L = 0; // 左电机停止
DIR_R = 0; // 右电机停止
}
void main() {
timer0_init(); // 初始化定时器0
while (1) {
distance = measure_distance();
if (distance < 30) { // 如果前方有障碍物
stop_car();
delay_ms(500);
turn_left(); // 向左转
delay_ms(1000);
stop_car();
delay_ms(500);
} else {
move_forward(); // 没有障碍物,前进
}
}
}
```
#### 功能解释
1. **超声波测距**
使用 `measure_distance` 函数测量前方障碍物的距离。通过触发超声波模块发送信号,并接收回响信号的时间差计算距离[^2]。
2. **PWM控制**
使用定时器0中断生成PWM信号,控制左右电机的速度。占空比设置为50%,可以根据需要调整占空比以改变电机速度。
3. **电机控制**
- `move_forward`:设置左右电机正转,使小车前进。
- `move_backward`:设置左右电机反转,使小车后退。
- `turn_left` 和 `turn_right`:通过分别控制左右电机的转向,实现小车的左转和右转。
- `stop_car`:停止左右电机,使小车停止。
4. **避障逻辑**
当检测到前方距离小于30厘米时,小车停止并左转,避免碰撞障碍物。如果没有障碍物,则保持前进状态。
####
阅读全文
相关推荐

