我也晒一下,mega16+1602+18b20的温度测量,可以显负温度!--自己写的,又不对的地方请各位
频率为外部晶振16M,我实验通过了!挺高兴的,但是始终觉得有点不理想,所以拿来跟大家分享一下,希望各位给点意见!一、主程序
//温度传感器DS18B20试验
//间隔2s采集一次温度值
//使用1602的液晶作为显示
#include <iom16v.h>
#include <macros.h>
#include "18B20.h"
#include "1602.h"
uchar adc_0[]={"wendu:"};
uchar adc_1[]={0xdf,0x43};
uchar adc_2[]={0x2b};//正号
uchar adc_3[]={0x2d};//负号
uchar adc_4[]={0x2e};//小数点
//延时函数在16M时延时1ms
void s_1ms(unsigned int ms)
{
unsigned int aa;
for(;ms>=1;ms--)
{
for(aa=0;aa<=2000;aa++)
{;}
}
}
void main()
{
unsigned int i,j,tem3,tem2,tem1,tem0;
//int TCC;
//float TC,t;
unsigned char buffer3;
//端口初始化
DDRA = 0xff;
PORTA = 0x00;
DDRB = 0xFF;
PORTB = 0xF0;
DDRC = 0x00;
PORTC = 0xFF;
DDRD = 0xff;
PORTD = 0xff;
//延时200ms
s_1ms(200);
//DS18B20复位
ds1820_reset();
//1602 初始化
LcdInit();
WriteChar(1,0,6,adc_0);
WriteChar(1,11,2,adc_1);
WriteChar(1,9,1,adc_4);
while (1)
{
ds1820_start(); //进行一次转换
s_1ms(2);
i = ds1820_read_temp(); //读取温度数值f
j=i&0xf000;
if(j)
{
i=~i+1;
WriteChar(1,6,2,adc_3);
}
else
{
WriteChar(1,6,2,adc_2);
}
i = (i * 10) / 16; //数值处理
//第3位没有显示
i = i % 1000;
//显示第2位
tem2= i / 100;
WriteNum(1,7,tem2);
i = i % 100;
//显示第1位
tem1= i / 10;
WriteNum(1,8,tem1);
tem0= i % 10;
WriteNum(1,10,tem0);
}
}
二、18B20
//DS18B20连接在端口C的第7引脚
//设置成输入
#define DQ_INPUT DDRC &= ~(1 << PC7)
//设置成输出
#define DQ_OUT DDRC |= (1 << PC7)
//设置成低电平
#define DQ_LO PORTC &= ~(1 << PC7)
//设置成高电平
#define DQ_HI PORTC |= (1 << PC7)
//读出
#define DQ_R PINC & (1 << PC7)
//中断标志
unsigned char init_f;
//延时函数
void s_10us(unsigned int ms)
{
unsigned int aa;
for(;ms>=1;ms--)
{
for(aa=0;aa<=17;aa++)
{;}
}
}
//DS18B20复位
void ds1820_reset(void)
{
unsigned char i;
//中断保护
init_f = SREG;
//关中断
CLI();
DQ_OUT;
DQ_LO;
s_10us(50); //延时500us
DQ_HI;
DQ_INPUT;
s_10us(8); //延时80us
i = DQ_R;
s_10us(50); //延时500us
if (init_f & 0x80)//恢复中断状态
{
SEI();
}
}
//DS18B20字节读取
unsigned char ds1820_read_byte(void)
{
unsigned char i;
unsigned char value = 0;
//中断保护
init_f = SREG;
//关中断
CLI();
for (i = 8; i != 0; i--) {
value >>= 1;
DQ_OUT;
DQ_LO;
s_10us(1);
DQ_HI;
DQ_INPUT;
s_10us(1);
if (DQ_R) {
value|=0x80;
}
s_10us(5); //延时60us
}
if (init_f & 0x80) //恢复中断状态
{
SEI();
}
return(value);
}
//DS18B20字节写入
void ds1820_write_byte(unsigned char value)
{
unsigned char i;
//中断保护
init_f = SREG;
//关中断
CLI();
for (i = 8; i != 0; i--) {
DQ_OUT;
DQ_LO;
s_10us(1);
if (value & 0x01) {
DQ_HI;
}
s_10us(8); //延时80us
DQ_HI;
value >>= 1;
}
if (init_f & 0x80)//恢复中断状态
{
SEI();
}
}
//启动ds1820转换
void ds1820_start(void)
{
ds1820_reset();
ds1820_write_byte(0xCC); //勿略ROM
ds1820_write_byte(0x44); //启动转换
}
//读温度
unsigned int ds1820_read_temp(void)
{
unsigned int i;
unsigned char buf;
ds1820_reset();
ds1820_write_byte(0xCC); //勿略ROM
ds1820_write_byte(0xBE); //读温度
for (i = 0; i < 8; i++)
{
buf = ds1820_read_byte();
}
i = buf;
i <<= 8;
i |= buf;
return i;
}
三、1602液晶
这个就不用了吧! 沙发 楼主的18b20是否能长线高温工作? 回复:【2楼】 gxy508
实验中,呵呵!应该没有问题的! mark 能不能把1602的也贴上啊!!!!! {:2_35:}能不能用!能的话赞一个! 我来贴这个1602吧
#define uchar unsigned char
#define uint unsigned int
#define RS 5
#define RW 6
#define EN 7
void s_ms(uint ms)
{
for(;ms>1;ms--);
}
//查忙
void busy(void)
{
uchar temp;
s_ms(500);
PORTA&=~(1<<RS); //RS=0
s_ms(500);
PORTA|=(1<<RW); //RW=1
s_ms(500);
while(temp)
{
PORTA|=(1<<EN); //EN=1
s_ms(500);
DDRD=0x00; //A口变输入
PORTD=0xff; //上拉使能
s_ms(500);
temp = PIND&0x80; //读取A口
s_ms(500);
DDRD=0xff;
PORTD=0xff; //A口变输出
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
}
}
//写指令
void writecom(uchar com)
{
busy();
s_ms(500);
PORTA&=~(1<<RS); //RS=0
s_ms(500);
PORTA&=~(1<<RW); //RW=0
s_ms(500);
PORTA|=(1<<EN); //EN=1
s_ms(500);
PORTD = com; //输出指令
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
}
//1602初始化
void LcdInit(void)
{
DDRD = 0xff;
PORTD = 0x00;
writecom(0x38);
s_ms(1000);
writecom(0x01);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
s_ms(1000);
writecom(0x02);
s_ms(1000);
writecom(0x06);
s_ms(1000);
writecom(0x0c);
s_ms(1000);
writecom(0x38);
s_ms(1000);
}
//写数据
void writedata(uchar data)
{
busy();
s_ms(500);
PORTA|=(1<<RS); //RS=1
s_ms(500);
PORTA&=~(1<<RW); //RW=0
s_ms(500);
PORTA|=(1<<EN); //EN=1
s_ms(500);
PORTD = data; //输出数据
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
}
//读数据
uchar readdata(void)
{
uchar temp;
busy();
s_ms(500);
PORTA|=(1<<RS);//RS=1
s_ms(500);
PORTA|=(1<<RW);//RW=1
s_ms(500);
PORTA|=(1<<EN);//EN=1
s_ms(500);
DDRD=0x00; //A端口变输入
s_ms(500);
temp = PIND; //读A端口
s_ms(500);
DDRD=0xff; //A端口变输出
s_ms(500);
PORTA&=~(1<<EN); //EN=0
s_ms(500);
return temp;
}
//=================================================
// 描述: 写LCD内部CGRAM函数
// 入口: ‘num’要写的数据个数
// ‘pbuffer’要写的数据的首地址
// 出口: 无
//================================================
void WriteCGRAM(uint num, const uint *pBuffer)
{
uint i,t;
writecom(0x40);
PORTA|=(1<<RS);
PORTA&=~(1<<RW);
for(i=num;i!=0;i--)
{
t = *pBuffer;
PORTA|=(1<<EN);
PORTD = t;
PORTA&=~(1<<EN);
pBuffer++;
}
}
//=================================================
//描述:写菜单函数,本程序使用的LCD规格为 16 * 2
//入口:菜单数组首地址
//出口:无
//=================================================
void WriteMenu(const uchar *pBuffer)
{
uchar i,t;
writecom(0x80); //数据地址
PORTA|=(1<<RS);
PORTA&=~(1<<RW);
s_ms(50);
for(i=0;i<16;i++)
{
t = *pBuffer;
PORTD = t;
PORTA|=(1<<EN);
s_ms(50);
PORTA&=~(1<<EN);
pBuffer++;
}
writecom(0xC0);
PORTA|=(1<<RS);
PORTA&=~(1<<RW);
s_ms(50);
for(i=0;i<16;i++)
{
t = *pBuffer;
PORTD = t;
PORTA|=(1<<EN);
s_ms(50);
PORTA&=~(1<<EN);
pBuffer++;
}
}
//====================================================
// 描述:在任意位置写数字函数
// 入口:’row‘表示要写数字所在的行地址,只能为1或2
// ’col‘表示要写数字所在的列地址,只能为0--15
// ‘num’表示要写的数字,只能为0--9
// 出口:无
//===================================================
void WriteNum(uint row,uint col,uint num)
{
if (row == 1) row = 0x80 + col;
else row = 0xC0 + col;
writecom(row);
if (num<=0 | num>9) num =0x30;
else num = 0x30 + num;
PORTA|=(1<<RS);
s_ms(500);
PORTA&=~(1<<RW);
s_ms(500);
PORTD = num;
s_ms(500);
PORTA|=(1<<EN);
s_ms(500);
PORTA&=~(1<<EN);
s_ms(500);
}
//================================================================
// 描述:在任意位置写任意多个字符
// 入口:’row‘要写的字符所在的行,只能为1或2;
// ‘col’要写的字符所在的列,只能为0---15
// ‘num’要写字符的个数
// ‘pbuffer’要写字符的首地址
//==================================================================
void WriteChar(uchar row,uchar col,uint num,uchar *pBuffer)
{
uchar i,t;
if (row == 1) row = 0x80 + col;
else row = 0xC0 + col;
writecom(row);
//if (num<=0 | num>9) num =0x30;
//else num = 0x30 + num;
PORTA|=(1<<RS);
s_ms(500);
PORTA&=~(1<<RW);
s_ms(500);
for(i=num;i!=0;i--)
{
t = *pBuffer;
s_ms(500);
PORTD = t;
s_ms(500);
PORTA|=(1<<EN);
s_ms(500);
PORTA&=~(1<<EN);
s_ms(500);
pBuffer++;
}
}
学习了,最近也想做个。 学习一下....
页:
[1]