标题: stc代码学习 [打印本页]

作者: jch352122    时间: 2025-3-23 17:58
标题: stc代码学习
如以下代码均实际可用:   

#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上电并延时


stc代码学习1新OK.zip

44.49 KB, 下载次数: 0

stc代码学习okkk.zip

10.95 KB, 下载次数: 0

stc代码学习新OK.zip

15 KB, 下载次数: 0


作者: aaron0888    时间: 2025-3-25 23:24
新手学习,感谢分享!
作者: 白水大虾2016    时间: 2025-3-27 19:25
这个挺有用




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1