#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// PIC18F452 Configuration Bit Settings 4 xpll ak tif 12mhz KTISTALLE 48MHZDE CALISIYOR.
#pragma config OSC = HSPLL //
#pragma config OSCS = ON //
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = OFF // Brown-out Reset Enable bit (Brown-out Reset enabled)
#pragma config BORV = 20 // Brown-out Reset Voltage bits (VBOR set to 2.0V)
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 128 // Watchdog Timer Postscale Select bits (1:128)
#pragma config CCP2MUX = OFF // CCP2 Mux bit (CCP2 input/output is multiplexed with RC1)
#pragma config STVR = ON // Stack Full/Underflow Rack Full/Underflow will cause RESET)
#pragma config LVP = OFF // Low Voltage ICSP Enable bit (Low Voltage ICSP disabled)
#define _XTAL_FREQ 12000000 //12mhz istege gore 20mhz kadar olabilir
#ifndef uchar
typedef unsigned char uchar;
#endif
#ifndef ushort
typedef unsigned short ushort;
#endif
#ifndef uint
typedef unsigned int uint;
#endif
#ifndef ulong
typedef unsigned long ulong;
#endif
//////////////////LCD REGISTER AYARLARI////////////////////////////////////
#define LCD_FIRST_ROW 128
#define LCD_SECOND_ROW 192
#define LCD_THIRD_ROW 148
#define LCD_FOURTH_ROW 212
#define LCD_CLEAR 1
#define LCD_RETURN_HOME 2
#define LCD_CURSOR_OFF 12
#define LCD_UNDERLINE_ON 14
#define LCD_BLINK_CURSOR_ON 15
#define LCD_MOVE_CURSOR_LEFT 16
#define LCD_MOVE_CURSOR_RIGHT 20
#define LCD_TURN_OFF 0
#define LCD_TURN_ON 8
#define LCD_SHIFT_LEFT 24
#define LCD_SHIFT_RIGHT 28
//////////////////////LCD PORT AYATLARI///////////////////////////////////////////
#define LCD_RD7 LATBbits.LATB7 // D7
#define TRISRB7 TRISBbits.TRISB7
#define LCD_RD6 LATBbits.LATB6 // D6
#define TRISRB6 TRISBbits.TRISB6
#define LCD_RD5 LATBbits.LATB5 // D5
#define TRISRB5 TRISBbits.TRISB5
#define LCD_RD4 LATBbits.LATB4 // D4
#define TRISRB4 TRISBbits.TRISB4
#define LCD_EN LATBbits.LATB3 // EN
#define TRISEN TRISBbits.TRISB3
#define LCD_RS LATBbits.LATB2 // RS
#define TRISRS TRISBbits.TRISB2
///////////////STEP VE YUKARI ASAGI BUTONU/////GIRIS OLARAK AYARLANDI////
#define TRISC0 = 1;
#define TRISC1 = 1;
#define TRISC2 = 1;
#define STEP PORTCbits.RC0
#define YUKARI PORTCbits.RC1
#define ASAGI PORTCbits.RC2
//////////////////////////////////////////////////////////////////////////////////////
#define SDA LATBbits.LATB0 // port B0 CIKIS
#define SCK LATBbits.LATB1 // port B1 CIKIS
///////////////////BIR SIFIR AYARLARI/////////////////////////////////////////
#define Set_SDA_Low SDA = 0 // SDA KONUMU data
#define Set_SDA_High SDA = 1 // SDA KONUMU
#define Set_SCK_Low SCK = 0 // SCK KONUMU saat
#define Set_SCK_High SCK = 1 //SCK KONUMU
//////////////////////////////////////////////////////////////////////////////////
#define I2C_Speed 40// I2C gecikmesi durma gore azaltilip cogaltila bilinir.
////////////////////////si5351/////////////////////////////////////////////////////////////
#define SYNTH_MS_0 42 // PPL A CIKIS Degeri 42
#define SI5351A_ADDRESS 192 //Aslinda 96 192 kullanmak gerekiyor
#define SI_CLK0_CONTROL 16
#define SI_CLK1_CONTROL 17
#define SI_CLK2_CONTROL 18
#define SI_SYNTH_PLL_A 26
#define SI_SYNTH_PLL_B 34
#define SI_SYNTH_MS_0 42
#define SI_SYNTH_MS_1 50
#define SI_SYNTH_MS_2 58
#define SI_PLL_RESET 177
#define SI_R_DIV_1 0
#define SI_R_DIV_2 16
#define SI_R_DIV_4 32
#define SI_R_DIV_8 48
#define SI_R_DIV_16 64
#define SI_R_DIV_32 80
#define SI_R_DIV_64 96
#define SI_R_DIV_128 112
#define SI_CLK_SRC_PLL_A 0
#define SI_CLK_SRC_PLL_B 32
#define XTAL_FREQ 25000000 //Kristal frekansi 25 YADA 27 MHZ FARKETMEZ
#define XTAL_LOAD_CAP 183 //10 pf ic kondansator aktiv resisterin 183 une yazilacak
#define SI5351_CRYSTAL_LOAD_10PF (3<<6) //10pf ic kondansator
///////////////////////////////////////////////////////////////////////////////////////////
void Lcd_Init(void);
void Lcd_Char(char c);
void Lcd_Command(unsigned char command);//LCD COMMAND
void Lcd_yazi(unsigned char y, unsigned char x, const char *buffer);//harf sayi gostermek icin
void print(unsigned char y, unsigned char x, char *buffer);
/////////////////////// I2C ICIN FONKSIYONLAR /////////////////////////////
void i2c_yaz( unsigned char byte); //baslangicta fonksiyon tanimliyoruz
void i2c_init( void ); //baslangicta fonksiyon tanimliyoruz
void i2c_basla( void ); //baslangicta fonksiyon tanimliyoruz
void i2c_durdur( void ); //baslangicta fonksiyon tanimliyoruz
void yaz(unsigned char RegisterAddresi, unsigned int Registerdegeri);
///////////////////////////////SI5351 ICIN FONKSIYONLAR//////////////////
void SetFreq(unsigned long frequency);
void kur_bolucu(unsigned char synth, unsigned long divider, unsigned char Div);
void kur_pll(unsigned char pll,unsigned char mult,unsigned long num,unsigned long denom);
void Delayms(unsigned int gecik);
void Lcd_Delay5us(void);
void Lcd_Delay5500us(void);
///////////////////////////////////////////////////////////////////////////////////
void Lcd_Delay5us(void){
__delay_us(5);
__delay_us(5);
}
void Lcd_Delay5500us(void){
__delay_us(5500);
}
void Delayms(unsigned int gecik)
{
unsigned int i,j;
for(i=0;i<gecik;i++)
for(j=0;j<1500;j++);
}
char step=4; //baslangic step 1khz
unsigned long long frekans=7150000; //baslangic frekansi
unsigned char TempBuffer[60]=""; //LCD de yaziyi gostermek icin
//lcd portları
void Lcd_Init(void){
unsigned char data;
TRISRB7 = 0;
TRISRB6 = 0;
TRISRB5 = 0;
TRISRB4 = 0;
TRISEN = 0;
TRISRS = 0;
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 0;
LCD_RD4 = 0;
LCD_EN = 0;
LCD_RS = 0;
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
for(data = 1; data < 4; data ++)
{
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 1;
LCD_RD4 = 1;
LCD_EN = 0;
LCD_RS = 0;
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 1;
LCD_RD4 = 1;
LCD_EN = 1;
LCD_RS = 0;
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 1;
LCD_RD4 = 1;
LCD_EN = 0;
LCD_RS = 0;
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
}
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 1;
LCD_RD4 = 0;
LCD_EN = 0;
LCD_RS = 0;
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 1;
LCD_RD4 = 0;
LCD_EN = 1;
LCD_RS = 0;
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
Lcd_Delay5us();
LCD_RD7 = 0;
LCD_RD6 = 0;
LCD_RD5 = 1;
LCD_RD4 = 0;
LCD_EN = 0;
LCD_RS = 0;
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
Lcd_Delay5500us();
data = 40; Lcd_Command(data);
data = 16; Lcd_Command(data);
data = 1; Lcd_Command(data);
data = 15; Lcd_Command(data);////lcd portları bitis
Lcd_Command(LCD_CURSOR_OFF);
}
void Lcd_Char(char c){
LCD_EN = 0; LCD_RS = 1;
LCD_RD7 = (c & 0b10000000)>>7;
LCD_RD6 = (c & 0b01000000)>>6;
LCD_RD5 = (c & 0b00100000)>>5;
LCD_RD4 = (c & 0b00010000)>>4;
_delay(5);
LCD_EN = 1;
Lcd_Delay5us();
Lcd_Delay5us();
LCD_EN = 0;
LCD_RD7 = (c & 0b00001000)>>3;
LCD_RD6 = (c & 0b00000100)>>2;
LCD_RD5 = (c & 0b00000010)>>1;
LCD_RD4 = (c & 0b00000001);
_delay(5);
LCD_EN = 1;
Lcd_Delay5us();
Lcd_Delay5us();
LCD_EN = 0;
Lcd_Delay5500us();
}
void Lcd_Command(unsigned char command){
LCD_EN = 0; LCD_RS = 0;
LCD_RD7 = (command & 0b10000000)>>7;
LCD_RD6 = (command & 0b01000000)>>6;
LCD_RD5 = (command & 0b00100000)>>5;
LCD_RD4 = (command & 0b00010000)>>4;
_delay(5);
LCD_EN = 1;
Lcd_Delay5us();
Lcd_Delay5us();
LCD_EN = 0;
LCD_RD7 = (command & 0b00001000)>>3;
LCD_RD6 = (command & 0b00000100)>>2;
LCD_RD5 = (command & 0b00000010)>>1;
LCD_RD4 = (command & 0b00000001);
_delay(5);
LCD_EN = 1;
Lcd_Delay5us();
Lcd_Delay5us();
LCD_EN = 0;
Lcd_Delay5500us();
Lcd_Delay5500us();
}
void print(unsigned char y, unsigned char x, char *buffer){
unsigned char data;
switch(y){
case 1: data = 127 + x; break;
case 2: data = 191 + x; break;
case 3: data = 147 + x; break;
case 4: data = 211 + x; break;
default: break;}
Lcd_Command(data);
while(*buffer)
{
Lcd_Char(*buffer);
buffer++;
}
return;
}
void Lcd_yazi(unsigned char y, unsigned char x, const char *buffer){
unsigned char data;
switch(y){
case 1: data = 127 + x; break;
case 2: data = 191 + x; break;
case 3: data = 147 + x; break;
case 4: data = 211 + x; break;
default: break;}
Lcd_Command(data);
while(*buffer)
{
Lcd_Char(*buffer);
buffer++;
}
return;
}
void kur_pll(unsigned char pll, unsigned char mult, unsigned long num, unsigned long denom)
{
unsigned long P1; unsigned long P2; unsigned long P3; //degiskenler p1,p2,p3
P1 = (unsigned long)(128 * ((float)num / (float)denom));
P1 = (unsigned long)(128 * (unsigned long)(mult) + P1 - 512);
P2 = (unsigned long)(128 * ((float)num / (float)denom));
P2 = (unsigned long)(128 * num - denom * P2); P3 = denom;
yaz(pll + 0, (P3 & 0x0000FF00) >> 8);
yaz(pll + 1, (P3 & 0x000000FF));
yaz(pll + 2, (P1 & 0x00030000) >> 16);
yaz(pll + 3, (P1 & 0x0000FF00) >> 8);
yaz(pll + 4, (P1 & 0x000000FF));
yaz(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
yaz(pll + 6, (P2 & 0x0000FF00) >> 8);
yaz(pll + 7, (P2 & 0x000000FF));
}
void kur_bolucu(unsigned char synth, unsigned long divider, unsigned char Div) // konmaz
{
unsigned long P1; //ayar P1 degisken
unsigned long P2; // ayr P2 degisken
unsigned long P3; // ayarP3 degisken
P1 = 128 * divider - 512;
P2 = 0; // P2 = 0, P3 = 1, bölücü için bir tam sayi
P3 = 1;
yaz(synth + 0, (P3 & 0x0000FF00) >> 8);
yaz(synth + 1, (P3 & 0x000000FF));
yaz(synth + 2, ((P1 & 0x00030000) >> 16) | Div);
yaz(synth + 3, (P1 & 0x0000FF00) >> 8);
yaz(synth + 4, (P1 & 0x000000FF));
yaz(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
yaz(synth + 6, (P2 & 0x0000FF00) >> 8);
yaz(synth + 7, (P2 & 0x000000FF));
}
void SetFreq(unsigned long frequency) // (frequency degisken)
{
unsigned long pllFreq; // degisken
unsigned long xtalFreq = XTAL_FREQ; // degisken
unsigned long l; // degisken
double f;//float f; // degisken
unsigned char mult; // degisken
unsigned long num; // degisken
unsigned long denom; // degisken
unsigned long divider; // degisken
divider = 900000000 / frequency; // Bölme orani 900000000
if (divider%2) //bolumden kalani eksilt
divider --; // Bir çift tamsayi bölme
pllFreq = divider * frequency; // hesapla bölücü
mult = pllFreq / xtalFreq; //pll çarpan
l = pllFreq % xtalFreq; //Üç bölüm
f = l; // tamsayi
f *= 1048575; // num ve denom, kesirli kisimlar, pay ve payda
f /= xtalFreq; //her biri 20 bittir (aralik 0..1048575)
num = (ulong)f; //çarpan mult + num / denom
denom = 1048575; // payda maksimum 1048575
kur_pll(SI_SYNTH_PLL_A, mult, num, denom); // pll ye git
kur_bolucu(SI_SYNTH_MS_0, divider, SI_R_DIV_1); //bolucuye git
yaz(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A); // yaz git A ciktisini ac
}
void i2c_init(void)
{
Set_SDA_High;// SDA = 1;
Set_SCK_High;// SCK = 1;
}
void i2c_basla( void ){
int i;
Set_SDA_High;
for(i = 0; i<I2C_Speed; ++i );
Set_SCK_High;
for(i = 0; i<I2C_Speed; ++i );
Set_SDA_Low;
for(i = 0; i<I2C_Speed; ++i );
Set_SCK_Low;
for(i = 0; i<I2C_Speed; ++i );
for( i = 0; i<I2C_Speed; ++i );
for(i = 0; i<I2C_Speed; ++i );
for(i = 0; i<I2C_Speed; ++i );
}
//----------------- I2C -----------------------------------------------//
void i2c_durdur( void ){
int i;
Set_SDA_Low;
for(i = 0; i<I2C_Speed; ++i ); //gecikme I2C_Speed
Set_SCK_High;
for(i = 0; i<I2C_Speed; ++i ); //gecikme I2C_Speed
Set_SDA_High;
for(i = 0; i<I2C_Speed; ++i ); //gecikme I2C_Speed
for( i = 0; i<I2C_Speed; ++i ); //gecikme I2C_Speed
for( i = 0; i<I2C_Speed; ++i ); //gecikme I2C_Speed
for( i = 0; i<I2C_Speed; ++i ); //gecikme I2C_Speed
}
void i2c_yaz( unsigned char byte ){
unsigned char temp=byte;
int i,j;
for(j = 0; j<8; ++j ){ //Beytleri taramak icin for dongusu
for(i = 0; i<I2C_Speed; ++i ) //gecikmeyi ver
if( (temp&0x80) == 0x80 ) //eger temp 0x80 se esitle 0x80 ne
Set_SDA_High; // bir yap yukarda define ile tanimli (Set_SDA_High)
else
Set_SDA_Low; // sifir yap yukarda define ile tanimli (Set_SDA_Low)
temp <<=1; //sola yit
for(i = 0; i<I2C_Speed; ++i ) //gecikme
Set_SCK_High;
for(i = 0; i<I2C_Speed; ++i )
Set_SCK_Low;
}
TRISB0 = 1; //8 inci bit icin SDA giris yapildi.
for(i = 0; i<I2C_Speed; ++i )
Set_SCK_High;
for(i = 0; i<I2C_Speed; ++i )
Set_SCK_Low;
TRISB0 = 0; //SDA cikis yapildi
}
void yaz(unsigned char RegisterAddresi, unsigned int Registerdegeri)
{
i2c_basla(); // basla'ya gitI2C yi baslat
i2c_yaz(SI5351A_ADDRESS); //i2c_yaza git si5351nin adresini yaz (192 )
i2c_yaz(RegisterAddresi); //i2c_yaza git ilk beyti sal
i2c_yaz(Registerdegeri); //i2c_yaza git ikinci beyti sal
i2c_durdur(); //i2c_durdura git durdur
}
//LCDde frekans gostermek icin
void segmentler(unsigned long t, unsigned char *str, unsigned char n)
{
unsigned char a[12]; int i, j;
a[0]= (t/100000000000)%10;
a[1]= (t/10000000000)%10;
a[2]= (t/1000000000)%10;
a[3]= (t/100000000)%10;
a[4]= (t/10000000)%10;
a[5]= (t/1000000)%10;
a[6]= (t/100000)%10;
a[7]= (t/10000)%10;
a[8]= (t/1000)%10;
a[9]= (t/100)%10;
a[10]=(t/10)%10;
a[11]=(t/1)%10;
for(i=0; i<12; i++) a=a+'0';
for(i=0; a=='0' && i<=4; i++);
for(j=12-n; j<i; j++) { *str=' ';
if ((j == 8) || (j == 5)) *++str = 46; str++; } //46 noktayi temsil eder ornek 7.155.000
for(; i<12; i++) { *str=a;
if ((i == 8) || (i == 5)) *++str = 46; str++; } //46 noktayi temsil eder ornek 14.155.000
*str='\0'; }
void main()
{
TRISA=0x00;
TRISB=0x00; //
TRISC = 0x07;// 1 2 ve 3 pini giris digerleri cikis
PORTA=0x00;PORTB=0x00; PORTC=0x00; //portlar temizledi
Lcd_Init();
Lcd_Command(LCD_CLEAR);
Lcd_Command(LCD_CURSOR_OFF);
i2c_init();
Lcd_yazi(2,2, "Yasa"); //harf sayi gostermek icin
Delayms(1200);Delayms(1200);
yaz(XTAL_LOAD_CAP,SI5351_CRYSTAL_LOAD_10PF); //25mhz nin kristalin 10 pf sini aktiv et(XTAL_LOAD_CAP)
Lcd_yazi(2,2, "1 khz ");
SetFreq(frekans); //SetFreq fonksiyona git icindeki isleri yap
segmentler(frekans,&TempBuffer[0],10);
print(1, 2, &TempBuffer[0]); Delayms(200);
while(1) // while nin arasina calisacak gorevler yazilir
{
if(STEP== 0) { step++; if (step>7) step=1; Delayms(800);
if(step== 1) { Lcd_yazi(2,2, "1 hrz "); }
if(step== 2) {Lcd_yazi(2,2, "10 hrz "); }
if(step== 3) { Lcd_yazi(2,2, "100 hrz "); }
if(step== 4) {Lcd_yazi(2,2, "1 khz "); }
if(step== 5) {Lcd_yazi(2,2, "10 khz "); }
if(step== 6) {Lcd_yazi(2,2, "100 khz "); }
if(step== 7) {Lcd_yazi(2,2, "1 mhz "); } }
if(ASAGI== 0) { Delayms(200);
if(step== 1) {frekans=frekans - 1; }
if(step== 2) {frekans=frekans - 10; }
if(step== 3) {frekans=frekans - 100; }
if(step== 4) {frekans=frekans - 1000; }
if(step== 5) {frekans=frekans - 10000; }
if(step== 6) {frekans=frekans - 100000; }
if(step== 7) {frekans=frekans - 1000000; }
if(frekans >1600000000 ) frekans=0;
if(frekans <1 ) frekans=0 ;
SetFreq(frekans); //SetFreq fonksiyona git icindeki isleri yap
segmentler(frekans,&TempBuffer[0],10); // lcdde_frekansgoster
print(1, 2, &TempBuffer[0]); ;Delayms(200); } //buton gecikmesi
if(YUKARI== 0) { Delayms(200);
if(step== 1) { frekans=frekans +1; }
if(step== 2) {frekans=frekans +10; }
if(step== 3) { frekans=frekans +100; }
if(step== 4) { frekans=frekans +1000; }
if(step== 5) {frekans=frekans + 10000; }
if(step== 6) {frekans=frekans + 100000; }
if(step== 7) {frekans=frekans +1000000; }
if(frekans >1600000000 ) frekans=0;
if(frekans <1 ) frekans=0 ;
SetFreq(frekans); //SetFreq fonksiyona git icindeki isleri yap
segmentler(frekans,&TempBuffer[0],10); // lcdde_frekansgoster
print(1, 2, &TempBuffer[0]); Delayms(200); } //buton gecikmesi
}
}