如有雷同请莫怪,高手请不要飘过本人就是懒虫硬件很随便
一个用单片机adc+ntc热敏电阻构成的时钟电路分享
制作出来的实物图如下:
电路原理图如下:
单片机源程序如下:
- #include"reg52.h"
- #include"ds1302.h"
- #include"intrins.h"
- //#include"EEP.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define on 1
- #define off 0
- #define NOP(N) NOP##N()
- sfr ADC_CONTR = 0xBC; //ADC控制寄存器
- sfr ADC_RES = 0xBD; //ADC高8位结果
- sfr ADC_RESL = 0xBE; //ADC低2位结果
- sfr P1ASF = 0x9D; //P1口第2功能控制寄存器
- uint get_temperature(uint adc);
- void Get_Temp(void);
- //段码位选
- sbit G1= P3^4;
- sbit G2= P3^5;
- sbit G3= P3^6;
- sbit G4= P3^7;
- //按键定义
- sbit set=P3^0;
- sbit jia=P3^1;
- sbit zh=P3^3; // 颠倒开关
- #define N 8 //ADC采样使用递推平均滤波算法,采样次数
- unsigned int Temp_Buf[N+1]; //采样数组
- unsigned char ADCcount; //数码管显示计数变量,ADC采样次数变量
- uchar tab[4]={0}; //显示缓存
- unsigned int temp[3];
- #define FOSC 11059200L
- #define T1MS (65536-FOSC/12/33) //12T模式 30MS
- sfr AUXR = 0x8e; //Auxiliary register
- sbit P10 = P1^0; //调用闹钟用
- sfr P1M0 = 0x92;
- sfr P1M1 = 0x91;
- bit nf=0; //闹钟开标志:受水银影响
- bit gk=0; //光控开标志
- bit nk=0; //闹钟开标志:受设置影响
- bit nx=1; //闹钟响标志:受时间影响
- bit ps=0; //颠倒开关标志
- bit flag1=1,
- wflag1=0;
- int ld=1;
- char menu=0;
- char flag;
- //没有小数点 共阳数码管
- uchar table1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
- 0x80,0x90,0xff,0x88,0xc7}; //c4
- //显示小数点 a l
- uchar table2[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
- 0x00,0x10,0xff,};
- //倒没有小数点
- uchar table3[]={0xC0,0xCF,0xA4,0x86,0x8B,0x92,0x90,0xC7,
- 0x80,0x82,0xff,};
- //倒显示小数点
- uchar table4[]={0x40,0x4F,0x24,0x06,0x0B,0x12,0x10,0x47,
- 0x00,0x02,0xff,0x70,};
- //延时ms
- void delay_ms(uchar ms){
- uchar i;
- while(ms--){
- for(i=0;i<123;i++);
- }
- }
- //温度显示
- void display_temperatue(){
- G1 = off;
- G2 = on;
- G3 = on;
- G4 = on;
- P2 = table1[tab[0]];
- delay_ms(8);
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- P2 = table1[tab[1]];
- delay_ms(8);
-
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- // P2 = table3[tab[2]];
- P2 = table4[11];
- delay_ms(8);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = on;
- P2 = table4[tab[3]];
- // P2 = table1[tab[3]];
- delay_ms(5);
- }
- //时间显示
- void display_time(){
- G1 = off;
- G2 = on;
- G3 = on;
- G4 = on;
- P2 = table1[tab[0]];
- delay_ms(5);
- if(flag>0){
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- P2 = table1[tab[1]];
- delay_ms(5);
-
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- P2 = table3[tab[2]];
- delay_ms(5);
-
- }else{
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- P2 = table2[tab[1]];
- delay_ms(5);
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- P2 = table4[tab[2]];
- delay_ms(5);
- }
- if(nx==0){
- if(flag>0){
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- P2 = table1[tab[3]];
- delay_ms(5);
- }
- else{
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- P2 = table2[tab[3]];
- delay_ms(5);
- }
- }else{
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- P2 = table1[tab[3]];
- delay_ms(5);
- }
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = on;
- }
- //音频调用
- void display_Audio(){
- G1 = off;
- G2 = on;
- G3 = on;
- G4 = on;
- if(temp[1]>5){P2=0xcf;}else{P2=0xff;}
- delay_ms(10);
- if(temp[1]>30){P2=0xf9;}else{P2=0xff;}
- delay_ms(10);
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- if(temp[1]>60){P2=0xcf;}else{P2=0xff;}
- delay_ms(10);
- if(temp[1]>90){P2=0xf9;}else{P2=0xff;}
- delay_ms(10);
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- if(temp[1]>120){P2=0xf9;}else{P2=0xff;}
- delay_ms(10);
- if(temp[1]>150){P2=0xcf;}else{P2=0xff;}
- delay_ms(10);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- if(temp[1]>180){P2=0xcf;}else{P2=0xff;}
- delay_ms(10);
- if(temp[1]>210){P2=0xf9;}else{P2=0xff;}
- delay_ms(10);
- }
- //闹钟用 ,光控用
- void display_alme(){
- G1 = off;
- G2 = on;
- G3 = on;
- G4 = on;
- P2 = table1[tab[0]];
- delay_ms(8);
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- P2 = table2[tab[1]];
- delay_ms(8);
-
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- P2 = table4[tab[2]];
- delay_ms(8);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- P2 = table2[tab[3]];
- delay_ms(5);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = on;
- }
- /*
- //设计调用
- void display_set1(){
- G1 = off;
- G2 = on;
- G3 = on;
- G4 = on;
- P2 = table1[tab[0]];
- delay_ms(8);
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- P2 = table2[tab[1]];
- delay_ms(8);
-
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- P2 = table4[tab[2]];
- delay_ms(8);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- P2 = table1[tab[3]];
- delay_ms(5);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = on;
- } */
- //设计调用
- void display_set(){
- G1 = off;
- G2 = on;
- G3 = on;
- G4 = on;
- P2 = table1[tab[0]];
- delay_ms(8);
- G1 = on;
- G2 = off;
- G3 = on;
- G4 = on;
- P2 = table2[tab[1]];
- delay_ms(8);
-
- G1 = on;
- G2 = on;
- G3 = off;
- G4 = on;
- P2 = table4[tab[2]];
- delay_ms(8);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = off;
- P2 = table1[tab[3]];
- delay_ms(5);
- G1 = on;
- G2 = on;
- G3 = on;
- G4 = on;
- }
- //ADC初始化
- void ic_adc_init(){
- ADC_CONTR = 0xE0; //90T, ADC power on
- delay_ms(5);
- }
- //读ADC值
- uint get_adc_temp(uchar channel){
- ADC_RES = 0;
- ADC_RESL = 0;
- ADC_CONTR = (ADC_CONTR & 0xe0) | 0x08 | channel; //start the ADC
- delay_ms(1);
- while((ADC_CONTR & 0x10) == 0) ; //wait for ADC finish
- ADC_CONTR &= ~0x10; //清除ADC结束标志
- return (((uint)ADC_RES << 2) | (ADC_RESL & 3));
- }
- void key(){
- if(zh==0){ps=0;}else ps=1;
- if(ps==0){
- if(set==0){
- delay_ms(10);
- if(set==0){
- menu+=1;
- if(menu==1)// read_time();
- if(menu==3){ read_nao();}
- // if(menu==5) // IapProgramByte(IAP_ADDRESS+5,gk&0x01); display_alme();//调显示
- // if(menu==6) // IapProgramByte(IAP_ADDRESS+6,nk&0x01); display_alme();//调显示
- if(menu==7)menu=0; write_time();
- while(set==0);
- display_set();//调显示
- }
- }
- if(menu==1){ //调分钟
- if(jia==0){
- delay_ms(10);
- if(jia==0){
- fen=fen+1;
- if(fen == 0x5a)
- fen = 0;
- if((fen & 0x0f) >= 0x0a)
- fen = (fen & 0xf0) + 0x10;
- while(jia==0);
- }
- } display_set();//调显示
- }
- if(menu==2){ //小时
- if(jia==0){
- delay_ms(10);
- if(jia==0){
- shi=shi+1;
- if(shi == 0x24)
- shi = 0;
- if((shi & 0x0f) >= 0x0a)
- shi = (shi & 0xf0) + 0x10;
- while(jia==0);
- }
- }display_set();//调显示
- }
- if(menu==3){ //分钟
- if(jia==0){
- delay_ms(10);
- if(jia==0){
- nfen=nfen+1;
- if(nfen == 0x5a)
- nfen = 0;
- if((nfen & 0x0f) >= 0x0a)
- nfen = (nfen & 0xf0) + 0x10;
- while(jia==0);
- }
- } display_alme();//调显示
- }
- if(menu==4){ //小时
- if(jia==0){
- delay_ms(10);
- if(jia==0){
- nshi=nshi+1;
- if(nshi == 0x24)
- nshi = 0;
- if((nshi & 0x0f) >= 0x0a)
- nshi = (nshi & 0xf0) + 0x10;
- while(jia==0);
- }
- }display_alme();//调显示
- }
- if(menu==5){ //调光控
- if(jia==0){
- delay_ms(10);
- if(jia==0){
-
- while(jia==0);
- gk=!gk;
-
- // IapProgramByte(0x03,gk);
- }
- } display_set();//调显示
- }
- if(menu==6){ //调闹钟
- if(jia==0){
- delay_ms(10);
- if(jia==0){
-
- while(jia==0);
- nk=!nk;
- // IapProgramByte(0x02,nk);
-
- }
- }display_alme();//调显示
- }
- }
- }
- void main(){
- // AUXR |= 0x80; //定时器0为1T模式
- AUXR &= 0x7f; //定时器0为12T模式
- TMOD = 0x00; //设置定时器为模式0(16位自动重装载)
- TL0 = T1MS; //初始化计时值
- TH0 = T1MS >> 8;
- TR0 = 1; //定时器0开始计时
- ET0 = 1; //使能定时器0中断
- EA = 1;
- ic_adc_init();
- init_ds1302_io();
- init_ds1302();
- read_nao();
- P1M0=0X00;
- P1M1=0Xff;
- while(1){
-
- if(nk==1){if(shi==nshi && fen==nfen && nf==0){nx=0;}else{nx=1;}} //开闹钟
- key();
- if(ps==0){
- if(menu==0){//主菜单
- if(flag1==1){ //显示时间
- temp[2]=get_adc_temp(1);
- if(gk==1){
-
- if(temp[2]<100) ld=5;
- if(temp[2]>100&&temp[2]<300)ld=10;
- if(temp[2]>300&&temp[2]<500)ld=50;
- if(temp[2]>500&&temp[2]<600)ld=80;
- if(temp[2]>600&&temp[2]<700)ld=100;
- if(temp[2]>700&&temp[2]<800)ld=120;
- if(temp[2]>900&&temp[2]<1000)ld=130;
- if(temp[2]>1000)ld=150;
- }else ld=5;
- read_time();
- tab[0]=shi/16;
- tab[1]=shi%16;
- tab[2]=fen/16;
- tab[3]=fen%16;
- display_time();
- delay_ms(ld);
- }
- if(flag1==0) //显示温度
- {
- if(wflag1==0){wflag1=1;}
- Get_Temp();
- display_temperatue();
- delay_ms(ld);
- }
- }else{ //设置菜单
-
- if(menu==1){ //调时间分
- tab[0]=shi/16;
- tab[1]=shi%16;
- if(flag>0){
- tab[2]=fen/16;
- tab[3]=fen%16;
- }else{
- tab[2]=10;
- tab[3]=10;
- }
- }
- if(menu==2){ //调时间时
- tab[2]=fen/16;
- tab[3]=fen%16;
- if(flag>0){
- tab[0]=shi/16;
- tab[1]=shi%16;
- }else{
- tab[0]=10;
- tab[1]=10;
- }
- }
- if(menu==3){ //调闹钟分
-
- tab[0]=nshi/16;
- tab[1]=nshi%16;
- if(flag>0){
- tab[2]=nfen/16;
- tab[3]=nfen%16;
- }else{
- tab[2]=10;
- tab[3]=10;
- }
- }
- if(menu==4){ //调闹钟时
-
- if(flag>0){
- tab[0]=nshi/16;
- tab[1]=nshi%16;
- }else{
- tab[0]=10;
- tab[1]=10;
- }
- tab[2]=nfen/16;
- tab[3]=nfen%16;
- }
- if(menu==5){ //调光控
- tab[0]=11;
- tab[1]=gk;
- tab[2]=gk;
- tab[3]=gk;
-
- }
- if(menu==6){ //调闹钟
- tab[0]=12;
- tab[1]=nk;
- tab[2]=nk;
- tab[3]=nk;
- }
- }
- }
- if(ps==1){ //端口一定要设计置高阻输入
- temp[1]=get_adc_temp(0);
- display_Audio();//
- }
- }
- }
- char t;
- int t1;
- // Timer0 interrupt routine 定时0中断
- void tm0_isr() interrupt 1 using 1
- {
- P10 = ! P10; //将测试口取反
- t++;
- t1++;
- if(t==20)
- {
- t=0;
- wflag1=0;
- flag=!flag;
- // if(nx==0)bell=!bell;
- }
- if(t1>0 && t1<350)flag1=1;
- if(t1>350 && t1<430)flag1=0;
- if(t1>430)t1=0;
- }
- //NTC温度
- void Get_Temp(void)
- {
- unsigned char xx;
- unsigned int sum,tempvalue;
- sum = tempvalue =0;
- Temp_Buf[N]=get_adc_temp(2); //将ADC转换结果放数组最高位
- if( ++ADCcount < 8) //采样初期不使用滤波算法
- {
- for(xx=0;xx<N;xx++) //准备滤波算法的数据
- {
- Temp_Buf[xx]=Temp_Buf[xx+1];//所有数据循环左移
- }
- tempvalue=Temp_Buf[N];//采样初期使用当前采样值
- }
- else //只有采样次数大于8次以后才使用滤波算法
- {
- ADCcount=8; //采样次数超过8次后,固定设置为8
- for(xx=0;xx<N;xx++) //滤波算法
- {
- Temp_Buf[xx]=Temp_Buf[xx+1];//所有数据循环左移
- sum+=Temp_Buf[xx]; //求和
- }
- tempvalue=sum/N; //求平均值
- } //
- tempvalue=get_temperature(tempvalue);
- // tab[0]=tempvalue/1000;
- tab[0]=tempvalue%1000/100; //十位
- tab[1]=tempvalue%100/10;//个位加小数点
- // tab[3]=tempvalue%10; //小数位
- }
- // MF52E 10K at 25, B = 3534, ADC = 12 bits
- uint code temp_table[]={
- 140, //;-40 0
- 149, //;-39 1
- 159, //;-38 2
- 168, //;-37 3
- 178, //;-36 4
- 188, //;-35 5
- 199, //;-34 6
- 210, //;-33 7
- 222, //;-32 8
- 233, //;-31 9
- 246, //;-30 10
- 259, //;-29 11
- 272, //;-28 12
- 286, //;-27 13 14
- 301, //;-26 14 15
- 317, //;-25 15 16
- 334,
- 351,
- 369,
- 387,
- 406,
- 425,
- 445,
- 466,
- 487,
- 509,
- 528, //
- 555,
- 579,
- 603,
- 628,
- 654,
- 681,
- 709,
- 738,
- 768,
- 799,
- 824, //;-4 36
- 858, //;-3 37 9
- 893, //;-2 38
- 929, //;-1 39
- 965, //;0 40
- 1003, //;1 41
- 1041, //;2 42
- 1080, //;3 43
- 1119, //;4 44
- 1139,
- 1160, //;5 45
- 1180,
- 1201, //;6 46
-
- 1243, //;7 47
- 1285, //;8 48
- 1328, //;9 49
- 1371, //;10 50
- 1414, //;11 51
- 1459, //;12 52
- 1503, //;13 53
- 1548, //;14 54
- 1593, //;15 55
- 1638, //;16 56
- 1684, //;17 57
- 1730, //;18 58
- 1775, //;19 59
- 1821, //;20 60
- 1867, //;21 61
- 1912, //;22 62
- 1958, //;23 63
- 2003, //;24 64
- 2048, //;25 65
- 2093, //;26 66
- 2137, //;27 67
- 2182, //;28 68
- 2225, //;29 69
- 2269, //;30 70
- 2312, //;31 71
- 2354, //;32 72
- 2397, //;33 73
- 2438, //;34 74
- 2479, //;35 75
- 2519, //;36 76
- 2559, //;37 77
- 2598, //;38 78
- 2637, //;39 79
- 2675, //;40 80
- 2712, //;41 81
- 2748, //;42 82
- 2784, //;43 83
- 2819, //;44 84
- 2853, //;45 85
- 2887, //;46 86
- 2920, //;47 87
- 2952, //;48 88
- 2984, //;49 89
- 3014, //;50 90
- 3044, //;51 91
- 3073, //;52 92
- 3102, //;53 93
- 3130, //;54 94
- 3157, //;55 95
- 3183, //;56 96
- 3209, //;57 97
- 3234, //;58 98
- 3259, //;59 99
- 3283, //;60 100
- 3306, //;61 101
- 3328, //;62 102
- 3351, //;63 103
- 3372, //;64 104
- 3393, //;65 105
- 3413, //;66 106
- 3432, //;67 107
-
- };
- /******************** 计算温度 ***********************************************/
- // 计算结果: 0对应-40.0度, 400对应0度, 625对应25.0度, 最大1600对应120.0度.
- // 为了通用, ADC输入为12bit的ADC值.
- // 电路和软件算法设计: Coody
- /**********************************************/
- #define D_SCALE 10 //结果放大倍数, 放大10倍就是保留一位小数
- uint get_temperature(uint adc)
- {
- uint code *p;
- uint i;
- uchar j,k,min,max;
-
- // adc = 1024 - adc; //Rt接地
- p = temp_table;
- if(adc < p[0]) return (0xfffe);
- if(adc > p[160]) return (0xffff);
-
- min = 0; //-40度
- max = 160; //120度
- for(j=0; j<5; j++) //对分查表
- {
- k = min / 2 + max / 2;
- if(adc <= p[k]) max = k;
- else min = k;
- }
- if(adc == p[min]) i = min * D_SCALE;
- else if(adc == p[max]) i = max * D_SCALE;
- else // min < temp < max
- {
- while(min <= max)
- {
- min++;
- if(adc == p[min]) {i = min * D_SCALE; break;}
- else if(adc < p[min])
- {
- min--;
- i = p[min]; //min
- j = (adc - i) * D_SCALE / (p[min+1] - i);
- i = min;
- i *= D_SCALE;
- i += j;
- break;
- }
- }
- }
- return i;
- }
复制代码
所有资料51hei提供下载:
ds1302 4seg NTC 2K .zip
(88.88 KB, 下载次数: 285)
|