欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: 基于STC89C52RC單片機(jī)芯片的智能小車加上oled顯示就不能正常循跡 [打印本頁]

作者: 孤久則慣    時(shí)間: 2025-5-23 22:18
標(biāo)題: 基于STC89C52RC單片機(jī)芯片的智能小車加上oled顯示就不能正常循跡
在主函數(shù)while(1)里面加上兩句代碼:
Distance = GetDistance();if(g_mode == MODE_AUTO)
我是在循跡的基礎(chǔ)上加的oled(循跡也有點(diǎn)小問題,時(shí)不能正常循跡
改了好久都解決不了,請(qǐng)大佬瞅一瞅,看一看。感覺oled占用太多的空間,整個(gè)代碼效率不高。
超聲波我用了定時(shí)器2,循跡使用了定時(shí)器0,藍(lán)牙串口使用了定時(shí)器1,代碼:
主函數(shù):
#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>
//函數(shù)初始化
void System_Init();
void main() {
    System_Init();
        // 開機(jī)動(dòng)畫
    OLED_ShowStringWithTypewriter(24, 2, "Smart Car", 16);
    Delay(500);
    OLED_Clear();
    while(1)
        {
                Distance = GetDistance();//超聲波測(cè)距
                OLED_Refresh();//OLED顯示
                if(g_mode == MODE_AUTO)
                {
            // 自動(dòng)模式:循跡+避障
            Track_Logic();
            if(GetDistance() < SAFE_DIST)
                        {
                ObstacleAvoidance();
            }
        }
        else
                {
            // 藍(lán)牙模式
            if(g_bt_cmd) // 狀態(tài)檢測(cè)
                        {
                Bluetooth_Control(g_bt_cmd);
                g_bt_cmd = 0;  // 清除指令標(biāo)志
            }
        }
                Delay(20); // 適當(dāng)延時(shí)
    }               
}

void System_Init() {
    Motor_Init();                // 電機(jī)初始化
        Timer0_Init();      // PWM定時(shí)器0
    Timer2_Init();      // 超聲波定時(shí)器2
        UART_Init();                // 串口初始化,定時(shí)器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;          // 清零控制寄存器(默認(rèn)16位自動(dòng)重裝載模式)
    T2MOD = 0;          // 清零模式寄存器(遞增計(jì)數(shù))
    RCAP2H = 0;         // 重裝載值高位(初始為0,用于超時(shí)計(jì)數(shù))
    RCAP2L = 0;         // 重裝載值低位
    TH2 = TL2 = 0;      // 計(jì)數(shù)器初值歸零

    ET2 = 1;            // 開啟定時(shí)器2中斷
    PT2 = 1;            // 設(shè)置定時(shí)器2為高優(yōu)先級(jí)
    EA = 1;             // 總中斷使能
}

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

    Trig = 1;           // 觸發(fā)信號(hào)
    Delay20us();        // 20us延時(shí)
    Trig = 0;

    while(!Echo);       // 等待回波高電平
    TR2 = 1;            // 啟動(dòng)定時(shí)器2
    while(Echo && !timeout); // 等待回波結(jié)束或超時(shí)
    TR2 = 0;            // 停止計(jì)時(shí)

    if(timeout) {       // 超時(shí)處理
        timeout = 0;
        return 999;     // 返回?zé)o效值
    }

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

//小車避障
void ObstacleAvoidance()
{
    // 停止運(yùn)動(dòng)
    Motor_Control(STOP, STOP, 0, 0);
    Delay(200);

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

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

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

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


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

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



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

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

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

oled部分代碼:

/* 打字機(jī)效果顯示函數(shù) */
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);  // 調(diào)整延時(shí)獲得打字速度
        if(x > 120) {  // 換行處理
            x = 0;
            y += 2;
        }
    }
}


/* 顯示紅外循跡狀態(tài)(二進(jìn)制格式) */
void OLED_ShowTrackState(unsigned char x, unsigned char y)
{
    char binary[5] = {0};
    // 獲取低四位并轉(zhuǎn)換為二進(jìn)制字符串
    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);
}
/* 主顯示更新函數(shù) */
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);
    // 第三行:顯示循跡狀態(tài)
    OLED_ShowString(0, 4, "Track:", 16);
    OLED_ShowTrackState(48, 4);

}

循跡基礎(chǔ)加oled.zip

123.76 KB, 下載次數(shù): 0

基于51循跡避障加oled顯示


作者: qingxingdluntan    時(shí)間: 2025-6-5 18:04
遇到了一樣的問題
作者: 單片機(jī)重購    時(shí)間: 2025-6-5 23:32
我感覺不是你OLED加進(jìn)來的問題哦,是你使用單片機(jī)的時(shí)候,使用的配置寄存器,以及串口和中斷系統(tǒng)使用的問題。
作者: 瀟湘KK    時(shí)間: 2025-6-9 09:41
OLED 驅(qū)動(dòng)占用過多 RAM,STC89C52RC 僅有 128B RAM,OLED 驅(qū)動(dòng)可能導(dǎo)致堆棧溢出
作者: weijoyer    時(shí)間: 2025-6-19 18:39
代碼阻塞了,采集響應(yīng)不及時(shí),建議改成時(shí)間片輪轉(zhuǎn)式的代碼結(jié)構(gòu),可以提高運(yùn)行效率




歡迎光臨 (http://www.raoushi.com/bbs/) Powered by Discuz! X3.1