PIC16F1827 AD9834DDS SG
JH7UBC 2021.2.2
ケースは、以前周波数カウンタに使っていたものを流用しました。
内部の様子です。
XC8のソースリストです。
#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 RB2 //エンコーダA #define ECB RB3 //エンコーダB unsigned char EA; unsigned char EB; volatile unsigned char curDat; volatile unsigned char befDat; volatile signed char count= 0; /* STEP関係設定 */ unsigned long Step = 1000000; //STEP初期値 1MHz #define STEP_SW RB5 /* AD9834DDS関係定義 */ #define FSYNC RA0 #define SCLK RA1 #define SDATA RA2 unsigned long Freq = 1000000; //周波数初期値 1MHz unsigned long Freq_old; //周波数の前の値 /* 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_cursor(4,0); printf("%8ld",frequency); } void Step_disp(unsigned long stp){ LCD_cursor(5,1); printf("%7ld",stp); } void Step_change(){ __delay_ms(5); if(Step == 10){ Step = 1000000; }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; //割り込みフラッグクリア IOCBF2 = 0; IOCBF3 = 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 = 0b00111110 ; // RB1(SDA),RB2(REA),RB3(REB),RB4(SDA),RB5は入力他は出力 PORTA = 0b00000000 ; // PORTA初期化 PORTB = 0b00000000 ; // PORTB初期化 OPTION_REGbits.nWPUEN=0; // ウィークプルアップ許可 WPUB = 0b00101100; // RB2,RB3,RB5をプルアップ /* IOC割り込み設定 */ IOCBN = 0b00001100; //RB2,RB3立下り割り込み設定 IOCBP = 0b00001100; //RB2,RB3立ち上がり割り込み設定 IOCIE = 1; //IOC割り込み許可 GIE = 1; //全割り込み許可 I2C_init(); //I2C初期化 LCD_init(); //LCD初期化 /* Roatry Encoder 初期値 */ EA = ECA; EB = ECB; befDat = EA + (EB<<1); /* 初期表示と初期周波数設定 */ LCD_cursor(13,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){ Fnc_DDS(Freq); Freq_disp(Freq); Freq_old = Freq; } } } |