|
如以下代碼均實際可用:
#include <stc15.h> // 包含STC15系列單片機頭文件
#include "intrins.h"//不顯示
#define IR_PIN P33 // 紅外接收模塊連接到P3.3引腳
unsigned char ir_data[4]; // 存儲接收的32位數據
unsigned char key_value; // 解析后的按鍵值
bit flag = 0;
// 微秒級延時函數
void delay_us(unsigned int us) {
while (us--) {
_nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_();
}
}
// 紅外接收初始化
void ir_init() {
P3M1 &= ~0x08; // 設置P3.3為準雙向模式
P3M0 &= ~0x08;
IT1 = 1; // 外部中斷1下降沿觸發
EX1 = 1; // 使能外部中斷1
EA = 1; // 全局中斷使能
}
// 外部中斷1服務函數
void ir_isr() interrupt 2 {
unsigned char i, j;
unsigned char byte = 0;
// 跳過9ms引導碼
while (IR_PIN == 0); // 等待高電平
delay_us(9000); // 延時確認引導碼
// 接收32位數據
for (i = 0; i < 4; i++) {
for (j = 0; j < 8; j++) {
while (IR_PIN == 0); // 等待高電平
delay_us(560); // 560us基準延時
if (IR_PIN == 1) { // 檢測邏輯1(1.68ms)
byte |= (1 << j);
delay_us(1680 - 560); // 補足剩余時間
} else { // 邏輯0(560us)
byte &= ~(1 << j);
}
}
ir_data[i] = byte;
}
flag = 1;
// 解析按鍵值(數據碼)
key_value = ir_data[2];
// 顯示到P1口(低6位)和P3.6/P3.7(高2位)
P1 = key_value & 0x3F;
P36 = (key_value >> 6) & 0x01;
P37 = (key_value >> 7) & 0x01;
flag = 0;
}
void main() {
// 初始化IO口
P1M0 = 0x00; // P1口設置為準雙向
P1M1 = 0x00;
P3M0 = 0x00; // P3.6/P3.7設為準雙向
P3M1 = 0x00;
P1 = 0xFF; // 初始高電平
P36 = 1;
P37 = 1;
ir_init(); // 初始化紅外接收
while(1) {
if(flag) { // 可根據需要添加狀態處理
flag = 0;
}
// 按鍵功能處理
switch(key_value) {
case 0x00: break; // 無按鍵
case 0x01: /* 執行按鍵1動作 */ break;
case 0x02: /* 執行按鍵2動作 */ break;
// 添加更多按鍵處理...
default: break;
}
}
}
#include "stc15.h"//模數
#include "intrins.h"
sfr ADC_LOW2 = 0xBE; // ADC低2位結果
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define ADC_POWER 0x80 // ADC電源控制位
#define ADC_FLAG 0x10 // ADC完成標志
#define ADC_START 0x08 // ADC起始控制位
#define ADC_SPEEDLL 0x00 // 540個時鐘
void InitADC();
WORD GetADCResult(BYTE ch); // 返回10位ADC結果
void Delay1us(unsigned int us) {
unsigned int i, j;
for (i = us; i > 0; i--)
for (j = 1085; j > 0; j--); // 1us 延時
}
void main() {
// 初始化所有端口為準雙向模式
P0M0 = P0M1 = 0x00;
P1M0 = P1M1 = 0x00;
P2M0 = P2M1 = 0x00;
P3M0 = 0xFF; P3M1 = 0x00; // P3口配置
P4M0 = P4M1 = 0x00;
P5M0 = P5M1 = 0x00;
P6M0 = P6M1 = 0x00;
P7M0 = P7M1 = 0x00;
InitADC(); // 初始化ADC
while (1) {
// 讀取ADC通道0和通道1的值,并控制P3.2和P3.3
if (GetADCResult(0) > 1000) { // 10位ADC,閾值改為512(對應8位的128)
P32 = 0; // 如果通道0的值大于512,P3.2置為0
} else {
P32 = 1; // 否則P3.2置為1
}
if (GetADCResult(1) > 900) { // 10位ADC,閾值改為500
P33 = 1; // 如果通道1的值大于500,P3.3置為1
} else {
P33 = 0; // 否則P3.3置為0
}
}
}
WORD GetADCResult(BYTE ch) {
WORD result; // 在函數開頭聲明result變量
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; // 啟動ADC轉換
_nop_(); // 等待1個機器周期
_nop_(); // 等待1個機器周期
_nop_(); // 等待1個機器周期
Delay1us(22); // 延時22微秒,確保ADC初始化和信號穩定
while (!(ADC_CONTR & ADC_FLAG)); // 等待ADC轉換完成
ADC_CONTR &= ~ADC_FLAG; // 清除ADC完成標志
// 組合高8位和低2位,得到10位ADC結果
result = (ADC_RES << 2) | (ADC_LOW2 & 0x03); // 高8位左移2位,低2位直接拼接
return result; // 返回10位ADC結果
}
void InitADC() {
P1ASF = 0xFF; // 設置P1口為AD口
ADC_RES = 0; // 清除結果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL; // 啟動ADC
Delay1us(10); // ADC上電并延時
|
|