历史上的今天
今天是:2025年02月14日(星期五)
2020年02月14日 | 51单片机多点18b20温度测量系统
2020-02-14 来源:51hei
分享我的期末作业,基于51单片机的多点温度测量
同时多点温度测量是在单总线上挂载多个18b20温度传感器
单片机源程序如下:
#include #include #define uchar unsigned char #define uint unsigned int #define MAXNUM 4 //宏定义单总线上最大可扫描DS18B20个数 //*****************************// //**初始定义管脚、变量与数组***// //*****************************// sbit DS=P3^7; sbit lcden=P2^7;//液晶使能端 sbit lcdrs=P2^6;//液晶数0据命令选择端 sbit lcdrw=P2^5; union{ uchar c[2]; uint x; }temp; uchar time=0; uint cc,xs; //变量cc中保存计算出的温度值的整数部分,xs保存计算出的温度值的小数部分的第一位 uchar idata disbuffer[6]; //LCD显示缓存数组 uchar idata ID[4][8]={0};//{{0x28,0xff,0x80,0x2e,0x70,0x16,0x03,0xad},{0x28,0xff,0x95,0xb5,0x81,0x16,0x03,0x50},{0x28,0xff,0x02,0x96,0xa1,0x16,0x04,0x59},{0x28,0xff,0xf0,0xf5,0x62,0x16,0x04,0xd3}}; //{"82FF08E2076130DA","82FF595B18613005","82FF20691A614095","82FF0F5F2661403D"}; //用于记录各DS18B20的ROM序列号 uchar idata RomID_temp[8]; //匹配DS18B20时临时记录要匹配DS18B20的序列号 uchar east[5]=" EAST"; uchar west[5]=" WEST"; uchar south[5]="SOUTH"; uchar north[5]="NORTH"; uchar m=0; uchar num=0; //***************************// //*******18b20时序延时*******// //***************************// void delay(uint i) //i*9.62us { uint j; for(j=i;j>0;j--); } void delay_ms(uchar i) //(j*2+1+2)*i+5 { uchar j; //12MHz 0.5*i ms do{j=248; do{j--;}while(j); i--; }while(i); } void delay_2us(uchar i) // 2*i+5 us { while(--i); } //**************************// //******18b20子程***********// //**************************// uchar DS_init(void) //18B20复位,初始化函数 { uchar presence; DS=0; delay_2us(250); //根据DS18B20的复位时序.先把总线拉低555us DS=1; delay_2us(30); //再释放总线,65us后读取DS18B20发出的信号 presence=DS; delay_2us(250); //如果复位成功,则presence的值为0;否则为1 return (presence); //返回0则初始化成功,否则失败 } uchar read_byte(void) //读1字节 { uchar i,j,dat=0; for(i=1;i<=8;i++) //作8个循环,读出的8位组成一个字节 {DS=0; _nop_(); //先将总线拉低1us, DS=1; delay_2us(2); //再释放总线,产生读起始信号,延迟9us后读取总线上的DS18B20发出的值 j=DS; delay_2us(30); //一位读完后,延迟65us后读下一位 dat=(j<<7)|(dat>>1); //读出的数据最低位在一个字节的最低位,这样刚好一个字节在DAT里 } return(dat); } uchar read_2bit(void) //读2位 { uchar i=0,j=0; DS=0; _nop_(); //先将总线拉低1us, DS=1; delay_2us(2); //再释放总线,产生读起始信号,延迟9us后读取总线上的DS18B20发出的值 j=DS; delay_2us(30); //一位读完后,延迟65us后读下一位 DS=0; _nop_(); DS=1; delay_2us(2); i=DS; delay_2us(30); i=j*2+i; //将读出的两位放到变量i中,其中第一个读出的位处于i的第1位;而第二个读出的位处于i的第0位 return(i); } void write_byte(uchar dat) //写1字节 { uchar i; for(i=0;i<8;i++) //作8个循环,写入的8位组成一个字节 {DS=0; //先将总线拉低 DS = dat&0x01; //向总线上放入要写的值 delay_2us(50); //延迟105us,以使DS18B20能采样到要写入的值 DS = 1; //释放总线,准备写入下一位 dat>>=1; //将要写的下一位移到dat的最低位 } } void write_bit(bit dat) //写1位 { DS=0; //先将总线拉低 DS=dat; //向总线上放入要写的值 delay_2us(50); //延迟105us,以使DS18B20能采样到要写入的值 DS = 1; //释放总线 } //************************// //*******1602延时*********// //************************// void delay1(uint z) { uint i,j; for(i=z;i>0;i--) for(j=110;j>0;j--); } //************************// //******1602子程**********// //************************// void write_com(uchar com) //写命令 { lcdrs=0;//选择写命令模式 P0=com;//将要写的命令字送到数据总线上 delay1(5);//稍作延时以待数据稳定 lcden=1;//使能端给一高电平脉冲,因为初始化函数中已将lcden置零 delay1(5);//稍作延时 lcden=0;//将使能端置零完成高脉冲 } void write_data(uchar date) //写数据 { lcdrs=1;//选择写数据操作 P0=date;//将要写的数据送到数据总线上 delay1(5);//稍作延时 lcden=1;//使能端给一高电平脉冲 delay1(5); lcden=0; } void init() //1602初始化 { lcdrw=0; lcden=0; write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口 write_com(0x0c);//设置开显示,不显示光标 write_com(0x06);//写一个字节后地址指针加1 write_com(0x01);//显示清零,数据指针清零 write_com(0x80);//设置数据指针起点 } //****************************// //***读取18b20温度数据子程 ***// //****************************// void Read_Temperature_rom(void) //读取温度函数 { uchar i; DS_init(); write_byte(0x55); //匹配ROM for(i=0;i<8;i++) //发出64位ROM编码 write_byte(RomID_temp[i]); write_byte(0x44); //开始转换温度 DS_init(); write_byte(0x55); //匹配ROM for(i=0;i<8;i++) //发出64位ROM编码 write_byte(RomID_temp[i]); write_byte(0xBE); //发读温度命令 temp.c[1]=read_byte(); //读低字节,之所以c[1]中放低字节,是因为C51采用的是大端格式 temp.c[0]=read_byte(); //读高字节,之所以c[0]中放低字节,是因为C51采用的是大端格式 //共用体定义 } void Temperature_cov(void) //温度转化 { cc=temp.x/16; //计算出温度值的整数部分,这个语句相当于数值乘0.0625再取整数部分 xs=temp.x&0x0f; //取温度值小数部分的第一位 xs=xs*10; //这两条语句相当于乘0.625,得小数位的第一位,注意不是乘0.0625 xs=xs/16; } //***********************// //******显示子程*********// //***********************// void display_m(void) //显示18b20个数或方向 { uchar i; write_com(0x8B); //write_data('0'+m); if(m==0) for(i=0;i<5;i++) {write_data(east[i]);} if(m==1) for(i=0;i<5;i++) {write_data(west[i]);} if(m==2) for(i=0;i<5;i++) {write_data(south[i]);} if(m==3) for(i=0;i<5;i++) {write_data(north[i]);} } void display_ROMID(void) //显示序列号 { uchar tmp[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36, 0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
史海拾趣
|
我是第一次作这方面的东西: 我感觉:首先要判断次外设的存在(包括他的插入于拔除) 向外设发送控制命令(包括向他提供数据)。 不知道思路是不是有问题,请各位给个思路。 … 查看全部问答> |
|
C5000音频电容触摸套件套件具体指标如下:MP3 Encode & DecodeSD Card File SystemUSB Mass Storage ClassOLED, CodecUART client interface可使用该套件配合launchpad制作音乐播放器:MP3 PlayerVoice RecorderFire Alarm – MSP430 detects tem ...… 查看全部问答> |
|
MSP430F149的定时器A的连续计数模式的CCR0的作用?增计数模式是从0增加到CCR0就复位,增减计数模式是从0增加到CCR0,在减到0。可是连续计数模式呢?CCR0的作用?… 查看全部问答> |
|
很详细的c函数介绍文档,我一直把他当做工具书来用,分享给大家! 如果哪位大侠把这个网页式的工具做成chm格式的电子书就完美了,哈哈 截图,先睹为快 [ 本帖最后由 HOHO 于 2012-8-8 16:42 编辑 ]… 查看全部问答> |




