{"id":538,"date":"2016-05-29T22:24:22","date_gmt":"2016-05-29T19:24:22","guid":{"rendered":"http:\/\/ozenozkaya.com\/blog\/?p=538"},"modified":"2016-06-26T19:29:16","modified_gmt":"2016-06-26T16:29:16","slug":"pic-programlama-10-eeprom","status":"publish","type":"post","link":"http:\/\/ozenozkaya.com\/blog\/?p=538","title":{"rendered":"PIC Programlama \u2013 10 \u2013 EEPROM"},"content":{"rendered":"<p>Merhabalar, doktora yeterlik s\u0131nav\u0131 dolay\u0131s\u0131yla ara verdi\u011fim blog yaz\u0131lar\u0131ma, yeterlik a\u015famas\u0131n\u0131 ge\u00e7ti\u011fimden dolay\u0131 devam ediyorum \ud83d\ude00 PIC16F84A ile ilgili, geriye kalan son bir iki konuyu da irdeleyece\u011fimiz bu yaz\u0131da, ana g\u00fcndemimiz EEPROM olacak.<\/p>\n<p>&#8220;EEPROM nedir?&#8221; sorusuna yan\u0131t arayanlar i\u00e7in <a href=\"https:\/\/tr.wikipedia.org\/wiki\/EEPROM\">WIKIPEDIA<\/a>\u00a0sayfas\u0131nda yeterli bilgi oldu\u011funu belirtmek isterim. K\u0131saca \u00f6zetlemek gerekirse EEPROM, elektriksel olarak yaz\u0131l\u0131p silinebilen, kal\u0131c\u0131 bir bellek tipi; yani elektrik gitse de i\u00e7erisinde kay\u0131tl\u0131 olan veri kendili\u011finden silinmiyor. Flash belle\u011fe g\u00f6re yaz\u0131m \u00f6mr\u00fcn\u00fcn \u00e7ok fazla olmas\u0131, bu devre eleman\u0131n\u0131 bu g\u00fcn dahi pop\u00fcler tutmaya yetiyor.<\/p>\n<p>PIC16F84A i\u00e7inde de 64 byte&#8217;l\u0131k bir EEPROM bulunuyor. 64 byte kadar k\u00fc\u00e7\u00fck bir EEPROM olsa da, \u00f6zellikle kal\u0131c\u0131 konfig\u00fcrasyonlar\u0131 saklama konusunda, bu mod\u00fcl hayat kurtar\u0131yor. Bu durumda bize d\u00fc\u015fen de, PIC16FLIB ad\u0131yla geli\u015ftirdi\u011fimiz alternatif PIC k\u00fct\u00fcphanesine bu mod\u00fcl\u00fc de eklemek olacak. \u00d6yleyse hemen ba\u015flayal\u0131m!<\/p>\n<p>\u0130lk ad\u0131m olarak, her zamanki gibi <a href=\"http:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/35007C.pdf\">datasheet&#8217;i<\/a> okuyup anlayarak, yaz\u0131l\u0131msal olarak modelleyece\u011fiz. Datasheet&#8217;te EEPROM mod\u00fcl\u00fc, sistemin blok diyagram\u0131nda \u015f\u00f6yle yer al\u0131yor:<\/p>\n<div id=\"attachment_539\" style=\"width: 571px\" class=\"wp-caption alignnone\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-539\" data-attachment-id=\"539\" data-permalink=\"http:\/\/ozenozkaya.com\/blog\/?attachment_id=539\" data-orig-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?fit=810%2C686\" data-orig-size=\"810,686\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"pic16f84a blok diyagram\u0131\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;PIC16F84A veri ka\u011f\u0131d\u0131ndan al\u0131nm\u0131\u015ft\u0131r.&lt;\/p&gt;\n\" data-medium-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?fit=300%2C254\" data-large-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?fit=640%2C542\" class=\" wp-image-539\" src=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?resize=561%2C476\" alt=\"\" width=\"561\" height=\"476\" srcset=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?w=810 810w, https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?resize=300%2C254 300w, https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png?resize=768%2C650 768w\" sizes=\"auto, (max-width: 561px) 100vw, 561px\" \/><p id=\"caption-attachment-539\" class=\"wp-caption-text\">PIC16F84A veri ka\u011f\u0131d\u0131ndan al\u0131nm\u0131\u015ft\u0131r.<\/p><\/div>\n<p>Buradan da g\u00f6r\u00fcld\u00fc\u011f\u00fc gibi EEPROM mod\u00fcl\u00fcm\u00fcz 64*8 bitlik veriyi saklayabiliyor. \u015eimdi de, EEPROM ile ilgili k\u00fct\u00fcklerin (register), hangi adreslerde oldu\u011funa bakal\u0131m.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"542\" data-permalink=\"http:\/\/ozenozkaya.com\/blog\/?attachment_id=542\" data-orig-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?fit=798%2C697\" data-orig-size=\"798,697\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"pic16f84a_eeprom_regs\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?fit=300%2C262\" data-large-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?fit=640%2C559\" class=\"alignnone size-full wp-image-542\" src=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?resize=640%2C559\" alt=\"\" width=\"640\" height=\"559\" srcset=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?w=798 798w, https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?resize=300%2C262 300w, https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png?resize=768%2C671 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>\u0130lgili k\u00fct\u00fckleri fosforlu sar\u0131 ile i\u015faretledi\u011fimden adreslerini g\u00f6rebilirsiniz. Art\u0131k adreslerini ve yap\u0131lar\u0131n\u0131 da bildi\u011fimizden, bu k\u00fct\u00fckleri yazd\u0131\u011f\u0131m\u0131z PIC k\u00fct\u00fcphanesine ekleyebiliriz. EEPROM mod\u00fcl\u00fcn\u00fc de derlemeye dahil edip etmemeyi se\u00e7imli yapmak i\u00e7in i\u015fe pic16flib_conf.h dosyas\u0131na a\u015fa\u011f\u0131daki i\u015faretli sat\u0131r\u0131 ekleyerek ba\u015fl\u0131yoruz.<\/p>\n<pre class=\"lang:c mark:20 decode:true\" title=\"pic16flib_conf.h\">\/* \r\n * File:   pic16flib_conf.h\r\n * Author: ozenozkaya\r\n *\r\n * Created on 25 Eyl\u00fcl 2015 Cuma, 00:46\r\n *\/\r\n\r\n#ifndef PIC16FLIB_CONF_H\r\n#define\tPIC16FLIB_CONF_H\r\n\r\n#ifdef\t__cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\n#define MAX_INT_CALLBACK_NUM (1)\r\n\r\n\/\/#define PIC16LIB_USE_RB0_INT\r\n\/\/#define PIC16LIB_USE_PORTB_INT\r\n\/\/#define PIC16LIB_USE_TIMER0_INT\r\n#define PIC16LIB_USE_EEPROM\r\n    \r\n#ifdef\t__cplusplus\r\n}\r\n#endif\r\n\r\n#endif\t\/* PIC16FLIB_CONF_H *\/\r\n<\/pre>\n<p>\u015eimdi\u00a0pic16f84a_lib.h i\u00e7erisindeki k\u00fct\u00fck tan\u0131mlamalar\u0131na ge\u00e7elim. A\u015fa\u011f\u0131daki i\u015faretli sat\u0131rlar\u0131\u00a0pic16f84a_lib.h dosyas\u0131na ekliyoruz.<\/p>\n<pre class=\"lang:c mark:21,45-49,62-69,165-193,218-222 decode:true\" title=\"pic16f84a_lib.h\">\/* \r\n * File:   pic16f84a_lib.h\r\n * Author: ozenozkaya\r\n *\r\n * Created on 20 Temmuz 2015 Pazartesi, 00:05\r\n *\/\r\n\r\n#ifndef PIC16F84A_LIB_H\r\n#define\tPIC16F84A_LIB_H\r\n\r\n#ifdef\t__cplusplus\r\nextern \"C\" {\r\n#endif\r\n \r\n#include &lt;stdint.h&gt;\r\n#include \"pic16flib_conf.h\"\r\n    \r\n#define PIC16LIB_ERROR_NONE     (0)\r\n#define PIC16LIB_ERROR_CB_NULL  (-1)\r\n#define PIC16LIB_ERROR_CB_ALREADY_REGISTERED (-2)\r\n#define PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS (-3)\r\n\r\n#define F_OSC (1000000UL)\r\n    \r\n#define _REG_TIMER0_ADDR (0x01)\r\n#define REG_TIMER0 (*( volatile uint8_t*)_REG_TIMER0_ADDR)\r\n    \r\n#define _REG_PROGRAM_COUNTER_ADDR (0x02)\r\n#define REG_PROGRAM_COUNTER (*( volatile uint8_t*)_REG_PROGRAM_COUNTER_ADDR)\r\n\r\n#define _REG_STATUS_ADDR (0x03)\r\n#define REG_STATUS (*( volatile uint8_t*)_REG_STATUS_ADDR)\r\n    \r\n#define _REG_PORTA_ADDR (0x05)\r\n#define REG_PORTA (*( volatile uint8_t*)_REG_PORTA_ADDR)\r\n    \r\n#define _REG_PORTB_ADDR (0x06)\r\n#define REG_PORTB (*( volatile uint8_t*)_REG_PORTB_ADDR)\r\n    \r\n#define PORT_PIN_LOW  (0)\r\n#define PORT_PIN_HIGH (1)\r\n#define PORT_ALL_LOW  (0)\r\n#define PORT_ALL_HIGH (0xFF)\r\n    \r\n#define _REG_EEDATA_ADDR (0x08)\r\n#define REG_EEDATA (*( volatile uint8_t*)_REG_EEDATA_ADDR)\r\n\r\n#define _REG_EEADR_ADDR (0x09)\r\n#define REG_EEADR (*( volatile uint8_t*)_REG_EEADR_ADDR)\r\n    \r\n#define _REG_TRISB_ADDR (0x86)\r\n#define REG_TRISB (*( volatile uint8_t*)_REG_TRISB_ADDR)\r\n \r\n#define _REG_TRISA_ADDR (0x85)\r\n#define REG_TRISA (*( volatile uint8_t*)_REG_TRISA_ADDR)\r\n    \r\n#define TRIS_PIN_OUTPUT (0)\r\n#define TRIS_PIN_INPUT  (1)\r\n#define TRIS_PORT_OUTPUT (0)\r\n#define TRIS_PORT_INPUT  (0xFF)\r\n\r\n#define _REG_EECON1_ADDR (0x88)\r\n#define REG_EECON1 (*( volatile uint8_t*)_REG_EECON1_ADDR)\r\n\r\n#define _REG_EECON2_ADDR (0x89)\r\n#define REG_EECON2 (*( volatile uint8_t*)_REG_EECON2_ADDR)\r\n\r\n#define EECON2_PROTECTION_SEQ_1 (0x55)    \r\n#define EECON2_PROTECTION_SEQ_2 (0xAA)  \r\n    \r\n#define _REG_INTCON_ADDR (0x0B)\r\n#define REG_INTCON (*( volatile uint8_t*)_REG_INTCON_ADDR)\r\n#define INT_ENABLE (1)\r\n#define INT_ENABLE_ALL (0xFF)\r\n#define INT_DISABLE (0)\r\n#define INT_DISABLE_ALL (0)\r\n#define INT_FLAG_CLEAR (0)\r\n\r\n#define _REG_OPTION_ADDR (0x81)\r\n#define REG_OPTION (*( volatile uint8_t*)_REG_OPTION_ADDR)\r\n#define INT_EDGE_FALLING (0)\r\n#define INT_EDGE_RISING  (1)\r\n   \r\n\r\ntypedef struct \r\n{\r\n    \/\/one bit is stored in one BYTE\r\n    uint8_t pin0:1;\r\n    uint8_t pin1:1;\r\n    uint8_t pin2:1;\r\n    uint8_t pin3:1;\r\n    uint8_t pin4:1;\r\n    uint8_t pin5:1;\r\n    uint8_t pin6:1;\r\n    uint8_t pin7:1;\r\n}_tris_port_pin_t, *_tris_port_pin_ptr_t;\r\n\r\ntypedef union\r\n{\r\n    _tris_port_pin_t pins;\r\n    uint8_t port;\r\n}tris_port_t,*tris_port_ptr_t;\r\n\r\n#define REG_TRISA_UNION (*(tris_port_ptr_t)_REG_TRISA_ADDR) \r\n#define REG_TRISB_UNION (*(tris_port_ptr_t)_REG_TRISB_ADDR) \r\n#define REG_PORTA_UNION (*(tris_port_ptr_t)_REG_PORTA_ADDR) \r\n#define REG_PORTB_UNION (*(tris_port_ptr_t)_REG_PORTB_ADDR) \r\n\r\n\r\ntypedef struct\r\n{\r\n    uint8_t RBIF:1;\r\n    uint8_t INTF:1;\r\n    uint8_t T0IF:1;\r\n    uint8_t RBIE:1;\r\n    uint8_t INTE:1;\r\n    uint8_t T0IE:1;\r\n    uint8_t EEIE:1;\r\n    uint8_t GIE:1;\r\n}_intcon_reg_t,*_intcon_reg_ptr_t;\r\n\r\ntypedef struct\r\n{\r\n    uint8_t PS:3;\r\n    uint8_t PSA:1;\r\n    uint8_t T0SE:1;\r\n    uint8_t T0CS:1;\r\n    uint8_t INTEDG:1;\r\n    uint8_t RBPU:1;\r\n}_option_reg_t,*_option_reg_ptr_t;\r\n\r\n#define T0CS_SOURCE_RA4_T0CKI_PIN (0x01)\r\n#define T0CS_SOURCE_INTERNAL_CLOCK (0x00)\r\n\r\n#define PSA_ASSIGN_TO_WATCHDOG  (0x01)\r\n#define PSA_ASSIGN_TO_TIMER0    (0x00)\r\n\r\n#define PS_TMR0_RATE_DIVIDE_2   (0x00)\r\n#define PS_TMR0_RATE_DIVIDE_4   (0x01)\r\n#define PS_TMR0_RATE_DIVIDE_8   (0x02)\r\n#define PS_TMR0_RATE_DIVIDE_16   (0x03)\r\n#define PS_TMR0_RATE_DIVIDE_32   (0x04)\r\n#define PS_TMR0_RATE_DIVIDE_64   (0x05)\r\n#define PS_TMR0_RATE_DIVIDE_128   (0x06)\r\n#define PS_TMR0_RATE_DIVIDE_256   (0x07)\r\n\r\n#define REG_OPTION_UNION (*(option_reg_ptr_t)_REG_OPTION_ADDR) \r\n\r\ntypedef union\r\n{\r\n  _intcon_reg_t bits;\r\n  uint8_t value;  \r\n}intcon_reg_t, *intcon_reg_ptr_t;\r\n#define REG_INTCON_UNION   (*(intcon_reg_ptr_t)_REG_INTCON_ADDR)\r\n\r\ntypedef union\r\n{\r\n    uint8_t value;\r\n    uint8_t count;\r\n}timer0_reg_t, *timer0_reg_ptr_t;\r\n#define TIMER0_MAX_CNT (0xFF)\r\n#define TIMER0_ASSIGN_CNT(NEW_TMR0_CNT)    (TIMER0_MAX_CNT - NEW_TMR0_CNT)\r\n#define REG_TIMER0_UNION   (*(timer0_reg_ptr_t)_REG_TIMER0_ADDR)\r\n\r\n\r\ntypedef struct\r\n{\r\n    uint8_t RD:1;\r\n    uint8_t WR:1;\r\n    uint8_t WREN:1;\r\n    uint8_t WRERR:1;\r\n    uint8_t EEIF:1;\r\n    uint8_t _RESERVED:3;\r\n}_eecon1_reg_t,*_eecon1_reg_ptr_t;\r\n\r\n#define EEPROM_MAX_ADDRESS      (0x3F)\r\n\r\n#define RD_EEPROM_INIT_READ     (0x01)\r\n#define RD_EEPROM_DEINIT_READ   (0x00)\r\n\r\n#define WR_EEPROM_INIT_WRITE    (0x01)\r\n#define WR_EEPROM_DEINIT_WRITE  (0x00)\r\n\r\n#define EEPROM_SELECT_ADDRESS(EE_ADDR) do{REG_EEADR=EE_ADDR;}while(0)\r\n#define EEPROM_GET_DATA()  (uint8_t)(REG_EEDATA)\r\n\r\ntypedef union\r\n{\r\n  _eecon1_reg_t bits;\r\n  uint8_t value;  \r\n}eecon1_reg_t, *eecon1_reg_ptr_t;\r\n#define REG_EECON1_UNION   (*(eecon1_reg_ptr_t)_REG_EECON1_ADDR)\r\n\r\n\r\n\r\n\r\n#define WAIT_LOOP_FOREVER()  while(1)\r\n#define DO_FOREVER()  while(1)\r\n\r\n#ifdef PIC16LIB_USE_RB0_INT\r\ntypedef void (*rb0_int_callback_t)();\r\nint8_t register_rb0_int_callback(rb0_int_callback_t new_cb);\r\nint8_t unregister_rb0_int_callback(rb0_int_callback_t cb_to_unreg);\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\ntypedef void (*portb_int_callback_t)();\r\nint8_t register_portb_int_callback(portb_int_callback_t new_cb);\r\nint8_t unregister_portb_int_callback(portb_int_callback_t cb_to_unreg);\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\ntypedef void (*timer0_int_callback_t)();\r\nint8_t register_timer0_int_callback(timer0_int_callback_t new_cb);\r\nint8_t unregister_timer0_int_callback(timer0_int_callback_t cb_to_unreg);\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_EEPROM\r\nint8_t eeprom_read_data(uint8_t ee_address, uint8_t *ee_read_data_ptr);\r\nint8_t eeprom_write_data(uint8_t ee_address, uint8_t ee_write_data_val);\r\n#endif\r\n\r\n#ifdef\t__cplusplus\r\n}\r\n#endif\r\n\r\n#endif\t\/* PIC16F84A_LIB_H *\/\r\n<\/pre>\n<p>Register tan\u0131mlar\u0131n\u0131 nas\u0131l yapt\u0131\u011f\u0131m\u0131z\u0131 daha \u00f6nceki yaz\u0131larda \u00e7ok\u00e7a a\u00e7\u0131klad\u0131\u011f\u0131mdan bu defa tekrara d\u00fc\u015fmemek ad\u0131na a\u00e7\u0131klamayaca\u011f\u0131m. Her zamanki gibi, veri ka\u011f\u0131d\u0131ndaki bilgileri modelleyerek k\u00fct\u00fck tan\u0131mlar\u0131n\u0131 yapt\u0131k.<\/p>\n<p>\u015eimdi gelelim eeprom&#8217;dan veri okuma ve eeprom&#8217;a veri yazma fonksiyonlar\u0131na. Onlar\u0131 da a\u015fa\u011f\u0131da g\u00f6rebilirsiniz:<\/p>\n<pre class=\"lang:c decode:true \" title=\"eeprom fonksiyonlar\u0131\">int8_t eeprom_read_data(uint8_t ee_address, uint8_t *ee_read_data_ptr)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EECON1_UNION.bits.RD=1;\r\n    *ee_read_data_ptr=REG_EEDATA;\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n\r\nint8_t eeprom_write_data(uint8_t ee_address, uint8_t ee_write_data_val)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    \r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EEDATA=ee_write_data_val;\r\n    REG_EECON1_UNION.bits.WREN=1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_2;\r\n    REG_EECON1_UNION.bits.WR=1;\r\n    \r\n    REG_INTCON_UNION.bits.EEIE=1;\r\n    while(REG_EECON1_UNION.bits.EEIF == 0)\r\n    {\r\n        asm (\"nop\");\r\n    }\r\n    REG_INTCON_UNION.bits.EEIE=0;\r\n    REG_EECON1_UNION.bits.EEIF=0;\r\n    REG_EECON1_UNION.bits.WREN=0;\r\n}<\/pre>\n<p>Her iki fonksiyon giri\u015finde de, girilen adresin 63 de\u011ferinden b\u00fcy\u00fck olup olmad\u0131\u011f\u0131n\u0131 kontrol ettik. Toplamda 64 byte&#8217;l\u0131k bir eeprom&#8217;umuz oldu\u011fundan, en y\u00fcksek adres 63 oluyor. Ard\u0131ndan okuma yapmak i\u00e7in, okuma yapaca\u011f\u0131m\u0131z adresi se\u00e7tik. Sonras\u0131nda RD bitini 1 yaparak okumay\u0131 ba\u015flatt\u0131k ve okunan de\u011feri REG_EEDATA k\u00fct\u00fc\u011f\u00fcnden okuduk.<\/p>\n<p>Yazma k\u0131sm\u0131nda ise i\u015fler biraz daha kar\u0131\u015f\u0131k \u015fekilde \u00e7\u00f6z\u00fcl\u00fcyor. Yine adres se\u00e7imini yapt\u0131ktan sonra ilk i\u015f olarak yazmak istedi\u011fimiz veriyi REG_EEDATA k\u00fct\u00fc\u011f\u00fcne yaz\u0131yoruz. Ard\u0131ndan WREN bitini 1 yaparak yazma izni vermi\u015f oluyoruz. Sonras\u0131nda, veri ka\u011f\u0131d\u0131ndan okudu\u011fumuza g\u00f6re EECON2 k\u00fct\u00fc\u011f\u00fcne s\u0131ras\u0131yla 0x55 ve 0xAA yazmak gerekiyor. Bu, koruma ama\u00e7l\u0131 konmu\u015f ve veri ka\u011f\u0131d\u0131na \u00fcretici taraf\u0131ndan yaz\u0131lm\u0131\u015f bir ek sekans \ud83d\ude42 Kodu yazan ne yapt\u0131\u011f\u0131n\u0131 biliyorsa, ancak o zaman yazabilsin demi\u015fler. Sayg\u0131m\u0131z sonsuz \ud83d\ude09 Ard\u0131ndan WR bitini 1 yaparak yaz\u0131m s\u00fcrecini ba\u015flat\u0131yoruz. Yaz\u0131m hemen bitmiyor; bu durumda yaz\u0131m\u0131n bitti\u011fini anlayabilmek i\u00e7in tek \u00e7aremiz EEI (eeproma veri yaz\u0131ld\u0131) kesmesini kurarak, kesme bayra\u011f\u0131 1 olana kadar beklemek. Burada bekleme i\u015fini asm(&#8220;nop&#8221;); sat\u0131r\u0131 ile yapt\u0131k. asm(KOMUT) fonksiyonu, XC8 derleycilerinde C kodunun i\u00e7erisnde assembly komutlar\u0131 \u00e7a\u011f\u0131rmaya yarar. Biz de &#8220;nop&#8221; yani &#8220;bir \u015fey yapmadan 1 saat darbesi bekle&#8221; komutunu \u00e7al\u0131\u015ft\u0131rarak bekleme sa\u011flad\u0131k. Ard\u0131ndan kesme bayra\u011f\u0131 1 olup while d\u00f6ng\u00fcs\u00fcnden \u00e7\u0131kt\u0131\u011f\u0131m\u0131zda kesmeyi kapat\u0131p, kesme bayra\u011f\u0131n\u0131 temizleyip, WREN k\u00fct\u00fc\u011f\u00fcn\u00fc s\u0131fara \u00e7ekerek \u00e7\u0131k\u0131p gidiyoruz \ud83d\ude42 Verimiz yaz\u0131ld\u0131.<\/p>\n<div class=\"su-note\"  style=\"border-color:#e5e54c;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\"><div class=\"su-note-inner su-u-clearfix su-u-trim\" style=\"background-color:#FFFF66;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">Dikkat! Burada while d\u00f6ng\u00fcs\u00fc sonsuza kadar s\u00fcrebilir. Bunu engellemek i\u00e7in while i\u00e7inde bir de\u011fi\u015fkeni her turda 1 art\u0131r\u0131p, d\u00f6ng\u00fc say\u0131s\u0131 bir \u00fcst s\u0131n\u0131r de\u011ferini ge\u00e7erse ve yaz\u0131m i\u015flemi hala bitmemi\u015fse hata d\u00f6nd\u00fcrerek \u00e7\u0131kmas\u0131n\u0131 sa\u011flamakta fayda vard\u0131r. <\/div><\/div>\n<p>Yukar\u0131daki fonksiyonlar\u0131n eklendi\u011fi durumda\u00a0pic16f84a_lib.c dosyam\u0131z \u015f\u00f6yle oluyor:<\/p>\n<pre class=\"lang:c mark:211-249 decode:true\" title=\"pic16f84a_lib.c\">#include \"pic16f84a_lib.h\"\r\n\r\n#define BIT_TOGGLE(x) (x^=1)\r\n\r\n#ifndef NULL\r\n#define NULL ((void*)0)\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_RB0_INT\r\nrb0_int_callback_t rb0_int_callback_list[MAX_INT_CALLBACK_NUM];\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\nportb_int_callback_t portb_int_callback_list[MAX_INT_CALLBACK_NUM];\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\ntimer0_int_callback_t timer0_int_callback_list[MAX_INT_CALLBACK_NUM];\r\n#endif\r\n\r\n\r\n#if defined(PIC16LIB_USE_RB0_INT) || defined(PIC16LIB_USE_PORTB_INT) || defined(PIC16LIB_USE_TIMER0_INT)\r\nstatic void interrupt global_isr_handler()\r\n{\r\n#ifdef PIC16LIB_USE_RB0_INT\r\n    if(REG_INTCON_UNION.bits.INTF)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL != rb0_int_callback_list[cb_index])\r\n            {\r\n                rb0_int_callback_list[cb_index]();\r\n            }\r\n        }\r\n        BIT_TOGGLE(REG_OPTION_UNION.bits.INTEDG);\r\n        REG_INTCON_UNION.bits.INTF=INT_FLAG_CLEAR;\r\n    }\r\n#endif\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\n    if(REG_INTCON_UNION.bits.RBIF)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL != portb_int_callback_list[cb_index])\r\n            {\r\n                portb_int_callback_list[cb_index]();\r\n            }\r\n        }\r\n        BIT_TOGGLE(REG_OPTION_UNION.bits.INTEDG);\r\n        REG_INTCON_UNION.bits.RBIF=INT_FLAG_CLEAR;\r\n    }\r\n#endif\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\n    if(REG_INTCON_UNION.bits.T0IF)\r\n    {\r\n        REG_INTCON_UNION.bits.T0IF=INT_FLAG_CLEAR;\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL != timer0_int_callback_list[cb_index])\r\n            {\r\n                timer0_int_callback_list[cb_index]();\r\n            }\r\n        }\r\n    }\r\n#endif\r\n}\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_RB0_INT\r\nint8_t register_rb0_int_callback(rb0_int_callback_t new_cb)\r\n{\r\n    if(NULL != new_cb)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL == rb0_int_callback_list[cb_index])\r\n            {\r\n                rb0_int_callback_list[cb_index]=new_cb;\r\n            }\r\n        }\r\n        if(MAX_INT_CALLBACK_NUM == cb_index)\r\n        {\r\n            return PIC16LIB_ERROR_CB_ALREADY_REGISTERED; \/\/All callbacks are already registered\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return 0;\r\n}\r\n\r\nint8_t unregister_rb0_int_callback(rb0_int_callback_t cb_to_unreg)\r\n{\r\n    if(NULL != cb_to_unreg)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(cb_to_unreg == rb0_int_callback_list[cb_index])\r\n            {\r\n                rb0_int_callback_list[cb_index]=NULL;\r\n            }\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n#endif\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\nint8_t register_portb_int_callback(portb_int_callback_t new_cb)\r\n{\r\n    if(NULL != new_cb)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL == portb_int_callback_list[cb_index])\r\n            {\r\n                portb_int_callback_list[cb_index]=new_cb;\r\n            }\r\n        }\r\n        if(MAX_INT_CALLBACK_NUM == cb_index)\r\n        {\r\n            return PIC16LIB_ERROR_CB_ALREADY_REGISTERED; \/\/All callbacks are already registered\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n \r\n \r\n \r\nint8_t unregister_portb_int_callback(portb_int_callback_t cb_to_unreg)\r\n{\r\n    if(NULL != cb_to_unreg)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(cb_to_unreg == portb_int_callback_list[cb_index])\r\n            {\r\n                portb_int_callback_list[cb_index]=NULL;\r\n            }\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n#endif\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\nint8_t register_timer0_int_callback(timer0_int_callback_t new_cb)\r\n{\r\n    if(NULL != new_cb)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL == timer0_int_callback_list[cb_index])\r\n            {\r\n                timer0_int_callback_list[cb_index]=new_cb;\r\n            }\r\n        }\r\n        if(MAX_INT_CALLBACK_NUM == cb_index)\r\n        {\r\n            return PIC16LIB_ERROR_CB_ALREADY_REGISTERED; \/\/All callbacks are already registered\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return (int8_t)PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n \r\n \r\n \r\nint8_t unregister_timer0_int_callback(timer0_int_callback_t cb_to_unreg)\r\n{\r\n    if(NULL != cb_to_unreg)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(cb_to_unreg == timer0_int_callback_list[cb_index])\r\n            {\r\n                timer0_int_callback_list[cb_index]=NULL;\r\n            }\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_EEPROM\r\nint8_t eeprom_read_data(uint8_t ee_address, uint8_t *ee_read_data_ptr)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EECON1_UNION.bits.RD=1;\r\n    *ee_read_data_ptr=REG_EEDATA;\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n\r\nint8_t eeprom_write_data(uint8_t ee_address, uint8_t ee_write_data_val)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    \r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EEDATA=ee_write_data_val;\r\n    REG_EECON1_UNION.bits.WREN=1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_2;\r\n    REG_EECON1_UNION.bits.WR=1;\r\n    \r\n    REG_INTCON_UNION.bits.EEIE=1;\r\n    while(REG_EECON1_UNION.bits.EEIF == 0)\r\n    {\r\n        asm (\"nop\");\r\n    }\r\n    REG_INTCON_UNION.bits.EEIE=0;\r\n    REG_EECON1_UNION.bits.EEIF=0;\r\n    REG_EECON1_UNION.bits.WREN=0;\r\n}\r\n#endif\r\n<\/pre>\n<p>Art\u0131k k\u00fct\u00fcphanemiz haz\u0131r oldu\u011funa g\u00f6re, basit bir test fonksiyonu yazaca\u011f\u0131z. 0x01 adresli EEPROM bellek alan\u0131na 1 byte&#8217;l\u0131k &#8216;X&#8217; karakterini yazan ve do\u011fru yaz\u0131p yazmad\u0131\u011f\u0131n\u0131 kontrol eden bir kod, a\u015fa\u011f\u0131da yer almakta.<\/p>\n<pre class=\"lang:c decode:true \" title=\"main.c\">\/* \r\n * File:   main.c\r\n * Author: ozenozkaya\r\n *\r\n *\/\r\n\r\n#include \"pic16f84a_lib.h\"\r\n\r\n\/\/ CONFIG\r\n#pragma config FOSC = XT        \/\/ Oscillator Selection bits (XT oscillator)\r\n#pragma config WDTE = ON        \/\/ Watchdog Timer (WDT enabled)\r\n#pragma config PWRTE = ON       \/\/ Power-up Timer Enable bit (Power-up Timer is enabled)\r\n#pragma config CP = OFF         \/\/ Code Protection bit (Code protection disabled)\r\n\r\n#define EEPROM_TEST_ADDR    (0x01)\r\n#define EEPROM_TEST_DATA    ('X')\r\n\r\nvoid main() {\r\n    \r\n    uint8_t rd_data=0;\r\n    \r\n    REG_TRISB_UNION.port = TRIS_PORT_OUTPUT;\r\n    REG_PORTB_UNION.port = PORT_ALL_LOW;\r\n    \r\n    eeprom_write_data(EEPROM_TEST_ADDR,EEPROM_TEST_DATA);\r\n    eeprom_read_data(EEPROM_TEST_ADDR,&amp;rd_data);\r\n    \r\n    if(EEPROM_TEST_DATA==rd_data)\r\n    {\r\n        REG_PORTB_UNION.port=0xAA;\r\n    }\r\n    while(1);\r\n}\r\n<\/pre>\n<p>Bu kodumuz, yaz\u0131m ve okuma i\u015flemleri ba\u015far\u0131l\u0131 ise B portuna 0xAA yaz\u0131yor. E\u011fer hata olursa B portu ilk de\u011feri olan 0x00 de\u011ferinde kal\u0131yor. B portuna 0xAA=10101010 de\u011ferinin yaz\u0131lmas\u0131, s\u0131ras\u0131yla pinlerin y\u00fcksekte ve al\u00e7akta olmas\u0131na sebep oluyor.<\/p>\n<p>Kodda bir di\u011fer \u00f6nemli k\u0131s\u0131m ise #pragma ile ba\u015flayan konfig\u00fcrasyon sat\u0131rlar\u0131. Buna g\u00f6re osilat\u00f6r olarak kristal osilat\u00f6r se\u00e7mi\u015f olduk. Ayr\u0131ca, mikrokontrol\u00f6r\u00fcn donup kald\u0131\u011f\u0131 durumlarda ona reset atacak olan watchdog timer mod\u00fcl\u00fcn\u00fc aktive ettik. Yine g\u00fc\u00e7 dalgalanmalar\u0131nda reset atmaya yarayan power on reset&#8217;i aktive ettik ve kod korumay\u0131 kapatt\u0131k. Kod koruma a\u00e7\u0131k olarak mikrokontrol\u00f6re yaz\u0131l\u0131m atarsan\u0131z, o kod bir daha okunamayacak ve kolayl\u0131kla de\u011fi\u015ftirilemeyecektir. Prototip a\u015famas\u0131nda CP (code protection, kod koruma) se\u00e7ene\u011fini OFF yap\u0131n\u0131z (varsay\u0131lan de\u011fer de budur).<\/p>\n<p>Bu kodun \u00e7al\u0131\u015ft\u0131\u011f\u0131 duruma ili\u015fkin Proteus ISIS sim\u00fclasyon \u00e7\u0131kt\u0131s\u0131 ise a\u015fa\u011f\u0131da yer al\u0131yor.<\/p>\n<p><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"544\" data-permalink=\"http:\/\/ozenozkaya.com\/blog\/?attachment_id=544\" data-orig-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_test.png?fit=276%2C267\" data-orig-size=\"276,267\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"pic16f84a_eeprom_test\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_test.png?fit=276%2C267\" data-large-file=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_test.png?fit=276%2C267\" class=\"alignnone size-full wp-image-544\" src=\"https:\/\/i0.wp.com\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_test.png?resize=276%2C267\" alt=\"\" width=\"276\" height=\"267\" \/><\/p>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, EEPROM\u00a0s\u00fcr\u00fcc\u00fcm\u00fcz de ba\u015far\u0131yla \u00e7al\u0131\u015f\u0131yor \ud83d\ude42<\/p>\n<p>Projenin kaynak kodlar\u0131n\u0131 <a href=\"http:\/\/ozenozkaya.com\/files\/codes\/pic16f84a_eeprom.rar\">BURADAN <\/a>indirebilirsiniz.<\/p>\n<p>Bu g\u00fcnl\u00fck de bu kadar. \u0130leride yeni yaz\u0131larla devam edece\u011fiz.<\/p>\n<p>Yaz\u0131lar\u0131 be\u011fendiyseniz, faydalanabilecek tan\u0131d\u0131klar\u0131n\u0131zla payla\u015fmay\u0131 unutmay\u0131n\u0131z.<\/p>\n<a href=\"http:\/\/ozenozkaya.com\/blog\/?p=523\" class=\"su-button su-button-style-3d\" style=\"color:#FFFFFF;background-color:#2D89EF;border-color:#246ec0;border-radius:5px\" target=\"_self\"><span style=\"color:#FFFFFF;padding:6px 16px;font-size:13px;line-height:20px;border-color:#6cadf4;border-radius:5px;text-shadow:none\"><i class=\"sui sui-arrow-circle-o-left\" style=\"font-size:13px;color:#FFFFFF\"><\/i> \u00d6nceki Sayfa<\/span><\/a> \u00a0<a href=\"http:\/\/ozenozkaya.com\/blog\/?p=565\" class=\"su-button su-button-style-3d\" style=\"color:#FFFFFF;background-color:#2D89EF;border-color:#246ec0;border-radius:5px\" target=\"_self\"><span style=\"color:#FFFFFF;padding:6px 16px;font-size:13px;line-height:20px;border-color:#6cadf4;border-radius:5px;text-shadow:none\"><i class=\"sui sui-arrow-circle-right\" style=\"font-size:13px;color:#FFFFFF\"><\/i> Sonraki Sayfa<\/span><\/a>\n","protected":false},"excerpt":{"rendered":"<p>Merhabalar, doktora yeterlik s\u0131nav\u0131 dolay\u0131s\u0131yla ara verdi\u011fim blog yaz\u0131lar\u0131ma, yeterlik a\u015famas\u0131n\u0131 ge\u00e7ti\u011fimden dolay\u0131 devam ediyorum \ud83d\ude00 PIC16F84A ile ilgili, geriye kalan son bir iki konuyu da irdeleyece\u011fimiz bu yaz\u0131da, ana g\u00fcndemimiz EEPROM olacak. &#8220;EEPROM nedir?&#8221; sorusuna yan\u0131t arayanlar i\u00e7in WIKIPEDIA\u00a0sayfas\u0131nda yeterli bilgi oldu\u011funu belirtmek isterim. K\u0131saca \u00f6zetlemek gerekirse EEPROM, elektriksel olarak yaz\u0131l\u0131p silinebilen, kal\u0131c\u0131 bir <a class=\"read-more\" href=\"http:\/\/ozenozkaya.com\/blog\/?p=538\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_tr_post_content":"Merhabalar, doktora yeterlik s\u0131nav\u0131 dolay\u0131s\u0131yla ara verdi\u011fim blog yaz\u0131lar\u0131ma, yeterlik a\u015famas\u0131n\u0131 ge\u00e7ti\u011fimden dolay\u0131 devam ediyorum :D PIC16F84A ile ilgili, geriye kalan son bir iki konuyu da irdeleyece\u011fimiz bu yaz\u0131da, ana g\u00fcndemimiz EEPROM olacak.\r\n\r\n\"EEPROM nedir?\" sorusuna yan\u0131t arayanlar i\u00e7in <a href=\"https:\/\/tr.wikipedia.org\/wiki\/EEPROM\">WIKIPEDIA<\/a>\u00a0sayfas\u0131nda yeterli bilgi oldu\u011funu belirtmek isterim. K\u0131saca \u00f6zetlemek gerekirse EEPROM, elektriksel olarak yaz\u0131l\u0131p silinebilen, kal\u0131c\u0131 bir bellek tipi; yani elektrik gitse de i\u00e7erisinde kay\u0131tl\u0131 olan veri kendili\u011finden silinmiyor. Flash belle\u011fe g\u00f6re yaz\u0131m \u00f6mr\u00fcn\u00fcn \u00e7ok fazla olmas\u0131, bu devre eleman\u0131n\u0131 bu g\u00fcn dahi pop\u00fcler tutmaya yetiyor.\r\n\r\nPIC16F84A i\u00e7inde de 64 byte'l\u0131k bir EEPROM bulunuyor. 64 byte kadar k\u00fc\u00e7\u00fck bir EEPROM olsa da, \u00f6zellikle kal\u0131c\u0131 konfig\u00fcrasyonlar\u0131 saklama konusunda, bu mod\u00fcl hayat kurtar\u0131yor. Bu durumda bize d\u00fc\u015fen de, PIC16FLIB ad\u0131yla geli\u015ftirdi\u011fimiz alternatif PIC k\u00fct\u00fcphanesine bu mod\u00fcl\u00fc de eklemek olacak. \u00d6yleyse hemen ba\u015flayal\u0131m!\r\n\r\n\u0130lk ad\u0131m olarak, her zamanki gibi <a href=\"http:\/\/ww1.microchip.com\/downloads\/en\/DeviceDoc\/35007C.pdf\">datasheet'i<\/a> okuyup anlayarak, yaz\u0131l\u0131msal olarak modelleyece\u011fiz. Datasheet'te EEPROM mod\u00fcl\u00fc, sistemin blok diyagram\u0131nda \u015f\u00f6yle yer al\u0131yor:\r\n\r\n[caption id=\"attachment_539\" align=\"alignnone\" width=\"561\"]<img class=\" wp-image-539\" src=\"http:\/\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_block_diag-1.png\" alt=\"\" width=\"561\" height=\"476\" \/> PIC16F84A veri ka\u011f\u0131d\u0131ndan al\u0131nm\u0131\u015ft\u0131r.[\/caption]\r\n\r\nBuradan da g\u00f6r\u00fcld\u00fc\u011f\u00fc gibi EEPROM mod\u00fcl\u00fcm\u00fcz 64*8 bitlik veriyi saklayabiliyor. \u015eimdi de, EEPROM ile ilgili k\u00fct\u00fcklerin (register), hangi adreslerde oldu\u011funa bakal\u0131m.\r\n\r\n<img class=\"alignnone size-full wp-image-542\" src=\"http:\/\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_regs.png\" alt=\"\" width=\"798\" height=\"697\" \/>\r\n\r\n\u0130lgili k\u00fct\u00fckleri fosforlu sar\u0131 ile i\u015faretledi\u011fimden adreslerini g\u00f6rebilirsiniz. Art\u0131k adreslerini ve yap\u0131lar\u0131n\u0131 da bildi\u011fimizden, bu k\u00fct\u00fckleri yazd\u0131\u011f\u0131m\u0131z PIC k\u00fct\u00fcphanesine ekleyebiliriz. EEPROM mod\u00fcl\u00fcn\u00fc de derlemeye dahil edip etmemeyi se\u00e7imli yapmak i\u00e7in i\u015fe pic16flib_conf.h dosyas\u0131na a\u015fa\u011f\u0131daki i\u015faretli sat\u0131r\u0131 ekleyerek ba\u015fl\u0131yoruz.\r\n<pre class=\"lang:c mark:20 decode:true\" title=\"pic16flib_conf.h\">\/* \r\n * File:   pic16flib_conf.h\r\n * Author: ozenozkaya\r\n *\r\n * Created on 25 Eyl\u00fcl 2015 Cuma, 00:46\r\n *\/\r\n\r\n#ifndef PIC16FLIB_CONF_H\r\n#define\tPIC16FLIB_CONF_H\r\n\r\n#ifdef\t__cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\n#define MAX_INT_CALLBACK_NUM (1)\r\n\r\n\/\/#define PIC16LIB_USE_RB0_INT\r\n\/\/#define PIC16LIB_USE_PORTB_INT\r\n\/\/#define PIC16LIB_USE_TIMER0_INT\r\n#define PIC16LIB_USE_EEPROM\r\n    \r\n#ifdef\t__cplusplus\r\n}\r\n#endif\r\n\r\n#endif\t\/* PIC16FLIB_CONF_H *\/\r\n<\/pre>\r\n\u015eimdi\u00a0pic16f84a_lib.h i\u00e7erisindeki k\u00fct\u00fck tan\u0131mlamalar\u0131na ge\u00e7elim. A\u015fa\u011f\u0131daki i\u015faretli sat\u0131rlar\u0131\u00a0pic16f84a_lib.h dosyas\u0131na ekliyoruz.\r\n<pre class=\"lang:c mark:21,45-49,62-69,165-193,218-222 decode:true\" title=\"pic16f84a_lib.h\">\/* \r\n * File:   pic16f84a_lib.h\r\n * Author: ozenozkaya\r\n *\r\n * Created on 20 Temmuz 2015 Pazartesi, 00:05\r\n *\/\r\n\r\n#ifndef PIC16F84A_LIB_H\r\n#define\tPIC16F84A_LIB_H\r\n\r\n#ifdef\t__cplusplus\r\nextern \"C\" {\r\n#endif\r\n \r\n#include &lt;stdint.h&gt;\r\n#include \"pic16flib_conf.h\"\r\n    \r\n#define PIC16LIB_ERROR_NONE     (0)\r\n#define PIC16LIB_ERROR_CB_NULL  (-1)\r\n#define PIC16LIB_ERROR_CB_ALREADY_REGISTERED (-2)\r\n#define PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS (-3)\r\n\r\n#define F_OSC (1000000UL)\r\n    \r\n#define _REG_TIMER0_ADDR (0x01)\r\n#define REG_TIMER0 (*( volatile uint8_t*)_REG_TIMER0_ADDR)\r\n    \r\n#define _REG_PROGRAM_COUNTER_ADDR (0x02)\r\n#define REG_PROGRAM_COUNTER (*( volatile uint8_t*)_REG_PROGRAM_COUNTER_ADDR)\r\n\r\n#define _REG_STATUS_ADDR (0x03)\r\n#define REG_STATUS (*( volatile uint8_t*)_REG_STATUS_ADDR)\r\n    \r\n#define _REG_PORTA_ADDR (0x05)\r\n#define REG_PORTA (*( volatile uint8_t*)_REG_PORTA_ADDR)\r\n    \r\n#define _REG_PORTB_ADDR (0x06)\r\n#define REG_PORTB (*( volatile uint8_t*)_REG_PORTB_ADDR)\r\n    \r\n#define PORT_PIN_LOW  (0)\r\n#define PORT_PIN_HIGH (1)\r\n#define PORT_ALL_LOW  (0)\r\n#define PORT_ALL_HIGH (0xFF)\r\n    \r\n#define _REG_EEDATA_ADDR (0x08)\r\n#define REG_EEDATA (*( volatile uint8_t*)_REG_EEDATA_ADDR)\r\n\r\n#define _REG_EEADR_ADDR (0x09)\r\n#define REG_EEADR (*( volatile uint8_t*)_REG_EEADR_ADDR)\r\n    \r\n#define _REG_TRISB_ADDR (0x86)\r\n#define REG_TRISB (*( volatile uint8_t*)_REG_TRISB_ADDR)\r\n \r\n#define _REG_TRISA_ADDR (0x85)\r\n#define REG_TRISA (*( volatile uint8_t*)_REG_TRISA_ADDR)\r\n    \r\n#define TRIS_PIN_OUTPUT (0)\r\n#define TRIS_PIN_INPUT  (1)\r\n#define TRIS_PORT_OUTPUT (0)\r\n#define TRIS_PORT_INPUT  (0xFF)\r\n\r\n#define _REG_EECON1_ADDR (0x88)\r\n#define REG_EECON1 (*( volatile uint8_t*)_REG_EECON1_ADDR)\r\n\r\n#define _REG_EECON2_ADDR (0x89)\r\n#define REG_EECON2 (*( volatile uint8_t*)_REG_EECON2_ADDR)\r\n\r\n#define EECON2_PROTECTION_SEQ_1 (0x55)    \r\n#define EECON2_PROTECTION_SEQ_2 (0xAA)  \r\n    \r\n#define _REG_INTCON_ADDR (0x0B)\r\n#define REG_INTCON (*( volatile uint8_t*)_REG_INTCON_ADDR)\r\n#define INT_ENABLE (1)\r\n#define INT_ENABLE_ALL (0xFF)\r\n#define INT_DISABLE (0)\r\n#define INT_DISABLE_ALL (0)\r\n#define INT_FLAG_CLEAR (0)\r\n\r\n#define _REG_OPTION_ADDR (0x81)\r\n#define REG_OPTION (*( volatile uint8_t*)_REG_OPTION_ADDR)\r\n#define INT_EDGE_FALLING (0)\r\n#define INT_EDGE_RISING  (1)\r\n   \r\n\r\ntypedef struct \r\n{\r\n    \/\/one bit is stored in one BYTE\r\n    uint8_t pin0:1;\r\n    uint8_t pin1:1;\r\n    uint8_t pin2:1;\r\n    uint8_t pin3:1;\r\n    uint8_t pin4:1;\r\n    uint8_t pin5:1;\r\n    uint8_t pin6:1;\r\n    uint8_t pin7:1;\r\n}_tris_port_pin_t, *_tris_port_pin_ptr_t;\r\n\r\ntypedef union\r\n{\r\n    _tris_port_pin_t pins;\r\n    uint8_t port;\r\n}tris_port_t,*tris_port_ptr_t;\r\n\r\n#define REG_TRISA_UNION (*(tris_port_ptr_t)_REG_TRISA_ADDR) \r\n#define REG_TRISB_UNION (*(tris_port_ptr_t)_REG_TRISB_ADDR) \r\n#define REG_PORTA_UNION (*(tris_port_ptr_t)_REG_PORTA_ADDR) \r\n#define REG_PORTB_UNION (*(tris_port_ptr_t)_REG_PORTB_ADDR) \r\n\r\n\r\ntypedef struct\r\n{\r\n    uint8_t RBIF:1;\r\n    uint8_t INTF:1;\r\n    uint8_t T0IF:1;\r\n    uint8_t RBIE:1;\r\n    uint8_t INTE:1;\r\n    uint8_t T0IE:1;\r\n    uint8_t EEIE:1;\r\n    uint8_t GIE:1;\r\n}_intcon_reg_t,*_intcon_reg_ptr_t;\r\n\r\ntypedef struct\r\n{\r\n    uint8_t PS:3;\r\n    uint8_t PSA:1;\r\n    uint8_t T0SE:1;\r\n    uint8_t T0CS:1;\r\n    uint8_t INTEDG:1;\r\n    uint8_t RBPU:1;\r\n}_option_reg_t,*_option_reg_ptr_t;\r\n\r\n#define T0CS_SOURCE_RA4_T0CKI_PIN (0x01)\r\n#define T0CS_SOURCE_INTERNAL_CLOCK (0x00)\r\n\r\n#define PSA_ASSIGN_TO_WATCHDOG  (0x01)\r\n#define PSA_ASSIGN_TO_TIMER0    (0x00)\r\n\r\n#define PS_TMR0_RATE_DIVIDE_2   (0x00)\r\n#define PS_TMR0_RATE_DIVIDE_4   (0x01)\r\n#define PS_TMR0_RATE_DIVIDE_8   (0x02)\r\n#define PS_TMR0_RATE_DIVIDE_16   (0x03)\r\n#define PS_TMR0_RATE_DIVIDE_32   (0x04)\r\n#define PS_TMR0_RATE_DIVIDE_64   (0x05)\r\n#define PS_TMR0_RATE_DIVIDE_128   (0x06)\r\n#define PS_TMR0_RATE_DIVIDE_256   (0x07)\r\n\r\n#define REG_OPTION_UNION (*(option_reg_ptr_t)_REG_OPTION_ADDR) \r\n\r\ntypedef union\r\n{\r\n  _intcon_reg_t bits;\r\n  uint8_t value;  \r\n}intcon_reg_t, *intcon_reg_ptr_t;\r\n#define REG_INTCON_UNION   (*(intcon_reg_ptr_t)_REG_INTCON_ADDR)\r\n\r\ntypedef union\r\n{\r\n    uint8_t value;\r\n    uint8_t count;\r\n}timer0_reg_t, *timer0_reg_ptr_t;\r\n#define TIMER0_MAX_CNT (0xFF)\r\n#define TIMER0_ASSIGN_CNT(NEW_TMR0_CNT)    (TIMER0_MAX_CNT - NEW_TMR0_CNT)\r\n#define REG_TIMER0_UNION   (*(timer0_reg_ptr_t)_REG_TIMER0_ADDR)\r\n\r\n\r\ntypedef struct\r\n{\r\n    uint8_t RD:1;\r\n    uint8_t WR:1;\r\n    uint8_t WREN:1;\r\n    uint8_t WRERR:1;\r\n    uint8_t EEIF:1;\r\n    uint8_t _RESERVED:3;\r\n}_eecon1_reg_t,*_eecon1_reg_ptr_t;\r\n\r\n#define EEPROM_MAX_ADDRESS      (0x3F)\r\n\r\n#define RD_EEPROM_INIT_READ     (0x01)\r\n#define RD_EEPROM_DEINIT_READ   (0x00)\r\n\r\n#define WR_EEPROM_INIT_WRITE    (0x01)\r\n#define WR_EEPROM_DEINIT_WRITE  (0x00)\r\n\r\n#define EEPROM_SELECT_ADDRESS(EE_ADDR) do{REG_EEADR=EE_ADDR;}while(0)\r\n#define EEPROM_GET_DATA()  (uint8_t)(REG_EEDATA)\r\n\r\ntypedef union\r\n{\r\n  _eecon1_reg_t bits;\r\n  uint8_t value;  \r\n}eecon1_reg_t, *eecon1_reg_ptr_t;\r\n#define REG_EECON1_UNION   (*(eecon1_reg_ptr_t)_REG_EECON1_ADDR)\r\n\r\n\r\n\r\n\r\n#define WAIT_LOOP_FOREVER()  while(1)\r\n#define DO_FOREVER()  while(1)\r\n\r\n#ifdef PIC16LIB_USE_RB0_INT\r\ntypedef void (*rb0_int_callback_t)();\r\nint8_t register_rb0_int_callback(rb0_int_callback_t new_cb);\r\nint8_t unregister_rb0_int_callback(rb0_int_callback_t cb_to_unreg);\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\ntypedef void (*portb_int_callback_t)();\r\nint8_t register_portb_int_callback(portb_int_callback_t new_cb);\r\nint8_t unregister_portb_int_callback(portb_int_callback_t cb_to_unreg);\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\ntypedef void (*timer0_int_callback_t)();\r\nint8_t register_timer0_int_callback(timer0_int_callback_t new_cb);\r\nint8_t unregister_timer0_int_callback(timer0_int_callback_t cb_to_unreg);\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_EEPROM\r\nint8_t eeprom_read_data(uint8_t ee_address, uint8_t *ee_read_data_ptr);\r\nint8_t eeprom_write_data(uint8_t ee_address, uint8_t ee_write_data_val);\r\n#endif\r\n\r\n#ifdef\t__cplusplus\r\n}\r\n#endif\r\n\r\n#endif\t\/* PIC16F84A_LIB_H *\/\r\n<\/pre>\r\nRegister tan\u0131mlar\u0131n\u0131 nas\u0131l yapt\u0131\u011f\u0131m\u0131z\u0131 daha \u00f6nceki yaz\u0131larda \u00e7ok\u00e7a a\u00e7\u0131klad\u0131\u011f\u0131mdan bu defa tekrara d\u00fc\u015fmemek ad\u0131na a\u00e7\u0131klamayaca\u011f\u0131m. Her zamanki gibi, veri ka\u011f\u0131d\u0131ndaki bilgileri modelleyerek k\u00fct\u00fck tan\u0131mlar\u0131n\u0131 yapt\u0131k.\r\n\r\n\u015eimdi gelelim eeprom'dan veri okuma ve eeprom'a veri yazma fonksiyonlar\u0131na. Onlar\u0131 da a\u015fa\u011f\u0131da g\u00f6rebilirsiniz:\r\n<pre class=\"lang:c decode:true \" title=\"eeprom fonksiyonlar\u0131\">int8_t eeprom_read_data(uint8_t ee_address, uint8_t *ee_read_data_ptr)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EECON1_UNION.bits.RD=1;\r\n    *ee_read_data_ptr=REG_EEDATA;\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n\r\nint8_t eeprom_write_data(uint8_t ee_address, uint8_t ee_write_data_val)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    \r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EEDATA=ee_write_data_val;\r\n    REG_EECON1_UNION.bits.WREN=1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_2;\r\n    REG_EECON1_UNION.bits.WR=1;\r\n    \r\n    REG_INTCON_UNION.bits.EEIE=1;\r\n    while(REG_EECON1_UNION.bits.EEIF == 0)\r\n    {\r\n        asm (\"nop\");\r\n    }\r\n    REG_INTCON_UNION.bits.EEIE=0;\r\n    REG_EECON1_UNION.bits.EEIF=0;\r\n    REG_EECON1_UNION.bits.WREN=0;\r\n}<\/pre>\r\nHer iki fonksiyon giri\u015finde de, girilen adresin 63 de\u011ferinden b\u00fcy\u00fck olup olmad\u0131\u011f\u0131n\u0131 kontrol ettik. Toplamda 64 byte'l\u0131k bir eeprom'umuz oldu\u011fundan, en y\u00fcksek adres 63 oluyor. Ard\u0131ndan okuma yapmak i\u00e7in, okuma yapaca\u011f\u0131m\u0131z adresi se\u00e7tik. Sonras\u0131nda RD bitini 1 yaparak okumay\u0131 ba\u015flatt\u0131k ve okunan de\u011feri REG_EEDATA k\u00fct\u00fc\u011f\u00fcnden okuduk.\r\n\r\nYazma k\u0131sm\u0131nda ise i\u015fler biraz daha kar\u0131\u015f\u0131k \u015fekilde \u00e7\u00f6z\u00fcl\u00fcyor. Yine adres se\u00e7imini yapt\u0131ktan sonra ilk i\u015f olarak yazmak istedi\u011fimiz veriyi REG_EEDATA k\u00fct\u00fc\u011f\u00fcne yaz\u0131yoruz. Ard\u0131ndan WREN bitini 1 yaparak yazma izni vermi\u015f oluyoruz. Sonras\u0131nda, veri ka\u011f\u0131d\u0131ndan okudu\u011fumuza g\u00f6re EECON2 k\u00fct\u00fc\u011f\u00fcne s\u0131ras\u0131yla 0x55 ve 0xAA yazmak gerekiyor. Bu, koruma ama\u00e7l\u0131 konmu\u015f ve veri ka\u011f\u0131d\u0131na \u00fcretici taraf\u0131ndan yaz\u0131lm\u0131\u015f bir ek sekans :) Kodu yazan ne yapt\u0131\u011f\u0131n\u0131 biliyorsa, ancak o zaman yazabilsin demi\u015fler. Sayg\u0131m\u0131z sonsuz ;) Ard\u0131ndan WR bitini 1 yaparak yaz\u0131m s\u00fcrecini ba\u015flat\u0131yoruz. Yaz\u0131m hemen bitmiyor; bu durumda yaz\u0131m\u0131n bitti\u011fini anlayabilmek i\u00e7in tek \u00e7aremiz EEI (eeproma veri yaz\u0131ld\u0131) kesmesini kurarak, kesme bayra\u011f\u0131 1 olana kadar beklemek. Burada bekleme i\u015fini asm(\"nop\"); sat\u0131r\u0131 ile yapt\u0131k. asm(KOMUT) fonksiyonu, XC8 derleycilerinde C kodunun i\u00e7erisnde assembly komutlar\u0131 \u00e7a\u011f\u0131rmaya yarar. Biz de \"nop\" yani \"bir \u015fey yapmadan 1 saat darbesi bekle\" komutunu \u00e7al\u0131\u015ft\u0131rarak bekleme sa\u011flad\u0131k. Ard\u0131ndan kesme bayra\u011f\u0131 1 olup while d\u00f6ng\u00fcs\u00fcnden \u00e7\u0131kt\u0131\u011f\u0131m\u0131zda kesmeyi kapat\u0131p, kesme bayra\u011f\u0131n\u0131 temizleyip, WREN k\u00fct\u00fc\u011f\u00fcn\u00fc s\u0131fara \u00e7ekerek \u00e7\u0131k\u0131p gidiyoruz :) Verimiz yaz\u0131ld\u0131.\r\n\r\n[su_note]Dikkat! Burada while d\u00f6ng\u00fcs\u00fc sonsuza kadar s\u00fcrebilir. Bunu engellemek i\u00e7in while i\u00e7inde bir de\u011fi\u015fkeni her turda 1 art\u0131r\u0131p, d\u00f6ng\u00fc say\u0131s\u0131 bir \u00fcst s\u0131n\u0131r de\u011ferini ge\u00e7erse ve yaz\u0131m i\u015flemi hala bitmemi\u015fse hata d\u00f6nd\u00fcrerek \u00e7\u0131kmas\u0131n\u0131 sa\u011flamakta fayda vard\u0131r. [\/su_note]\r\n\r\nYukar\u0131daki fonksiyonlar\u0131n eklendi\u011fi durumda\u00a0pic16f84a_lib.c dosyam\u0131z \u015f\u00f6yle oluyor:\r\n<pre class=\"lang:c mark:211-249 decode:true\" title=\"pic16f84a_lib.c\">#include \"pic16f84a_lib.h\"\r\n\r\n#define BIT_TOGGLE(x) (x^=1)\r\n\r\n#ifndef NULL\r\n#define NULL ((void*)0)\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_RB0_INT\r\nrb0_int_callback_t rb0_int_callback_list[MAX_INT_CALLBACK_NUM];\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\nportb_int_callback_t portb_int_callback_list[MAX_INT_CALLBACK_NUM];\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\ntimer0_int_callback_t timer0_int_callback_list[MAX_INT_CALLBACK_NUM];\r\n#endif\r\n\r\n\r\n#if defined(PIC16LIB_USE_RB0_INT) || defined(PIC16LIB_USE_PORTB_INT) || defined(PIC16LIB_USE_TIMER0_INT)\r\nstatic void interrupt global_isr_handler()\r\n{\r\n#ifdef PIC16LIB_USE_RB0_INT\r\n    if(REG_INTCON_UNION.bits.INTF)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL != rb0_int_callback_list[cb_index])\r\n            {\r\n                rb0_int_callback_list[cb_index]();\r\n            }\r\n        }\r\n        BIT_TOGGLE(REG_OPTION_UNION.bits.INTEDG);\r\n        REG_INTCON_UNION.bits.INTF=INT_FLAG_CLEAR;\r\n    }\r\n#endif\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\n    if(REG_INTCON_UNION.bits.RBIF)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL != portb_int_callback_list[cb_index])\r\n            {\r\n                portb_int_callback_list[cb_index]();\r\n            }\r\n        }\r\n        BIT_TOGGLE(REG_OPTION_UNION.bits.INTEDG);\r\n        REG_INTCON_UNION.bits.RBIF=INT_FLAG_CLEAR;\r\n    }\r\n#endif\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\n    if(REG_INTCON_UNION.bits.T0IF)\r\n    {\r\n        REG_INTCON_UNION.bits.T0IF=INT_FLAG_CLEAR;\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL != timer0_int_callback_list[cb_index])\r\n            {\r\n                timer0_int_callback_list[cb_index]();\r\n            }\r\n        }\r\n    }\r\n#endif\r\n}\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_RB0_INT\r\nint8_t register_rb0_int_callback(rb0_int_callback_t new_cb)\r\n{\r\n    if(NULL != new_cb)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL == rb0_int_callback_list[cb_index])\r\n            {\r\n                rb0_int_callback_list[cb_index]=new_cb;\r\n            }\r\n        }\r\n        if(MAX_INT_CALLBACK_NUM == cb_index)\r\n        {\r\n            return PIC16LIB_ERROR_CB_ALREADY_REGISTERED; \/\/All callbacks are already registered\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return 0;\r\n}\r\n\r\nint8_t unregister_rb0_int_callback(rb0_int_callback_t cb_to_unreg)\r\n{\r\n    if(NULL != cb_to_unreg)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(cb_to_unreg == rb0_int_callback_list[cb_index])\r\n            {\r\n                rb0_int_callback_list[cb_index]=NULL;\r\n            }\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n#endif\r\n#ifdef PIC16LIB_USE_PORTB_INT\r\nint8_t register_portb_int_callback(portb_int_callback_t new_cb)\r\n{\r\n    if(NULL != new_cb)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL == portb_int_callback_list[cb_index])\r\n            {\r\n                portb_int_callback_list[cb_index]=new_cb;\r\n            }\r\n        }\r\n        if(MAX_INT_CALLBACK_NUM == cb_index)\r\n        {\r\n            return PIC16LIB_ERROR_CB_ALREADY_REGISTERED; \/\/All callbacks are already registered\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n \r\n \r\n \r\nint8_t unregister_portb_int_callback(portb_int_callback_t cb_to_unreg)\r\n{\r\n    if(NULL != cb_to_unreg)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(cb_to_unreg == portb_int_callback_list[cb_index])\r\n            {\r\n                portb_int_callback_list[cb_index]=NULL;\r\n            }\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n#endif\r\n#ifdef PIC16LIB_USE_TIMER0_INT\r\nint8_t register_timer0_int_callback(timer0_int_callback_t new_cb)\r\n{\r\n    if(NULL != new_cb)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(NULL == timer0_int_callback_list[cb_index])\r\n            {\r\n                timer0_int_callback_list[cb_index]=new_cb;\r\n            }\r\n        }\r\n        if(MAX_INT_CALLBACK_NUM == cb_index)\r\n        {\r\n            return PIC16LIB_ERROR_CB_ALREADY_REGISTERED; \/\/All callbacks are already registered\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return (int8_t)PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n \r\n \r\n \r\nint8_t unregister_timer0_int_callback(timer0_int_callback_t cb_to_unreg)\r\n{\r\n    if(NULL != cb_to_unreg)\r\n    {\r\n        uint8_t cb_index=0;\r\n        for(cb_index=0;cb_index&lt;MAX_INT_CALLBACK_NUM; cb_index++)\r\n        {\r\n            if(cb_to_unreg == timer0_int_callback_list[cb_index])\r\n            {\r\n                timer0_int_callback_list[cb_index]=NULL;\r\n            }\r\n        }\r\n    }\r\n    else\r\n    {\r\n        return PIC16LIB_ERROR_CB_NULL; \/\/ Callback is NULL\r\n    }\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n#endif\r\n\r\n#ifdef PIC16LIB_USE_EEPROM\r\nint8_t eeprom_read_data(uint8_t ee_address, uint8_t *ee_read_data_ptr)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EECON1_UNION.bits.RD=1;\r\n    *ee_read_data_ptr=REG_EEDATA;\r\n    return PIC16LIB_ERROR_NONE;\r\n}\r\n\r\nint8_t eeprom_write_data(uint8_t ee_address, uint8_t ee_write_data_val)\r\n{\r\n    if(ee_address&gt;EEPROM_MAX_ADDRESS)\r\n    {\r\n        return PIC16LIB_ERROR_WRONG_EEPROM_ADDRESS;\r\n    }\r\n    \r\n    EEPROM_SELECT_ADDRESS(ee_address);\r\n    REG_EEDATA=ee_write_data_val;\r\n    REG_EECON1_UNION.bits.WREN=1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_1;\r\n    REG_EECON2=EECON2_PROTECTION_SEQ_2;\r\n    REG_EECON1_UNION.bits.WR=1;\r\n    \r\n    REG_INTCON_UNION.bits.EEIE=1;\r\n    while(REG_EECON1_UNION.bits.EEIF == 0)\r\n    {\r\n        asm (\"nop\");\r\n    }\r\n    REG_INTCON_UNION.bits.EEIE=0;\r\n    REG_EECON1_UNION.bits.EEIF=0;\r\n    REG_EECON1_UNION.bits.WREN=0;\r\n}\r\n#endif\r\n<\/pre>\r\nArt\u0131k k\u00fct\u00fcphanemiz haz\u0131r oldu\u011funa g\u00f6re, basit bir test fonksiyonu yazaca\u011f\u0131z. 0x01 adresli EEPROM bellek alan\u0131na 1 byte'l\u0131k 'X' karakterini yazan ve do\u011fru yaz\u0131p yazmad\u0131\u011f\u0131n\u0131 kontrol eden bir kod, a\u015fa\u011f\u0131da yer almakta.\r\n<pre class=\"lang:c decode:true \" title=\"main.c\">\/* \r\n * File:   main.c\r\n * Author: ozenozkaya\r\n *\r\n *\/\r\n\r\n#include \"pic16f84a_lib.h\"\r\n\r\n\/\/ CONFIG\r\n#pragma config FOSC = XT        \/\/ Oscillator Selection bits (XT oscillator)\r\n#pragma config WDTE = ON        \/\/ Watchdog Timer (WDT enabled)\r\n#pragma config PWRTE = ON       \/\/ Power-up Timer Enable bit (Power-up Timer is enabled)\r\n#pragma config CP = OFF         \/\/ Code Protection bit (Code protection disabled)\r\n\r\n#define EEPROM_TEST_ADDR    (0x01)\r\n#define EEPROM_TEST_DATA    ('X')\r\n\r\nvoid main() {\r\n    \r\n    uint8_t rd_data=0;\r\n    \r\n    REG_TRISB_UNION.port = TRIS_PORT_OUTPUT;\r\n    REG_PORTB_UNION.port = PORT_ALL_LOW;\r\n    \r\n    eeprom_write_data(EEPROM_TEST_ADDR,EEPROM_TEST_DATA);\r\n    eeprom_read_data(EEPROM_TEST_ADDR,&amp;rd_data);\r\n    \r\n    if(EEPROM_TEST_DATA==rd_data)\r\n    {\r\n        REG_PORTB_UNION.port=0xAA;\r\n    }\r\n    while(1);\r\n}\r\n<\/pre>\r\nBu kodumuz, yaz\u0131m ve okuma i\u015flemleri ba\u015far\u0131l\u0131 ise B portuna 0xAA yaz\u0131yor. E\u011fer hata olursa B portu ilk de\u011feri olan 0x00 de\u011ferinde kal\u0131yor. B portuna 0xAA=10101010 de\u011ferinin yaz\u0131lmas\u0131, s\u0131ras\u0131yla pinlerin y\u00fcksekte ve al\u00e7akta olmas\u0131na sebep oluyor.\r\n\r\nKodda bir di\u011fer \u00f6nemli k\u0131s\u0131m ise #pragma ile ba\u015flayan konfig\u00fcrasyon sat\u0131rlar\u0131. Buna g\u00f6re osilat\u00f6r olarak kristal osilat\u00f6r se\u00e7mi\u015f olduk. Ayr\u0131ca, mikrokontrol\u00f6r\u00fcn donup kald\u0131\u011f\u0131 durumlarda ona reset atacak olan watchdog timer mod\u00fcl\u00fcn\u00fc aktive ettik. Yine g\u00fc\u00e7 dalgalanmalar\u0131nda reset atmaya yarayan power on reset'i aktive ettik ve kod korumay\u0131 kapatt\u0131k. Kod koruma a\u00e7\u0131k olarak mikrokontrol\u00f6re yaz\u0131l\u0131m atarsan\u0131z, o kod bir daha okunamayacak ve kolayl\u0131kla de\u011fi\u015ftirilemeyecektir. Prototip a\u015famas\u0131nda CP (code protection, kod koruma) se\u00e7ene\u011fini OFF yap\u0131n\u0131z (varsay\u0131lan de\u011fer de budur).\r\n\r\nBu kodun \u00e7al\u0131\u015ft\u0131\u011f\u0131 duruma ili\u015fkin Proteus ISIS sim\u00fclasyon \u00e7\u0131kt\u0131s\u0131 ise a\u015fa\u011f\u0131da yer al\u0131yor.\r\n\r\n<img class=\"alignnone size-full wp-image-544\" src=\"http:\/\/ozenozkaya.com\/blog\/wp-content\/uploads\/pic16f84a_eeprom_test.png\" alt=\"\" width=\"276\" height=\"267\" \/>\r\n\r\nG\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi, EEPROM\u00a0s\u00fcr\u00fcc\u00fcm\u00fcz de ba\u015far\u0131yla \u00e7al\u0131\u015f\u0131yor :)\r\n\r\nProjenin kaynak kodlar\u0131n\u0131 <a href=\"http:\/\/ozenozkaya.com\/files\/codes\/pic16f84a_eeprom.rar\">BURADAN <\/a>indirebilirsiniz.\r\n\r\nBu g\u00fcnl\u00fck de bu kadar. \u0130leride yeni yaz\u0131larla devam edece\u011fiz.\r\n\r\nYaz\u0131lar\u0131 be\u011fendiyseniz, faydalanabilecek tan\u0131d\u0131klar\u0131n\u0131zla payla\u015fmay\u0131 unutmay\u0131n\u0131z.\r\n\r\n[su_button url=\"http:\/\/ozenozkaya.com\/blog\/?p=523\" style=\"3d\"\u00a0icon=\"icon: arrow-circle-o-left\"]\u00d6nceki Sayfa[\/su_button] \u00a0[su_button url=\"http:\/\/ozenozkaya.com\/blog\/?p=565\" style=\"3d\" icon=\"icon: arrow-circle-right\"]Sonraki Sayfa[\/su_button]","_tr_post_name":"pic-programlama-10-eeprom","_tr_post_excerpt":"","_tr_post_title":"PIC Programlama \u2013 10 \u2013 EEPROM","_en_post_content":"","_en_post_name":"","_en_post_excerpt":"","_en_post_title":"","edit_language":"tr","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[2,3],"tags":[],"class_list":["post-538","post","type-post","status-publish","format-standard","hentry","category-elektronik","category-gomulu-sistemler"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5gWM6-8G","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/538","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=538"}],"version-history":[{"count":6,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/538\/revisions"}],"predecessor-version":[{"id":577,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/538\/revisions\/577"}],"wp:attachment":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=538"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}