News:

Let's find out together what makes a PIC Tick!

Main Menu

EEPROM inquiry

Started by JackB, May 01, 2026, 03:39 PM

Previous topic - Next topic

JackB

Hello everyone,

Looking for a SOT-23 with EEPROM

does anyone know any sot-23-5,6 format microcontroller that
have internal memory or EEPROM to write/read data when running.

when asking AI it return PIC10F206, but from the datasheet no mention this IC have EEPROM.

any idea?
Thank's to all for comment.



Frizie

As far as I know, the PIC10F does not have an EEPROM on board :(
Ohm sweet Ohm | www.picbasic.nl

JackB

You're right, I doubt AI

trastikata

https://www.microchip.com/MAPS/

No such device, but depending on your application, maybe you can use the internal FLASH memory to store information, if lower erase endurance is acceptable.

JackB

#4
Many thanks for taking time to reply.

I saw a comment 2 weeks ago about using flash memory if internal EEPROM storage is not available,
my application is very small and it use a PIC10F322 that take 30% out of 512 words, and 15 variable out of 64
and need to store 2 word variable only.

Found out CRead16 CWrite CData, I'll do some test on the 10F322 and comeback with result.

definitely not compatible with 10F322
I'll replace it with an 12F1840.









JonW

#5
Sorry, I pressed enter before I posted.. The 10F322 can definitely read and write E2 during execution, they are pretty limited cores so alot of the compiler commands wont work.


I have posted the full code as its easier to read that way. This reads a value from E2 and writes to pwm, and when it receives a serial calibration command, it can store it in E2.  Works 100%


Device = 10F322
Xtal = 16
All_Digital = true


Config    FOSC_INTOSC,BOREN_OFF,WDTE_ON,PWRTE_ON,MCLRE_OFF,LVP_OFF,LPBOR_OFF,BORV_24,WRT_HALF,CP_ON     
;WRT_ALL EQU 0X27FF      ; 000h to 1FFh write protected, no addresses may be modified by PMCON control
;WRT_HALF EQU 0X2FFF     ; 000h to 0FFh write protected, 100h to 1FFh may be modified by PMCON control
;WRT_BOOT EQU 0X37FF     ; 000h to 07Fh write protected, 080h to 1FFh may be modified by PMCON control
'Declare
Declare RSIn_Timeout = 100 ' Timeout after 100mS seconds
Declare Serial_Baud = 9600
Declare RSIn_Mode = True
Declare RSIn_Pin = PORTA.2

;PORT CONFIGS


;Registers

       
;Dim PROG_DATA As word           ; Program Data to Write at PWM_ADDR
Dim PWM_ADDR As Word            ; ADDRESS for read and write
Dim PWM_VAL    As Word          ; PWM VALUE READ AND WRITTEN
Dim PWM_TMP_VAL As Word         ; temp Shift value


Dim RXBYTE As Byte              ; UART RECEIVE BYTE

'Constants
Symbol PWM_MEM = $1E1           ' mem location constant
Symbol CAL_MEM = $1F0           ' cal location constant   only factory to write to this
;****************************************************************************
;   
;                                  INITIALISE CHIP
;
;****************************************************************************
;Set Up  PWM as per datasheet PAGE 101

        CLKRCON = 0             ; No Clock out
        OSCCON = %01110000      ; 16MHz
        While OSCCON.3 = 0:Wend     ; Wait for Clk
        INTCON = 0      ; Disable all interrupte
        PIE1 = 0
        WDTCON = %00010111      ; WDT Enabled and set to 2 secs
       
        TRISA = %00001111       ; Only RA0 OUT
        PWM1CON = 0
        PR2 = $ff               ; Load the PR2 Register
        PWM1DCL = 0
        PWM2DCL = 0
        PIR1.1 = 0              ; Clear TMR2IF
        T2CON = %00000100       ; Timer on prescaler 1                                   
        PWM1CON.6 = 1           ; Enable Pin
        While PIR1.1 = 0:Wend   ; Wait for timer to overflow
        PWM1CON.7 = 1           ; Enable PWM Module
        TRISA = %00000110       ; RA0 Output
        PWM1CON = %11000000     ; Configure reset of PWN COntrol REG
;PWM SETUP  just need to set DCH

          GoTo Main
         
;*******************************  SUBS  **********************************************************************         

;****************************************************************************
;   PASS: PWM_ADDR
;   Return: PWM_VAL
;
;**************************************************************************** 
READ_FLASH:
        PWM_VAL = $FF               ; Flag $FF inclse Failure
        PMADRL = PWM_ADDR.LowByte
        PMADRH = PWM_ADDR.HighByte
        Clear    PMCON1.6
        Set      PMCON1.0
        Nop
        Nop
        PWM_VAL.LowByte = PMDATL
        PWM_VAL.HighByte = PMDATH
Return       
;****************************************************************************
;   PASS: Nothing
;   Return: Nothing
;
;**************************************************************************** 
UNLOCK_FLASH:
        PMCON2 = $55                   ; Required Writes
        PMCON2 = $AA                   ; Required Wrtits
        PMCON1.1 = 1                   ; Set WR to begin erase
        Nop
        Nop
        PMCON1.2 = 0                   ; Disable Writes
        Return
       
;****************************************************************************
;   PASS: PWM_ADDR to Erase 16 Words, Must start on a 16 Byte Boundary
;   Return: Nothing
;
;**************************************************************************** 
ERASE_FLASH:                           ; Erases 16 words from PWM_ADDRESS onward
        PMADRL = PWM_ADDR.LowByte
        PMADRH = PWM_ADDR.HighByte
        PMCON1.6 = 0                   ; Not config space
        PMCON1.4 = 1                   ; Specify an Erase Operation
        PMCON1.2 = 1                   ; Enable Writed
        Call UNLOCK_FLASH
        Return
       
WRITE_FLASH:
;****************************************************************************
;   PASS: PWM_ADDR & PWM_VAL To Write a location
;   Return: Nothing
;
;**************************************************************************** 
        Call ERASE_FLASH               ; Erase the Flash First
        PMADRL = PWM_ADDR.LowByte      ; Writes a single byte
        PMADRH = PWM_ADDR.HighByte
        PMDATL = PWM_VAL.LowByte       ; Write the PWM Value
        PMDATH = PWM_VAL.HighByte
        PMCON1.2 = 1                   ; Enable Writes
        Call UNLOCK_FLASH       
        PMCON1.2 = 0                   ; Disable Writes        pmcon1.2 = 0           
        Return
;****************************************************************************
;   PASS: PWM_VAL and it changes the Duty register
;   Return: Nothing
;
;****************************************************************************       
SET_DUTY:
        PWM_TMP_VAL = PWM_VAL <<6      ; Copy shifted PWMVAL in to temp reg, Preserve PWM_VAL
        PWM1DCL = PWM_VAL.LowByte      ; Load the Duty Cycle Register
        PWM1DCH = PWM_VAL.HighByte     ; Load the Duty Cycle Register
        Return   
     
;****************************************************************************
;   
;                                  MAIN ROUTINE
;
;****************************************************************************         
Main:
     ;PWM


     PWM_ADDR = PWM_MEM           ; Get CAL Address
     Call READ_FLASH              ; Read PWM Value from Flash     
     If PWM_VAL = 0 Then          ; If REG = 0 then Set Duty to 50%
        PWM_VAL = $1FF
     EndIf   
     If PWM_VAL > $3FF Then      ; If PWM_VAL  > $3FF (MAX 10 bit) or unwritten
        PWM_VAL = $1FF
     EndIf   
     Call SET_DUTY              ; Set the Duty Cycle
     DelayMS    10
     Call SET_DUTY              ; Set the Duty Cycle


       
RXLOOP: 
     
                                     ;Should spin here forever with no connection
        ;RXBYTE = RsIn,{TIMEOUT}
        RXBYTE = RsIn   
 
        Select RXBYTE
                Case "I"
                If PWM_VAL =  $1FF Then PWM_VAL = $1FE
                Inc PWM_VAL
                Call SET_DUTY
               
                Case "D"
                If PWM_VAL =  0 Then PWM_VAL = $01   
                Dec PWM_VAL
                Call SET_DUTY
                           
                Case "S"                                 ; Store PWM_VAL to User Memory
                ;PWM_VAL SHOULD BE SET ALREADY           ; Received CAL so initiate CAL Write @ CAL_MEM Location
                PWM_ADDR = PWM_MEM
                Call WRITE_FLASH                         ; This erases the full 16Bytes and then writes   
               ; Call set_duty       
               
                Case "R"                                 ; Recover CAL and Write to
                PWM_ADDR = CAL_MEM                       ; Load CAL Memory
                Call READ_FLASH                          ; Read the Flash and Value should be in PWM_VAL
                If PWM_VAL = $FF Then GoTo TIMEOUT
                If PWM_VAL = 0 Then GoTo TIMEOUT
                PWM_ADDR = PWM_MEM                       ; Load User Memory
                Call WRITE_FLASH                         ; Write to User Flash
                Call SET_DUTY                            ; Change the Duty
               
               
                Case "C"
                RXBYTE = RsIn,{TIMEOUT}                  ' Looking for "CAL" before write occurs
                If RXBYTE <> "A" Then GoTo TIMEOUT
                RXBYTE = RsIn,{TIMEOUT}
                If RXBYTE <> "L" Then GoTo TIMEOUT 
                RXBYTE = RsIn,{TIMEOUT}
                ;PWM_VAL SHOULD BE SET ALREADY           ; Received CAL so initiate CAL Write @ CAL_MEM Location
                PWM_ADDR = CAL_MEM                       ; Store the CAL In flash and change Duty
                Call WRITE_FLASH     
                PWM_ADDR = PWM_MEM
                Call WRITE_FLASH                         ; Factory Cal so copy the result into both memories
               ; call set_duty                     
        EndSelect   

        GoTo RXLOOP
TIMEOUT:
       GoTo RXLOOP


End



JonW

I have some, ill post in a few mins

JackB

Hello JonW,
I have to learn from your code listing,
many thanks


JackB

using CRead and CWrite I came up with interresting results with the PIC10F322.

 ( the CWrite is writing at $1F8,$1F9 address but both the CRead and CWrite have some issue)

1) either with WDTE_ON / OFF, when cycle a power on / power off the CWrite function
   is executed without waiting for PORTA.0 to be low via a tact switch.

