已经看了很久很久很久了一直未能解决这个问题...很绝望啊,国庆节就写好的,一直找到现在都还不知道哪里出了问题,太难受了!!!这是定时采集温度的单片机程序
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define MAIN_Fosc 11059200UL //宏定义主时钟HZ
- /*====================================
- 自定义类型名
- ====================================*/
- typedef unsigned char INT8U;
- typedef unsigned int INT16U;
- sbit TSCLK = P1^0;//时钟线 接到P10上用杜邦线
- sbit TIO = P1^1;//数据线,接到P11上
- sbit TRST = P1^2;//使能端,接到P12上
- sbit DS = P2^2; //DS18B20单总线
- uint wenduzhi[10];
- static n=0;
- sbit DU = P2^6; //数码管段选
- sbit WE = P2^7; //数码管位选
- sbit we = P2^7;
- sbit du = P2^6;
- sbit KEY1=P3^0;
- sbit KEY2=P3^1;
- sbit KEY3=P3^2;
- sbit KEY4=P3^3;
- uchar time_1=1;
- uchar shi1=0,shi2=0;
- uint wenduzhi[10]={0};
- uint p_1=0;
- void timer();
- void ds18b20();
- unsigned char pp;
- /*====================================
- 共阴极数码管段选码
- ====================================*/
- uchar code table[]={
- //0 1 2 3 4 5 6 7 8
- 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
- //9 A B C D E F - . 关显示
- 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
- };
- /*====================================
- 数码管位选码
- ====================================*/
- //第1位 2位 3位 4位 5位 6位 7位 8位
- uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码
- uchar code leddata[]={
- 0x3F, //"0"
- 0x06, //"1"
- 0x5B, //"2"
- 0x4F, //"3"
- 0x66, //"4"
- 0x6D, //"5"
- 0x7D, //"6"
- 0x07, //"7"
- 0x7F, //"8"
- 0x6F, //"9"
- 0x77, //"A"
- 0x7C, //"B"
- 0x39, //"C"
- 0x5E, //"D"
- 0x79, //"E"
- 0x71, //"F"
- 0x76, //"H"
- 0x38, //"L"
- 0x37, //"n"
- 0x3E, //"u"
- 0x73, //"P"
- 0x5C, //"o"
- 0x40, //"-"
- 0x00, //熄灭
- 0x00 //自定义
- };
- void delay1(uint z)
- {
- uint x,y;
- for(x = z; x > 0; x--)
- for(y = 114; y > 0 ; y--);
- }
- uchar code leddata[];
- void delay(uint z)
- {
- uint x,y;
- for(x = z; x > 0; x--)
- for(y = 114; y > 0 ; y--);
- }
- void Delay_us(uchar us)
- {
- while(us--);
- }
- void smg()
- {
- char i=0;
- unsigned char sj[4]={1,5,30,60};
- while(1)
- {
- we = 1;
- P0=0x7f;
- we=0;
- du=1;
- P0=leddata[sj[i]%10];
- du=0;
- delay(5);
-
- we = 1;
- P0=0xbf;
- we=0;
- du=1;
- P0=leddata[sj[i]/10];
- du=0;
- delay(5);
-
- we = 1;
- P0=0xdf;
- we=0;
- du=1;
- P0=leddata[22];
- du=0;
- delay(5);
- if(0==KEY1)
- {
- delay(10);
- if(0==KEY1)
- {
- i++;
- if(4==i)
- i=0;
- time_1=sj[i];
- }
- }
- if(0==KEY2) //检测按键是否按下
- {
- delay(10); //延时去抖
- if(0==KEY2)
- {
- break;
- }
- }
- }
- }
- void Delay_Ms(INT16U ms)
- {
- INT16U i;
- do{
- i = MAIN_Fosc / 96000;
- while(--i); //96T per loop
- }while(--ms);
- }
- void Display(uchar Hour, Min, Sec)
- {
- //------------------------------
- DU = 0;
- P0 = table[Hour/10];
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[0];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //-------------------------------
- DU = 0;
- P0 = table[Hour%10]; //为了加点|0x80
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[1];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[16];
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[2];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[Min/10];
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[3];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //-------------------------------
- DU = 0;
- P0 = table[Min%10]; // 为了加点|0x80 不错的算法
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[4];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[16];
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[5];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[Sec/10];
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[6];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //-------------------------------
- DU = 0;
- P0 = table[Sec%10];
- DU = 1;
- DU = 0;
- WE = 0;
- P0 = T_COM[7];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- }
- //写DS1302数据
- void Write_DS1302_DAT(uchar cmd, uchar dat)
- {
- uchar i;
- TRST = 0; //拉低使能端
- TSCLK = 0;//拉低数据总线
- TRST = 1; //拉高使能端,产生上升沿开始写数据
- for(i = 0; i < 8; i++)//每次写1位,写8次
- {
- TSCLK = 0; //拉低时钟总线
- TIO = cmd & 0x01; //写1位数据,从最低位开始写
- TSCLK = 1; //拉高时钟总线,产生上升沿数据被DS1302读走
- cmd >>=1; //右移一位
- }
- for(i = 0; i < 8; i++)//每次写1位,写8次
- {
- TSCLK = 0; //拉低时钟总线
- TIO = dat & 0x01; //写1位数据,从最低位开始写
- TSCLK = 1; //拉高时钟总线,产生上升沿数据被DS1302读走
- dat >>= 1; //右移一位
- }
- }
- //读DS1302数据
- uchar Read_DS1302_DAT(uchar cmd)
- {
- uchar i, dat;
- TRST = 0; //拉低使能端
- TSCLK = 0; //拉低数据总线
- TRST = 1; //拉高使能端,产生上升沿开始写数据
- for(i = 0; i < 8; i++)//每次写1位,写8次
- {
- TSCLK = 0; //拉低时钟总线
- TIO = cmd & 0x01;//写1位数据,从最低位开始写
- TSCLK = 1; //拉高时钟总线,产生上升沿数据被DS1302读走
- cmd >>=1; //右移一位
- }
- for(i = 0; i < 8; i++)//每次读1位,读8次
- {
- TSCLK = 0; //拉低时钟总线,产生下降沿,DS1302把数据放到TIO上
- dat >>= 1; //右移一位
- if(TIO) dat |= 0x80;//读取数据,从最低位开始
- TSCLK = 1; //拉高时钟总线,以备下一次产生下降沿
- }
- return dat; //返回读出数据
- }
- //数据转BCD码
- uchar Dat_Chg_BCD(uchar dat)
- {
- uchar dat1, dat2;
- dat1 = dat / 10;
- dat2 = dat % 10;
- dat2 = dat2 + dat1 * 16;
- return dat2;
- }
- //BCD码转换为数据
- uchar BCD_Chg_Dat(uchar dat)
- {
- uchar dat1, dat2;
- dat1 = dat / 16;
- dat2 = dat % 16;
- dat2 = dat2 + dat1 * 10;
- return dat2;
- }
- void ds1302()
- {
- uchar i;
- uchar Sec, Min, Hour;
- Write_DS1302_DAT(0x8e, 0);//清除写保护
- Write_DS1302_DAT(0x80, Dat_Chg_BCD(10));//30秒(并且进行BCD码转换)
- Write_DS1302_DAT(0x82, Dat_Chg_BCD(0));//15分
- Write_DS1302_DAT(0x84, Dat_Chg_BCD(0));//19时
- Write_DS1302_DAT(0x8e, 0x80);//开写保护
- while(1)
- {
- Write_DS1302_DAT(0x8e, 0); //清除写保护
- Sec = BCD_Chg_Dat(Read_DS1302_DAT(0x81));//读秒寄存器(并且进行BCD码转换)
- Min = BCD_Chg_Dat(Read_DS1302_DAT(0x83));//读分寄存器
- Hour = BCD_Chg_Dat(Read_DS1302_DAT(0x85));//读时寄存器
- Write_DS1302_DAT(0x8e, 0x80);//开写保护
- for(i = 0; i < 50; i++) //循环显示时钟
- Display(Hour, Min, Sec);
- if(n==10)
- {
- TR0=0;
- P1=0; // 最好写0x00 不然后面会误解 成位 就会 写错
- break;
- }
- }
- }
- bit ds_init()
- {
- bit i;
- DS = 1;
- _nop_();
- DS = 0;
- Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
- DS = 1; //释放总线
- Delay_us(4); //延时37.95us 等待18B20发回存在信号
- i = DS;
- Delay_us(20); //141.95us
- DS = 1;
- _nop_();
- return (i);
- }
- /*写一个字节*/
- void write_byte(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DS = 0;
- _nop_();//产生些时序
- DS = dat & 0x01;
- Delay_us(10);//76.95us
- DS = 1; //释放总线准备下一次数据写入
- _nop_();
- dat >>= 1;
- }
- }
- uchar read_byte()
- {
- uchar i, j, dat;
- for(i=0;i<8;i++)
- {
- DS = 0;
- _nop_();//产生读时序
- DS = 1;
- _nop_();//释放总线
- j = DS;
- Delay_us(10);//76.95us
- DS = 1;
- _nop_();
- dat = (j<<7)|(dat>>1);
- }
- return (dat);
- }
- void ds18b20()
- {
- uint i;
- uchar L, M;
- /* ds_init();//初始化DS18B20
- write_byte(0xcc);//发送跳跃ROM指令
- write_byte(0x4e);//写暂存器指令
- write_byte(0x7f);
- write_byte(0xf7);
- write_byte(0x1f);//配置工作在9位模式下
- ds_init();//初始化DS18B20
- write_byte(0xcc);//发送跳跃ROM指令
- write_byte(0x48);*/
- // while(1)
- // {
- ds_init();//初始化DS18B20
- write_byte(0xcc);//发送跳跃ROM指令
- write_byte(0x44);//发送温度转换指令
- ds_init();//初始化DS18B20
- write_byte(0xcc);//发送跳跃ROM指令
- write_byte(0xbe);//读取DS18B20暂存器值
- L = read_byte();
- M = read_byte();
- i = M;
- i <<= 8;
- i |= L;
- i = i * 0.0625 * 10 + 0.5;
- // Display(i);
- wenduzhi[n]=i;
- n++;
-
- // }
- }
- void smg2()
- {
- n=0;
- while(1)
- {
-
- //------------------------------
- DU = 0;
- P0 = table[16];
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[0];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //-------------------------------
- DU = 0;
- P0 = table[n/10]; //为了加点|0x80
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[1];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[n%10];
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[2];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[18];
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[3];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //-------------------------------
- DU = 0;
- P0 = table[18]; // 为了加点|0x80 不错的算法
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[4];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //------------------------------
- DU = 0;
- P0 = table[16];
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[5];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
-
- //------------------------------
- DU = 0;
- P0 = table[wenduzhi[n]/100]; //温度值扩大了 10倍 所以有三位数 23.5——235 个位实际上是十位,这样便于计算
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[6];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
- //-------------------------------
- DU = 0;
- P0 = table[wenduzhi[n]/10%10];
- DU = 1;
- DU = 0;
-
- WE = 0;
- P0 = T_COM[7];
- WE = 1;
- WE = 0;
- Delay_Ms(3);
-
-
- if(0==KEY3)
- {
- delay(10);
- if(0==KEY3)
- {
- n++;
- P1=0XFF;
- // P1=1; 这里p1是一个字节有八位 送1的话会默认为是十进制 也就是0x01了
- if(10==n)
- n=0;
- }
- }
- if(0==KEY4)
- {
- delay(10);
- if(0==KEY4)
- {
- break;
- }
- }
- }
-
- }
- void T0Init()
- {
- TMOD=0X01;
- TL0 = 0x00; //设置定时初值
- TH0 = 0x4C; //设置定时初值 50MS
- TR0=1;
- ET0=1;
- EA=1;
- }
- void main()
- {
- while(1)
- {
- // T0Init();
- smg();
- T0Init();//在数码管之后不行 1秒的时候会异常 在按键里设置tr0=1也是一样。
- ds1302();
- smg2();
- }
- }
- void T0timer() interrupt 1 //using 1 //加上会出现异常,我也不知道为什么
- {
- p_1++;
- TL0 = 0x00; //设置定时初值
- TH0 = 0x4C; //设置定时初值 50MS
- switch(time_1)
- {
- case(1):
- if(p_1==20)
- {
- p_1=0;
- ds18b20();
- }
- case(5):
- if(p_1==100)
- {
- p_1=0;
- ds18b20();
- }
- case(30):
- if(p_1==600)
- {
- p_1=0;
- ds18b20();
- }
- case(60):
- if(p_1==1200)
- {
- p_1=0;
- ds18b20();
- }
- }
- }
复制代码 |