Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

0 Neutral

About Dave_H

  • Rank
  1. Hi, I've looked around although can't see any other posts on this - I have certain Code Tree entries coloured red - why is this? Thanks D
  2. Hi I've fixed the problem by changing the subroutine to int values and by changing the return result to a short after searching ad problems from the forum this seems to have fixed the problem. I'll go back and change things one at a time next to find where exactly the problem was. Chisterz. What is the problem that you have been facing ?(I'll see if I can help ??!!) I tend to send the results to an LCD display to show the actual result from the a/d conversion. I'll have a play at writing the value to eeprom thanks for the tip. I have been using the eeprom memory to store recipe information for timers and other values which does save and recall values correctly see if this help . /* This function will hold 10 recipes with 5 data values which have been setup within the main function. The files are placed into an array for easier storage and easier unstorage. The I.C has a eeprom memory size of 256byte which will hold 51 recipes conbinations 'IF REQUIRED'*/ #include<system.h> #include"Eeprom memory storage.h" unsigned char stored_values[5]; // five timer values required to save per recipe unsigned power_stored; unsigned char value1; // READ value to eeprom memory unsigned short read_eeprom(unsigned char addr) { eeadr = addr; // low byte eeadrh = 0; // high byte clear_bit(eecon1,EEPGD); // select eeprom memory set_bit(eecon1,RD); // set read bit return(eedata); } // WRITE value to eeprom memory unsigned int write_eeprom(unsigned char addr,unsigned int data) { eeadrh = 0; // high byte eeadr = addr; // low byte eedath = 0; // high byte eedata = data; // low byte clear_bit(eecon1,EEPGD); // select eeprom data memory set_bit(eecon1,WREN); // enable write eecon2 = 0x55; eecon2 = 0xaa; set_bit(eecon1,WR); // write command while(eecon1&2); // wait untill writing is ready clear_bit(eecon1,WREN); // disable write } unsigned int Send_values_to_memory(unsigned char start_address) { int i=0; for ( i=0; i < 5; i++ ) { write_eeprom(start_address,stored_values[i]);// write values to eeprom memory start_address++; } // Save 16 bit number to, two 8 bit EEPROM addresses write_eeprom(start_address,(unsigned char)power_stored); // load power level to memory first 8 bits start_address++; // increment holding address write_eeprom(start_address,(unsigned char)(power_stored>>8)); // Load power level to memory second 8 bits } /* This function will hold 10 recipes with 5 data values which have been setup within the main function. The files are placed into a array for easier storage and easier unstorage*/ unsigned int write_to_memory (unsigned char pre_weld,unsigned char pre_warm_time,unsigned char weld_time,unsigned char dwell_time, unsigned int powerlevel,char save) { stored_values[0]=pre_weld; stored_values[1]=pre_warm_time; stored_values[2]=weld_time; stored_values[3]=dwell_time; power_stored= powerlevel; switch(save) { case 1 : Send_values_to_memory(0x00); break; case 2 : Send_values_to_memory(0x08); break; case 3 : Send_values_to_memory(0x0E); break; case 4 : Send_values_to_memory(0x14); break; case 5 : Send_values_to_memory(0x19); break; case 6 : Send_values_to_memory(0x1E); break; case 7 : Send_values_to_memory(0x23); break; case 8 : Send_values_to_memory(0x28); break; case 9 : Send_values_to_memory(0x2D); break; case 10 : Send_values_to_memory(0x32); break; } } unsigned char read_from_memory(char program_number) { switch(program_number) { case 1 : reload_values_from_memory(0x00); break; case 2 : reload_values_from_memory(0x08); break; case 3 : reload_values_from_memory(0x0E); break; case 4 : reload_values_from_memory(0x14); break; case 5 : reload_values_from_memory(0x19); break; case 6 : reload_values_from_memory(0x1E); break; case 7 : reload_values_from_memory(0x23); break; case 8 : reload_values_from_memory(0x28); break; case 9 : reload_values_from_memory(0x2d); break; case 10 : reload_values_from_memory(0x32); break; } } I hope this helps Dave Dave
  3. Hi I been trying to control a servo motor by using two analog ports as feedbacks to give the motors actual direction. I.E if analog port 2 is greater than 3 go clockwise. If 3 is greater than 2 go anticlockwise. But for some reason when the number exceed 255 on ethier port the motor changes direction as it is looping back to zero (0-255). I understand that I need to use a 16 bit int to get the whole range that I require which I thought I had done. The number appear correctly upon an LCD screen when 5v=1023 on both ports. So I'm not sure exactly what I'm doing wrong?? help ?????????????? First the program get the two results of mag_plus and mag_minus to find intially what is greater while(1) { // get mag_minus and mag_plus results Fwd_power(); mag_minus(); mag_plus(); if(fwd>3) // RF power is greater than 0.3V enable matchnet { set_bit(portb,1); // Turn on led tune_ca_left(); // Tune motor CA clockwise tune_ca_right(); // turn motor CA anticlockwise } else { clear_bit(portb,1); } } Then the program jumps to ethier loop depending on what is greater unsigned char tune_ca_left() { while(mag_p>mag_m) // is mag_p greater than mag_m { mag_minus(); // get mag_minus result mag_plus(); // get mag plus result set_bit(portb,4);// set motor direction intially set_bit(portb,5);// turn motor clockwise } } unsigned char tune_ca_right() { while(mag_m>mag_p) { mag_minus(); mag_plus(); set_bit(portb,5); clear_bit(portb,4);// set motor direction ??? delay(3000); } } mag_minus/mag_plus get the cursor position and get the returned result unsigned char mag_plus() { lcd_cursor(0,0); // Set cursor top left hand position mystrcpy(name2,magplus); // put magplus name on screen mag_p=ad_Channel_2(); // go analog routine and return result to mag_p } unsigned char mag_minus() { lcd_cursor(0,1); mystrcpy(name2,magminus); mag_m=ad_Channel_3(); } The routine then jumps to ad 2/3 to get the results to return unsigned int ad_Channel_2() //Channel_2 of A/D PORT RA2 mag_plus readback { unsigned int CH2_adcon0=0x15; // Select channel 2 unsigned int result; result= read_adc0(CH2_adcon0); // analog conversion result display1_value(result,2,0); // Display result and position on screen correctly return result; } unsigned int ad_Channel_3() //Channel_3 of A/D PORT RA3 mag_minus readback { unsigned int CH3_adcon0=0x1d; // Select channel 3 unsigned int result; result= read_adc0(CH3_adcon0); // analog conversion result display1_value(result,2,1); // Display result and position on screen correctly return result; } Then to get the analog routine to get the result unsigned char ADCRESL@0x9e; // control reg for A/D unsigned char ADCRESH@0x1e; int read_adc0 (unsigned char adcon_0 ) // Main A/D conversion sub { unsigned char h, l =0; unsigned int result=0; adcon0 = adcon_0 & 0xFb; /* Switch ADC channel*/ ad_delay(100); adcon0 = adcon0 + 0x04; //start conversion while ( adcon0 & 0x04 );//spin while the conversion runs h = ADCRESH; l = ADCRESL; result = (256 * h) + l; // Add high byte-to-low return result; } If anyone can see what I'm doing wrong I would be very grateful as I cannot find the problem Many thanks in advance Dave H
  4. I'm using a 16F877A. The first test was done using vdd . The second set of tests where done using vref on analog 3. After changing the adcon setting . Dave
  5. Hi DaveT I tried it with 5V ref on AN3 and also get a response of 1023 @ 5V. But again if I move the voltage down to 2.5V the response come out as 574 not 511. also 1V = 240 2V = 480 3V = 655 4V = 896 5v = 1023 I trying to control an amplifier which requires a D-A setpoint between 0-5 V. Which Then give an actual value back between 0-5V. Many thanks Dave H
  6. Hi thankyou for the reply 5V direct from a thandor test supply. VREF+ = 5v VDD VREF- = 0V VSS ADCON1=0X82; AN0-AN4=ANALOG. AN5-AN7 DIGITAL. I assumed that the ADC is 10bits wide once ADRESH and ADRESL is added together before the result is returned ?? Dave
  7. Hi I've beening testing the response from an A/D input RA0. By putting the result directly onto an LCD display. but it does not seem to be as linear as I expected . Here are the results that I've achieved. Tested using DC bench supply. 1.0V = 192 2.0V = 384 2.5V = 480 3.0V = 527 4.0V = 704 5.0V = 824 I assumed that @ 2.5V the digital response would be around 412 counts but it seems to be a long way out. It also seems to jump periodically in larger increment when you increment slowly from 0-5V. I've added filtering caps and resistors to the input but this does not seem to make any difference. Here is the code that I have been using #include<system.h> #include"AD channels.h" unsigned char ADCRESL@0x9e; // control reg for A/D unsigned char ADCRESH@0x1e; int ad_delay(int loop)// Allow A/D to settle { int t; for(t=0;t<loop;t++); } unsigned int display1_value (unsigned int value,char position) { // first get the digits unsigned int thou,hunds, tens, units; // first get the digits units= value % 10; value= value/10; tens= value % 10; value= value/10; hunds= value % 10; value= value / 10; thou = value % 10; lcd_cursor(position,1); // Result position upon on display lcd_print_ch ('0' + thou); lcd_print_ch ( '0' + hunds ); lcd_print_ch ( '0' + tens ); lcd_print_ch ( '0' + units ); } int read_adc0 (char adcon_0 ) // Main A/D conversion sub { unsigned char h, l =0; int result=0; adcon0 = adcon_0 & 0xFb; /* Switch ADC channel*/ ad_delay(15); adcon0 = adcon0 + 0x04; //start conversion while ( adcon0 & 0x04 );//spin while the conversion runs h = ADCRESH; l = ADCRESL; result = (256 * h) + l; // Add high byte-to-low return result; } unsigned char ad_Channel_0() //Channel_0 of A/D PORT RA0 Set for forward power readback { unsigned CH0_adcon0=0x05; // Select channel 1 unsigned int result; result= read_adc0(CH0_adcon0); // analog conversion result display1_value(result,4); // Display result and position on screen correctly } Can anybody spot what I'm doing wrong ? Many thanks for any help recieved Dave_H
  • Create New...