2) when using the CRead section the Do-Loop section is not executed, otherwise the Do-Loop is running.


3) when using PORTA.0 instead of LATA.0 the CWrite variables are automaticly saved in the flash memory before a powering the device.

   Also before each program download an 'Erase' & 'Blank Check' were performed.


Thank for all comments.



' PIC10F322
' Apr 5-2026
' "D:\Positron Code\10F322\MIC1555 Counter\MIC1555 Counter.bas"

Device = 10F322
Declare Xtal = 16
Config   FOSC_INTOSC , BOREN_OFF , WDTE_OFF , PWRTE_OFF , MCLRE_OFF , LVP_OFF , LPBOR_OFF , BORV_24 , WRT_HALF , CP_OFF
ANSELA = %00000000     
TRISA  = %00001001
OSCCON = $70

' Var to Write
Dim A1 As Word = 5521
Dim A2 As Word = 5521

' Var to Read
Dim B1 As Word = 0
Dim B2 As Word = 0

' CWrite Address
Dim wAddress As Word = $1F8

' CWrite Section
If PORTA.0 = 0 Then  ' Tact SW default = 1 , Press = 0 
'If LATA.0 = 0 Then  ' Tact SW default = 1 , Press = 0
    CWrite wAddress, [A1, A2]
EndIf

' CRead Section
 B1 = CRead $1F8
 B2 = CRead $1F9

Do
 SerOut PORTA.2,84, ["B1 :  ",Dec B1,"   B2 :  ",Dec B2, 13,10]
 DelayMS 500
Loop



trastikata

Hello JackB,

there are several issues with your code...

- you read immediately after FLASH write, the core needs some time to complete the write process. You can monitor specific register bit, or allow 3-5 ms delay between the write and read.

- you write word variables to byte sized locations and late addressing is also ambiguous.

- In general CWrite doesn't like multy byte writes, break your code in byte operations when dealing with FLASH writes.

- 0x01F8 FLSH address is not page aligned, so if you want to re-write it at a later point you will have to erase the page start address containing this location.

Try this:

' CWrite Section
If PORTA.0 = 0 Then  ' Tact SW default = 1 , Press = 0
'If LATA.0 = 0 Then  ' Tact SW default = 1 , Press = 0
    CWrite wAddress, [A1.Byte1]
    While PMCON1.1 = 1 : Wend
    CWrite wAddress + 1, [A1.Byte0]
    While PMCON1.1 = 1 : Wend
    CWrite wAddress + 2, [A2.Byte1]
    While PMCON1.1 = 1 : Wend
    CWrite wAddress + 3, [A2.Byte0]
    While PMCON1.1 = 1 : Wend
EndIf

