找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 495|回复: 5
收起左侧

51单片机自适应汽车巡航仿真

[复制链接]
ID:1167562 发表于 2026-3-9 21:28 | 显示全部楼层 |阅读模式
有没有哪位师傅带带我做自适应巡航系统仿真?
做了好几天了,现在在调节电机转速,但是好难啊。正好多天都整不明白,仿真不出来
回复

使用道具 举报

ID:844772 发表于 2026-3-10 09:41 | 显示全部楼层
使用啥电机啊,难在哪呢?发个目前成果给见识一下呗。
回复

使用道具 举报

ID:584814 发表于 2026-3-10 10:57 | 显示全部楼层
glinfei 发表于 2026-3-10 09:41
使用啥电机啊,难在哪呢?发个目前成果给见识一下呗。

就是免费教学百问必答从零做起的那种,啥电机得问你呀
回复

使用道具 举报

ID:1167562 发表于 2026-3-10 13:37 | 显示全部楼层
仿真图.png
#include <reg52.h>
sbit onn=P1^0;
sbit seet=P1^1;
sbit addd=P1^2;
sbit subb=P1^3;
sbit gass=P1^4;
sbit breakk=P1^5;
sbit IN1=P1^6;
sbit IN2=P1^7;
sbit ENA=P2^0;

//占空比,最大占空比
unsigned char ZKB,high=0,on=0,set=0,add=0,sub=0,sc=0,duty_zkb=0,ZKBB=0,cnt=0;


void Motor_Auto_add();
void Time0_Init(void);
void key_process(unsigned char key_num);
void key_scan();

void Time0_Init(void)
{
        TMOD=0X01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=ET0=1;
        TR0=1;
}

void main()
{        IN1=1;
        IN2=0;
       
        Time0_Init();
        //key_process(unsigned char key_num);
        while(1)
        {               
                Motor_Auto_add();
                key_scan();
               
        }
}


//按键扫描
void key_scan()
{
        int i=0;
        //开始建,自增速
        if(onn==0)
                for(i=0;i<200;i++);
                if(onn==0)
                {
                        on=1;//开始标志
                        while(onn==1);
                }
        if(seet==0)
                for(i=0;i<200;i++);
                if(seet==0)
                {
                        set=1;//巡航开始标志
                        duty_zkb=high;//将当前占空比保留
                        while(seet==1);
                }
        if(addd==0)
                for(i=0;i<200;i++);
                if(addd==0)
                {
                        add=1;//加速键标志位
                        while(addd==1);
                }
        if(subb==0)
                for(i=0;i<200;i++);
                if(subb==0)
                {
                        sub=1;//减速标志位
                        while(subb==1);
                }
}

//终端按键扫描执行程序
void key_process(unsigned char key_num)
{
        switch(key_num)
        {
                case 1:
                        high=0;
                        set=0;
                        break;
                case 2:
                        high=0;
                        set=0;
                        break;
                default:
                        break;
        }
}

//电机调速
void Motor_Auto_add()
{
        if(on==1)
        {
                high++;
                high%=100;
        }
        //else
        //{
        //ZKB=0;
        //}
       
        if(set==1)
        {
                high=duty_zkb;
        }
        else if(set==0)
        {high=0;}
       
        if(set==1&&add==1)
        {
                high=high+1;
                if(high==100)
                add=0;
        }
        if(set==1&&sub==1)
        {
                high=high-1;
                if(high<0)
                sub=0;
        }
}



//中断优先
void int0_srv() interrupt 0
{int i=0;
        for(i=0;i<200;i++);
                if(breakk==0)
                {
                        key_process(1);
                        while(breakk==1);
                }
                else if(gass==0)
                {
                        key_process(2);
                        while(gass==1);
                }
}

void time0_srv() interrupt 1
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        cnt++;
        cnt%=100;
        if(cnt<high)
        {
                ENA=1;
        }
        else
        {
                ENA=0;
        }
}

使用的直流电机





回复

使用道具 举报

ID:1167562 发表于 2026-3-10 15:21 | 显示全部楼层
仿真图.png
#include <reg52.h>
sbit onn=P1^0;
sbit seet=P1^1;
sbit addd=P1^2;
sbit subb=P1^3;
sbit gass=P1^4;
sbit breakk=P1^5;
sbit IN1=P1^6;
sbit IN2=P1^7;
sbit ENA=P2^0;

