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); /
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』