对于蓝桥杯比赛,很多人对于比赛官方给出的三个驱动不知道怎么具体使用。其实官方给出的驱动是在原有的芯片基础上做出的驱动,但是后来比赛官方对比赛专用版CT107D上使用了IAP1F2K61S2转接板,驱动的一些位置都相应的做出了该变。
首先对于驱动,我们的看法是去建立一个存在主函数的C 文件去调用这个驱动的C文件和H文件。而不是在给出的驱动上直接书写程序,因为那样的编程思想是会使编译很乱,不方便调试。
首先我们先对CT107D板上的温度传感器进行分析,首先它应用的是单总线协议,三条线两条电源线--VCC与GND,另一条是进行信号传输。
一、 首先我们需要对官方给出的C文件驱动进行修改编译。
#include "onewire.h"
void Delay_OneWire(unsigned int t) //单总线延时函数
{
unsigned char i;
while(t--){
for(i=12;i>0;i--); //对于比赛驱动,需要在此加一个for循环,因为是12倍处理速度
}
}
//通过单总线向DS18b20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18b20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
/*************************以下需要自己去写的函数****************************************/
float rd_temperature(void)
{
unsigned int temp;
unsigned char low,high; //收集数据的--高低位
float tempreturn;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44); //直接使用温度转换(这种地方自己看手册芯片理解CC、BE、44的用法)
Delay_OneWire(200);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();
high=Read_DS18B20();
temp = high;
temp<<=8;
temp |=low;
tempreturn = temp*0.0625; //精度为0.0625,需要乘以0.0625
return tempreturn; //返回温度数值,直接在主函数里获取就可以直接使用了
}
二、接下来我们需要对官方给出的H文件驱动进行修改编译。
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include "reg52.h"
sbit DQ = P1^4; //定义单总线接口
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
float rd_temperature(void);
/*****************主要是对驱动C文件的函数进行声明,对接口进行声明*****************/
#endif
三、现在开始使用主程序和定时器进行显示了。
//主调用程序是使用了定时器0进行数字显示,
//想进行其他功能可以再自行添加,本文只是做出最简单的显示,方便初学者理解
#include "reg52.h"
#include "onewire.h"
#include "intrins.h"
#define FOSC 11059200L
#define T1MS (65536-FOSC/12/1000)
sbit buzzer=P0^6;
unsigned char fanhuizhi;
unsigned int count; //中断标志位
unsigned char code sum[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char code was[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char xs[2]; //显示数组
void gb_eupument()
{
P2=((P2&0x1f)|0xa0); buzzer=0; P2 &=0x1f; //关闭蜂鸣器
P2=((P2&0x1f)|0x80); P0=0xff; P2 &=0x1f; //关闭LED
}
void tm0_init()
{
TMOD = 0x01; //set timer0 as mode1 (16-bit)
TL0 = T1MS; //initial timer0 low byte
TH0 = T1MS >> 8; //initial timer0 high byte
TR0 = 1; //timer0 start running
ET0 = 1; //enable timer0 interrupt
EA = 1; //open global interrupt switch
count = 0; //initial counter
}
void main()
{
gb_eupument();
tm0_init();
while (1)
{
EA=0; //关闭中断,避免对显示产生干扰
fanhuizhi=(unsigned char)rd_temperature();
EA=1; //打开中断,进行正常显示
xs[0]=fanhuizhi/10;
xs[1]=fanhuizhi%10;
}
}
/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{
static unsigned char i;
TL0 = T1MS;
TH0 = T1MS >> 8;
if (count-- == 0) //1ms
{
count = 1;
P2=((P2&0x1f)|0xc0); P0=was[i]; P2 &=0x1f;
P2=((P2&0x1f)|0xe0); P0=~sum[xs[i]]; P2 &=0x1f;
i++;
if(i==2) i=0;
}
}
以上便是对CT107D版上的DS18b20温度传感器基于单总线协议的调用,希望多多练习。