' CRead Section
 B1.Byte1 = CRead wAddress
 B1.Byte0 = CRead wAddress + 1
 B2.Byte1 = CRead wAddress + 2
 B2.Byte0 = CRead wAddress + 3

JackB

Hello Trastikata,

here's the results.

1) with PORTA.0 and CRead enable reading on Pickit variables are stored and the Do-Loop is not running

2) with LATA.0  and CRead enable reading on Pickit variables are not stored and the Do-Loop is not running

3) with LATA.0  and CRead disable reading on Pickit variables are stored and the Do-Loop is running

Many thanks


JonW

Just use the code provided?
Much easier as you have total control of all the registers.

I see this sooo many times on this forum. Granted, the compiler is never flawless, none are, but learn to use the basic asm or commands to do the function on the specific core. 

I rarely use the larger features of the compiler, not because they dont work, but more to ensure that I understand the architecture of the core and to know the flow...

Dont ask for advice if you aren't prepared to try or listen.

trastikata

#12
I looked at the Assembler code and there seem to be a problem with the generated code when using the built in CWrite and Cread.

As JonW said just use direct register access and write to FLASh using registers or modify his code to your needs, the code JonW provided is straight from the datasheet.

Here's a modified version of JonW's code with procedures which should ease the work in your code listing. If you don't want to erase the entire row before FLASH Write, just comment out "EraseFlash(wAddress)".

Device = 10F322
Declare Xtal = 16
Config   FOSC_INTOSC , BOREN_OFF , WDTE_OFF , PWRTE_OFF , MCLRE_OFF , LVP_OFF , LPBOR_OFF , BORV_24 , WRT_HALF , CP_OFF
ANSELA = %00000000    
TRISA  = %00001001
OSCCON = $70

' Var to Write
Dim A1 As Word = 5521
Dim A2 As Word = 5521

' Var to Read
Dim B1 As Word = 0
Dim B2 As Word = 0

' CWrite Address
Dim wAddress As Word = $1F8
Dim wData As Word

' CWrite Section
If PORTA.0 = 0 Then  ' Tact SW default = 1 , Press = 0
    EraseFlash(wAddress)
    WriteFlash(wAddress, A1)
    WriteFlash(wAddress + 2, A2)
EndIf

' CRead Section
 B1 = ReadFlash(wAddress)
 B2 = ReadFlash(wAddress + 2)

Do
 SerOut PORTA.2,84, ["B1 :  ",Dec B1,"   B2 :  ",Dec B2, 13,10]
 DelayMS 500
Loop

End

Proc WriteFlash(wAddress As wAddress, wData As wData)
    PMADRL = wAddress.LowByte      ; Writes a single byte
    PMADRH = wAddress.HighByte
    PMDATL = wData.LowByte         ; Write the PWM Value
    PMDATH = wData.HighByte
    PMCON1.2 = 1                   ; Enable Writes
    UnlockFlash()      
    PMCON1.2 = 0                   ; Disable Writes        pmcon1.2 = 0    
    While PMCON1.1 = 1 : Wend
EndProc

Proc UnlockFlash()
    PMCON2 = $55                   ; Required Writes
    PMCON2 = $AA                   ; Required Wrtits
    PMCON1.1 = 1                   ; Set WR to begin erase
    Nop
    Nop
    PMCON1.2 = 0                   ; Disable Writes
EndProc

Proc ReadFlash(wAddress As wAddress), wData
    PMADRL = wAddress.LowByte
    PMADRH = wAddress.HighByte
    Clear    PMCON1.6
    Set      PMCON1.0
    Nop
    Nop
    Result.LowByte = PMDATL
    Result.HighByte = PMDATH
EndProc

Proc EraseFlash(wAddress As wAddress)
    PMADRL = wAddress.LowByte
    PMADRH = wAddress.HighByte
    PMCON1.6 = 0                   ; Not config space
    PMCON1.4 = 1                   ; Specify an Erase Operation
    PMCON1.2 = 1                   ; Enable Writed
    UnlockFlash()
    While PMCON1.1 = 1 : Wend
EndProc

JonW

Apologies if I sounded blunt, but coding a mcu requires a certain understanding of the architecture and the compiler.
There are bugs in every compiler, I used to code in asm as it was the only way to fully control the code.
Ive only ever  use compilers for speed and as a rule, code all my own functions from base code. If this fails, I would always fall to asm and errata datasheets.

Bugs alaways exist,and I tend to work round them, build my own known code and simplify.

J