Electronic – analog output from pic 18f4520

analogdac

i am trying to generate analog signal using pic and dac circuit attached
when i simulate using Proteus the signal does not make a full cycle
i thought that pic make reset after 24ms so i make the timer0 interrupt 50u instead of 100u then the signal make like reset after 12us
can any one help me in that ?
the signal is [vo=2,5+1,5 sin(2 pi 25 t) + 0.5 sin (2 pi 1000 t)
ts = 100 us
t = 0 : 40 ms]

#include"pic18f4520.h"
#pragma config WDT = OFF
unsigned char k = 0;
unsigned char m = 401;
unsigned char signal[] = {128,144,155,156,148,134,120,112,113,124,140,156,167,168,160,146,132,124,125,    136,152,168,178,179,171,
    157,143,135,136,147,163,179,189,190,182,168,154,146,147,157,173,189,199,200,1    92,178,164,155,156,166,
        182,198,208,209,201,186,172,164,164,174,190,206,216,217,208,193,179,170,171,1    81,196,212,222,222,214,
199,184,175,176,186,201,216,226,226,217,203,188,179,179,189,204,219,229,229,220,205,190,180,180,190,
205,220,229,229,220,205,189,180,180,189,204,219,228,228,218,203,187,178,177,186,201,216,225,224,214,
199,183,174,173,182,196,211,220,219,209,193,178,168,167,176,190,204,213,212,202,186,171,160,160,168,
182,196,205,204,194,178,162,152,151,159,173,187,196,195,184,168,152,142,141,149,163,177,185,184,174,
157,141,131,130,138,152,166,174,173,162,146,130,119,118,126,140,154,162,161,150,134,118,107,106,114,
128,142,150,149,138,122,106,95,94,102,116,130,138,137,126,110,94,83,82,90,104,118,126,125,115,
99,82,72,71,79,93,107,115,114,104,88,72,61,60,69,83,97,105,104,94,78,62,52,51,60,
74,88,96,96,85,70,54,44,43,52,66,80,89,88,78,63,47,37,36,45,60,74,83,82,73,
57,42,32,31,40,55,70,79,78,69,53,38,28,28,37,52,67,76,76,67,51,36,27,27,36,
51,66,76,76,66,51,36,27,27,37,52,67,77,77,68,53,39,30,30,40,55,70,80,81,72,
57,42,34,34,44,60,75,85,86,77,63,48,39,40,50,66,82,92,92,84,70,55,47,48,58,
74,90,100,101,92,78,64,56,57,67,83,99,109,110,102,88,74,66,67,77,93,109,120,121,113,
99,85,77,78,88,104,120,131,132,124,110,96,88,89,100,116,132,143,144,136,122,108,100,101,112,128};
//unsigned char signal[] = { 128, 217, 255, 217, 128, 37, 0, 37 };

void InitTimer0()
{
T08BIT = 1;     //8bit mode
T0CS = 0;
PSA = 0;
T0PS2 = 0; T0PS1 = 0; T0PS0 = 1;
TMR0L = 5;
TMR0H    = 0xFC;
TMR0IF = 0;
TMR0ON = 1; 
T0IE = 1;
GIE = 1;


}
void interrupt timer( void )
{
GIE = 0;
if( TMR0IF ){
    TMR0L = 0x17;          ///T=0,02496
    TMR0H    = 0xFC;
    TMR0IF = 0;
   //i?lem 
    k++;
    LATC = signal[k];

    if( k == 401) 
    {TMR0ON = 0;
    LATC = 0;
    }
}
GIE = 1;
}
void main(void)
{
InitTimer0();
TRISC = 0x00;
LATC = signal[k];
while(1){
}
}

result of 100us interrupt

result of 50us interrupt

Best Answer

The variable k is unsigned char so can only hold values up to 255. Ideally it should also be volatile as it's used in both main and interrupt.

Change the declaration to volatile unsigned short k = 0; and see if that helps, similar with m too, so something like:

#include"pic18f4520.h"
#pragma config WDT = OFF
volatile unsigned short k = 0;
volatile unsigned short m = 401;
// etc.

Actually, the code you posted doesn't use m, but maybe that's not all of your code, so just be aware.

Assuming you are using Microchip's XC8 compiler, the supported data types and ranges are all described from page 151 of the XC8 Compiler User Guide. For example, here are the two relevant tables:

data types

integer ranges

If you want to ensure that your code is portable, regardless of differing compiler defaults, you can #include <stdint.h>, which defines types that specifically identify the size. For example:

#include <stdint.h>
volatile k uint16_t = 0;    // 16-bit unsigned integer

Other types follow a similar pattern, for example int32_t is a 32-bit signed integer, uint8_t is 8-bit unsigned, etc.