//占空比,最大占空比
unsigned char ZKB,on=0,set=0,add=0,sub=0,duty_zkb=0,cnt=0;
unsigned char high=0;
unsigned int j=0;

void Motor_Auto_add();
void Time0_Init(void);
void key_process(unsigned char key_num);
void key_scan();
void Int0_Init(void);
       
void Int0_Init(void)
{
        IT0=1;//下降沿触发
        EX0=1;// 使能外部中断0
        EA=1;// 开总中断
}
void Time0_Init(void)
{
        TMOD=0X01;//定时器0工作模式1(16位定时器)
        TH0=(65536-1000)/256;// 1ms定时初值(12MHz晶振)
        TL0=(65536-1000)%256;
        ET0=1;   // 使能定时器0中断
        TR0=1;// 启动定时器0
}

void main()
{        IN1=1;// 电机正转方向
        IN2=0;
        ENA=0;
        Int0_Init();//初始化外部中断0
        Time0_Init();//初始化定时器0

        while(1)
        {               
               
                key_scan();
                Motor_Auto_add();// 电机调速逻辑
        }
}


//按键扫描
void key_scan()
{
unsigned int i=0;
        //开始建,自增速
        if(onn==0)
        {
                for(i=0;i<200;i++);
                if(onn==0)
                {
                        on=!on;//开始标志
                        while(onn==0);
                }
        }
        if(seet==0)
        {
                for(i=0;i<200;i++);
                if(seet==0)
                {
                        set=!set;//巡航开始标志
                        if(set)
                        {duty_zkb=high;//将当前占空比保留
                        }

                        while(seet==0);
                }
        }
        if(addd==0)
        {
                for(i=0;i<200;i++);
                if(addd==0)
                {
                        add=1;//加速键标志位
                        while(addd==0);
                }
        }
        if(subb==0)
        {for(i=0;i<200;i++);
                if(subb==0)
                {
                        sub=1;//减速标志位
                        while(subb==0);
                }
        }
}

//终端按键扫描执行程序
void key_process(unsigned char key_num)
{
        switch(key_num)                //电机停转
        {
                case 1:
                        high=0;
                        duty_zkb=0;
                        set=0;
                        on=0;
                        break;
                case 2:
                        high=0;
                        duty_zkb=0;
                        set=0;
                        on=0;
                        break;
                default:
                        break;
        }
}

//电机调速
void Motor_Auto_add()
{
        if(on==1 && !set)
        {
                j++;
                if(j>=50)//每50ms增加1%占空比
                {
                                j=0;
                                if(high<100)
                                high++;
                }
        }
       
       
        if(on==1 && set==1)
        {
                high=duty_zkb;
                //巡航加速
                if(add==1)
                {
                        if(duty_zkb<100)
                                duty_zkb++;
                        add=0;//清除标志位
                }
                if(sub==1)
                {
                        if(duty_zkb>0)
                                duty_zkb--;
                        sub=0;
                }
        }

       
        //未启动,占空比清零
        if(on==0)
        {
                high=0;
               
                duty_zkb=0;
                j=0;
               
        }
}



//中断优先(刹车/油门)
void int0_srv() interrupt 0
{int i=0;
        for(i=0;i<200;i++);
                if(breakk==0)
                {
                        key_process(1);
                        while(breakk==0);
                }
                else if(gass==0)
                {
                        key_process(2);
                        while(gass==0);
                }
}

//定时器中断生成PWM
void time0_srv() interrupt 1
{
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;
        cnt++;
        cnt%=100;
        if(cnt<high)
        {
                ENA=1;
        }
        else
        {
                ENA=0;
        }
}

现在自动加速可以实现,巡航状态下加减速也可以实现。但是巡航时无法保持持当前速度,油门与刹车按钮无法使电机停转。

回复

使用道具 举报

ID:844772 发表于 2026-3-11 10:19 | 显示全部楼层
刹车不接到中断口上,怎么可能生效?那还不如写到键盘程序里,取消中断呢。
没看到保持速度的传感器,不太懂这个部分的原理。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表