历史上的今天
今天是:2025年03月03日(星期一)
2020年03月03日 | arm力天电子 lpc2148 基于DS18b20的温度采集实验程序详解
2020-03-03 来源:eefocus
1#include 2#include 3#include "uart.h" //系统时钟 4#define Fosc 12000000UL //晶振时钟 【Hz】 5#define Fcclk (Fosc * 5) //系统频率,必须为Fosc的整数倍(1~32),且<=60MHZ 6#define Fcco (Fcclk * 4) //CCO频率,必须为Fcclk的2、4、8、16倍,范围为156MHz~320MHz 7#define Fpclk (Fcclk / 4) * 4 // VPB时钟频率,只能为(Fcclk / 4)的1 ~ 4倍 //接口声明 8#define DS_OUT() IO0DIR_bit.P0_19 = 1 //设置为输出 9#define DS_IN() IO0DIR_bit.P0_19 = 0 //设置为输入 10#define DS_L() IO0CLR_bit.P0_19 = 1 //端口底电平 11#define DS_H() IO0SET_bit.P0_19 = 1 //端口高电平 12#define DS_R() IO0PIN_bit.P0_19 //读入端口数据 //函数声明 13void PLL_Init(void); 14void Tmp_Change(void); 15void Delayn(unsigned long n); 16void DelaynUs(unsigned int n); 17float tmp(void); 18void DS_Reset(void); //主函数 19void main(void) 20{ 21 char buf[100]; 22 float a; 23 PLL_Init(); //初始化系统时钟 24 InitUart0(); //初始化串口 25 PINSEL1_bit.P0_19 = 0;//初始化端口 26 DS_IN(); //定时器1初始化,产生定时基准 27 T1IR = 0xFF; // reset match and capture event interrupts 28 T1TC = 0; // Clear timer counter 29 T1PR = 0; // 0 Prescalar 30 T1TCR=0x00000003; //T0PC和T0TC复位(有误,跟T0啥关系呢) 31 T1TCR=0x00000001; //使能 32 while(1){ 33 Tmp_Change(); //数据开始转换 34 DelaynUs(1000); //延时等待1000微秒,即1ms 35 a=tmp(); //读取数据 //输出转换结果 36 sprintf(buf,"The current temperature is %.1f.n",a); 37 sendStr(buf); 38 DelaynUs(1000000); //等待1s 39 } 40} //PLL初始化 41void PLL_Init(void) 42{ /* 设置系统各部分时钟 */ 43 PLLCON = 1; 44 #if ((Fcclk / 4) / Fpclk) == 1 45 VPBDIV = 0; 46 #endif 47 #if ((Fcclk / 4) / Fpclk) == 2 48 VPBDIV = 2; 49 #endif 50 #if ((Fcclk / 4) / Fpclk) == 4 51 VPBDIV = 1; 52 #endif 53 #if (Fcco / Fcclk) == 2 54 PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5); 55 #endif 56 #if (Fcco / Fcclk) == 4 57 PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5); 58 #endif 59 #if (Fcco / Fcclk) == 8 60 PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5); 61 #endif 62 #if (Fcco / Fcclk) == 16 63 PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5); 64 #endif 65 PLLFEED = 0xaa; //发送PLL馈送序列,执行设定PLL的动作 66 PLLFEED = 0x55; 67 while((PLLSTAT & (1 << 10)) == 0); //等待PLL锁定 68 PLLCON = 3; //设置激活并连接PLL 69 PLLFEED = 0xaa; //发送PLL馈送序列,执行激活和连接动作 70 PLLFEED = 0x55; // Memory map init flash memory is maped on 0 address 71 MEMMAP_bit.MAP = 1; 72} //复位(参考资料见DS18B20中文资料P7-10及DS18B20幻灯片) 73void DS_Reset(void) //send reset and initialization command 74{ 75 DS_OUT(); //(端口设置为输出) 76 DS_L(); //DS=0,主机发送一个端口低电平 77 DelaynUs(800); //800us, 78 DS_IN(); //input,(端口设置为输入) 79 DelaynUs(100); //100us 80 /*if(DS_R()!=0) 81 sendStr("There are no 18B20 !n"); 82 else 83 sendStr("Init 18B20 succeed!n");*/ 84 while(DS_R()==0); //等待低电平过去 85} //读一位数据 86unsigned char tmpreadbit(void) //read a bit 87{ 88 unsigned char dat; 89 DS_OUT(); //端口设置为输出 90 DS_L(); //DS=0 91 //Delayn(1); //2uS 92 DS_IN(); //input 93 //Delayn(1); 94 if(DS_R()!=0) 95 dat=1; 96 else 97 dat=0; 98 DelaynUs(50); 99 return (dat); 100} //读一个字节数据 101unsigned char tmpread(void) //read a byte date 102{ 103 unsigned char i,j,dat; 104 dat=0; //什么意思,见下面 105 for(i=1;i<=8;i++) 106 { 107 j=tmpreadbit(); 108 dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里 109 } 110 return(dat); 111} //86-111这段程序在另外一篇文章里有介绍 (http://blog.csdn.net/yueniaoshi/article/details/7835790) //写数据 112void tmpwritebyte(unsigned char dat) //write a byte to ds18b20 113{ 114 unsigned char j; 115 unsigned char testb; 116 for(j=1;j<=8;j++) 117 { 118 testb=dat&0x01; //(利用与运算取出要写的第0位二进制数据) 119 dat=dat>>1; //将此位右移1位,为的是使dat中将要取出的位始终位于第0位 120 if(testb) //write 1 121 { 122 DS_OUT(); 123 DS_L(); //DS=0,写周期一开始做为主机先把总线拉低1微秒表示写周期开始 124 //Delayn(1); 125 DS_IN(); //input 126 DelaynUs(50); 127 } 128 else //write 0 129 { 130 DS_OUT(); 131 DS_L(); //DS=0; 132 DelaynUs(45); 133 DS_IN(); //input 134 DelaynUs(2); 135 } 136 } 137} //DS18B20 begin change,转换数据 138void Tmp_Change(void) 139{ 140 DS_Reset(); 141 DelaynUs(1000); 142 tmpwritebyte(0xcc); // address all drivers on bus(跳过ROM,忽略64位ROM地址,直接向 // DS18B20发温度变换命令) 143 tmpwritebyte(0x44); // initiates a single temperature conversion,启动DS18B20进 //行温度转换,转换时间最长为500ms(典型为200ms)结果存入内部9字节RAM中 144} //get the temperature ,读取温度值 145float tmp(void) 146{ 147 float tt; 148 unsigned int temp; 149 unsigned char a,b; 150 DS_Reset(); //复位DS18B20(主机发出复位操作并接收DS18B20的应答存在脉冲) 151 DelaynUs(1000); 152 tmpwritebyte(0xcc); //跳过ROM,忽略64位ROM地址,直接向DS18B20发温度变换命令 153 tmpwritebyte(0xbe); //读暂存器,读内部RAM中9字节的内容(即读温度),如果只想读取温//度数据, //那在读完第0和第1个数据后就不在理会后面DS18B20发出的数据即可,读取的数据是低位//在前的 154 a=tmpread(); //连续两次调用tmpread(),把最先发出的两个字节读回 155 b=tmpread(); //这两个字节分别是温度的高字节和低字节 156 temp=b; 157 temp<<=8; //two byte compose a int variable 158 temp=temp|a; //组合成完整数据 159 tt=temp*0.0625; //将测到的数值乘以0.0625即可得到实际温度(原因自己也搞不懂,但在最后附一张图片,上面有一些介绍) 160 temp=tt*10+0.5; //0.5是干嘛的呢?应该是精度差 161 return temp; //具体是哪个地方呢?应该是返回到 tt=tt*10+0.5这个地方
史海拾趣
|
我的keil 老是出错, 比如: void main(void) { unsigned int w; w=10; } 程序执行到‘}’结束符就出错。 *** error 65: access violation at C:0x0A00 &nb ...… 查看全部问答> |
|
小弟这两天碰到一个很诡异的问题。 我在以前写的工程中加入代码调试运行时,新写的代码不运行。具体如下: 假如先前函数代码: [code]OnBnClickedBtnPrint1() { int a=0; a++; &nb ...… 查看全部问答> |
|
今天看了一下ST的datasheet: RM0016 Reference manual December 2009 I2C 是400K? 4M? 400k.JPG (80.43 KB) 下载次数:2 2010-9-15 22:01 4M.JPG (75. ...… 查看全部问答> |
|
打算用MAX7456,需要个27M的晶振。想把晶振省掉,用STM32的MCO来输出给它。 该CLKIN输入datasheet如下,VDVCC是5V供电。 下载 (31.48 KB) 2011-1-28 09:37 打算STM32用9M的晶振,PLL用6倍频到主时钟54M,然后MCO用PLL ...… 查看全部问答> |




