?? monitor.c
字號:
/****************************************/
/* Copyright (c) 2004, 通信工程學院 */
/* All rights reserved. */
/****************************************/
#include <at898252.h>
#include "vehicle.h"
#define LIMIT 60
#define uint unsigned int
#define uchar unsigned char
#define CSA P2_1
#define CSB P2_0
#define DI P2_6
#define RW P2_5
sbit uip_bit=ACC^7;//ds12c887 register a bit 7
sbit busy_bit=ACC^7;//lcd state byte bit 7
sbit run_bit=P3^3;
uchar timer0_flag=0;
uchar int0_flag=0;
uchar active_buffer=1;
uint page_counter=0;
uint buffer_counter=0;
//uchar active_buffer=1;
uchar circle=0;
uchar time_counter=0;
uchar year,month,day,hour,min,sec;
unsigned long ttcy=0;
//delay 100ms,should be adjusted for frequency and compile
void dl_100ms(void)
{
unsigned char i,j;
for (i=10;i>0;i--) for (j=0;j<250;j++) ;
}
/*下面是對液晶屏gxm12864d操作的函數,其內置的控制器是hd61202,
128x64點陣,漢字顯示,CSA,CSB用來進行左右顯示區的選擇。
R/W,D/I兩個信號我沒有接在地址線上,而是用單獨的端口控制,
數據訪問通過對外部數據區的0xffff訪問實現。E信號由地址譯碼產生
*/
/* 發命令i到主窗口*/
void lcd_mwc(uchar i)
{
CSA=1;
CSB=0;
RW=1;
DI=0;
do {ACC=LCD;}
while (busy_bit) ;//wait for lcd not busy
RW=0;
LCD=i;
}
/* 寫數據i到主窗口*/
void lcd_mwd(uchar i)
{
CSA=1;
CSB=0;
RW=1;
DI=0;
do {ACC=LCD;} while (busy_bit);//wait for lcd not busy
RW=0;
DI=1;
LCD=i;
}
/* 清屏 */
void lcd_clear(void)
{
uchar i;
uchar page;
for (page=0xb8;page<0xc0;page++)
{
lcd_mwc(page); /*設置顯示頁面*/
lcd_mwc(0x40); /*設置列地址*/
for (i=0;i<64;i++)
{
lcd_mwd(0);
}
}
}
//初始化lcd
void lcd_init(void)
{
lcd_mwc(0xc0);
lcd_mwc(0x3f);
}
//dispm_hz_up() display up half of a hanzi in left area
void dispm_hz_up(uchar code * hz)
{
uchar i;
for (i=0;i<16;i++) lcd_mwd(*(hz+i));
}
//dispm_hz_down() display down half of a hanzi in left area
void dispm_hz_down(uchar code * hz)
{
uchar i;
for (i=16;i<32;i++) lcd_mwd(*(hz+i));
}
void disp_num(uchar i)
{
uchar j;
for (j=0;j<8;j++) lcd_mwd(ARAB[j+i*8]);
}
/*set mcu counter0 as 5s timer,clk is 500ms*/
void set_5s_counter(void)
{
TMOD=0x16;//counter0 mode 2
TH0=-10;
TL0=-10;
IP=0x01;//int0 high,counter0 low
IT0=1;
EA=1;//enable interrupt
ET0=1;
EX0=1;
TR0=1;
}
/*下面是對flash存儲卡at45d041的操作,數據接口為spi接口,
卡共2048頁,每頁264字節
*/
void write_spi(uchar dat)
{
SPDR = dat;
while (!(SPSR & 0x80)) ; // wait for data transfer to be completed
}
uchar df_busy(void)
{
P1 &= ~DF_CHIP_SELECT; // enable DataFlash
write_spi(STAT_REG_READ);
write_spi(0x00); // don't cares
P1 |= DF_CHIP_SELECT; // disable DataFlash
return SPDR;
}
//write_to_flash write data to buffer,if buffer is full write buffer to memory page
void write_to_flash(uchar flash_data)
{
// checking if flash is busy
while (!(df_busy()&0x80)) ;
P1 &= ~DF_CHIP_SELECT; // enable DataFlash
if (active_buffer==1) write_spi(BUFFER_1_WRITE);
else write_spi(BUFFER_2_WRITE);
write_spi(0x00); // don't cares
write_spi((uchar)(buffer_counter>>8)); // don't cares plus first bit of buffer address
write_spi((uchar)buffer_counter); // buffer address
write_spi(flash_data); // write data into SPI Data Register
P1 |= DF_CHIP_SELECT; // disable DataFlash
buffer_counter++;
if (buffer_counter > 263) // if buffer full write buffer into memory page
{
buffer_counter = 0;
if (page_counter < 2047) // if memory is not full
{
P1 &= ~DF_CHIP_SELECT; // enable DataFlash
if (active_buffer==1) write_spi(B1_TO_MM_PAGE_PROG_WITHOUT_ERASE);// write data from buffer1 to page
else write_spi(B2_TO_MM_PAGE_PROG_WITHOUT_ERASE);//write data from buffer2 to page
write_spi((uchar)(page_counter>>7));
write_spi((uchar)(page_counter<<1));
write_spi(0x00); // don't cares
P1 |= DF_CHIP_SELECT; // disable DataFlash
page_counter++; //page_counter 指向下一可用頁
}
if (active_buffer==1) active_buffer=0;
else active_buffer=1;
}
}
uchar cardin(void)
{
SPCR=0x5d;//interrupt disabled,spi enabled,master,msb first,spi mode 3,Fosc/16
P1 &= ~DF_CHIP_SELECT; // enable DataFlash
write_spi(MAIN_MEMORY_PAGE_READ) ;
write_spi(0x00) ;
write_spi(0x00) ;
write_spi(0x00) ;
write_spi(0x00) ;
write_spi(0x00) ;
write_spi(0x00) ;
write_spi(0x00) ;
write_spi(0xff) ;//write dummy value to start register shift
P1 |= DF_CHIP_SELECT ;//disable flash card
return SPDR;
}
/*下面是對日歷時鐘芯片ds12c887的部分操作,芯片初始化的操作在settime.c中實現*/
//getlstpage()從DS12C887中讀取最近可用頁地址
uint getcurpage(void)
{
uchar i=0;
uint j=0;
i=TIME_LSTPGH;
j=i+j;//maybe wrong
i=TIME_LSTPGL;
j=j<<8;
j=j+i;
return j;
}
//getfrnpg()從DS12C887中讀取最近可用的存放終止頁地址的頁地址
uint getfrnpg(void)
{
uchar i=0;
uint j=0;
i=TIME_FRNPGH;
j+=i;
i=TIME_FRNPGL;
j=j<<8;
j+=i;
return j;
}
//storetime() read time from ds12887 then store in flash card
void storetime(void)
{
// uchar year,month,day,hour,min,sec;
do {ACC=TIME_A;} while (uip_bit) ;//wait for UIP bit turn 0
sec=TIME_SEC;
min=TIME_MIN;
hour=TIME_HOUR;
day=TIME_DAY;
month=TIME_MONTH;
year=TIME_YEAR;
write_to_flash(year);
write_to_flash(month);
write_to_flash(day);
write_to_flash(hour);
write_to_flash(min);
write_to_flash(sec);
}
/*下面是鍵盤掃描和給鍵賦值的操作*/
//keyscan() scan keyboard and return key code
uchar keyscan(void)
{
uchar sccode,recode;
P2=0x78;
if ((P2&0x78)!=0x78)
{
dl_100ms();
if ((P2&0x78)!=0x78)
{
sccode=0xfe;
while ((sccode&0x08)!=0)
{
P2=sccode;
if((P2&0x78)!=0x78)
{
recode=(P2&0x78)|0x87;
return ((~sccode)+(~recode));
}
else sccode=(sccode<<1)|0x01;
}
}
}
return (0);
}
//getkey() translate key code to number ,return keyboard input number
uint getkey(void)
{
uchar num1=0;
uint num2=0;
while (num1!=0x44)
{
num1=keyscan();
switch(num1)
{
case 0x09:
num1=0;
num2=num2*10;
disp_num(num1);
break;
case 0x11:
num1=1;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x21:
num1=2;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x41:
num1=3;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x0a:
num1=4;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x12:
num1=5;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x22:
num1=6;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x42:
num1=7;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x0c:
num1=8;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x14:
num1=9;
num2=num2*10+num1;
disp_num(num1);
break;
case 0x24:
num1=0;
num2=0;
lcd_mwc(0xba);
lcd_mwc(0x40);
for (num1=0;num1<8;num1++) disp_num(10);
lcd_mwc(0xba);
lcd_mwc(0x40);
break;
case 0x44:
lcd_mwc(0xba);
lcd_mwc(0x40);
for (num1=0;num1<8;num1++) disp_num(10);
lcd_mwc(0xba);
lcd_mwc(0x40);
break;
}
}
return(num2);
}
/*兩個中斷處理函數*/
void timer0(void) interrupt 1 using 1
{
EA=0;//diable interrupt
time_counter++;
P3_5=0;//enable cpld
circle=P0;
P3_5=1;
ttcy+=circle;
timer0_flag=1;
EA=1;
}
void int0(void) interrupt 0 using 2
{
EA=0;
WMCON=WMCON&0xfe;
int0_flag=1;
}
void main(void)
{
uint a;
uchar m,n,l;
for (m=0;m<200;m++) for (n=0;n<250;n++) ; //delay 200ms,should be adjusted to be not less then 200ms
//in order to wait peripheral to be ready
P3_0=0;//turn alarm off
P3_5=1;//diable cpld output
P3_2=1;//ready for int0
buffer_counter=6;
lcd_clear();
lcd_init();
lcd_mwc(0xb8);
lcd_mwc(0x40);
dispm_hz_up(&QING);
dispm_hz_up(&CHA);
dispm_hz_up(&KA);
lcd_mwc(0xb9);
lcd_mwc(0x40);
dispm_hz_down(&QING);
dispm_hz_down(&CHA);
dispm_hz_down(&KA);//display "請插卡"
P1=0xff;
while (cardin()&0xa0) ;//這個地方,用什么來表示已經插卡需要商量。
page_counter=getcurpage();
lcd_mwc(0xb8);
lcd_mwc(0x50);
// dispm_hz_up(&QING);
dispm_hz_up(&SHU);
dispm_hz_up(&CHE);
dispm_hz_up(&HAO);
lcd_mwc(0xb9);
lcd_mwc(0x50);
// dispm_hz_down(&QING);
dispm_hz_down(&SHU);
dispm_hz_down(&CHE);
dispm_hz_down(&HAO);//display "請輸車號"
lcd_mwc(0xba);
lcd_mwc(0x40);
a=getkey();
write_to_flash((uchar)(a>>8));
write_to_flash((uchar)a);//store 車號
lcd_mwc(0xb8);
lcd_mwc(0x60);
// dispm_hz_up(&QING);
// dispm_hz_up(&SHU);
dispm_hz_up(&ZHAN);
// dispm_hz_up(&HAO);
lcd_mwc(0xb9);
lcd_mwc(0x60);
// dispm_hz_down(&QING);
// dispm_hz_down(&SHU);
dispm_hz_down(&ZHAN);
// dispm_hz_down(&HAO);//display "請輸站號"
lcd_mwc(0xba);
lcd_mwc(0x40);
a=getkey();
write_to_flash((uchar)(a>>8));
write_to_flash((uchar)a);//store 站號
// buffer_counter=0;
set_5s_counter();
lcd_mwc(0xb8);
lcd_mwc(0x40);
dispm_hz_up(&SU);
dispm_hz_up(&DU);
lcd_mwc(0xb9);
lcd_mwc(0x40);
dispm_hz_down(&SU);
dispm_hz_down(&DU);//display "速度"
lcd_mwc(0xbc);
lcd_mwc(0x40);
dispm_hz_up(&LI);
dispm_hz_up(&CHENG);
lcd_mwc(0xbd);
lcd_mwc(0x40);
dispm_hz_down(&LI);
dispm_hz_down(&CHENG);//display "里程"
while (!run_bit) ;//wait for vehicle move
storetime();
buffer_counter=10;
WMCON=0xe0;//2.048s watchdog timer
WMCON=WMCON|0x01;//enable watchdog
while (1)//sycling wait
{
for (m=0;m<250;m++) for (n=0;n<250;n++) ;
for (m=0;m<250;m++) for (n=0;n<250;n++) ;//should be adjusted for 500ms delay
WMCON=WMCON|0x02;//reset watchdog
if (circle>LIMIT) P3_0=1;
else P3_0=0;//if overspeed then alarm
if (timer0_flag==1)
{
write_to_flash(circle);
timer0_flag=0;
}
WMCON=WMCON|0x02;//reset watchdog
if (time_counter>=120)//if 10 min,show speed and distance
{
time_counter=0;
m=36*circle/35;
n=m/100;
lcd_mwc(0xba);
lcd_mwc(0x40);
disp_num(n);
l=(m-n*100)/10;
disp_num(l);
disp_num(m-n*100-l*10);
disp_num(11);
n=(36*circle-35*m)*10/35;
disp_num(n);//以上計算速度并顯示
a=ttcy/700;
m=a/100;
lcd_mwc(0xbd);
lcd_mwc(0x40);
disp_num(m);
n=(a-m*100)/10;
disp_num(n);
disp_num(a-m*100-n*10);
disp_num(11);
m=(ttcy-700*a)*10/700;
disp_num(m);//以上計算并顯示里程
}
WMCON=WMCON|0x02;//reset watchdog
if (int0_flag==1)
{
write_to_flash(0xf0);
write_to_flash(0xf1);
storetime();
lcd_clear();
lcd_init();
lcd_mwc(0xb8);
lcd_mwc(0x40);
dispm_hz_up(&QING);
dispm_hz_up(&SHU);
dispm_hz_up(&ZHAN);
dispm_hz_up(&HAO);
lcd_mwc(0xb9);
lcd_mwc(0x40);
dispm_hz_down(&QING);
dispm_hz_down(&SHU);
dispm_hz_down(&ZHAN);
dispm_hz_down(&HAO);//display "請輸站號"
lcd_mwc(0xba);
lcd_mwc(0x40);
a=getkey();
write_to_flash((uchar)(a>>8));
write_to_flash((uchar)a);//store 站號
if (buffer_counter!=0)
{
while (!(df_busy()&0x80)) ;
P1 &= ~DF_CHIP_SELECT; // enable DataFlash
if (active_buffer==1) write_spi(B1_TO_MM_PAGE_PROG_WITHOUT_ERASE);
else write_spi(B2_TO_MM_PAGE_PROG_WITHOUT_ERASE);
write_spi(0x00); // don't cares
write_spi((uchar)(page_counter>>7)); // don't cares plus first 4 bits of page address
write_spi((uchar)(page_counter<<1)); // page address
write_spi(0x00); // don't cares
P1 |= DF_CHIP_SELECT; // disable DataFlash
if (active_buffer==1) active_buffer=0;
else active_buffer=1;
buffer_counter=0;
}
a=getfrnpg();
write_to_flash((uchar)(page_counter>>8));
write_to_flash((uchar)page_counter);
while (!(df_busy()&0x80)) ;
P1 &= ~DF_CHIP_SELECT; // enable DataFlash
if (active_buffer==1) write_spi(B1_TO_MM_PAGE_PROG_WITHOUT_ERASE);
else write_spi(B2_TO_MM_PAGE_PROG_WITHOUT_ERASE);
write_spi(0x00); // don't cares
write_spi((uchar)(a>>7)); // don't cares plus first 4 bits of page address
write_spi((uchar)(a<<1)); // page address
write_spi(0x00); // don't cares
P1 |= DF_CHIP_SELECT; // disable DataFlash
page_counter++;
TIME_LSTPGH=(uchar)(page_counter>>8);
TIME_LSTPGL=(uchar)(page_counter);
a--;
TIME_FRNPGH=(uchar)(a>>8);
TIME_FRNPGL=(uchar)a;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -