久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 242|回復: 1
打印 上一主題 下一主題
收起左側

基于STC89C52RC單片機芯片的智能小車加上oled顯示就不能正常循跡

[復制鏈接]
回帖獎勵 20 黑幣 回復本帖可獲得 20 黑幣獎勵! 每人限 1 次(中獎概率 10%)
跳轉到指定樓層
樓主
ID:1147086 發表于 2025-5-23 22:18 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
在主函數while(1)里面加上兩句代碼:
Distance = GetDistance();if(g_mode == MODE_AUTO)
我是在循跡的基礎上加的oled(循跡也有點小問題,時不能正常循跡
改了好久都解決不了,請大佬瞅一瞅,看一看。感覺oled占用太多的空間,整個代碼效率不高。
超聲波我用了定時器2,循跡使用了定時器0,藍牙串口使用了定時器1,代碼:
主函數:
#include <REGX52.H>
#include "config.h"
#include "motor.h"
#include "HCSR04.h"
#include "Track.h"
#include "Delay.H"
#include "Bluetooth.H"
#include <iic.H>
#include <oled.H>
//函數初始化
void System_Init();
void main() {
    System_Init();
        // 開機動畫
    OLED_ShowStringWithTypewriter(24, 2, "Smart Car", 16);
    Delay(500);
    OLED_Clear();
    while(1)
        {
                Distance = GetDistance();//超聲波測距
                OLED_Refresh();//OLED顯示
                if(g_mode == MODE_AUTO)
                {
            // 自動模式:循跡+避障
            Track_Logic();
            if(GetDistance() < SAFE_DIST)
                        {
                ObstacleAvoidance();
            }
        }
        else
                {
            // 藍牙模式
            if(g_bt_cmd) // 狀態檢測
                        {
                Bluetooth_Control(g_bt_cmd);
                g_bt_cmd = 0;  // 清除指令標志
            }
        }
                Delay(20); // 適當延時
    }               
}

void System_Init() {
    Motor_Init();                // 電機初始化
        Timer0_Init();      // PWM定時器0
    Timer2_Init();      // 超聲波定時器2
        UART_Init();                // 串口初始化,定時器1
        OLED_init();        // 初始化OLED
    OLED_Clear();       // 清屏
        OLED_Display_On();
}

超聲波:
#include <REGX52.H>
#include "config.h"
#include "HCSR04.h"
#include "intrins.h"
#include "Delay.H"
#include "Motor.h"
bit timeout = 0;

void Timer2_Init()
{
    T2CON = 0;          // 清零控制寄存器(默認16位自動重裝載模式)
    T2MOD = 0;          // 清零模式寄存器(遞增計數)
    RCAP2H = 0;         // 重裝載值高位(初始為0,用于超時計數)
    RCAP2L = 0;         // 重裝載值低位
    TH2 = TL2 = 0;      // 計數器初值歸零

    ET2 = 1;            // 開啟定時器2中斷
    PT2 = 1;            // 設置定時器2為高優先級
    EA = 1;             // 總中斷使能
}

unsigned int GetDistance()
{
    unsigned int time_us = 0;

    Trig = 1;           // 觸發信號
    Delay20us();        // 20us延時
    Trig = 0;

    while(!Echo);       // 等待回波高電平
    TR2 = 1;            // 啟動定時器2
    while(Echo && !timeout); // 等待回波結束或超時
    TR2 = 0;            // 停止計時

    if(timeout) {       // 超時處理
        timeout = 0;
        return 999;     // 返回無效值
    }

    time_us = (TH2 << 8) | TL2;  // 獲取計數值(注意:需在TR2=0時讀取)
    TH2 = TL2 = 0;      // 定時器復位
    return (time_us * 0.017);    // 計算距離(cm)
}

//小車避障
void ObstacleAvoidance()
{
    // 停止運動
    Motor_Control(STOP, STOP, 0, 0);
    Delay(200);

    // 后退避讓
    Motor_Control(REV, REV, 70, 70);
    Delay(500);

    // 右轉尋找新路徑
    Motor_Control(FWD, REV, 80, 80);
    Delay(400);

    // 恢復循跡
    TH2 = TL2 = 0;      // 超聲波定時器復位
}
/* 定時器2中斷處理超時*/
void Timer2_ISR() interrupt 5
{
    static unsigned int timeout_cnt = 0;
    TF2 = 0;            // 必須手動清除中斷標志
    if(++timeout_cnt > 60000) { // 約350ms超時
        timeout_cnt = 0;
        timeout = 1;
    }
}

藍牙串口:
#include <REGX52.H>
#include "Bluetooth.H"
#include "Motor.h"
#include "config.h"
#include "Delay.H"
#define BT_BAUD 9600    // 波特率
// 模式枚舉
volatile SystemMode g_mode = 0;
// 藍牙指令緩存
volatile char g_bt_cmd = 0;


//串口初始化
void UART_Init() {
    // 定時器1配置
    TMOD &= 0x0F;       // 保留定時器0配置
    TMOD |= 0x20;       // 定時器1模式2(8位自動重載)
    TH1 = TL1 = 0xFD;   // 波特率9600@11.0592MHz
    TR1 = 1;            // 啟動定時器1

    // 串口配置
        PCON &= 0x7F;
    SCON = 0x50;        // 模式1,允許接收
    ES = 1;             // 使能串口中斷
    EA = 1;             // 總中斷使能
        
}



// 串口中斷
void UART_ISR() interrupt 4 {
    if(RI)
        {

        g_bt_cmd = SBUF;    // 接收藍牙指令
        RI = 0;
                // 模式切換指令解析
        switch(g_bt_cmd) {
            case 'A':       // 自動模式指令
                g_mode = MODE_AUTO;
                IN1 = IN2 = IN3 = IN4 =0;//先注釋
                break;
            case 'B':       // 藍牙模式指令
                g_mode = MODE_BT;
                IN1 = IN2 = IN3 = IN4 =0;
                break;
        }        
    }
}

void Bluetooth_Control(char cmd) {
    switch(cmd) {
        case '1':       // 前進
            Motor_Control(FWD, FWD, 70, 70);
                        Delay(50);
            break;
        case '2':       // 后退
            Motor_Control(REV, REV, 70, 70);
                        Delay(50);
            break;
        case '3':       // 左轉
            Motor_Control(FWD, REV, 70, 70);
                        Delay(50);
            break;
        case '4':       // 右轉
            Motor_Control(REV, FWD, 70, 70);
                        Delay(50);
            break;
        case '0':       // 停止
            Motor_Control(STOP, STOP, 0, 0);
                        Delay(50);
            break;
    }
}

oled部分代碼:

/* 打字機效果顯示函數 */
void OLED_ShowStringWithTypewriter(unsigned char x, unsigned char y, char *str, unsigned char Char_size)
{
    while(*str) {
        OLED_ShowChar(x, y, *str++, Char_size);
        x += 8;  // 字符寬度+間距
        Delay(70);  // 調整延時獲得打字速度
        if(x > 120) {  // 換行處理
            x = 0;
            y += 2;
        }
    }
}


/* 顯示紅外循跡狀態(二進制格式) */
void OLED_ShowTrackState(unsigned char x, unsigned char y)
{
    char binary[5] = {0};
    // 獲取低四位并轉換為二進制字符串
    binary[0] = (Track_State & 0x08) ? '1' : '0';
    binary[1] = (Track_State & 0x04) ? '1' : '0';
    binary[2] = (Track_State & 0x02) ? '1' : '0';
    binary[3] = (Track_State & 0x01) ? '1' : '0';
    OLED_ShowString(x, y, binary, 16);
}
/* 主顯示更新函數 */
void OLED_Refresh()
{
    char dispBuf[16];
    // 第一行:顯示模式
    OLED_Set_Pos(0,0);
    switch(g_mode){
        case MODE_AUTO: OLED_ShowString(0, 0, "Mode:Auto  ", 16); break;
        case MODE_BT:   OLED_ShowString(0, 0, "Mode:BT    ", 16); break;
    }

    // 第二行:顯示距離
    sprintf(dispBuf, "Dist:%3dcm", Distance);
    OLED_ShowString(0, 2, dispBuf, 16);
    // 第三行:顯示循跡狀態
    OLED_ShowString(0, 4, "Track:", 16);
    OLED_ShowTrackState(48, 4);

}

循跡基礎加oled.zip

123.76 KB, 下載次數: 0

基于51循跡避障加oled顯示

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1152543 發表于 2025-6-5 18:04 | 只看該作者
遇到了一樣的問題
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 中文字幕一区二区三区四区 | 日韩在线观看视频一区 | 精品日本久久久久久久久久 | 国产精品亚洲一区二区三区在线 | 精品一二区 | 一起操网站 | 久久av一区二区三区 | 黄色片视频网站 | 伊人精品国产 | 国内精品久久精品 | 久久久精彩视频 | 91一区二区三区 | 国产一级片免费在线观看 | 人成在线| 精品一区二区三区入口 | 狠狠干天天干 | 亚洲激精日韩激精欧美精品 | 日日碰碰 | 国产精品99久久久久久宅男 | 欧美一区二区三区在线 | 成人免费福利视频 | 91精品国产91久久久久久密臀 | 成人福利网站 | 一区二区在线 | 99久久精品免费 | 亚洲国产精品一区二区三区 | 成人在线免费电影 | 一级黄色播放 | 国产精品久久久久久久久久免费看 | 看羞羞视频免费 | 国产午夜精品久久久久免费视高清 | 日韩精品一区二区三区久久 | 天堂久| 日韩欧美不卡 | 国产成人精品一区 | 美女一区 | 精品国产高清一区二区三区 | 欧美手机在线 | 在线伊人 | 国产成人综合网 | 日韩精品中文字幕一区二区三区 |