Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
December 09, 2016, 08:17:56 20:17


Login with username, password and session length


Pages: [1]
Print
Author Topic: MC145170 Source C  (Read 4523 times)
0 Members and 1 Guest are viewing this topic.
folkeu
Active Member
***
Offline Offline

Posts: 134

Thank You
-Given: 84
-Receive: 155


« on: July 15, 2009, 11:51:29 11:51 »

Hello,

Somebody have a source in C for MCC18, Hi-tech, mikroC for drive a MC145170 (PLL)?
Google help me not !
@+
Logged
ipek
Junior Member
**
 Muted
Offline Offline

Posts: 95

Thank You
-Given: 54
-Receive: 79


« Reply #1 on: July 18, 2009, 03:36:22 15:36 »

http://www.geocities.com/hagtronics/2_meter.html
only CCSC code easy convert any C

http://www.geocities.com/hagtronics/2_meter.c

//==================================================================
//=====                            =====
//=====              2 Meter Receiver Program                  =====
//=====              By: Steve Hageman 29Mar98                 =====
//=====            www.sonic.net/~shageman             =====    
//==================================================================
//=====          Copyright 1998 by Steven C. Hageman           =====
//=====                 All rights reserved                    =====
//==================================================================
//=====  Version: 0.0 - Initial Writing - 29Mar98              =====
//=====  Version: 1.0 - First release - 19Sep98                =====
//==================================================================


//-----< Include Files, setup fuses >-----
#include <16c73a.h>
#include <stdio.h>
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT


//-----< Compiler use statements >-----
// Tell compiler clock speed, baud, and Hardware UART pins
#use delay(clock=10000000)          
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)


//-----< Port location defines >-----
#pragma byte port_a = 0x05
#pragma byte port_b = 0x06
#pragma byte port_c = 0x07


//-----< Pin defines >-----
#pragma bit AUDIO_PIN    = port_a.2   // Audio override pin
#pragma bit A_SW    = port_b.0   // Encoder A switch input         
#pragma bit B_SW        = port_b.1   // Encoder B switch input
#pragma bit INC_SW   = port_b.2   // Freq increment select switch
#pragma bit SCAN_SW   = port_b.3   // Scan select switch
#pragma bit RS232_PIN   = port_c.7   // RS232 input pin


//-----< MC145170 PLL Chip Pins >-----
#pragma bit DIN    = port_b.5
#pragma bit CLK    = port_b.6
#pragma bit EN       = port_b.7


//-----< General Program Defines >-----

#define DOOMSDAY   0   // Not here yet!
#define AUDIO_OFF    1   // Set AUDIO OFF
#define AUDIO_ON   0   // Set AUDIO ON
#define PUSHED      0   // For switched closed sense
#define   RSSI      0   // Analog input for RSSI
#define SQUELCH      1   // Analog input for squelch pot
#define BAT      3   // Analog input for battery voltage
#define EOT      255   // End of RS232 transmission character


//-----< Global Variables >-----
unsigned long Channel;      // PLL channel number 0 - 799 for 5 kHz steps
int Increment;         // Frequency increment (in channel units)
int Changed;         // Frequency changed flag
int Rssi_val;         // RSSI A/D value
int Squelch_val;      // Squelch pot setting
int Bat_val;         // Battery voltage value
int Keep_scanning;      // Flag used during scanning


//-----< LCD Routines >----------------------------------------------

// LCD is connected to port c, definitions below

// LCD Connections -
//   C5  C4    C3   C2   C1   C0 - PORT PINS
//   E   R/S   D7   D6   D5   D4 - LCD PINS


void blip_e_delay()
{
   // Set enable high for 2 cycles then low
   // Minimum E cycle time is 450 nS.
   #asm
      bsf port_c,5
      nop
      nop
      bcf port_c,5
   #endasm
   
   // Wait for longest lcd routine to finish, takes time
   // but saves code in not checking for the busy flag.
   delay_ms(5);
}

void blip_e()
{
   // Set enable high for 2 cycles then low
   // Minimum E cycle time is 450 nS.
   #asm
      bsf port_c,5
      nop
      nop
      bcf port_c,5
   #endasm
   
   // Wait for shortest lcd routine to finish, takes time
   // but saves code in not checking for the busy flag.
   delay_us(50);
}

void first_line()
{
   // Set the LCD to the first display line
   // Send 0x80 for first line.
   port_c = 0x08;
   blip_e();
   
   port_c = 0x00;
   blip_e();
}

void second_line()
{
   // Set the LCD to the second display line
   // Send 0xc0 for second line.
   port_c = 0x0c;
   blip_e();
   
   port_c = 0x00;
   blip_e();
}

void init_lcd()
{
   // Clear and initilize LCD panel to 4 bit mode
   // two line mode, cursor off, display on.
   // RS needs to be low for all of these instructions.
   // -> Takes 60 mS to complete <-
      
   // Send 0x03 three times
   port_c = 0x03;
   blip_e_delay();
   
   port_c = 0x03;
   blip_e_delay();

   port_c = 0x03;
   blip_e_delay();

   // Send 0x02
   port_c = 0x02;
   blip_e_delay();
   
   // send 0x28
   port_c = 0x02;
   blip_e_delay();
   
   port_c = 0x08;
   blip_e_delay();
   
   // send 0x01
   port_c = 0x00;
   blip_e_delay();
   
   port_c = 0x01;
   blip_e_delay();

   // send 0x06
   port_c = 0x00;
   blip_e_delay();
   
   port_c = 0x06;
   blip_e_delay();

   // send 0x0c
   port_c = 0x00;
   blip_e_delay();
   
   port_c = 0x0c;
   blip_e_delay();

   // Send 0x0f to set cursor on with blink
   // Send 0x0e to set cursor on w/o blink

   // Clean up port on exit
   port_c = 0x00;
}

void write_lcd(byte ch)
{
   // writes the char ch to the lcd. HB then LB.
   // The OR sets RS high
   port_c = (ch/0x10) | 0x10;         
   blip_e();
   port_c = (ch & 0x0f) | 0x10;
   blip_e();
   
   // Clean up port on exit
   port_c = 0x00;
}


void display_frequency(void)
{
unsigned long freq;

   // Calculate actual frequency
   freq = Channel*5 + 4000;
         
   // Write frequency to display
   first_line();
   write_lcd("14");
   write_lcd((int)(freq / 1000) + '0');
   write_lcd('.');
   write_lcd((int)((freq / 100) % 10) + '0');
   write_lcd((int)((freq / 10) % 10) + '0');
   write_lcd((int)(freq % 10) + '0');
   write_lcd(" MHz");
   
   // Write increment to display
   switch(Increment)
   {
      case 0:
         write_lcd(" Lock");
         break;
               
      case 1:
         write_lcd("   5k");
         break;
         
      case 2:
         write_lcd("  10k");
         break;
            
      case 20:
         write_lcd(" 100k");
         break;
               
      case 200:
         write_lcd("   1M");
         break;
   }
}


//-----< PLL Routines >----------------------------------------------
   
void setup_pll(void)
{

// PLL setup routine, only needs to be done once, at startup.
// Note: Until control register is set, the PIC clock will be running at
// 1.25 MHz.

   //----- Initilize PLL -----
   // EN High, Din Low, 4 clocks
   CLK = 0;
   DIN = 0;
   EN = 1;

   CLK = 1;
   CLK = 0;   

   CLK = 1;
   CLK = 0;   

   CLK = 1;
   CLK = 0;   

   CLK = 1;
   CLK = 0;   

   // EN Low, Din Low (except clock 4 = 1), 5 clocks
   DIN = 0;
   EN = 0;

   CLK = 1;
   CLK = 0;   

   CLK = 1;
   CLK = 0;   

   CLK = 1;
   CLK = 0;   

   DIN = 1;
   CLK = 1;
   CLK = 0;
   DIN = 0;   

   CLK = 1;
   CLK = 0;   

   EN = 1;
   // PLL is now reset
   
   //----- Setup C Reg with proper bits -----
   EN = 0;
   
   // Bit 7 - PD Polarity
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   // Bit 6 - PD Output
   DIN = 1;
   CLK = 1;
   CLK = 0;
   
   // Bit 5 - Lock Detect Off
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   // Bit 4, 3, 2 - Ref divider output (001 = /1)
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   DIN = 1;
   CLK = 1;
   CLK = 0;

   // Bit 1 - FV off -- NOTE: Set this bit high to get
   // the N counter out on pin 10.
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   // Bit 0 - FR off -- NOTE: Set this bit high to get
   // the PD ref frequency on pin 9.
   DIN = 0;
   CLK = 1;
   CLK = 0;
   DIN = 0;
   // EN back high
   EN = 1;

   // Note: The PIC clock will now be 10 MHz
   
   //----- Setup Ref Divider -----
   // 10 MHz / 2000 = 5 KHz (2000 = 0x07d0)
   EN = 0;

   // BIT 14-12 = 000
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   // BIT 11-8 = 0111    
   CLK = 1;
   CLK = 0;
   
   DIN = 1;
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   // BIT 7-4 = 1101
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   DIN = 1;
   CLK = 1;
   CLK = 0;
   
   // BIT 4-0 = 0000
   DIN = 0;
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   CLK = 1;
   CLK = 0;
   
   // Enable Back High
   EN = 1;
}   


void tune_pll(void)
{
int ctr;
unsigned long n_reg;

   // Convert channel number to N counter value
   n_reg = Channel + 30940;

   // Set clock, enable low
   CLK = 0;
   EN = 0;
   
   // Shift in channel frequency to N reg (MSB first)
   for( ctr = 0 ; ctr <= 15 ; ctr++)
   {
      // Decompose the PLL N value into bits, set data pin
      DIN = shift_left(&n_reg, 2, 0);
      
      // Cycle the clock
      CLK = 1;
      CLK = 0;   
   }
   
   // Clean up and set enable high which
   // transfers count to N reg
   DIN = 0;
   EN = 1;

}

//-----< Set Analog Globals >----------------------------------------
void update_analog(void)
{
   // Read all the analog channels and set their global variables
   set_adc_channel(RSSI);
   delay_us(20);
   Rssi_val = read_adc();
   
   // Bound the value, so it does not interfere with RS232 'EOT'.
   // As design was orginaly done, this won't ever hapen.
   // I put this here just in case something is changed.
   if( Rssi_val == 255 )
      Rssi_val = 254;

   set_adc_channel(SQUELCH); // The /4 scales the squelch range
   delay_us(20);        // to match the RSSI range
   Squelch_val = read_adc()/4;
   
   set_adc_channel(BAT);
   delay_us(20);

   Bat_val = read_adc();
   
   // Bound the value, so it does not interfere with RS232 'EOT'.
   if( Bat_val == 255 )
      Bat_val = 254;

}


//-----< RS232 Control loop >-----------------------------------------
void rs232_mode(void)
{
char buf;
int hb, lb;

   // We just stay in this routine forever!
   
   // Update LCD display
   write_lcd("-- Hagtronics --");
   second_line();
   write_lcd("-- RS232 Mode --");
   
   while(!DOOMSDAY)
   {
      // Get command
      buf = getc();
         
      // Process command
      switch(buf)
      {
         case 'A':   // Set Audio
         {
            // Say first char was OK
            putc(EOT);
            
            // Get mode
            buf = getc();
            
            switch(buf)
            {
               case 'N': // Set audio on
                  AUDIO_PIN = AUDIO_ON;
                  putc(EOT);
                  break;
               
               case 'F': // Set audio off
                  AUDIO_PIN = AUDIO_OFF;
                  putc(EOT);
                  break;
               
               default: // What did they want?
                  putc('?');
                  putc(EOT);
                  break;
            }
         break;
         }
         
         case 'C':   // Channel Set
         {
            // Say first char was OK
            putc(EOT);
            
            // Get channel bytes  HB, LB
            hb = getc();
            
            // Say HB was OK
            putc(EOT);
            
            // Get LB
            lb = getc();
            
            // Say it was good!
            putc(EOT);
            
            // Figure channel number
            Channel = hb * 256 + lb;

            // Set N Reg with frequency
            tune_pll();
         
            break;
         }
         
         case 'D': // Write data valid status out
         {
            //Send back current signal levels
            update_analog();   
            putc(Rssi_val);
            putc(Bat_val);
            putc(EOT);
            break;
         }

         default:  // Say char was not understood
         {
            putc('?');
            putc(EOT);
         }
                     
      } // End of first char switch

   } // End of main while
}


void update_audio(void)
{
   // Decide if RSSI level is greater than the squelch level
   // This will determine if the audio needs to be turned on or not
   
   // Get current RSSI and squelch value
   update_analog();
   
   if(Rssi_val >= Squelch_val)
   {
      // Set audio on
      AUDIO_PIN = AUDIO_ON;
   }
   else
   {
      // Set audio off
      AUDIO_PIN = AUDIO_OFF;
   }
}

//-----< Scanning routine >------------------------------------------
// Note: Scan is also killed by turning the tune knob
void scan(void)
{
int ctr;

   // Turn off audio to start with
   AUDIO_PIN = AUDIO_OFF;
   
   // Initilize variable
   Keep_scanning = TRUE;
   
   // Scan till the cows come home
   while(Keep_scanning == TRUE)
   {
      
      // Increment channel
      Channel += Increment;
            
      // Bound the channel values -- implements roll over
      if( Channel > 60000 )   // Catch unsigned underflow
         Channel = 800;
      if( Channel > 800 )   // Catch overflow
         Channel = 0;

      // Update PLL & wait a while
      tune_pll();
      delay_ms(20); // Enough time for a full scale step
               
      // Update display
      display_frequency();
      
      // Check if anything is on this channel
      update_analog();
            
      while((Rssi_val >= Squelch_val) && (Keep_scanning == TRUE))
      {
         // Yup got a signal, turn Audio on
         AUDIO_PIN = AUDIO_ON;
            
         // Delay a while (2 seconds) on signal, but check scan switch
         // This loop runs at about 10 times a second
         for(ctr = 0; ctr <= 19 ; ctr++)
         {
            // Hurry up and wait!
            delay_ms(100);
            
            // Is the scan switch depressed?
            if(SCAN_SW == PUSHED)
            {
               // Clean up display for the user, giving feedback
               second_line();
               write_lcd("                ");
               
               // Wait 'till switch is not pressed
               while(SCAN_SW == PUSHED);
               
               // Exit out of here
               Keep_scanning = FALSE;
            }
            
            // If audio drops during this time turn it off
            // but stay in loop (keep resetting loop counter)
            update_analog();
            if(Rssi_val >= Squelch_val)
            {   
               AUDIO_PIN = AUDIO_ON;
               ctr = 0;
            }      
            else
               AUDIO_PIN = AUDIO_OFF;

            // If something has set keep_scanning false,
            // break out of loop
            if(keep_scanning == FALSE)
               break;   
      
         } // End of signal delay loop
         
      } // End of signal capture delay while loop
      
      // Check to see if scan is stopped
      if(SCAN_SW == PUSHED)
      {
         // Clean up display for the user, giving feedback
         second_line();
         write_lcd("                ");
         
         // wait till switch is not pushed
         while(SCAN_SW == PUSHED);
         
         // Now get outa town
         Keep_scanning = FALSE;
      }
   
   } // End of main loop               
   
   // Clean up display for the user, giving feedback
   second_line();
   write_lcd("                ");
   
   // Turn the audio back off, it will turn on later is there is
   // still a signal
   AUDIO_PIN = AUDIO_OFF;
}   


void change_increment(void)
{
// Change to next tuning increment value (Step size)

   switch(Increment)   
   {
      case 0: // 0 Channels = Locked
         Increment = 1;
         break;
      
      case 1: // 1 Channel = 5 kHz
         Increment = 2;
         break;
                     
      case 2: // 2 Channels = 10 kHz
         Increment = 20;
         break;
         
      case 20: // 20 Channels = 100 kHz
         Increment = 200;
         break;
         
      case 200: // 200 Channels = 1 MHz
         Increment = 0;
         break;

      default:  // Just in case, set 1 channel
         Increment = 1;
   }
}


void update_rssi_display(void)
{                           
static int old_rssi;       // Note: old_rssi is not initilized
int scaled_rssi, char_pos;

   // Displays the RSSI level of a signal on the LCD
   // Note: This one A/D read is used several placed below
   update_analog();
         
   scaled_rssi = Rssi_val/2;   // Divide by 2 to maximize range
      
   // Scale RSSI a/d value
   if(scaled_rssi > Cool
   {
      scaled_rssi -= 8; // The 8 offsets the display to zero
   }
   else
   {
      scaled_rssi = 0;  // Floor a/d value
   }   
         
   if(scaled_rssi > 16)   // Bound scaled a/d value
      scaled_rssi = 16;
         
   // Only update display if RSSI value changed
   if(scaled_rssi != old_rssi)
   {
      second_line();
      for(char_pos=1 ; char_pos <= 16 ; char_pos++)
      {
         if(char_pos <= scaled_rssi)
         {
            write_lcd(255);   
         }
         else
         {
            write_lcd(' ');
         }
      }
      old_rssi = scaled_rssi;
   }
}


//-----< Rotary Encoder routine >------------------------------------
#INT_EXT   // Change on falling edge of RB
      // Note: Must set int reg to get falling edge trigger
      
void encoder(void)
{
   // If here then the A encoder must have had a falling edge...
   
   // Read encoder B switch and check direction
   if( B_SW == 1 )
   {
      // CW Direction
      Channel += Increment;
   }
   else
   {
      // CCW Direction
      Channel -= Increment;
   }
   
   // Bound the channel values -- implements roll over
   if( Channel > 60000 )   // Catch unsigned underflow
      Channel = 800;

   if( Channel > 800 )   // Catch overflow
      Channel = 0;

   // Set the changed flag, cancel scanning (if we were scanning)
   Changed = TRUE;
   Keep_scanning = FALSE;

}


//-----< Main >------------------------------------------------------

// Note: At powerup the PIC clock will be 1.25 MHz. After PLL setup is
// done the clock will be 10 MHz. No RS232 can take place untill PLL
// is setup.

void main(void)
{
int ctr; // Local variables

   //----- Setup Ports / Unused pins are set to output
   set_tris_a(0b00001011);   //

   set_tris_b(0b00001111);   //

   set_tris_c(0b10000000);   //
   
   port_b_pullups(TRUE);   // ON for the switches

   //----- Housekeeping -----
   // Initilize Pins
   EN = 1;
   AUDIO_PIN = AUDIO_OFF;
   
   // Initilize global/local variables
   Channel = 400;   // Set for 146.000 MHz
   Changed = TRUE; // Update display
   Increment = 2;   // Set for 10 kHz increment
   
   // Initilize interrupts
   disable_interrupts(GLOBAL);

   ext_int_edge(H_TO_L);   
   
   // Initilize A/D
   setup_port_a(RA0_RA1_RA3_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   
   // Wait for LCD powerup
   // Note: Here clock is really 1.25 MHz, so delay is not
   // accurate (8 times more than value called out)
   delay_ms(100);

   // Initilize LCD
   init_lcd();

   // Display power on banner
   write_lcd("   Hagtronics   ");
   second_line();
   write_lcd("2 Meter Receiver");
      
   // Reset PLL, setup C, R regs
   setup_pll();
      
   // Setup PLL for initial turn on frequency of 146 MHz
   tune_pll();
      
   // Clean up display
   delay_ms(1000);
   init_lcd();

   //----- Determine if RS232 cable is hooked up
   // Read from RS232 receive pin, if it is high then
   // RS232 is connected.
   if(RS232_PIN == 1)
   {
      // RS232 is connected, operate in the remote mode
      rs232_mode();      
   }
      
   //----- Main loop -----   
   // This outer loop operates about 4 times a second
   while(!DOOMSDAY)
   {
      disable_interrupts(GLOBAL);
      
      // Check battery level
      update_analog();
      if( Bat_val <= 141 )   // 141 gives about 1.1 volt per cell
      {
         // Low battery
         second_line();
         write_lcd("BAT");
      }
      
      
      // Update display / PLL if channel changed
      if( Changed )
      {
         display_frequency();
               
         // Update PLL
         tune_pll();
         
         // Reset the changed flag
         Changed = FALSE;
      }
      
      // Set the encoder interrupt on again
      enable_interrupts(GLOBAL);
      
      // Real time update loop
      for( ctr = 0 ; ctr <= 24 ; ctr++ )
      {
      
         // Check if scan switch is pushed
         if(SCAN_SW == PUSHED)
         {
            // Give user feedback that switch was pushed
            second_line();
            write_lcd("----Scanning----");
            
            // Wait till scan is not pushed anymore
            while(SCAN_SW == PUSHED);

            // OK, Let's scan Smiley
            scan();
         }               
            
         // Check if Increment switch has been changed
         if(INC_SW == PUSHED)
         {
            // Increment tuning step size
            change_increment();
            
            // Give user feedback on button being pushed
            display_frequency();   
            
            // Wait till increment switch is not pushed anymore
            while(INC_SW == PUSHED);
         }
      
         // Update signal strength display
         update_rssi_display();
         
         // Check squelch level, open audio if needed
         update_audio();
         
         delay_ms(10); // Update loop about every 10 mSec

      } // End of 'real time' loop

   } // End of main while loop         

} //----- End of main -----
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC