/**********************************************************************
* 文件名称: main.c
* 程序作者: kidcao1987
* 程序版本: V1.0
* 功能描述: 装上LCD1602,在其上,显示当前的温度。
* 编译器:WinAVR-20090313
* 芯片:ATmega16,外部11.0592MHZ晶振
* 技术支持:http://bbs.cepark.com
**********************************************************************/
#include<avr/io.h>
#include<util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define DQ PORTC&=~(1<<PC7)//不再变化
#define DQ_ActiveHigh DDRC&=~(1<<PC7) //IO改为输入口,高阻态,外部上拉电阻拉高
#define DQ_ActiveLow DDRC|=(1<<PC7) //改为输出口,输出低电平
#define DQ_SetInput DDRC&=~(1<<PC7)
#define DQ_Readback (PINC&0x80)
#define RS PA4
#define RW PA5
#define EN PA6
unsigned char const LedData[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char const LedPos[]=
{0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar DisplayNum[]={"0123456789.-C"};
uchar const CharacterChar[]={"Now the Tempera-ture is: "};
uchar Num[4];
uchar TemperatureL,TemperatureH,m;
uint Temperature;
void LCD1602_Initial(void);
void LCD1602_CommandWrite(uchar com);
void LCD1602_ByteWrite(uchar date);
void LCD1602_Display(uchar adr,uchar date);
void LCD1602_BusyCheck(void);
void DS18B20_Reset(void);
void DS18B20_PORTx_Initial(void);
void DS18B20_High_BitWrite(void);
void DS18B20_Low_BitWrite(void);
void DS18B20_ByteWrite(uchar command);
uchar DS18B20_ByteRead(void);
int main(void)
{
DS18B20_PORTx_Initial();
LCD1602_Initial();
while(1)
{
DS18B20_Reset();//复位
DS18B20_ByteWrite(0xcc);//跳过ROM匹配
DS18B20_ByteWrite(0x44);//温度转换
_delay_ms(600);//延时等待温度转换结束,这个很重要!!
DS18B20_Reset();//复位
DS18B20_ByteWrite(0xcc);//跳过ROM匹配
DS18B20_ByteWrite(0xbe);//读取温度
TemperatureL=DS18B20_ByteRead();
TemperatureH=DS18B20_ByteRead();//先低字节后高字节
DS18B20_Reset();//复位打算DS18B20的输出
/*以下是温度数据处理以及显示部分*/
Temperature=TemperatureL*6.25+TemperatureH*1600;
Num[0]=Temperature/1000;
Num[1]=(Temperature%1000/100);
Num[2]=Temperature%100/10;
Num[3]=Temperature%10;
for(m=0;m<16;m++)
{
LCD1602_Display(0x80+m,CharacterChar[m]);
}
for(m=0;m<9;m++)
{
LCD1602_Display(0x80+0x40+m,CharacterChar[16+m]);
}
LCD1602_ByteWrite(DisplayNum[Num[0]]);
LCD1602_ByteWrite(DisplayNum[Num[1]]);
LCD1602_ByteWrite(DisplayNum[10]);
LCD1602_ByteWrite(DisplayNum[Num[2]]);
LCD1602_ByteWrite(DisplayNum[Num[3]]);;
LCD1602_ByteWrite(0xdf);
LCD1602_ByteWrite(DisplayNum[12]);
}
}
void DS18B20_PORTx_Initial(void)
{
DDRB=0xff;//B口全部输出
PORTB=0xff;//B口全部低电平
DQ;
DQ_ActiveHigh;
}
void DS18B20_Reset(void)
{
DQ_ActiveLow;
_delay_us(600);//延时至少480us
DQ_ActiveHigh;//释放数据线
_delay_us(70);//延时大于60us
while(DQ_Readback);//检测存在信号
_delay_us(500);//延时保证时序完整性
}
void DS18B20_High_BitWrite(void)
{
DQ_ActiveLow;//拉成低电平
_delay_us(2);//保持至少1us
DQ_ActiveHigh;//释放数据线
_delay_us(65);//等待足够时间使DS18B20采样数据线
}
void DS18B20_Low_BitWrite(void)
{
DQ_ActiveLow;//拉成低电平
_delay_us(65);//等待足够时间使DS18B20采样数据线
DQ_ActiveHigh;//释放数据线
}
uchar DS18B20_BitRead(void)
{
DQ_ActiveLow;//拉成低电平
_delay_us(2);//保持至少1us
DQ_ActiveHigh;//释放数据线
_delay_us(4);//延时使主机再15us的后阶段读取数据线
if(DQ_Readback)
return 1;
else
return 0;
}
/*DS18B20字节写函数*/
void DS18B20_ByteWrite(uchar command)
{
uchar n=0;
for(n=0;n<8;n++)
{
if(command&0x01)
DS18B20_High_BitWrite();
else
DS18B20_Low_BitWrite();
command>>=1;
_delay_us(5);
}
}
/*DS18B20字节读函数*/
uchar DS18B20_ByteRead(void)
{
uchar n=0,Readback=0;
for(n=0;n<8;n++)
{
Readback>>=1;
if(DS18B20_BitRead())
Readback|=0x80;
_delay_us(65);
}
return Readback;
}
void LCD1602_Initial(void)
{
PORTA&=~((1<<RS)|(1<<RW)|(1<<EN));
DDRA|=(1<<RS)|(1<<RW)|(1<<EN);
PORTB=0x00;
DDRB=0xff;
LCD1602_CommandWrite(0x38);
_delay_ms(15);
LCD1602_CommandWrite(0x38);
_delay_ms(5);
LCD1602_CommandWrite(0x38);
_delay_ms(5);
LCD1602_CommandWrite(0x01);
_delay_ms(1);
LCD1602_CommandWrite(0x38);
_delay_ms(1);
LCD1602_CommandWrite(0x0c);
_delay_ms(1);
LCD1602_CommandWrite(0x06);
}
/*1602写命令字子函数*/
void LCD1602_CommandWrite(uchar com)
{
LCD1602_BusyCheck();
PORTA&=~(1<<RS); //RS引脚置为低电平,写命令字节
PORTB=com; //将数据送到8位并行数据口
PORTA|=(1<<EN); //EN引脚电平上升将命令字写入1602内部
_delay_ms(1); //延时5ms,保持EN电平
PORTA&=~(1<<EN); //时钟脉冲复位,准备下一次写操作
}
/*1602写数据子函数*/
void LCD1602_ByteWrite(uchar date)
{
LCD1602_BusyCheck();
PORTA|=(1<<RS); //RS引脚高电平,准备写数据字节
PORTB=date; //将数据送到8位并行数据口
PORTA|=(1<<EN); //EN引脚上升将数据字节写入1602
_delay_ms(1); //延时5ms,保持EN电平
PORTA&=~(1<<EN); //时钟脉冲复位,准备下一次写操作
}
/*在某位置显示某字符,参数adr为待写地址,date为待写字节*/
void LCD1602_Display(uchar adr,uchar date)
{
LCD1602_BusyCheck();
LCD1602_CommandWrite(adr);
LCD1602_BusyCheck();
LCD1602_ByteWrite(date);
}
void LCD1602_BusyCheck(void)
{
PORTB=0xff;
DDRB=0x00;
PORTA|=(1<<RW);
PORTA&=~(1<<RS);
PORTA|=(1<<EN);
_delay_us(5);
while(PINB&0x80);
PORTA&=~(1<<EN);
PORTA&=~(1<<RW);
PORTB=0xff;
DDRB=0xff;
}
视频地址:http://v.youku.com/v_show/id_XMTYxNDkyOTgw.html
https://static.assets-stash.eet-china.com/album/old-resources/2010/3/31/05c90c56-f2d8-4ee1-b0da-7d62171994f1.zip
文章评论(0条评论)
登录后参与讨论