亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
為什么紅外遙控解碼響應一次,然后再按遙控就沒反應了
[打印本頁]
作者:
xiaoyuxinke
時間:
2026-4-26 14:17
標題:
為什么紅外遙控解碼響應一次,然后再按遙控就沒反應了
//****************************************************************
#include <STC32G.h> // 包含STC32G系列寄存器定義頭文件
#include <intrins.h> // 包含 intrinsics 內聯函數頭文件
#include <hong.h> // 包含自定義紅外解碼相關頭文件
#define SJM_MIN 26 //數據0高電平最小計數值
#define SJM_MAX 30 //數據0高電平最大計數值
#define DATA_NUM 32 //紅外數據總長度(位)
//****************************************************************
//函數聲明
//****************************************************************
void buzz(void); // 蜂鳴器驅動函數
void DelayMs(u16 ms); // 毫秒級延時函數
void Delay(u8 us); // 微秒級延時函數
void Update_duty(void); // PWM占空比更新函數
void liangducabiao(void); // 亮度等級查表函數
void dssq(void);
//****************************************************************
//全局變量
//****************************************************************
bit Flag0 = 0; //紅外遙控解碼標志位
bit Flag1 = 0; //充電功能是否開啟標志位
bit Flag2 = 0; //是否點亮LED光源標志位
bit Flag3 = 0; //紅外接收完成標志位
bit ydordata = 0; //引導碼識別完成標志
bit ydmgdbzw = 0; //引導碼狀態機標志位
bit sjmgdbzw = 0;
u8 ydm_low = 0; //引導碼低電平計數值暫存
u8 ydm_high = 0; //引導碼高電平計數值暫存
u8 ydmtime = 0; //引導碼總計數值暫存
u8 code_low = 0; //引導碼低電平計數值
u8 code_high = 0; //引導碼高電平計數值
u8 sjm_high = 0; //數據碼高電平時間計數暫存
u8 sjm_low = 0; //數據碼低電平時間計數暫存
u8 sjmtime = 0;
u32 irdata = 0; //紅外32位原始數據
u32 irdata2=0;
u8 data_cnt = 0; //紅外數據位計數器
u8 ir_data[DATA_NUM]; //紅外數據緩存數組
u8 liangdudengji = 0; //燈亮度等級(共10級)
u8 sjjsqbl = 0; //時間計數器變量
u16 duty = 0; //PWM占空比初值
//****************************************************************
//【IO口定義】
//****************************************************************
sbit norun = P3^0; //禁止運行,此引腳為低電平,全系統禁止充電放電和其它功能
sbit led1 = P3^4; //紅色充電指示燈,未充電時主光源板亮起紅燈常亮,否則紅燈閃爍
sbit led2 = P3^5; //綠色充電指示燈,充電時綠燈閃爍,電壓不足時紅燈閃
sbit led3 = P3^6; //紅外接收指示引腳(預留)
sbit IR_IN = P3^3; //紅外接收頭輸入引腳
sbit pwmx = P1^0; //PWM充放電上管控制腳
sbit pwms = P1^1; //PWM充放電下管控制腳
sbit gfkz = P1^4; //光伏板開關控制線
sbit ldkz = P1^5; //亮燈控制線
sbit bootkz = P5^4; //半橋驅動升壓控制線
sbit adc1 = P1^6; //光伏板電壓ADC
sbit adc2 = P1^3; //電池電壓ADC
sbit adc3 = P1^7; //電池電流ADC
//****************************************************************
//【紅外遙控解碼狀態機】
//【此功能部分要求相當嚴格,不得隨意更改任何參數】
//【紅外解碼分兩部分完成-先確認引導碼再解數據碼】
//****************************************************************
void INT1_Isr() interrupt 2 // INT1 中斷服務函數,中斷號2
{
if (ydordata==0) // 判斷是否處于“引導碼/同步碼”解碼階段
{
if(IR_IN==0&&ydmgdbzw==0) // 如果是下降沿且處于初始狀態
{
ydm_low = 0; // 低電平計數器清零
ydmgdbzw=0; // 引導碼狀態機清零(此處似乎邏輯重復或多余)
TR0=1; // 啟動定時器0開始計數低電平寬度
ET0=1; // 允許定時器0中斷(如果使用溢出中斷)
}
else if(IR_IN==1&&ydmgdbzw==0) // 如果是上升沿且處于初始狀態
{
ydm_high=0; // 高電平計數器清零
ydmgdbzw=1; // 標記已經進入高電平測量階段
}
else if(IR_IN==0&&ydmgdbzw==1) // 如果是下降沿且已完成高電平測量
{
TR0=0; // 停止定時器0
ET0=0; // 禁止定時器0中斷
code_low=ydm_low; // 保存低電平計數值
code_high=ydm_high; // 保存高電平計數值
ydmtime=ydm_low+ydm_high; // 計算總周期(脈沖低電平時間+脈沖高電平時間)
if(ydmtime>86&&ydmtime<96) // 判斷引導碼是否符合格/同步碼時長
{
ydmtime=0; // 清空變量
ydm_low=0; // 清空變量
ydm_high=0; // 清空變量
ydmgdbzw = 0; // 重置引導碼狀態機
ydordata=1; // 引導碼解碼完成,轉換狀態,準備解數據碼
led1=!led1;
}
}
}
//****************************************************************
//【紅外數據碼解碼部分】
//【此功能部分要求相當嚴格,不得隨意更改任何參數】
//【紅外解碼分兩部分完成-先確認引導碼再解數據碼】
//****************************************************************
else if (ydordata==1) // 判斷是否處于“數據碼”解碼階段
{ // 【嚴重語法警告】這里少了一個 '{',導致下面代碼邏輯與INT1_ISR綁定
if(ydordata==1&&IR_IN==0&&sjmgdbzw==0) // 數據階段的下降沿觸發
{
sjm_low = 0; // 數據位低電平計數清零
sjmgdbzw=0; // 數據位狀態機清零
TR1=1; // 啟動定時器1
ET1=1; // 允許定時器1中斷
}
else if(ydordata==1&&IR_IN==1&&sjmgdbzw==0) // 數據階段的上升沿
{
sjm_high=0; // 數據位高電平計數清零
sjmgdbzw=1; // 標記進入高電平測量
}
else if(ydordata==1&&IR_IN==0&&sjmgdbzw==1) // 數據位結束(下一個下降沿)
{
TR1=0; // 停止定時器1
ET1=0; // 禁止定時器1中斷
sjmtime=sjm_low+sjm_high; // 計算數據位總周期
//****************************************************************
if(data_cnt < 32) // 如果還未接收完32位數據
{
if(sjmtime > 50 && sjmtime < 60) // 判斷是否為"0"碼(短脈沖實際應該是56)
{
ir_data[data_cnt] = sjmtime; // 存儲原始數據
irdata = (irdata << 1) | 0; // 左移并補0
data_cnt++; // 數據位計數加1
sjmtime=0;
}
else if(sjmtime > 100 && sjmtime < 120) // 判斷是否為"1"碼(長脈沖實際應該是112)
{
ir_data[data_cnt] = sjmtime; // 存儲原始數據
irdata = (irdata << 1) | 1; // 左移并補1
data_cnt++; // 數據位計數加1
sjmtime=0;
}
}
else if(data_cnt >= 32) // 如果32位數據接收完成
{
irdata2 = 0;
irdata2 = irdata; // 備份完整的32位數據
sjm_low = 0;
sjm_high = 0;
sjmtime = 0;
data_cnt = 0; // 數據計數器清零,準備下次接收
irdata = 0; // 數據寄存器清零
sjmgdbzw = 0; // 數據狀態機復位
ydordata = 0;
}
}
}
}
//****************************************************************
//紅外對碼匹配函數
//****************************************************************
void IR_Code_Match(u32 irdata2)
{
if(irdata2 == 0x00FFA25D) /*紅色鍵*/ {liangdudengji=3;liangducabiao();}
else if(irdata2 == 0x00FF629D) /*ON鍵*/ {liangdudengji=10;liangducabiao();led2=0;}
else if(irdata2 == 0x00FF22DD) /*OFF鍵*/ {liangdudengji=0;liangducabiao();led2=1;}
else if(irdata2 == 0x00FFC23D) /*圓上鍵*/ {}
else if(irdata2 == 0x00FFB04F) /*圓下鍵*/ {}
else if(irdata2 == 0x00FFE01F) /*圓左鍵*/ {if(liangdudengji <10) {liangdudengji++;liangducabiao();}}
else if(irdata2 == 0x00FF906F) /*圓右鍵*/ {if(liangdudengji >0) {liangdudengji--;liangducabiao();}}
else if(irdata2 == 0x00FF10EF) /*圓中鍵*/ {}
else if(irdata2 == 0x00FF9867) /*長條鍵*/ {}
else if(irdata2 == 0x00FFA857) /*003H鍵*/ {sjjsqbl=3;liangdudengji = 10;liangducabiao();RTCCR=0x01;}
else if(irdata2 == 0x00FF6897) /*005H鍵*/ {sjjsqbl=5;liangdudengji = 10;liangducabiao();RTCCR=0x01;}
else if(irdata2 == 0x00FF18E7) /*008H鍵*/ {sjjsqbl=8;liangdudengji = 10;liangducabiao();RTCCR=0x01;}
}
//****************************************************************
//燈亮度查表函數
//****************************************************************
void liangducabiao(void)
{
if (liangdudengji == 0) { duty = 0; }
else if (liangdudengji == 1) { duty = 6; }
else if (liangdudengji == 2) { duty = 28; }
else if (liangdudengji == 3) { duty = 65; }
else if (liangdudengji == 4) { duty = 115;}
else if (liangdudengji == 5) { duty = 180;}
else if (liangdudengji == 6) { duty = 259;}
else if (liangdudengji == 7) { duty = 352;}
else if (liangdudengji == 8) { duty = 460;}
else if (liangdudengji == 9) { duty = 580;}
else if (liangdudengji == 10) { duty = 1023;}
else { return; }
Update_duty();
}
//****************************************************************
//定時減亮度
//****************************************************************
void dssq(void)
{
if(sjjsqbl==3)
{
RTCCR=0x01;
if(RTCMIN==0x00) {liangdudengji=8;liangducabiao();}
else if(RTCMIN==0x01) {liangdudengji=6;liangducabiao();}
else if(RTCMIN==0x02) {liangdudengji=4;liangducabiao();}
else if(RTCMIN==0x03) {liangdudengji=2;liangducabiao();}
else if(RTCMIN==0x04&&RTCSEC==0x01) {RTCCR=0x00;INIMIN=0x00;RTCMIN=0x00;RTCSEC=0x00;RTCCFG=0x03;liangdudengji=0;liangducabiao();sjjsqbl=0;}
}
if(sjjsqbl==5)
{
RTCCR=0x01;
if(RTCMIN==0x00) {liangdudengji=8;liangducabiao();}
else if(RTCMIN==0x10) {liangdudengji=6;liangducabiao();}
else if(RTCMIN==0x20) {liangdudengji=4;liangducabiao();}
else if(RTCMIN==0x30) {liangdudengji=2;liangducabiao();}
else if(RTCMIN==0x31&&RTCSEC==0x01) {RTCCR=0x00;INIMIN=0x00;RTCMIN=0x00;RTCSEC=0x00;RTCCFG=0x03;liangdudengji=0;liangducabiao();sjjsqbl=0;}
}
if(sjjsqbl==8)
{
RTCCR=0x01;
if(RTCHOUR==0x00) {liangdudengji=8;liangducabiao();}
else if(RTCHOUR==0x01) {liangdudengji=6;liangducabiao();}
else if(RTCHOUR==0x02) {liangdudengji=4;liangducabiao();}
else if(RTCHOUR==0x03) {liangdudengji=2;liangducabiao();}
else if(RTCHOUR==0x04&&RTCMIN==0x00&&RTCSEC==0x01) {RTCCR=0x00;INIMIN=0x00;RTCMIN=0x00;RTCSEC=0x00;RTCCFG=0x03;liangdudengji=0;liangducabiao();sjjsqbl=0;}
}
}
//****************************************************************
//定時器0初始化
//****************************************************************
void Timer0_Init(void) //150微秒@24.000MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0xF0; //設置定時初始值
TH0 = 0xF1; //設置定時初始值
TF0 = 0; //清除TF0標志
TR0 = 0; //定時器0開始計時
ET0 = 0;
}
//****************************************************************
//定時器1初始化
//****************************************************************
void Timer1_Init(void) //20微秒@24.000MHz
{
AUXR |= 0x40; //定時器時鐘1T模式
TMOD &= 0x0F; //設置定時器模式
TL1 = 0x20; //設置定時初始值
TH1 = 0xFE; //設置定時初始值
TF1 = 0; //清除TF1標志
TR1 = 0; //定時器1開始計時
ET1 = 0;
}
//****************************************************************
//定時器0中斷服務函數
//****************************************************************
void Timer0_ISR(void) interrupt 1
{
TF0 = 0;
if(IR_IN==0)
{
ydm_low++;
}
else if(IR_IN==1)
{
ydm_high++;
}
}
//****************************************************************
//定時器1中斷服務函數
//****************************************************************
void Timer1_ISR(void) interrupt 3
{
TF1 = 0;
if(IR_IN==0)
{
sjm_low++;
}
else if(IR_IN==1)
{
sjm_high++;
}
}
//****************************************************************
//更新PWM占空比函數
//****************************************************************
void Update_duty(void)
{
PWMA_CCR1H = (u8)(duty >> 8);
PWMA_CCR1L = (u8)(duty & 0xFF);
}
//****************************************************************
//主函數
//****************************************************************
void main(void)
{
WTST = 0;
EAXFR = 1;
CKCON = 0;
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x33; P1M1 = 0xc8;
P2M1 = 0x00; P2M0 = 0x00;
P3M0 = 0x70; P3M1 = 0x08;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x10; //P5.4升壓控制端為強推
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
pwms = 1; //開機關閉升降壓功能上MOS
pwmx = 1; //開機關閉升降壓功能下MOS
norun = 1; //當前狀態允許運行
led1 = 1; //開機默認電源指示燈不亮
led2 = 1; //開機默認充電指示燈不亮
led3 = 0;
ldkz = 1; //開機關閉LED光源板
gfkz = 1; //單片機初始化時斷開光伏板
bootkz = 0; //單片機初始化時關閉MOS驅動升壓功能
//*****************************************************************
//【單片機內部時鐘模塊定義】
//*****************************************************************
RTCCFG=0x03; //內外部時鐘源選擇并初始化所有時間寄存器
IRC32KCR=0x80; //啟動內部32K晶振
while (!(IRC32KCR & 1)); //等待時鐘穩定
INIHOUR=0x00; //初始化小時
INIMIN=0x00; //初始化分鐘
INISEC=0x00; //初始化秒鐘
INISSEC=0x00; //初始化1/128秒
//RTCCR=0x01; //使能內部實時時鐘
RTCCR=0x00; //暫停內部實時時鐘
//*****************************************************************
//【單片機使用外部中斷功能】
//*****************************************************************
IT1 = 0;
EX1 = 1;
//****************************************************************
// 充電功能部分PWM兩路互補,一路主動PWM,另一路互補
// 晶振:30MHz 頻率:35kHz 死區:有效
// P1.0(PWM1P)=85% P1.1(PWM1N)=15%
//****************************************************************
PWMA_CR1 = 0x00; // 關閉計數器
PWMA_CCER1 = 0x00; // 關閉通道1輸出
PWMA_CCER2 = 0x00; // 關閉通道2,避免干擾
// ---------- 時基:30MHz → 40kHz ----------
PWMA_PSCRH = 0x00;
PWMA_PSCRL = 0x00; // 預分頻=1
PWMA_ARRH = 0x02; // ARR高8位
PWMA_ARRL = 0xED; // ARR低8位
// ---------- 模式:PWM模式1,互補 ----------
PWMA_CCMR1 = 0x68; // PWM模式1,預裝載
// ---------- 死區 ----------
PWMA_DTR = 0x10; // 死區不變
// ---------- 輸出使能 ----------
PWMA_CCER1 = 0x55; // 使能PWM1P+PWM1N,默認高有效
PWMA_ENO = 0x03; // P1.0、P1.1 輸出
PWMA_BKR = 0x80; // 主輸出使能
PWMA_CR1 = 0x01; // 開啟計數器
duty = (749 * 0.85); // 40kHz 正確公式
//*****************************************************************
//【單片機其它功能初始化】
//*****************************************************************
Timer0_Init();
Timer1_Init();
EA = 1;
while(1)
{
IR_Code_Match(irdata2);
dssq();
}
} 現在這個程序紅色led只響應一次,第二次再按遙控鍵沒反應了,看半天沒看出來哪里的問題,先不說解碼是否正確,至少每次按鍵應該LED都可以反轉的才對,坐等大神指導。。。
作者:
人中狼
時間:
2026-4-26 20:29
打印完后EX0沒重新打開
作者:
xiaoyuxinke
時間:
2026-4-29 10:38
已經解決了,是Flag3的問題
作者:
ydatou
時間:
2026-4-29 17:24
xiaoyuxinke 發表于 2026-4-29 10:38
已經解決了,是Flag3的問題
正確的應該2樓。打印時關閉了解碼,打印完后要再次開啟。
作者:
xiaoyuxinke
時間:
2026-5-1 11:02
發表于 2026-4-29 17:24
正確的應該2樓。打印時關閉了解碼,打印完后要再次開啟。
最后發現,每次打開中斷前,要清中斷標志,不然不能循環
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1