![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
X9C102 digital potentiometer problem |
Posted: Thu Sep 13, 2012 9:39 am |
|
|
Hey,
my problem is to get work X9C102 dig.pot
it's wiper goes up and down but I can't store zero position value
is here any person to help me to get things work ...
brdgs
-arto-
Code: |
/*/CHECK LIST:
freq.range ei toimi
1. 20 JA 40 DB RELEET EI SAA VETÄÄ YHTÄAIKAA
2.run napin koordinaatit nyt väärin
3.kato kaikki TEST
4. offset ei toimi ihan ok !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5.lisää kuormavastus ihan outputtiin esim. 10k
6. attenuator ei mene -20dB portain ????
7. wr atten tekstit pissii näytöllä
8. vaatii aina viiveen 5s kun valitaan sinewave
9. mieti värit loogisiksi
10. analog napin jälkeen wait ilmoitus kesto 5 s
11. tee lopullinen offset hienosäätö lopullisella virtalähteellä
*/
#include<18F4525.h>
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
//#include <math.h>
#use delay(clock=20000000)
#use rs232(FORCE_SW,baud=9600,xmit=pin_c6,rcv=pin_c7,stream=LCD)
#fuses HS,NOWDT,NOPROTECT,NOPUT,BROWNOUT
#INT_EXT
#define pot_cs (PIN_C3) //digital potentiometer chip select, active LOW
#define pot_up_down (PIN_C4) //digital potentiometer up/down, LOW = DOWN
#define pot_inc (PIN_C5) //digital potentiometer incremental
#define rel_20dB (PIN_C2) //-20dB attenuator relay
#define rel_40dB (PIN_C1) //-40dB attenuator relay
#define on_off_rel (PIN_C0) //signal on/off relay, 10s delay at startup
#define rel_20Hz (PIN_A0) //20Hz relay and 20 Hz sin. filter
#define rel_200Hz (PIN_A1) //200Hz relay and 200Hz sin. filter
#define rel_2kHz (PIN_A2) //2kHz relay and 2kHz sin. filter
#define rel_20kHz (PIN_A3) //20kHz relay and 20kHz sin. filter
#define LCD_reset (PIN_A4) //reset LCD display module
#define dist_AD (PIN_A5) //distortion meter A/D input
#define triangle_rel (PIN_E0) //triangle wave ON state, otherwise sin (XR2206 board)
#define square_rel (PIN_E1) //square wave if ON (XR2206 board)
#define sine_rel (PIN_E2) //skip sinewave filter when using triangle or square wave
#define DA_cs (PIN_B5) //D/A converter chip select,active LOW
#define DA_wr (PIN_B4) //D/A converter write,active LOW
//#define up_button input(PIN_B0) //up button for test purposes only, NORMALLY D/A INPUT!
//#define dwn_button input(PIN_B1) //down button for test purposes only, NORMALLY D/A INPUT!
#define sine 1 //for sel_wavemode function
#define triangle 2 //for sel_wavemode function
#define square 3 //for sel_wavemode function
#define Hz20 1 //for freq_area function
#define Hz200 2 //for freq_area function
#define Hz2k 3 //for freq_area function
#define Hz20k 4 //for freq_area function
#define dB0 0 //for atten_rel function
#define dB20 1 //for atten_rel function
#define dB40 2 //for atten_rel function
//#define dB60 3 //for atten_rel function
//color LCD functions:
void com_ok(void);
int8 screen_1(void);
//void screen_test(void);
void RB_isr(void);
void autobaud(void);
void display_on(void);
void display_off(void);
void backlight_off(void);
void backlight_on(void);
void backlight_colour(int16 bck_colour); //look color picker !
void draw_buttons_test(void);
void draw_buttons_1(void);
void draw_button(short int state,int16 x_TOP_LEFT,int16 y_TOP_LEFT,int16 colour,
int8 size,int16 text_colour, char text[]);
void en_touch_screen(void);
void touch_region(int16 x1,int16 x2,int16 y1,int16 y2);
void analog_gen(void);
void wr_range(int8 range);
void wr_divider(int8 divider);
void an_buttons(void); //draw analog buttons
void redraw_mode(int8 mode);
void wr_offset(float offset_v);
void sel_wavemode(int8 wave); //select sine, triangle or square wave mode
void freq_area(int8 freq_area); /*freq. area and corresponding filter selected:
1...4: 20Hz,200Hz,2kHz and 20 kHz*/
void atten_rel(int8 atten); //signal attenuation 0, -20, -40 dB
//global identifiers:
int8 freq_range,mode;
float offset;
//************************************************************************************************
void main(void)
{
int8 freq_range,mode,divider;
float offset;
output_high(DA_cs); //D/A converter not selected
output_high(DA_wr); //D/A write not selected
output_high(pot_cs); //dig. pot not selected
output_low(pot_up_down);
output_low(pot_inc);
//LCD reset pin 5 is pin A4
output_low(PIN_A4); //reset
delay_ms(2000);
output_high(PIN_A4); //lcd on
delay_ms(1000);
autobaud();
display_on();
backlight_colour(0xF800); //backlight colour red
putc(0x45); com_ok(); //clear screen
delay_ms(1000);
if(screen_1() == 1)
{
//delay_ms(500);
analog_gen();
}
//analog_gen();
backlight_colour(0xF800); //backlight colour red
putc(0x45); com_ok(); //clear screen
poo:;goto poo;
}
//************************************************************************************************
void analog_gen(void)
{
//freq_range,mode,offset are global identifiers
int8 x_coord_LSB, x_coord_MSB,y_coord_LSB,y_coord_MSB,range,divider,loop;
int16 x_place,y_place,delay;
//first these settings:
freq_area(Hz200); //20...200 relay ON
divider = 0; //no attenuation 0dB
atten_rel(divider);
sel_wavemode(sine); //sinewave relay ON
x_place = y_place = 0;
an_buttons(); //draw analog buttons
/*write default values: range = 1(20...200Hz),mode = 1 (sinewave), divider = 1 (1/1)
offset = 0 V */
mode = 1;
range =1;
wr_range(range); //frequence range default value =1 = 20-200Hz
freq_area(range); //frequence relay ON first 20...200Hz area
wr_divider(0);
//offset_v 0V...+-2.2V
offset = 0.0000;
wr_offset(offset); //default value 0.00 V
delay_ms(5000); //for sine wave to stabilize
output_high(on_off_rel);//TEST muuta myöhemmin???????????????????????????????????????????
en_touch_screen();
do //DO until CANCEL pressed
{
x_place = y_place = 0;
putc(0x6F); //cmd
putc(0x01); //wait until touch press
while(!kbhit(LCD))
delay_us(1);
x_coord_MSB = getc(LCD); //read character from UART
x_coord_LSB = getc(LCD); //read character from UART
y_coord_MSB = getc(LCD); //read character from UART
y_coord_LSB = getc(LCD); //read character from UART
x_place = make16( x_coord_MSB,x_coord_LSB); //return 16 bit value
y_place = make16( y_coord_MSB,y_coord_LSB);
if((x_place > 9) & (x_place < 171) & (y_place > 9) & (y_place < 35))
{
if(range < 5) //freq.range 1...4
++range;
if(range == 5)
range = 1;
wr_range(range); //write freq.area to display
freq_area(range); //frequence relay ON
}
if((x_place > 9) & (x_place < 171) & (y_place > 131) & (y_place < 155))
{
if(divider < 3) //divider 0dB = 0 -20 = 1 or -40 dB = 2
++divider;
if(divider == 3)
divider = 0;
wr_divider(divider);
atten_rel(divider);
}
if((x_place > 9) & (x_place < 171) & (y_place > 39) & (y_place < 65))
{
mode = 1; //mode sine wave
redraw_mode(1);
sel_wavemode(sine); //sinewave relay ON
}
if((x_place > 9) & (x_place < 171) & (y_place > 69) & (y_place < 95))
{
mode = 2; //mode triangle wave
redraw_mode(2);
sel_wavemode(triangle); //sinewave relay ON
}
if((x_place > 9) & (x_place < 171) & (y_place > 99) & (y_place < 125))
{
mode = 3; //mode square wave
redraw_mode(3);
sel_wavemode(square); //square relay ON
}
//RUN button pressed:
if((x_place > 9) & (x_place < 171) & (y_place > 199) & (y_place < 237))
{
backlight_colour(0xFFFF); //backlight colour white
putc(0x45); com_ok(); //clear screen
/*/make these 6 lines only if offset voltage is <> 0 V
output_low(pot_cs); //dig. pot selected
delay_ms(10);
output_high(pot_inc); //store wiper position
delay_ms(10);
output_high(pot_cs); //dig. pot selected
delay_ms(10);*/
return;
}
//+ offset button pressed:
if((x_place > 121) & (x_place < 139) & (y_place > 159) & (y_place < 185))
{
delay = 200;
loop = 0;
do
{
if(offset < 2.199 ) //some groundings?!
{ offset = offset + 0.044;
wr_offset(offset); //return;
}
delay_ms(delay);
//offset + button released
putc(0x6F); //cmd
putc(0x04); //wait until touch activity, 0 = no activity, 2= touch release
while(!kbhit(LCD))
delay_us(1);
x_coord_MSB = getc(LCD); //read character from UART
x_coord_LSB = getc(LCD); //read character from UART
y_coord_MSB = getc(LCD); //read character from UART
y_coord_LSB = getc(LCD); //read character from UART
if(loop > 5)
delay = 20;
//set offset towards positive voltage:
output_high(pot_cs); //dig. pot not selected
output_low(pot_up_down); //dig.pot wiper down, makes offset V higher!
delay_ms(10);
output_high(pot_inc); //pulse dig. pot
delay_ms(10);
output_low(pot_cs); //dig. pot selected
output_low(pot_inc); //no store ... return to standby
delay_ms(10);
output_high(pot_cs); //dig. pot NOT selected
delay_ms(10);
++loop;
}while(x_coord_LSB!=2); //result is in x_coord LSB
}
//- offset button pressed:
if((x_place > 153) & (x_place < 169) & (y_place > 159) & (y_place < 185))
{
delay = 200;
loop = 0;
do
{
if(offset > -2.199 ) //some groundings?!
{ offset = offset - 0.044;
wr_offset(offset); //return;
}
delay_ms(delay);
//offset + button released
putc(0x6F); //cmd
putc(0x04); //wait until touch activity, 0 = no activity, 2= touch release
while(!kbhit(LCD))
delay_us(1);
x_coord_MSB = getc(LCD); //read character from UART
x_coord_LSB = getc(LCD); //read character from UART
y_coord_MSB = getc(LCD); //read character from UART
y_coord_LSB = getc(LCD); //read character from UART
if(loop > 5)
delay = 20;
//set offset towards negative voltage:
output_high(pot_cs); //dig. pot not selected
output_high(pot_up_down); //dig.pot wiper up, makes offset V lower!
delay_ms(10);
output_high(pot_inc); //pulse dig. pot
delay_ms(10);
output_low(pot_cs); //dig. pot selected
output_low(pot_inc); //no store ... return to standby
delay_ms(10);
output_high(pot_cs); //dig. pot NOT selected
delay_ms(10);
++loop;
}while(x_coord_LSB!=2); //result is in x_coord LSB
}
}while(!((x_place < 274) & (x_place > 129) & (y_place > 199) & (y_place < 237)));
}
//************************************************************************************************
void wr_offset(float offset)
{
//clear offset area
putc(0x72); //command
putc(0); //top left horisontal start coordinate MSB
putc(190); //top left horisontal start coordinate LSB
putc(0); //top left vertical start coordinate MSB
putc(155); //top left vertical start coordinate LSB
putc(1); //bottom right horisontal end coordinate MSB
putc(53); //bottom right horisontal end coordinate LSB
putc(0); //bottom right vertical end coordinate MSB
putc(180); //bottom right vertical end coordinate LSB
putc(0xFF); //backround color white
putc(0xFF);
com_ok();
//return;
//first clean old value:
putc(0x73); //cmd draw text string
putc(17); //column in character units
putc(10); //row in character units
putc(0x03); //font 8 x 12
putc(0x00); //string colour msb = black
putc(0x00);
printf("%s"," ");
putc(0x00); //string terminator
com_ok();
//pause:;goto pause;
//then write new value:
putc(0x73); //cmd draw text string
putc(17); //column in character units
putc(10); //row in character units
putc(0x03); //font 8 x 12
putc(0x00); //string colour msb = black
putc(0x00);
if(offset==0.0000)
printf(" %1.3f V",offset);
if(offset > 0.000)
printf("+%1.3f V",offset);
if(offset < 0.000)
printf("%1.3f V",offset);
putc(0x00); //string terminator
com_ok();
}
//************************************************************************************************
void redraw_mode(int8 mode)
{
char text[12];
switch (mode)
{
case 1:
strcpy(text," SINEWAVE ");
draw_button(TRUE,10,40,0x0000,2,0x9772,text);
strcpy(text," TRIANGLE ");
draw_button(TRUE,10,70,0x9772,2,0xF800,text);
strcpy(text," SQUARE ");
draw_button(TRUE,10,100,0x9772,2,0xF800,text);
break;
case 2:
strcpy(text," SINEWAVE ");
draw_button(TRUE,10,40,0x9772,2,0xF800,text);
strcpy(text," TRIANGLE ");
draw_button(TRUE,10,70,0x0000,2,0x9722,text);
strcpy(text," SQUARE ");
draw_button(TRUE,10,100,0x9772,2,0xF800,text);
break;
case 3:
strcpy(text," SINEWAVE ");
draw_button(TRUE,10,40,0x9772,2,0xF800,text);
strcpy(text," TRIANGLE ");
draw_button(TRUE,10,70,0x9772,2,0xF800,text);
strcpy(text," SQUARE ");
draw_button(TRUE,10,100,0x0000,2,0x9722,text);
break;
}
}
//************************************************************************************************
void an_buttons(void)
{
char text[12];
putc(0x45); com_ok(); //clear screen
/*button area 30,30 ...243,99
state=TRUE;
x_TOP_LEFT = 75;
y_TOP_LEFT = 62;
colour = 0x9772; //lightgreen
size = 2; // 2x (8x12)
text_colour = 0xF800; //red
draw_button(state,x_TOP_LEFT,y_TOP_LEFT,colour,size,text_colour,text);*/
strcpy(text,"FREQ.RANGE");
draw_button(TRUE,10,10,0x9772,2,0x00000,text);
strcpy(text," SINEWAVE ");
draw_button(TRUE,10,40,0x0000,2,0x9772,text);
strcpy(text," TRIANGLE ");
draw_button(TRUE,10,70,0x9772,2,0xF800,text);
strcpy(text," SQUARE ");
draw_button(TRUE,10,100,0x9772,2,0xF800,text);
strcpy(text," DIVIDER ");
draw_button(TRUE,10,130,0x9772,2,0x0000,text);
strcpy(text,"OFFSET");
draw_button(TRUE,10,160,0x9772,2,0x0000,text);
strcpy(text,"+");
draw_button(TRUE,122,160,0x9772,2,0xF800,text);
strcpy(text,"-");
draw_button(TRUE,154,160,0x9772,2,0xF800,text);
strcpy(text,"RUN");
draw_button(TRUE,10,200,0xF800,3,0x9772,text);
strcpy(text,"CANCEL");
draw_button(TRUE,130,200,0x0000,3,0x9772,text);
}
//************************************************************************************************
void wr_range(int8 range)
{
//white background:
putc(0x72); //command
putc(0); //top left horisontal start coordinate MSB
putc(190); //top left horisontal start coordinate LSB
putc(0); //top left vertical start coordinate MSB
putc(9); //top left vertical start coordinate LSB
putc(1); //bottom right horisontal end coordinate MSB
putc(53); //bottom right horisontal end coordinate LSB
putc(0); //bottom right vertical end coordinate MSB
putc(34); //bottom right vertical end coordinate LSB
putc(0xFF); //backround color white
putc(0xFF);
com_ok();
//first clean old value:
putc(0x73); //cmd draw text string
putc(17); //column in character units
putc(0x01); //row in character units
putc(0x03); //font 8 x 12
putc(0x00); //string colour msb = black
putc(0x00);
printf("%s"," ");
putc(0x00); //string terminator
com_ok();
//then write new value:
putc(0x73); //cmd draw text string
putc(17); //column in character units
putc(0x01); //row in character units
putc(0x03); //font 8 x 12
putc(0x00); //string colour msb = black
putc(0x00); //black lsb
switch (range)
{
case 1:
printf("20-200Hz");
break;
case 2:
printf("0.2-2kHz");
break;
case 3:
printf("2-20kHz");
break;
case 4:
printf("..200kHz");
break;
}
putc(0x00); //string terminator
com_ok();
}
//************************************************************************************************
void wr_divider(int8 divider)
{
//clear divider area white backround
putc(0x72); //command
putc(0); //top left horisontal start coordinate MSB
putc(190); //top left horisontal start coordinate LSB
putc(0); //top left vertical start coordinate MSB
putc(124); //top left vertical start coordinate LSB
putc(1); //bottom right horisontal end coordinate MSB
putc(53); //bottom right horisontal end coordinate LSB
putc(0); //bottom right vertical end coordinate MSB
putc(144); //bottom right vertical end coordinate LSB
putc(0xFF); //backround color white
putc(0xFF);
com_ok();
//first clean old value:
putc(0x73); //cmd draw text string
putc(17); //column in character units
putc(8); //row in character units
putc(0x03); //font 8 x 12
putc(0x00); //string colour msb = black
putc(0x00); //black lsb
printf(" ");
putc(0x00); //string terminator
com_ok();
putc(0x73); //cmd draw text string
putc(17); //column in character units
putc(8); //row in character units
putc(0x03); //font 8 x 12
putc(0x00); //string colour msb = black
putc(0x00); //black lsb
switch (divider)
{
case 0:
printf(" 0 dB ");
break;
case 1:
printf(" -20 DB ");
break;
case 2:
printf(" -40 dB ");
break;
}
putc(0x00); //string terminator
com_ok();
}
//************************************************************************************************
int8 screen_1(void)
{
int8 x_coord_LSB, x_coord_MSB,y_coord_LSB,y_coord_MSB;
int16 x_place,y_place;
char text[12];
backlight_colour(0x867D); //backlight colour sky blue
putc(0x45); com_ok(); //clear screen
delay_ms(1000);
en_touch_screen();
touch_region(75,243,62,178); //detect touch region, buttons area only
do
{
//button area 75,62 ...243,99
/*state=TRUE;
x_TOP_LEFT = 75;
y_TOP_LEFT = 62;
colour = 0x9772; //lightgreen
size = 3;
text_colour = 0xF800;*/ //red
strcpy(text,"ANALOG ");
draw_button(TRUE,75,62,0x9772,3,0xF800,text);
strcpy(text,"DIGITAL");
draw_button(TRUE,75,142,0x9772,3,0x0000,text);
//en_touch_screen();
//touch_region(75,243,62,178); //detect touch region, buttons area only
//wait until touch press forever:
putc(0x6F); //cmd
putc(0x01); //get touch coordinates
while(!kbhit(LCD))
delay_us(1);
x_coord_MSB = getc(LCD); //read character from UART
x_coord_LSB = getc(LCD); //read character from UART
y_coord_MSB = getc(LCD); //read character from UART
y_coord_LSB = getc(LCD); //read character from UART
x_place = make16( x_coord_MSB,x_coord_LSB);
y_place = make16( y_coord_MSB,y_coord_LSB);
}while((y_place > 99) & (y_place < 142)); //centre area not in use
touch_region(0,319,0,239); //detect touch region, whole display
if(y_place <99)
return 1;
else
return 2;
}
//************************************************************************************************
void draw_button(short int state,int16 x_TOP_LEFT,int16 y_TOP_LEFT,int16 colour,
int8 size,int16 text_colour, char text[])
{
//draw text button 1
putc(0x62); //cmd
putc(state); //button up or down
putc(x_TOP_LEFT>>8); //top left horizontal pos byte MSB
putc(x_TOP_LEFT); //top left horizontal pos byte LSB
putc(y_TOP_LEFT>>8); //top left horizontal pos byte MSB
putc(y_TOP_LEFT); //top left horizontal pos byte LSB
putc(colour>>8); //button colour MSB
putc(colour); //button colour LSB
putc(0x01); //font 8x12
putc(text_colour>>8); //text colour MSB
putc(text_colour); //text colour LSB
putc(size); //widht x magnification
putc(size); //height y magnification
printf(text);
putc(0x00); //string terminator
com_ok();
}
//************************************************************************************************
void com_ok(void)
{
int8 i;
int8 response;
while(!kbhit(LCD))
delay_us(1);
response = getc(LCD); //read character from UART
goto ohi;
if(response == 0x06)
{ for(i=0;i<5;++i){output_high(PIN_A5); delay_ms(30); output_low(PIN_A5);
delay_ms(30);}}
ohi:
if(response != 0x06)
{for(i=0;i<5;++i){output_low(PIN_A5); delay_ms(300); output_high(PIN_A5);
delay_ms(300);}}
//delay_ms(15);
}
//************************************************************************************************
#INT_EXT
void RB_isr(void) //this make reset
{
output_low(PIN_A4); //reset
delay_ms(6000);
output_high(PIN_A4); //lcd on
}
//************************************************************************************************
void autobaud(void)
{ putc(0x55); com_ok();}
//************************************************************************************************
void display_on(void)
{putc(0x59); putc(0x01); putc(0x01); com_ok();}
//************************************************************************************************
void display_off(void)
{putc(0x59); putc(0x01); putc(0x00); com_ok();}
//************************************************************************************************
void backlight_off(void)
{putc(0x59); putc(0x00); putc(0x00); com_ok();}
//************************************************************************************************
void backlight_on(void)
{putc(0x59); putc(0x00); putc(0x01); com_ok();}
//************************************************************************************************
void backlight_colour(int16 bck_colour)
{
putc(0x4B); //cmd
putc(bck_colour >> 8); //MSB
putc(bck_colour); //LSB
com_ok();
}
//************************************************************************************************
void en_touch_screen(void)
{
putc(0x59); //cmd
putc(0x05); //touch control, enable touch screen
putc(0x00); //touch control, enable touch screen
com_ok();
}
//************************************************************************************************
void touch_region(int16 x1,int16 x2,int16 y1,int16 y2)
{
putc(0x75); //cmd
putc(x1>>8); //x1 = top left hor start pos.pixels MSB
putc(x1); //x1 = top left hor start pos.pixels LSB
putc(y1>>8); //y1 = top left vert start pos.pixels MSB
putc(y1); //y1 = top left vert start pos.pixels LSB
putc(x2>>8); //x2 = bottom right hor end pos.pixels MSB
putc(x2); //x2 = bottom right hor end pos.pixels LSB
putc(y2>>8); //y2 = bottom right vert end pos.pixels MSB
putc(y2); //y2 = bottom right vert end pos.pixels LSB
com_ok();
}
//************************************************************************************************
void sel_wavemode(int8 wave) //select sine, triangle or square wave mode
{
//default sine wave:
output_low(triangle_rel); //triangle wave OFF, sine wave ON
delay_ms(50);
output_low(square_rel); //square wave OFF
delay_ms(50);
output_low(sine_rel); //sine filter ON
delay_ms(50);
switch(wave)
{
case 1: //default sine wave
break;
case 2: //triangle wave
output_high(sine_rel); //sine filter OFF
delay_ms(50);
output_high(triangle_rel); //triangle wave ON, sine wave OFF
delay_ms(50);
break;
case 3: //square wave
output_high(sine_rel); //sine filter OFF
delay_ms(50);
output_high(square_rel); //square wave ON
delay_ms(50);
break;
}
}
//************************************************************************************************
void freq_area(int8 freq_area) /*frequency area 1...4: 20Hz,200Hz,2kHz and 20 kHz
also corresponding filter selected*/
{
//first all the relays OFF:
output_low(rel_20Hz);
delay_ms(50);
output_low(rel_200Hz);
delay_ms(50);
output_low(rel_2kHZ);
delay_ms(50);
output_low(rel_20kHZ);
delay_ms(50);
switch(freq_area)
{
case 1: output_high(rel_20Hz); //20...200 Hz frequency area selected
delay_ms(50);
break;
case 2: output_high(rel_200HZ); //200...2kHz frequency area selected
delay_ms(50);
break;
case 3: output_high(rel_2kHz); //2kHz...20kHz frequency area selected
delay_ms(50);
break;
case 4: output_high(rel_20kHZ); //20kHz...200kHz frequency area selected
delay_ms(50);
break;
}
}
//************************************************************************************************
void atten_rel(int8 atten) //signal attenuation 0, -20, -40 or -60 dB
{
//first both the relays ON, attenuation = -60 dB:
output_high(rel_20dB);
delay_ms(50);
output_high(rel_40dB);
delay_ms(50);
switch(atten)
{
case 0: //no attenuation
output_low(rel_20dB);
delay_ms(50);
output_low(rel_40dB);
delay_ms(50);
break;
case 1: output_high (rel_20dB); //-20 dB attenuation
delay_ms(50);
output_low (rel_40dB);
delay_ms(50);
break;
case 2:
output_high (rel_40dB); //-40 dB attenuation
delay_ms(50);
output_low (rel_20dB);
delay_ms(50);
break;
case 3:
//-60 dB attenuation, both relays ON
break; }
}
//************************************************************************************************ |
|
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Sep 13, 2012 9:47 am |
|
|
Post the shortest possible complete and compilable code which shows your problem.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Thu Sep 13, 2012 10:20 am |
|
|
Mike Walne wrote: | Post the shortest possible complete and compilable code which shows your problem.
Mike |
thank's for your answer...
I'll try to make my code shorter ...
but idea is that touch screen controls those digital pot inputs
I'm busy next weekend ... I'll make my source file shorter and
more understandable later next week...
but problem is it do not remember dig. pot. setting after power up
good weekend for you |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Sep 13, 2012 11:57 am |
|
|
with ext oscillator
change your NOPUT fuse to PUT
AND
Code: |
output_low(pot_cs); //dig. pot selected
delay_ms(10);
output_high(pot_inc); //store wiper position
delay_ms(10);
output_high(pot_cs); //dig. pot selected
delay_ms(10);*/
.......
output_high(pot_cs); //dig. pot not selected
output_high(pot_up_down); //dig.pot wiper up, makes offset V lower!
delay_ms(10);
output_high(pot_inc); //pulse dig. pot
delay_ms(10);
output_low(pot_cs); //dig. pot selected
output_low(pot_inc); //no store ... return to standby
delay_ms(10);
output_high(pot_cs); //dig. pot NOT selected
delay_ms(10);
|
do you think your delays are long enough ?????
this would be a safe settling time if your pot is located 1000 ft from the pic
![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Fri Sep 14, 2012 3:34 am |
|
|
asmboy wrote: | with ext oscillator
change your NOPUT fuse to PUT
AND
Code: |
output_low(pot_cs); //dig. pot selected
delay_ms(10);
output_high(pot_inc); //store wiper position
delay_ms(10);
output_high(pot_cs); //dig. pot selected
delay_ms(10);*/
.......
output_high(pot_cs); //dig. pot not selected
output_high(pot_up_down); //dig.pot wiper up, makes offset V lower!
delay_ms(10);
output_high(pot_inc); //pulse dig. pot
delay_ms(10);
output_low(pot_cs); //dig. pot selected
output_low(pot_inc); //no store ... return to standby
delay_ms(10);
output_high(pot_cs); //dig. pot NOT selected
delay_ms(10);
|
do you think your delays are long enough ?????
this would be a safe settling time if your pot is located 1000 ft from the pic
![Very Happy](images/smiles/icon_biggrin.gif) |
Changing NOPUT fuse to PUT (power up timer) did not help
Ok my delays are rather long but these are only for test purposes
I'll trim tose delays maybe to 10us
![Embarassed](images/smiles/icon_redface.gif) |
|
![](templates/subSilver/images/spacer.gif) |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Fri Sep 14, 2012 4:25 am |
|
|
asmboy wrote: | with ext oscillator
change your NOPUT fuse to PUT
AND
Code: |
output_low(pot_cs); //dig. pot selected
delay_ms(10);
output_high(pot_inc); //store wiper position
delay_ms(10);
output_high(pot_cs); //dig. pot selected
delay_ms(10);*/
.......
output_high(pot_cs); //dig. pot not selected
output_high(pot_up_down); //dig.pot wiper up, makes offset V lower!
delay_ms(10);
output_high(pot_inc); //pulse dig. pot
delay_ms(10);
output_low(pot_cs); //dig. pot selected
output_low(pot_inc); //no store ... return to standby
delay_ms(10);
output_high(pot_cs); //dig. pot NOT selected
delay_ms(10);
|
do you think your delays are long enough ?????
this would be a safe settling time if your pot is located 1000 ft from the pic
![Very Happy](images/smiles/icon_biggrin.gif) |
HI,
I found this dokument
"Understanding the Xicor 3-wire XDCP Interface"
http://www.datasheetcatalog.com/datasheets_pdf/A/N/9/2/AN92.shtml
When I have time I gonna experiment its advice |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Fri Sep 14, 2012 7:01 am |
|
|
the MCP4141 might be a better part to use as it avoids the sloppy consumer up/down interface of the part you presently have selected |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Fri Sep 14, 2012 9:05 am |
|
|
Just stepping back, there are a few things in the code that could be causing really problematic behaviour.
The #INT_EXT directive, is meant to be followed immediately by the routine called by the interrupt. You have it once sitting at the top of the code, and the first routine after it is the function prototype for com_ok. Then again later in the code with a routine....
Then as a comment, the code layout is foul. the idea is that you indent more when you have a separate code section.
As an example:
Code: |
void com_ok(void) {
int8 i;
int8 response;
while(!kbhit(LCD))
delay_us(1); //This is a separate piece of code, dependant on the while
response = getc(LCD); //read character from UART
//Don't use GOTO's _unless these are essential, they are bad
//programming - they would get you fired from some companies, and
//lose marks on most university courses.....
//As written this code always jumps past the next section, so remove it....
if(response != 0x06) {
for(i=0;i<5;++i){
output_low(PIN_A5);
delay_ms(300);
output_high(PIN_A5);
delay_ms(300);
}
}
}
|
Bad layout in the code, makes errors more likely, and harder to find.
Then the comment already made about code size. The routines to talk to the pot need only be a few lines, when trying to debug something, remove everything else....
I've used these pot's in the past to control things like LCD contrast, and they are fine. The key thing is to understand the sequencing of CS.
All you do is:
First set all lines high on boot.
Ideally have pull up resistors, so the lines 'float high' when not driven, before the processor wakes.
To increment the pot.
Raise U/D
Drop CS
Drop INC
Raise CS
Raise INC
To decrement the pot
Drop U/D
Drop CS
Drop INC
Raise CS
Raise INC
To store the pot
Drop CS
Raise CS
The 'key' is that it is raising CS, while INC is high, which stores the position. By not raising INC, till after CS is raised, the normal transactions don't store the position. Since INC is left high, the 'not recommended' states do not get called, but simply dropping CS, and raising it again saved the current position.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
artohautala
Joined: 17 Nov 2011 Posts: 187
|
|
Posted: Sat Sep 15, 2012 8:03 pm |
|
|
Very many thanks for good advices !
It's clear that using GOTOS is very bad practise but this is only evaluation version to develop final software. For same reason I forgot line INT_EXT
to my code.
I've tried CS INC and U/D in many order but seems there's almost always one or more "ghost" pulses after powering up...
So I decided to use pullup resistors for dig.pot. input pins...
maybe rather big ohms ...10 kohms perhaps or even bigger
I know it's "legal" to use pullup resistors only for open collector outputs...
Does my PIC chip C-port fail if I solder rather big ohm > 10 k pullup resistor to Vcc + 5 V ?
(I know better practise would be using digital transistors with collector resistors to Vcc but then I have to make rather big changes to my PCB layout )
thks for your patience and good advices
-arto- |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|