亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

標(biāo)題: STC8H1K08 ADC不起作用 [打印本頁(yè)]

作者: dream2023    時(shí)間: 2026-6-19 11:01
標(biāo)題: STC8H1K08 ADC不起作用
程序如下,LED燈沒(méi)有變化

#include "STC8h.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit led=P1^1;       
u16 num;
void GPIO_Init()
{
        P1M0 = 0xFF;
        P1M1 = 0xFF;
        P5M0 = 0x00;
        P5M1 = 0x00;
        P3M0 = 0x00;
        P3M1 = 0x04;
}

void STC8ADC_Init()
{
    P_SW2 |= 0x80;
    ADCTIM = 0x3f;                       
    P_SW2 &= 0x7f;
    ADCCFG = 0x00;            
    ADC_CONTR = 0x8A;     
}

void ADC_Isr() interrupt 5
{
   EADC = 1;                        
  ADC_CONTR |= 0x40;
  _nop_();
  _nop_();
        while(  !(ADC_CONTR&0x20) );
  ADC_CONTR&= ~0x20;
  num=(ADC_RES<<8) | ADC_RESL;              
}

void main()
{
          GPIO_Init();
    STC8ADC_Init();
          EA=1;
   led=1;
        while(1)
{
if(num>300)
led=~led;
}}
作者: zhuls    時(shí)間: 2026-6-20 00:39
1、既然用中斷方式,那么EA=1總是要有的,否則中斷無(wú)效,你的代碼中沒(méi)有?
2、“~”的作用對(duì)象至少是字節(jié)(BYTE),可你的代碼是 led=~led,(P1^1),不匹配,可能會(huì)產(chǎn)生意料之外的結(jié)果。
3、ADC_CONTR = 0x8A ,說(shuō)明用的是ADC10,不同封裝ADC10對(duì)應(yīng)不同IO,IO選對(duì)了?
4、是否有ADC_Vref,參考電源有接?


作者: zhuls    時(shí)間: 2026-6-20 00:44
認(rèn)真看一下代碼,原來(lái)是在中斷中才開(kāi)EADC=1的,有才,左腳踩右腳了!
void ADC_Isr() interrupt 5
{
   EADC = 1;                        
  ADC_CONTR |= 0x40;
  _nop_();
  _nop_();
        while(  !(ADC_CONTR&0x20) );
  ADC_CONTR&= ~0x20;
  num=(ADC_RES<<8) | ADC_RESL;              
}


作者: zhuls    時(shí)間: 2026-6-20 00:54
來(lái)自STC AI助手的回答(最后附有改進(jìn)后代碼):

您的代碼有 多個(gè)關(guān)鍵問(wèn)題,逐一分析如下:
&#128308; 問(wèn)題 1:ADC 轉(zhuǎn)換從未啟動(dòng)(最核心問(wèn)題)

ADC_CONTR = 0x8A;   // 0x8A = 1000 1010

位         名稱(chēng)         值         含義
Bit 7         ADC_POWER         1         ✓ ADC電源已打開(kāi)
Bit 6         ADC_START         0         ✗ 從未啟動(dòng)轉(zhuǎn)換!
Bit 5         ADC_FLAG         0         標(biāo)志位
Bit 4         ADC_EPWMT         0         未使用PWM觸發(fā)
Bit 3-0         ADC_CHS         1010         ADC10通道(P3.2)

后果:ADC 不上電、不開(kāi)始轉(zhuǎn)換,中斷永遠(yuǎn)觸發(fā)不了,ISR中的代碼從未被執(zhí)行,num始終為 0。
&#128308; 問(wèn)題 2:ISR 內(nèi)部邏輯嚴(yán)重錯(cuò)誤(死鎖風(fēng)險(xiǎn))

void ADC_Isr() interrupt 5
{
    EADC = 1;                   // ① 在ISR中使能中斷——無(wú)意義,應(yīng)在主循環(huán)中設(shè)置
    ADC_CONTR |= 0x40;          // ② 啟動(dòng)新轉(zhuǎn)換
    _nop_(); _nop_();
    while( !(ADC_CONTR&0x20) ); // ③ 輪詢(xún)ADC_FLAG —— 死鎖!!!
    ADC_CONTR&= ~0x20;           // ④ 清標(biāo)志
    num=(ADC_RES<<8) | ADC_RESL;
}

對(duì)照手冊(cè)范例(STC8H手冊(cè) 21.7.2 中斷方式)正確的 ISR 應(yīng)為:

void ADC_Isr() interrupt 5
{
    ADC_CONTR &= ~0x20;     // ① 先清中斷標(biāo)志
    num = (ADC_RES << 8) | ADC_RESL;  // ② 讀結(jié)果
    ADC_CONTR |= 0x40;      // ③ 啟動(dòng)下一次轉(zhuǎn)換
}

您的代碼問(wèn)題:

    第③步 while(!(ADC_CONTR&0x20)) 在 ISR 內(nèi)輪詢(xún)標(biāo)志——此時(shí)ADC_START剛剛寫(xiě)入,轉(zhuǎn)換剛開(kāi)始,標(biāo)志還沒(méi)置位,會(huì)永遠(yuǎn)卡死在循環(huán)中(死鎖)。
    正常流程應(yīng)該是:先清標(biāo)志 → 讀結(jié)果 → 啟動(dòng)下次轉(zhuǎn)換 → RETI。

&#128308; 問(wèn)題 3:P1 口模式全部設(shè)為開(kāi)漏,LED 無(wú)法驅(qū)動(dòng)

P1M0 = 0xFF;
P1M1 = 0xFF;

對(duì)于 STC8H 系列,端口模式定義:
PnM1         PnM0         模式
0         0         準(zhǔn)雙向口
0         1         推挽輸出
1         0         高阻輸入
1         1         開(kāi)漏

P1M0=0xFF, P1M1=0xFF → 所有 P1 引腳均為開(kāi)漏模式。P1.1作為L(zhǎng)ED輸出,用開(kāi)漏模式無(wú)法輸出高電平驅(qū)動(dòng)LED,燈永遠(yuǎn)不亮。
&#128308; 問(wèn)題 4:ADC 通道與引腳對(duì)應(yīng)關(guān)系需確認(rèn)

您的 ADC_CONTR = 0x8A(ADC_CHS=1010)選擇的是 ADC10 通道。

對(duì)于 STC8H1K08 系列,查手冊(cè) 21.1.1 的通道映射表:
ADC_CHS         ADC通道         對(duì)應(yīng)引腳(STC8H1K08)
1010         ADC10         P3.2

而您在 GPIO_Init 中將 P3M1=0x04(即 P3.2 設(shè)為了高阻輸入),這步是對(duì)的。但您的 ADC 輸入信號(hào)實(shí)際接在哪個(gè)引腳上?請(qǐng)確認(rèn):

    如果輸入信號(hào)接在 P3.2 → ADC10(CHS=1010)✅
    如果輸入信號(hào)接在 P1.0 → ADC0(CHS=0000)
    如果輸入信號(hào)接在 P1.1 → ADC1(CHS=0001)

另外需要注意的是,STC8H1K08 只有 ADC0/1/8/9/10/11/12/13/14 和內(nèi)部1.19V 共11個(gè)通道,沒(méi)有 ADC2~ADC7。
&#128308; 問(wèn)題 5:ADCCFG = 0x00 設(shè)定左對(duì)齊,但讀法需匹配

ADCCFG = 0x00;  // RESFMT=0 → 左對(duì)齊

STC8H1K08 是 10位ADC,左對(duì)齊時(shí):

    ADC_RES[7:0] = 結(jié)果的高8位
    ADC_RESL[7:6] = 結(jié)果的低2位(ADC_RESL的低6位為0)

所以正確的讀取方式應(yīng)為:

num = (ADC_RES << 2) | (ADC_RESL >> 6);   // 10位值
// 或 num = (u16)ADC_RES * 4 + (ADC_RESL >> 6);

而您寫(xiě)的 (ADC_RES<<8) | ADC_RESL 會(huì)把 ADC_RES 左移8位(相當(dāng)于乘以256),值會(huì)嚴(yán)重偏大,遠(yuǎn)超300這個(gè)閾值。
✅ 修正后的完整代碼

以下是根據(jù) STC8H 手冊(cè) 21.7.2 范例修正的 中斷方式 代碼,假設(shè) ADC 輸入接 P3.2(ADC10),LED 接 P1.1:

#include "stc8h.h"
#include "intrins.h"

typedef unsigned char u8;
typedef unsigned int u16;

sbit led = P1^1;
u16 num;

void GPIO_Init()
{
    // P1.1 LED → 推挽輸出(P1M0.1=1, P1M1.1=0)
    // P1.0/1.2等保持準(zhǔn)雙向
    P1M0 = 0x02;   // 僅 P1.1 推挽
    P1M1 = 0x00;

    // P3.2 ADC輸入 → 高阻輸入(P3M1.2=1, P3M0.2=0)
    P3M0 = 0x00;
    P3M1 = 0x04;   // 僅 P3.2 高阻

    // P5保持默認(rèn)
    P5M0 = 0x00;
    P5M1 = 0x00;
}

void ADC_Init()
{
    P_SW2 |= 0x80;          // 使能訪問(wèn) XFR
    ADCTIM = 0x3F;          // ADC 內(nèi)部時(shí)序
    P_SW2 &= 0x7F;

    ADCCFG = 0x00;          // RESFMT=0 左對(duì)齊, SPEED=0000 最快速度

    ADC_CONTR = 0x80;       // ADC_POWER=1, CHS=0000(ADC0)
    // 稍后需要時(shí)再切換通道并啟動(dòng)
}

void ADC_Isr() interrupt 5
{
    ADC_CONTR &= ~0x20;             // 清 ADC_FLAG
    num = ((u16)ADC_RES << 2) | (ADC_RESL >> 6);   // 10位左對(duì)齊 → 數(shù)值
    led = (num > 300) ? (~led) : led;   // LED 根據(jù)結(jié)果翻轉(zhuǎn)
    // 可選:?jiǎn)?dòng)下一次轉(zhuǎn)換
    // ADC_CONTR |= 0x40;
}

void main()
{
    GPIO_Init();
    ADC_Init();

    EADC = 1;               // 使能 ADC 中斷
    EA = 1;

    // 選擇通道并啟動(dòng)第一次轉(zhuǎn)換
    ADC_CONTR = 0x80 | 0x0A;    // ADC_POWER=1, CHS=1010(ADC10=P3.2)
    _nop_(); _nop_();           // 等待 ADC 電源穩(wěn)定(實(shí)際需~1ms,最好加軟件延時(shí))
    ADC_CONTR |= 0x40;          // 啟動(dòng)第一次轉(zhuǎn)換

    led = 0;                    // LED初始滅(假設(shè)低電平滅)

    while(1)
    {
        // 也可以在 main loop 中查詢(xún)方式:
        // if(num > 300) led = ~led;
        // num 由 ISR 自動(dòng)更新
    }
}

&#128203; 問(wèn)題對(duì)照總結(jié)
問(wèn)題         代碼行         后果
❌ ADC_START 從未置1         ADC_CONTR = 0x8A         轉(zhuǎn)換永不啟動(dòng),ISR不觸發(fā),num恒為0
❌ ISR內(nèi)輪詢(xún)等待標(biāo)志         while(!(ADC_CONTR&0x20))         死鎖卡死
❌ ISR內(nèi)寫(xiě)EADC         EADC=1         不影響,應(yīng)寫(xiě)在main中
❌ P1全部開(kāi)漏         P1M0=P1M1=0xFF         LED無(wú)法驅(qū)動(dòng)
❌ 10位ADC結(jié)果讀法錯(cuò)誤         (ADC_RES<<8)|ADC_RESL         數(shù)值遠(yuǎn)大于300
⚠️ ADC通道選擇         0x8A→ADC10=P3.2         需確認(rèn)輸入信號(hào)接在哪
作者: joyb    時(shí)間: 2026-6-21 08:41
1. 修正GPIO初始化
只將ADC輸入腳設(shè)為高阻,LED腳設(shè)為推挽輸出:

c
void GPIO_Init()
{
    P1M0 = 0x02;      // P1.1 推挽輸出(bit1=1)
    P1M1 = 0x00;      // P1.1 推挽(M1=0)
    P1M0 &= ~0x04;    // P1.2 高阻輸入(M0=0)
    P1M1 |= 0x04;     // P1.2 高阻(M1=1)
    // 其他端口保持默認(rèn)或按需配置
}
如果您的ADC通道不是P1.2,請(qǐng)根據(jù)實(shí)際情況修改。

2. 完善ADC初始化
在STC8ADC_Init()中添加中斷使能,并清除相關(guān)標(biāo)志:

c
void STC8ADC_Init()
{
    P_SW2 |= 0x80;          // 訪問(wèn)特殊功能寄存器
    ADCTIM = 0x3f;          // 設(shè)置ADC時(shí)序
    P_SW2 &= 0x7f;
    ADCCFG = 0x00;          // 左對(duì)齊,12位結(jié)果
    ADC_CONTR = 0x8A;       // 開(kāi)啟ADC電源,選擇通道10(P1.2),不啟動(dòng)轉(zhuǎn)換
   
    // 使能ADC中斷
    IE2 |= 0x20;            // STC8H中EADC位在IE2.5
    // 或者使用 EADC = 1; (如果頭文件已定義)
}
3. 啟動(dòng)第一次轉(zhuǎn)換
在main()中,開(kāi)總中斷后立即啟動(dòng)轉(zhuǎn)換:

c
void main()
{
    GPIO_Init();
    STC8ADC_Init();
    EA = 1;
    led = 1;
    ADC_CONTR |= 0x40;      // 啟動(dòng)第一次ADC轉(zhuǎn)換(ADC_START位)
   
    while(1)
    {
        if(num > 300)
        {
            led = ~led;
            // 可根據(jù)需要加入延時(shí),避免翻轉(zhuǎn)過(guò)快
        }
    }
}
4. 精簡(jiǎn)中斷服務(wù)函數(shù)
移除EADC=1,確保轉(zhuǎn)換完成后自動(dòng)啟動(dòng)下一次:

c
void ADC_Isr() interrupt 5
{
    ADC_CONTR &= ~0x20;      // 清除完成標(biāo)志(ADC_FLAG)
    num = (ADC_RES << 8) | ADC_RESL;
    ADC_CONTR |= 0x40;       // 啟動(dòng)下一次轉(zhuǎn)換
}




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