PDA

View Full Version : Xin làm ơn giúp mình với lỗi này 1 tí


enti
28-11-2006, 12:50 PM
Chương trình mình viết cho đồnếg hồ số có thay đổi giờ và đặt giờ hẹn (lưu trong eeprom. Đồng hồ chạy bình thường, lưu giờ eeprom bình thường, báo giờ bình thường (mình dùng ngắt ngoài sử dụng chân SQW của DS1307-1Hz).
Nhưng khi thêm đoạn code bấm phím - hiển thị menu thì bị lỗi.

#include <16F877A.h>
//#device *=16 ADC=8
//#device *=16
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)


#use i2c(master,Slow,SDA=PIN_C4,SCL=PIN_C3)
#use rs232(baud=2400, xmit=PIN_C6, rcv=PIN_C7,parity=N,bits=8)

#define ADDRTC 0xD0
#define ACK 0
#define NACK 1

#define _0 0
#define _1 1
#define _21 2
#define _22 3
#define _311 4
#define _312 5
#define _321 6
#define _322 7

#include <LCD_VED.c>
#include <KBD_VED.c>
#include <stdlib.h>
#include <string.h>
#include <time_VED.h>

byte min_temp;

//-----------------------khai bao ham-------------------------
//giao tiep RTC
struct_date_time read_time_RTC();
void display_all(struct_date_time temp);
void display_bcd(byte param);

//giao tiep PC
void send_message();

//giao tiep eeprom
void write_time_eeprom(byte addr_wr, struct_time_eeprom m_time);
byte read_time_eeprom(byte m_addr, struct_time_eeprom &m_time);

//menu
void xuat_gio_hien_tai();
byte xuat_gio_da_luu(byte m_addr, step);
//int1 luu_gio_hen();
void cap1_xuat_menu_chinh();
void cap21_xuat_menu_chinh_gio();
void cap22_xuat_menu_hen_gio();

//-----------------------dinh nghia ham--------------------------
void init_time(struct_date_time param)
{
I2C_start(); /* The following Enables the Oscillator */
I2C_write(0xD0); /* address the part to write */
I2C_write(0x00); /* position the address pointer to 0 */
I2C_write(0); /* write 0 to the seconds register, clear the CH bit */

I2C_write(param.minutes);
I2C_write(param.hours|0x40);
I2C_write(param.day); // Thoi gian ban dau la: 3/11/2005 -12h/30ph/00sec
I2C_write(param.date);
I2C_write(param.month);
I2C_write(param.year);
I2C_write(0x10);/* enable sqwe, 1Hz output */
I2C_stop();
}

//giao tiep RTC
struct_date_time read_time_RTC()
{
struct_date_time temp;
byte Sec, Min, Hrs, Day, Date, Mon, Yr;

i2c_start();
i2c_write(0xD0); //Gui dia chi cua slave
i2c_write(0x00); //thiet lap lai con tro - set register pointer
I2C_start();
I2C_write(ADDRTC|1); // gui lenh doc du lieu
sec = i2c_read(1)&0x7F; // starts w/last address stored in register pointer
min = i2c_read(1);
hrs = i2c_read(1) & 0x3F;
day = i2c_read(1);
date = i2c_read(1);
mon = i2c_read(1) & 0x7F;
yr = i2c_read(0);
i2c_stop();
temp.seconds = sec;
temp.minutes = min;
temp.hours = hrs;
temp.day = day;
temp.date = date;
temp.month = mon;
temp.year=yr;
return temp;
}

//#org 0x1800//************them de sua loi*****************
#INT_EXT
display_time(){
struct_date_time temp;

//--------------Bien luu phut hien tai------------
byte m_minute,m_hour;
byte m_addr;
struct_time_eeprom m_time;
//------------------------------------------------
temp = read_time_RTC();

//-------------Kiem tra gio hen-------------------
m_addr = 0;
if(min_temp!=temp.minutes)//neu phut hien tai khac voi phut truoc do
{
min_temp=temp.minutes;
while(m_addr < 0x3f)//kiem tra dia chi co trong khong
{
if (read_eeprom(m_addr) == 0xff)//dia chi trong
m_addr = m_addr + 2;
else //khong trong
{
read_time_eeprom(m_addr, m_time); //doc tu eeprom
m_minute=(m_time.h_minute<<4)|m_time.l_minute;
m_hour=(m_time.h_hour<<4)|m_time.l_hour;
if(temp.hours == m_hour && temp.minutes == m_minute)
{
output_high(PIN_C0);
send_message();
delay_ms(100);
output_low(PIN_C0);
break;
}
else
{
m_addr = m_addr + 2;
}
}
}//end while
}//end if
display_all(temp);
}

void display_all(struct_date_time temp)
{
lcd_putc("\f ");
display_bcd(temp.Date);
lcd_putc("/");
display_bcd(temp.month);
lcd_putc("/20");
display_bcd(temp.year);
lcd_putc("\n ");
display_bcd(temp.hours);
lcd_putc(":");
display_bcd(temp.minutes);
lcd_putc(":");
display_bcd(temp.seconds);
}

void display_bcd(byte param)
{
char c;
c = param&0xF0;
c = c>>4;
lcd_putc(c + 0x30);
c = param&0x0F;
lcd_putc(c + 0x30);
}

//giao tiep may tinh
void send_message()
{
int8 i=0;
int8 j=0;
char c;
char message[] = "Alarm";
while(message[i] != '\0') {
j = putc(message[i]);
c = message[i];
i++;
}
delay_ms(10);
}

//giao tiep eeprom
void write_time_eeprom(byte addr_wr, struct_time_eeprom m_time)
{
byte temp;
// temp = 0;
temp = m_time.h_hour;
temp = temp<<4;
temp = temp + m_time.l_hour;
write_eeprom(addr_wr, temp);

// temp = 0;
temp = m_time.h_minute;
temp = temp<<4;
temp = temp + m_time.l_minute;
write_eeprom(addr_wr + 1, temp);
}

byte read_time_eeprom(byte m_addr, struct_time_eeprom &m_time)
{
byte temp;
temp = read_eeprom(m_addr);
m_time.h_hour = temp>>4;
m_time.l_hour = temp<<4>>4;

temp = read_eeprom(m_addr + 1);
m_time.h_minute = temp>>4;
m_time.l_minute = temp<<4>>4;

return m_addr;
}

void delete_time_eeprom(byte addr_del)
{
write_eeprom(addr_del,0xff);
lcd_putc("\f");
lcd_gotoxy(2,1);
lcd_putc("Da xoa gio hen.");

delay_ms(1000);
}

/*byte test_eeprom()
{
byte addr_begin;
byte temp;

addr_begin = 0x00;

while(addr_begin < 0x3f)
{
temp = read_eeprom(addr_begin);
if (temp == 0xff)
return addr_begin;
else
addr_begin = addr_begin + 2;

}
return 0x3f;
}*/

//********************menu**************************

//#org 0x1000//***************them de sua loi
void f_menu(char c, byte &m_cap_menu, byte &m_vitri_nhap)
{
byte m_addr;
int1 kt;
char pre_c;
switch (m_cap_menu)
{
case _0: //-----------------------------------hien gio--------------
if (c == '*')//them menu chinh
{
disable_interrupts(GLOBAL);
disable_interrupts(INT_EXT);
cap1_xuat_menu_chinh();
m_cap_menu = _1;
}
// f_cap_0(c, m_cap_menu,cho_phep);
break;//end case _0
///////////////
case _1: //-----------------------------hien menu chinh-------------
if (c == '1')//hien menu chinh gio
{
cap21_xuat_menu_chinh_gio();
m_cap_menu = _21;
}
else if (c == '2')//hien menu hen gio
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
}
else if (c == '*')//tro ve man hinh chinh
{
m_cap_menu = _0;
enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
}
// f_cap_1(c, m_cap_menu);
break;//end case _1
//////////////////
case _21://------------------truong hop chinh gio, chinh ngay
// f_cap_21(c, m_cap_menu);
if (c == '1')//hien menu chinh gio
{
//chinh gio
xuat_gio_hien_tai();
m_cap_menu = _311;
}else if (c == '2')//hien menu hen gio
{
//chinh ngay chua cai dat

}else if(c=='*')
{
cap1_xuat_menu_chinh();
m_cap_menu= _1;
}
break;//end case _21
//****************bi loi tu day******************
/* case _22://---------------------------truong hop hen gio
// f_cap_22(c, m_cap_menu);
if (c == '1')//phan them gio hen 00:00
{
// xuat_gio_mac_dinh();
lcd_putc("\f");
lcd_gotoxy(6,1);
lcd_putc("00:00");
m_cap_menu = _321;
}
else if (c == '2')//phan xoa gio
{
m_addr = xuat_gio_da_luu(0x00,2);
if (m_addr != 0x40)
m_cap_menu = _322;
else
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
}
}
else if (c == '*')//tro ve man hinh chinh
{
cap1_xuat_menu_chinh();
m_cap_menu = _1;
}
break;//end case _22*/
///////////////////////
case _311://---------------------------------chinh gio
// f_cap_311(c,m_cap_menu);
if (c == '*')//tro ve man hinh chinh
{
cap21_xuat_menu_chinh_gio();
m_cap_menu = _21;
}
break;//end case _311
////////////////////////
/* case _312://------------------------------chinh ngay
break;//end case _312*/
/////////////////////////////////////////////////
/* case _321://--------------------------nhap gio can hen
if (c == '*')//tro ve man hinh chinh
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
m_vitri_nhap = 1;
}
else if(c == '#')
{
kt = luu_gio_hen();
if (kt == 1)
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
m_vitri_nhap = 1;
}
}*/
/* else
{
// bat_phim_nhap_gio(m_vitri_nhap,c);
if(m_vitri_nhap == 1)//truong hop nhap so dau tien cua gio
{
if((0x29<c)&&(c < 0x33))
{
lcd_gotoxy(6,1);
lcd_putc(c);
// pre_c = c;
m_vitri_nhap = 2;
break;
}
}else if ( m_vitri_nhap == 2 )//nhap so thu 2 cua gio
{
pre_c = lcd_getc(6,1);
if(pre_c == '2')//chi nhap tu 0 => 3
{
if((0x29 < c)&&(c < 0x34))//20-23 gio
{
lcd_putc(c);
m_vitri_nhap = 3;
break;
}
}
else
{
if((0x29 < c)&&(c < 0x40))
{
lcd_putc(c);
m_vitri_nhap = 3;
break;
}
}
}else if(m_vitri_nhap == 3)
{
if((0x29 < c)&&(c < 0x36))
{
lcd_gotoxy(9,1);
lcd_putc(c);
m_vitri_nhap = 4;
}
}else if(m_vitri_nhap == 4)
{
if((0x29 < c)&&(c < 0x40))
{
lcd_putc(c);
m_vitri_nhap = 1;
}
}
}
break;//end case _321*/
/////////////////////////////////////////////////
/////////////////////////////////////////////////
/* case _322://----------------------chuc nang xoa gio
if(c =='4')
{//dich qua trai
m_addr = m_addr - 2;
m_addr = xuat_gio_da_luu(m_addr,-2);

if (m_addr != 0x40)
m_cap_menu = _322;
else
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
}
}
else if(c == '6')
{//dich qua phai
m_addr = m_addr + 2;
m_addr = xuat_gio_da_luu(m_addr,2);
if (m_addr != 0x40)
m_cap_menu = _322;
else
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
}
}
else if(c=='#')//xac nhan xoa gio
{
delete_time_eeprom(m_addr);

cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
}
else if(c=='*')
{
cap22_xuat_menu_hen_gio();
m_cap_menu = _22;
}
break;*///end case _322
}//end switch
}
//////////////////////////////////////////
void xuat_gio_hien_tai()
{
lcd_putc("\f");
lcd_gotoxy(6,1);
lcd_putc("00:00");
}
/////////////////////////===============================
byte xuat_gio_da_luu(byte m_addr, step)
{
struct_time_eeprom m_time;
char string_time[6];
byte temp;
byte i;

while((0x00<= m_addr) && (m_addr < 0x3f)){//kiem tra dia chi co trong khong
temp = read_eeprom(m_addr);
if (temp == 0xff)
m_addr = m_addr + step;
else
break;
}
if(m_addr == 0xFE && step == -2){
m_addr = 0x3e;
while((0x00 <= m_addr) &&(m_addr<0x3f))//kiem tra dia chi co trong khong
{
temp = read_eeprom(m_addr);
if (temp == 0xff)
m_addr = m_addr + step;
else
break;
}
}
if(m_addr == 0x40 && step == 2){
m_addr = 0x00;
while(m_addr < 0x3f)//kiem tra dia chi co trong khong
{
temp = read_eeprom(m_addr);
if (temp == 0xff)
m_addr = m_addr + step;
else
break;
}
}
//////////////////////////////////
if(m_addr == 0x40||m_addr==0xFE){
lcd_gotoxy(1,1);
lcd_putc("\f");
lcd_putc("Not alarm!");

delay_ms(1000);

return 0x40;
}
read_time_eeprom(m_addr, m_time);

string_time[0]=m_time.h_hour + 0x30;
string_time[1]=m_time.l_hour + 0x30;
string_time[2]=':';
string_time[3]=m_time.h_minute + 0x30;
string_time[4]=m_time.l_minute + 0x30;
string_time[5]='\0';

//hien gio tron m_time ra
i = 0;
lcd_putc("\f");
lcd_gotoxy(6,1);
while(string_time[i] != 0){
lcd_putc(string_time[i]);
i++;
}
return m_addr;
}
////////////
///////////
/*int1 luu_gio_hen()
{
char c;
byte m_addr;
struct_time_eeprom m_time;

m_addr = test_eeprom();
if(m_addr == 0x3f){

lcd_putc('\f');//clear LCD
lcd_gotoxy(4,1);
lcd_putc("Memory full");
return 0;//khong thuc hien chuc nang them gio
}

/////////////////////////////

c = lcd_getc( 6, 1) ;

m_time.h_hour = c - 0x30;
c = lcd_getc( 7, 1) ;
m_time.l_hour = c - 0x30;
c = lcd_getc( 9, 1) ;
m_time.h_minute = c - 0x30;
c = lcd_getc( 10, 1) ;
m_time.l_minute = c - 0x30;
//goi ham save lai
write_time_eeprom(m_addr,m_time);
////////////
lcd_putc("\f");
lcd_gotoxy(1,1);
lcd_putc("Time saved");
delay_ms(1000);
return 1;
}*/

void cap1_xuat_menu_chinh()
{
lcd_putc("\f");
lcd_gotoxy(3,1);
lcd_putc("1.Set time/date");
lcd_gotoxy(3,0);
lcd_putc("2.Set alarm");
}
/////cac ham xuat menu///////////
void cap21_xuat_menu_chinh_gio()
{
lcd_putc("\f");
lcd_gotoxy(2,1);
lcd_putc("1.Set time");
lcd_gotoxy(2,0);
lcd_putc("2.Set date");

}
/////////////////////
void cap22_xuat_menu_hen_gio()
{
lcd_putc("\f");
lcd_gotoxy(2,1);
lcd_putc("1.Add new");
lcd_gotoxy(2,0);
lcd_putc("2.Delete");
}
//////
/////////////////////////////////////

#zero_ram
void main()
{
//phan khai bao
struct_date_time temp;
char c;//bat phim
byte m_cap_menu;
byte m_vitri_nhap;

struct_time_eeprom m;//khai bao test
//khoi tao ngay gio cho RTC
temp.seconds = 0x00;
temp.minutes=0x00;
temp.hours=0x08;
temp.day=0x01;
temp.date=0x24;
temp.month=0x11;
temp.year=0x06;
init_time(temp);
//khoi tao lcd, keypad
lcd_init();
kbd_init();
port_b_pullups(true);
lcd_putc("\fReady...\n");

enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);

// test eeprom
// m.h_hour = 0;
// m.l_hour = 8;
// m.h_minute = 0;
// m.l_minute = 1;
// write_time_eeprom(0x18,m);

//////////////////
m_cap_menu = _0;
m_vitri_nhap = 1;

while (true){
c = kbd_getc();
if( c != 0 )
{
f_menu(c,m_cap_menu,m_vitri_nhap);
}
}
}


* Nếu không che đoạn code đó và không có khai báo #org thì báo lỗi "out of rom".
* Nếu mỉnh che bớt phần code menu từ chức năng _22 trở đi và có khai báo #org thì chương trình chạy bình thường.
* Nếu có khai báo #org và chỉ cần thêm 1 câu lệnh thôi thì compile không lỗi nhưng chương trình không bắt phím được.
Ai đã làm rồi và có kinh nghiệm sửa lỗi này thì giúp mình một chút. Cám ơn nhiều.

hanhluckyly
28-11-2006, 06:22 PM
Mình cũng từng làm luận văn và đã bị trường hợp này rồi
- Cũng bị out of ROM
- Khi compile cho con 16f877 khi báo là Rom >85% thì chương trình chạy sai hết.

Mình đã làm cách này mua con 18F458 về thay cũng chương trình đó chạy ngon lành.

enti
29-11-2006, 11:45 AM
Cám ơn bạn, mình đã giải quyết được vấn đề rồi. Mình định lại đại chỉ cho hàm là ok hết, chương trình tới 85% vẫn ok.