Quantcast
Channel: JH7UBCブログ
Viewing all articles
Browse latest Browse all 440

PIC16F1827 AD9834DDS VFO

$
0
0
 先日製作した3.5/7MHz SDRフロントエンドと組み合わせて実際の交信をしてみようと思い、7MHzのCW送信機を作ろうと思います。

 まず、AD9834DDSをPIC16F1827でコントロールして7MHz VFOを作ります。

 PIC16F883+AD9834 VFOのプログラムをPIC16F1827用に若干変更し、ロータリーエンコーダは、IOC割り込みを利用した方法にしました。

 回路図です。

イメージ 1

ブレッドボードです。

イメージ 2

AD9834DDSの出力の波形です。

イメージ 3

参考までに、プログラムです。

-----------------------------------------
/*
 * File:   main.c
 * Author: JH7UBC Keiji Hata
 * PIC16F1827_AD9834_VFO
 * Created on 2019/03/27
 */

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// CONFIG1
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config CLKOUTEN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF

// CONFIG2
#pragma config WRT = OFF
#pragma config PLLEN = ON
#pragma config STVREN = ON
#pragma config BORV = HI
#pragma config LVP = OFF
#define _XTAL_FREQ 32000000   //クロック32MHz

//LCD関係定義
#define LCD_EN 0b00000100   //Enable
#define LCD_BL 0b00001000   //Back Light
#define LCD_CMD 0x00
#define LCD_CHR 0x01
#define LCD_LINE1 0x80
#define LCD_LINE2 0xC0
#define LCD_addr 0x4E   //0x27<<1

/* ロータリーエンコーダ関係定義*/
#define ECA RB6 //エンコーダA
#define ECB RB7 //エンコーダB
unsigned char EA;
unsigned char EB;
volatile unsigned char curDat;
volatile unsigned char befDat;
volatile signed char count= 0;

/* STEP関係設定 */
unsigned int Step = 1000;       //STEP初期値
#define STEP_SW RB5

/* AD9834DDS関係定義 */
#define FSYNC RA0
#define SCLK RA1
#define SDATA RA2
unsigned long Freq = 7000000;   //周波数初期値
unsigned long Freq_old;         //周波数の前の値
const unsigned long Fre_Hi = 7200000; //周波数上限
const unsigned long Fre_Lo = 7000000; //周波数下限

/* I2C 初期化*/
void I2C_init(){
    SSP1CON1 = 0x28;        //SSPEN = 1,I2C Master Mode
    SSP1STATbits.SMP = 1;   //標準速度モード(100KHz)
    SSP1ADD = 0x4F;         //Fosc/(4*Clock)-1  Clock=100kHz,Fosc=32MHz
}

/* スタートコンディション */
void I2C_start(){
    SSP1CON2bits.SEN = 1;
    while(SSP1CON2bits.SEN);
}

/* ストップコンディション */
void I2C_stop(){
    SSP1IF = 0;
    SSP1CON2bits.PEN = 1;
    while(SSP1CON2bits.PEN);
    SSP1IF = 0;
}

/* I2Cに1byte送信 */
void I2C_write(unsigned char dat){
    SSP1IF = 0;
    SSP1BUF = dat;
    while(!SSP1IF);
}

void Write_data(unsigned char data){
    I2C_start();
    I2C_write(LCD_addr);
    I2C_write(data | LCD_EN | LCD_BL);
    I2C_write(data | LCD_BL);
    I2C_stop();
    __delay_us(100);
}

void LCD_write(unsigned char bits,unsigned char mode){
    //send High 4bits
    Write_data((bits & 0xF0) | mode);
    //send Low 4bits
    Write_data(((bits << 4) & 0xF0) | mode);
}

void LCD_init(){
    LCD_write(0x33,LCD_CMD);
    LCD_write(0x32,LCD_CMD);
    LCD_write(0x06,LCD_CMD);
    LCD_write(0x0C,LCD_CMD);
    LCD_write(0x28,LCD_CMD);
    LCD_write(0x01,LCD_CMD);
    __delay_ms(1);
}

void LCD_clear(){
    LCD_write(0x01,LCD_CMD);
    __delay_ms(1);
}

void LCD_home(){
    LCD_write(0x02,LCD_CMD);
    __delay_ms(1);
}

void LCD_cursor(unsigned char x,unsigned char y){
    if (y == 0){
        LCD_write(LCD_LINE1+x,LCD_CMD);
    }
    if (y == 1){
        LCD_write(LCD_LINE2+x,LCD_CMD);
    }
}

void putch(unsigned char ch){
    LCD_write(ch,LCD_CHR);
}

void Freq_disp(unsigned long frequency){
    LCD_home();
    printf("%8ld",frequency);
}

void Step_disp(unsigned int stp){
    LCD_cursor(4,1);
    printf("%4d",stp);
}

void Step_change(){
    __delay_ms(5);
    if(Step == 10){
        Step = 1000;
    }else{
    Step = Step/10;
    }
    Step_disp(Step);
    while(!STEP_SW){
    __delay_ms(5);
    }
}

/* AD9834DDSに16ビット送信 */
void Data_send(unsigned long data){
    for(unsigned char i = 0;i<16;i++){
        if(data & 0x8000){
            SDATA = 1;
        }else{
            SDATA = 0;
        }
        __delay_us(1);
        SCLK = 0;
        __delay_us(1);
        SCLK = 1;
        data <<= 1;
    }
}

/* AD9834DDSに周波数データを送る */
void Fnc_DDS(unsigned long frequency){
    unsigned long wrk = frequency << 2;
    unsigned int wrk1,wrk2,wrk3;
   
    wrk1 = 0x2000;          //コントロールワード
    wrk2 = wrk & 0x3fff;    //周波数データ下位
    wrk2 = wrk2 | 0x4000;
    wrk3 = wrk >> 14;
    wrk3 = wrk3 & 0x3fff;   //周波数データ上位
    wrk3 = wrk3 | 0x4000;
    SCLK = 1;
    FSYNC = 0;
    Data_send(wrk1);
    Data_send(wrk2);
    Data_send(wrk3);
    FSYNC = 1;
}

void interrupt isr(){
    IOCIF = 0;   //割り込みフラッグクリア
    IOCBF6 = 0;
    IOCBF7 = 0;
    __delay_ms(2);
    curDat = ECA + (ECB<<1);
    if (befDat != curDat){
        unsigned char d = ((befDat<<1)^curDat) & 3; //回転方向判定
        if(d < 2){
            count++;
        }else{
            count--;
        }
        befDat = curDat;
    }
    if(count >= 4){
        Freq += Step;
        count = 0;
    }else if(count <= -4){
        Freq -= Step;
        count = 0;
    }
}

void main(){
    OSCCON = 0b01110000 ;     // 内部クロック8MHz
    ANSELA = 0b00000000 ;     // AN0-AN4は使用しない
    ANSELB = 0b00000000 ;     // AN5-AN11は使用しない
    TRISA  = 0b00000000 ;     // PORTAは全て出力(RA5は入力)
    TRISB  = 0b11110010 ;     // RB1(SDA),RB4(SDA),RB5,RB6(REA),RB7(REB)は入力他は出力
    PORTA  = 0b00000000 ;     // PORTA初期化
    PORTB  = 0b00000000 ;     // PORTB初期化
    OPTION_REGbits.nWPUEN=0;  // ウィークプルアップ許可
    WPUB = 0b11100000;        // RB5,RB6,RB7をプルアップ
       
    /* IOC割り込み設定 */
    IOCBN = 0b11000000;     //RB6,RB7立下り割り込み設定
    IOCBP = 0b11000000;     //RB6,RB7立ち上がり割り込み設定
    IOCIE = 1;              //IOC割り込み許可
    GIE = 1;                //全割り込み許可
           
    I2C_init();             //I2C初期化
    LCD_init();             //LCD初期化
   
    /* Roatry Encoder 初期値 */
    EA = ECA;
    EB = ECB;
    befDat = EA + (EB<<1);  
  
    /* 初期表示と初期周波数設定 */
    LCD_cursor(9,0);
    printf("Hz");
    Freq_disp(Freq);
    Fnc_DDS(Freq);
    LCD_cursor(0,1);
    printf("STEP");
    Step_disp(Step);
   
   
    while(1){
        if(STEP_SW == 0){
            Step_change();
        }
        if(Freq != Freq_old){
            if(Freq < Fre_Lo)Freq = Fre_Lo;
            if(Freq > Fre_Hi)Freq = Fre_Hi;
            Fnc_DDS(Freq);
            Freq_disp(Freq);
            Freq_old = Freq;
        }
    }
}

Viewing all articles
Browse latest Browse all 440

Trending Articles