📄 ds18b20.c
字号:
#include <iom16v.h>
#include <macros.h>
#define DQ_IN DDRA &= ~(1 << PA7) /*设置输入*/
#define DQ_OUT DDRA |= (1 << PA7) /*设置输出*/
#define DQ_CLR PORTA &= ~(1 << PA7) /*置低电平*/
#define DQ_SET PORTA |= (1 << PA7) /*置高电平*/
#define DQ_R PINA & (1 << PA7) /*读了电平*/
unsigned char led_7[] = {0X3f,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0x40,0x00,};
unsigned char flag; /*中断标志缓存*/
unsigned char position[4]={0X07,0X0B,0X0D,0X0E};
//unsigned char time[2];//显示时,分,
unsigned char dis_buff[4]; // 显示缓冲区
unsigned char posit;
unsigned char led_buf[] = {0,0,0,0,}; /*显示信息*/
/*********************delay function********************/
void delay_1us(void) //1us延时函数
{
asm("nop");
}
void delay_nus(unsigned int n) //N us延时函数
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1us();
}
void delay_1ms(void) //1ms延时函数
{
unsigned int i;
for (i=0;i<1140;i++);
}
void delay_nms(unsigned int n) //N ms延时函数
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}
/*DS18B20复位函数*/
unsigned char ds1820_reset(void) {
unsigned char i;
flag = SREG; /*中断保护*/
CLI(); /*关中断*/
DQ_OUT;
DQ_CLR;
delay_nus(500); /*延时500uS(480-960)*/
DQ_SET;
DQ_IN;
delay_nus(80); /*延时80uS*/
i = DQ_R;
delay_nus(490); /*延时500uS(保持>480uS)*/
if (flag & 0x80) { /*恢复中断状态*/
SEI();
}
if (i) {
return 0x00;
}
else {
return 0x01;
}
}
/*DS18B20字节读取函数*/
unsigned char ds1820_read_byte(void) {
unsigned char i;
unsigned char value = 0;
flag = SREG; /*中断保护*/
CLI(); /*关中断*/
for (i = 8; i != 0; i--) {
value >>= 1;
DQ_OUT;
DQ_CLR;
delay_nus(10);
DQ_SET;
DQ_IN;
delay_nus(10);
if (DQ_R) {
value|=0x80;
}
delay_nus(60); /*延时60uS*/
}
if (flag & 0x80) { /*恢复中断状态*/
SEI();
}
return(value);
}
/*DS18B20字节写入函数*/
void ds1820_write_byte(unsigned char value) {
unsigned char i;
flag = SREG; /*中断保护*/
CLI(); /*关中断*/
for (i = 8; i != 0; i--) {
DQ_OUT;
DQ_CLR;
delay_nus(4);
if (value & 0x01) {
DQ_SET;
}
delay_nus(80); /*延时80uS*/
DQ_SET; /*位结束*/
value >>= 1;
}
if (flag & 0x80) { /*恢复中断状态*/
SEI();
}
}
/*启动ds1820转换*/
void ds1820_start(void) {
ds1820_reset();
ds1820_write_byte(0xCC); /*勿略地址*/
ds1820_write_byte(0x44); /*启动转换*/
}
/*DS8B20读取温度信息*/
unsigned int ds1820_read_temp(void) {
unsigned int i;
unsigned char buf[9];
ds1820_reset();
ds1820_write_byte(0xCC); /*勿略地址*/
ds1820_write_byte(0xBE); /*读取温度*/
for (i = 0; i < 9; i++) {
buf[i] = ds1820_read_byte();
}
i = buf[1];
i <<= 8;
i |= buf[0];
return i;
}
void time_to_disbuffer(int a,int b,int c,int d)//时间送显示缓冲区函数
{
dis_buff[0] = a;
dis_buff[1] =b;
dis_buff[2] = c;
dis_buff[3] =d;
}
void display(void)//数码管显示程序
{ PORTD = 0xff;
PORTC = led_7[dis_buff[posit]];
PORTD= position[posit];
if (++posit >=4 ) posit = 0;
}
// Timer 0 比较匹配中断服务
#pragma interrupt_handler TIMER0_COMP:20
void TIMER0_COMP(void)
{
display();
}
void main(void)
{
int i,j;
PORTD=0xFF; // 显示控制I/O端口初始化
DDRD=0xFF;
PORTC=0XfF;
DDRC=0xFF;
// T/C0 初始化
TCCR0=0x0B; // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
TCNT0=0x00;
OCR0=0x7C; // OCR0 = 0x7C(124),(124+1)/62.5=2ms
TIMSK=0x02; // 允许T/C0比较匹配中断
SEI(); //允许全局中断
while (1) {
ds1820_start(); /*启动一次转换*/
delay_nms(10); /*等待转换结束*/
i=ds1820_read_temp(); /*读取温度数值*/
if(i>=0xf000)//判断是不是负数
{
i=~i; //转换,先取反,在加1.
i+=1;
i = (i * 10) / 16; /*数值处理*/
led_buf[3] = i / 1000; /*将显示信息加载到显示缓存区*/
i = i % 1000;
led_buf[2] = i / 100;
i = i % 100;
led_buf[1] = i / 10;
led_buf[0] = i % 10;
time_to_disbuffer(led_buf[1],led_buf[2],10,11);
}
else
{
i = (i * 10) / 16; /*数值处理*/
led_buf[3] = i / 1000; /*将显示信息加载到显示缓存区*/
i = i % 1000;
led_buf[2] = i / 100;
i = i % 100;
led_buf[1] = i / 10;
led_buf[0] = i % 10;
time_to_disbuffer(led_buf[1],led_buf[2],led_buf[3],led_buf[0]);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -