การทดลองที่ 3 เทคนิคการเก็บข้อมูล Long, Float ลง EEPROM ด้วยวิธี UNION

การเก็บข้อมูลที่มีขนาดมากกว่า 1 Byte เราสามารถทำได้ประมาณ 3 วิธี

1. ทำการแบ่ง Byte ข้อมูลเป็นส่วนๆ ด้วยการหารเช่นกรณี unsigned int ถ้าเราหารด้วย 256 ก็จะได้ตัวแปร Byte High ถ้าเรา mod ด้วย 256 ก็จะได้ตัวแปร Byte Low จากนั้นก็เอาตัวแปรแต่ละตัวไปเก็บไว้ใน EEPROM วิธีนี้จะเสีย CYCLE ในการประมวลผลไปเปล่าๆ

2. ใช้ Pointer เราประกาศ Pointer เป็น char แล้วก็เลื่อน Pointer ไปทีละ 1 ไบต์ก็จะได้ตัวแปรแต่ละไบต์

3. ใช้ UNION วิธีนี้เป็นวิธีที่ผมใช้บ่อย ก่อนที่จะอธิบายการจัดเก็บ ผมขออธิบาย UNION ก่อนว่า UNION คืออะไร

UNION เป็นการประกาศตัวแปรที่ใช้หน่วยความจำร่วมกัน ตัวแปรที่ประกาศแบบ UNION จะมีหน่วยความจำอยู่ตำแหน่งทับกันหมดทุุกตัว เช่นตัวอย่างตัวแปร Dat_long.word ใช้ตำแหน่งหน่วยความจำเดียวกัน การแก้ไขตัวแปร Dat_long.word ก็จะมีผลกับตัวแปร Dat_long.byte[0-3]

รูปที่ 1 memory จากการใช้คำสั่ง UNION

รูปที่ 2 Schematic ที่ใช้ในการทดลอง 3

การประยุกต์ใช้งานกับหน่วยความจำ เพียงย้ายข้อมูลมาไว้ Float, long แล้ว เอาข้อมูลจากตัวแปร์ array มาเก็บไว้ใน EEPROM

//*******************************************************************//
//Project : union.mcp
//Description : Union
//Device : PIC16F873A
//By : ThaiEmbedded 2006
//Date : 25 Nov 2006
//*******************************************************************//

#include <pic.h>
#include <stdio.h>
#include <stdlib.h>

__CONFIG(XT & WDTDIS & PWRTEN & BORDIS & LVPDIS & DEBUGDIS & UNPROTECT);

long ee_buff[2];

union dat_long
{
?????unsigned char byte[4];
?????long word;
}Dat_long;
union dat_long Dat_long;
//——————————————————————————//
// Delay (mSec)
//——————————————————————————//
void dmsec (unsigned int Count)
{?????

?????unsigned char i;
?????while (Count)
?????{
??????????for (i=0;i<=100;i++);
??????????Count–;
?????}
}
//——————————————————————————//
// Main Program
//——————————————————————————//
void main ()
{
?????dmsec(200);
?????TRISB = 0b00000000; //Output mode

?????ee_buff[0] = 123456;
?????Dat_long.word = ee_buff[0];
?????EEPROM_WRITE(0, Dat_long.byte[0]);
?????EEPROM_WRITE(1, Dat_long.byte[1]);
?????EEPROM_WRITE(2, Dat_long.byte[2]);
?????EEPROM_WRITE(3, Dat_long.byte[3]);

?????dmsec(200);
?????Dat_long.word = 0;

?????Dat_long.byte[0] = EEPROM_READ(0);
?????Dat_long.byte[1] = EEPROM_READ(1);
?????Dat_long.byte[2] = EEPROM_READ(2);
?????Dat_long.byte[3] = EEPROM_READ(3);

?????ee_buff[1] = Dat_long.word;

?????if(ee_buff[0]==ee_buff[1])
??????????PORTB = 1;
?????else
??????????PORTB = 3;

?????while(1); //Loop Forever????????
}

?

แบบฝึกหัด

ลองเปลี่ยนตัวแปรจาก Long เป็น float ลอง Compile ดูว่า ให้ผลลัพท์เหมือนเดิมไหม

Download Code การทดลองที่ 3

การทดลองที่ 2 อ่าน/เขียนหน่วยความจำ EEPROM 16F87X

การทดลองที่ 2 อ่าน/เขียนหน่วยความจำ EEPROM 16F87X

โดยส่วนมากแล้ว PIC จะมี EEPROM ในตัวอยู่แล้ว ในเบอร์ 16F873A จะมี EEPROM อยู่ 128 B หน่วยความจะ EEPROM นี้จัดเป็นหน่วยความจำประเภท Non volatile memory เมื่อไปดับข้อมูลใน EEPROM จะไม่หายไปไหน สำหรับเบอร์ 16F873A มี Cycle Write/Erase อยู่ล้านครั้ง

//************************************************************************//
//Project : first873.mcp
//Description : I/O Port
//Device : PIC16F873A
//By : ThaiEmbedded 2006
//************************************************************************//#include <pic.h>
#include <stdio.h>
#include <stdlib.h>

__CONFIG(XT & WDTDIS & PWRTEN & BORDIS & LVPDIS & DEBUGDIS & UNPROTECT);

unsigned char i;
unsigned char dat;
//——————————————————————————//
// Delay (mSec)
//——————————————————————————//
void dmsec (unsigned int Count)
{ unsigned char i;
????? while (Count)
????? {
????? ????? for (i=0;i<=100;i++);
????? ????? Count–;
????? }
}
//——————————————————————————//
// Main Program
//——————————————————————————//
void main ()
{
?????TRISB = 0b00000000; //Output mode
????? while(1) //Loop Forever
????? {
?????????? dat = 0×01;
?????????? for(i=0;i<8;i++)
?????????? {
?????????? ????PORTB = dat;
????? ????? ???dat <<= 1;
????? ????? ???dmsec(500);
?????????? }
????? }
}

Download Code การทดลองที่ 2