📄 ex6-3.c
字号:
/*
标题:范例 6-3
版本:1.0
Target:89S51
程序描述:网络远端温度感测器,这个范例中使用到
(1)8051 的Port 1连接到LCD显示器,PORT 3的P3.3、P3.4和P3.5分别连接到LCD显示器的控制线,程序执行时可以让LCD显示器显示出时间和日期。
(2)温度感测组件AD590经由ADC0804将感测到的温度,转换成数位数据,然后经由PORT 0输入8051。
(3)igangcai 8051的第10和第11只脚RXD和TXD分别连线到MAX232,然后连接到PC的COM埠。
(4) 当PC端经由RS232传送S时,接下来PC送出的下 个byte就用来设定PORT 3的输出。
(5) 当PC端经由RS232传送T时,接下来PC连续送出五个bytes,这五个bytes是 "年月日时分",这是 PC 用来设定实验板的时间日期。
(6) 8051每 分钟就读入ADC0804转换的数字温度数据,然后通过RS232传送给PC端,再由PC端通过网络传送到远端的电脑。*/
**********************************************************
#include <REGX51.H>
#include <lcd.h>
#define XTAL 11059200
#define baudrate 9600
#define TIMER0_COUNT 0xD8F0 /*10000h-((12,000,000/(12*100))*/
/* 数字时钟的工作模式 */
#define SET 11
#define TRUE 1
#define FALSE 0
#define putchar write_LCD_data
#define adc_in P0
#define adc_rd P2_0
#define adc_wr P2_1
typedef struct {
char hour;
char minute;
char second;
} time;
typedef struct {
char year;
char month;
char day;
} date;
time now={23,59,0},display;
date today={04,12,15},tmpday;
static unsigned timer0_tick=100,mode=0,operation;
char code dayofmonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
char code weekday[7][4]={"MON","TUE","WED","THU","FRI","SAT",
"SUN"};
//char code command[9][6]={"Watch","One ","Two ","Three",
"Four ","Five ","Six ","Seven","Eight"};
char code int2char[]="0123456789";
unsigned char txOK,c;
void display_tempreture(unsigned char number)
{
unsigned char x,y;
y=(number<<1) - 263;
SBUF=y+32;
txOK=0;
x=y/10;
gotoxy(1,9);
write_LCD_data(int2char[x]);
x=y%10;
write_LCD_data(int2char[x]);
}
char gotkey();
void display_time(void)
{
gotoxy(1,0);
display_LCD_number(display.hour);
display_LCD_string(":");
display_LCD_number(display.minute);
display_LCD_string(":");
display_LCD_number(display.second);
}
void display_date()
{
char i,days=4;
gotoxy(2,2);
display_LCD_number(today.year);
display_LCD_string("/");
display_LCD_number(today.month);
display_LCD_string("/");
display_LCD_number(today.day);
display_LCD_string(" ");
if(today.month > 1)
for(i=0;i<=today.month-2;i++)
days+=(dayofmonth[i]%7);
if( today.year !=0 ) days+=((today.year-1)/4)+today.year+1;
if (today.year%4==0 && today.month >2) days++;
days=(days+today.day) % 7;
display_LCD_string(&weekday[days][0]);
}
int getdigit(unsigned char x,unsigned char y)
{
char keys;
do {
gotoxy(x,y);
putchar('_');
keys=gotkey();
gotoxy(x,y);
putchar(int2char[keys]);
} while(keys>9);
return(keys);
}
int gettime()
{
char temp;
do {
while((temp=getdigit(1,0))>2); //时的十位数不能大于2
temp=temp*10+getdigit(1,1);
if (temp > 23) display_time();
} while (temp > 23);
display.hour=temp;
while((temp=getdigit(1,3))>5);
display.minute=temp*10+getdigit(1,4);
return(TRUE);
}
char monthday(char year,char month)
{
if(month==2 && year%4==0) //润年的2月有29天
return(29);
else
return(dayofmonth[month-1]);//非闰年时的该月份天数
}
int getdate()
{
char temp,days;
temp=getdigit(2,2);
tmpday.year=temp*10+getdigit(2,3);
do {
while((temp=getdigit(2,5))>1); //月的十位数不能大于1
temp=temp*10+getdigit(2,6);
if (temp > 12) display_date(); //月份的数字不能大于12
} while (temp > 12);
tmpday.month=temp;
do {
while((temp=getdigit(2,8))>3); //日的十位数不能大于3
temp=temp*10+getdigit(2,9);
days=monthday(tmpday.year,tmpday.month);
//如果输入的日期大于该月份的日期就重新输入
if(temp > days || temp==0) display_date();
} while (temp > days || temp==0);
tmpday.day=temp;
return(TRUE);
}
static void timer0_isr(void) interrupt TF0_VECTOR using 1
{
TR0=0;
TL0=(TIMER0_COUNT & 0x00FF);
TH0=(TIMER0_COUNT >> 8);
TR0=1;
if(--timer0_tick) return;
timer0_tick=100;
now.second++; //秒加1
if (now.second==60) { //如果秒等于60
now.second=0; //秒恢复为0
adc_wr=0;
now.minute++; //分加1
adc_wr=1;
if (now.minute==60) { //如果分等于60
now.minute=0; //分恢复为0
now.hour++; //时加1
if (now.hour==24) { //如果时等于24
now.hour=0; //时恢复为0
today.day++; //日加1
if (today.day>monthday(today.year,
today.month)) {
today.day=1; //如果日超过当月最大日数,就变成1
today.month++; //月加1
if(today.month==13) { //如果月等于13
today.month=1; //月恢复为1
today.year++; //年加1
}
}
display_date();
}
}
}
if (operation==SET ) return;
display=now;
display_time();
}
static void timer0_initialize(void)
{
EA=0;
TR0=0;
TMOD &= 0XF0;
TMOD |=0x01;
TL0=(TIMER0_COUNT & 0x00FF);
TH0=(TIMER0_COUNT >> 8);
PT0=0;
ET0=1;
TR0=1;
EA=1;
}
static void int0_isr(void) interrupt 0 using 0
{
unsigned char voltage;
adc_in=0xFF;
adc_rd=0;
voltage=adc_in;
voltage=voltage <<1;
adc_rd=1;
display_tempreture(voltage);
}
static void com_isr(void) interrupt SIO_VECTOR using 1
{
unsigned char temp;
if(RI) {
temp=SBUF;
if (temp=='S') {
mode=1;
RI=0;
return;
}
if (temp=='T') {
mode=2;
c=0;
RI=0;
return;
}
if (mode==1) {
temp=SBUF;
P2=SBUF;
gotoxy(1,14);
putchar(int2char[temp]);
mode=0;
RI=0;
return;
}
if (mode==2) {
temp=SBUF;
switch(c) {
case 0 : today.year=temp;
break;
case 1 : today.month=temp;
break;
case 2 : today.day=temp;
break;
case 3 : now.hour=temp;
break;
case 4 : now.minute=temp;
break;
}
c++;
if (c==5) {
mode=0;
display_date();
display_time();
}
RI=0;
return;
}
}
if(TI!=0) {
TI=0;
txOK=1;
}
}
void com_initialize(void) {
PCON |= 0x80;
TMOD=0x20;
TH1=(unsigned char) (256-(XTAL/(16L*12L*baudrate)));
TR1=(unsigned char) (256-(XTAL/(16L*12L*baudrate)));
SCON=0x50;
ES=1;
TR1=1;
}
void main (void) {
char keys;
txOK=1;
init_LCD();
clear_LCD();
gotoxy(2,0);
display_LCD_string("20");
display=now;
display_time();
display_date();
EA=1;
com_initialize();
timer0_initialize();
IT0=1;
EX0=1;
do {
keys=gotkey();
if(keys==SET) {
operation=SET;
if ( gettime()) now=display;
if ( getdate()) {
today=tmpday;
display_date();
}
}
operation=0;
} while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -