进过学习和消化,将红色LED转接到P3.6口,将P1口空出来,p1.2作为信号检测端,终于将程序改了出来(具体工作见范例STC15.PDF第923页)
- #include "reg51.h"
- #include "intrins.h"
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- WORD idata Vbg_RAM _at_ 0xef; //对于只有256字节RAM的MCU存放地址为0EFH
- //注意:需要在下载代码时选择"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
- WORD code Vbg_ROM _at_ 0x0ff7; //4K程序空间的MCU
- sfr P1M1 = 0x91; //PxM1.n,PxM0.n =00--->Standard, 01--->push-pull
- sfr P1M0 = 0x92; // =10--->pure input, 11--->open drain
- sfr P0M1 = 0x93;
- sfr P0M0 = 0x94;
- sfr P2M1 = 0x95;
- sfr P2M0 = 0x96;
- sfr P3M1 = 0xB1;
- sfr P3M0 = 0xB2;
- sfr P4M1 = 0xB3;
- sfr P4M0 = 0xB4;
- sfr P5M1 = 0xC9;
- sfr P5M0 = 0xCA;
- sfr P6M1 = 0xCB;
- sfr P6M0 = 0xCC;
- sfr P7M1 = 0xE1;
- sfr P7M0 = 0xE2;
- sfr ADC_CONTR = 0xBC; //ADC控制寄存器
- sfr ADC_RES = 0xBD; //ADC高8位结果
- sfr ADC_LOW2 = 0xBE; //ADC低2位结果
- sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
- #define ADC_POWER 0x80 //ADC电源控制位
- #define ADC_FLAG 0x10 //ADC完成标志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540个时钟
- #define ADC_SPEEDL 0x20 //360个时钟
- #define ADC_SPEEDH 0x40 //180个时钟
- #define ADC_SPEEDHH 0x60 //90个时钟
- /*----------------------------
- 软件延时
- ----------------------------*/
- void Delay(WORD n) //@11.0592MHz 延迟1ms
- {
- unsigned char i, j;
- while (n--)
- {
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- BYTE GetADC(BYTE ch)
- {
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
- Delay(2); //ADC上电并延时
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
- _nop_(); //等待4个NOP
- _nop_();
- _nop_();
- _nop_();
- while (!(ADC_CONTR & ADC_FLAG)); //等待ADC转换完成
- ADC_CONTR &= ~ADC_FLAG; //清除ADC标志
- return ADC_RES;
- }
- void main()
- {
- BYTE ADCbg;
- BYTE ADCp0, ADCp1, ADCp2, ADCp3, ADCp4, ADCp5, ADCp6, ADCp7;
- WORD V0, V1, V2, V3, V4, V5, V6, V7;
- P3M0 = 0xC0; //led接在p3.6上,设为强推挽模式,参数说明见STC15.PDF第401页
- P3M1 = 0X00;
- while (1)
- {
-
- P1M0 = 0x00;
- P1M1 = 0xFF; //设为高阻模式
-
- //第一步:通过ADC的第9通道测试Bandgap电压的ADC测量值
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x00; //不设置P1ASF,即可从ADC的第9通道读取内部Bandgap电压的ADC测量值
- GetADC(0);
- GetADC(0);
- ADCbg = GetADC(0);
-
- //第二步:通过ADC的第2通道测试外部输入电压的ADC测量值 说明见STC15.PDF第926页
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x01; //设置P1.0口为模拟通道
- GetADC(0);
- GetADC(0);
- ADCp0 = GetADC(0);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x02; //设置P1.1口为模拟通道
- GetADC(1);
- GetADC(1);
- ADCp1 = GetADC(1);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x04; //设置P1.2口为模拟通道
- GetADC(2);
- GetADC(2);
- ADCp2 = GetADC(2);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x08; //设置P1.3口为模拟通道
- GetADC(3);
- GetADC(3);
- ADCp3 = GetADC(3);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x10; //设置P1.4口为模拟通道
- GetADC(4);
- GetADC(4);
- ADCp4 = GetADC(4);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x20; //设置P1.5口为模拟通道
- GetADC(5);
- GetADC(5);
- ADCp5 = GetADC(5);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x40; //设置P1.6口为模拟通道
- GetADC(6);
- GetADC(6);
- ADCp6 = GetADC(6);
- ADC_RES = 0; //清除结果寄存器
- P1ASF = 0x80; //设置P1.7口为模拟通道
- GetADC(7);
- GetADC(7);
- ADCp7 = GetADC(7);
-
- //第三步:通过公式计算外部输入的实际电压值
- //Vx = Vbg_RAM * ADCx / ADCbg; //使用RAM中的Bandgap电压参数进行计算
- V2 = Vbg_ROM * ADCp2 / ADCbg; //使用ROM中的Bandgap电压参数进行计算
-
- if( V2 > 50 )
- P3 = 0X40; //灯亮
- else
- P3= 0X00 ; //灯灭
-
-
- Delay(1000);
- }
- }
复制代码 将耳机线插入手机,播放音乐,LED灯将闪烁,证明检测到了信号,停止放音乐,LED灯灭,证明工作正常。P1.2口设为高阻状态,并用220K欧的电阻接地,否则会受到杂波干扰,记住隔直电容,把手机烧了就问题大了。
手头正好有某宝上买的成品延时电路,用的就是404AS芯片(记住是3按键的那种,4按键的用的新唐的单片机),把数码管拆了,就可以利用此电路做为一个8信号检测,无信号自动关机的成品了。 |