📄 ds1820-lcd.c
字号:
/*
本程序为采用mega8 和18b20的温度采集程序
选用mega8内部8M RC震荡,18b20 数据线接pd6,数据线和vcc间接一4.7k上拉电阻
*/
#include <iom8v.h> //和单片机类型相对应的头文件,选择Atmega8做实验;
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define osccal 0xAC//内部RC校正常数
#define WR 0B00100000//时钟线
#define DATA 0B00001000//数据线
#define CS 0b00010000//片选线
#define word_long 8
unsigned char seg_table[ ] ={0XFB,0X60,0XC7,0XE5,0X6C,0XAD,0XAF,0XE0,0XEF,0XED};
unsigned char count,con;
/*****************************************************************/
/*LCD系统命令(可选)*/
const char TAB_REST[10]={0b00000001,/*打开系统振荡器命令*/
0b00000011,/*打开LCD 偏压发生器命令*/
0b00000101,/*WDT 溢出标志输出失效命令*/
0b00000110,/*时基输出使能命令*/
0b00011000,/*系统时钟源片内RC振荡器命令*/
0b00101001,/*LCD1/3偏压选项4个公共口命令*/
0b01000000,/*声音频率4KHz命令*/
0b00001001,/*打开声音输出命令*/
0b10100000,/*时基/WDT 时钟输出1Hz命令*/
0b10001000};/*使/IRQ 输出有效命令*/
void send_data(unsigned char data_bus,unsigned char loop);
void lcd_display(void);
void delay_us(uint time);
void init_1820(void);
void write_1820(uchar x);
uchar read_1820(void);
void delay_us(uint x) //1.5us左右
{
do
x--;
while (x>1);
}
void init_1820()
{
DDRD|=(1<<6);
PORTD&=~(1<<6);
delay_us(500);
PORTD|=(1<<6);
DDRD&=~(1<<6);
delay_us(30);
while(PIND&(1<<6))
{
;
}
delay_us(200);
}
void write_1820(uchar cmd)
{
uchar i,j;
DDRD|=(1<<6);
for(j=0;j<=7;j++)
{
i=cmd&0x01;
if (i==0x01)
{
PORTD&=~(1<<6);
delay_us(10);
PORTD|=(1<<6);
delay_us(100);
}
else
{
PORTD&=~(1<<6);
delay_us(100);
PORTD|=(1<<6);
delay_us(10);
}
cmd=cmd>>1;
}
}
uchar read_1820()
{
uchar temp=0,tmp,i;
for(i=0;i<8;i++)
{
DDRD|=(1<<6);
PORTD&=~(1<<6);
delay_us(3);
PORTD|=(1<<6);
DDRD&=~(1<<6);
delay_us(10);
tmp=(PIND&(1<<6));
if(tmp!=0x00) temp|=0x80;
if(i<7) temp=temp>>1;
delay_us(100);
//DDRD|=(1<<6);
//delay_us(5);
}
return (temp);
}
void ht1621_int(void)
{
uchar t;
PORTB &=~CS;
PORTB |=WR;
asm("nop");
PORTB &=~WR;
asm("nop");
send_data(0b10000000,3);/*送3位命令模式代码100*/
for(t=0;t<=9;t++)
{
send_data(TAB_REST[t],9);/*送9位命令代码*/
}
PORTB |=CS;
PORTB |=WR;
PORTB |=DATA;
}
void lcd_display()
{
uchar temp[3];
uchar t;
PORTB &=~CS;
PORTB |=WR;
asm("nop");
PORTB &=~WR;
asm("nop");
send_data(0b10100000,3); /*送3位WRITE 模式命令代码101*/
send_data(0,6); /*送6位首地址00h*/
//temp[2] =count / 100; //转换百位值
temp[3] =(count-temp[2]*100)/10;
temp[6] =(count-temp[2]*100-temp[3]*10)%10;
//temp[3] =0;
temp[7] =con;
for(t=0;t<16;t++)
{
if (t<3) send_data(0,word_long);
//if (t==2) send_data(seg_table[temp[t]],word_long);
if (t==3) send_data(seg_table[temp[t]],word_long);
if (t==4) send_data(0,word_long);
if (t==5) send_data(0,word_long);
if (t==6) send_data(seg_table[temp[t]]|0x10,word_long);
if (t==7) send_data(seg_table[temp[t]],word_long);
if (t>7) send_data(0,word_long);
}
PORTB |=CS;
PORTB |=WR;
PORTB |=DATA;
}
void send_data(uchar data_bus,uchar loop)
{
for(;loop!=0;loop--)
{
delay_us(5);
PORTB &=~WR;
if((data_bus&0b10000000)==0)
{
PORTB &=~DATA;
}
else
{
PORTB |=DATA;
}
data_bus=data_bus<<1;
PORTB |=WR;
}
}
void main(void) //主函数
{
DDRB =0XFF;
PORTB =0XFF;
DDRD=0XFF;
PORTD=0XFF;
OSCCAL=0xac;//系统时钟校准,不同的芯片和不同的频率,
ht1621_int();
//lcd_display();
delay_us(100);
while(1)
{
uchar i,temh,teml;
uint temp;
init_1820(); //复位18b20
write_1820(0xcc); // 发出转换命令
write_1820(0x44);
for(i=0;i<200;i++) //每次转换需要延时400ms以上
delay_us(2000);
init_1820();
write_1820(0xcc); //发出读命令
write_1820(0xbe);
teml=read_1820(); //读数据
temh=read_1820();
temp=temh<<8;
temp=((temp+teml) & 0x7ff) ;
count=((temp>>4)& 0x7f);
con=(teml&0xf0)? 5:0;
lcd_display(); //显示温度
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -