|
如以下代码均实际可用:
#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上电并延时
|
|