PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Xin làm ơn giúp mình với lỗi này 1 tí (http://www.picvietnam.com/forum/showthread.php?t=771)

enti 28-11-2006 12:50 PM

Xin làm ơn giúp mình với lỗi này 1 tí
 
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.
Code:

#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
      [red]//****************bi loi tu day******************[/red]
/*      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.


Múi giờ GMT. Hiện tại là 11:43 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam