エアバンド用の受信機用局部発振器を作ろうとしてDDSから始まり、
うまくいかなかったので、si5351aを使用することにして実験をしています。
ところが、PIC16F1829基板を使用したsi5351aのi2c接続でとらぶっています。
以前PIC16F1829のMSSP2接続がうまくいかなかったことがあり、まずはi2c接続が
うまくいっているのかを確かめることにしました。
秋月電子通商のsi5351a基板のi2c信号配置とi2c接続小型キャラクタLCDモジュールの
信号配置が同じなことを知り、si5351a用に配線したコネクタにつなぎ変えてみます。
[スイッチサイエンス] I2C接続の小型LCD搭載ボード(3.3V版)
実験用のソフトとしてはi2cスキャンプログラムということにして、従来4ビット
LCD表示に加え、i2c接続LCDへの表示も移植してみました。
i2c接続LCDは以前2種類試したことがあり、今回のモジュールはSUNLINK社のものと
類似していたので割と簡単につなげました。
ということでMSSP2の動作はOKが確認され、次はsi5351aへのパラメータ設定値を
疑いデバッグしないといけません。
今回の液晶表示改造のi2c SCAnプログラムのメインは次の通り。
/* * File: main_i2clcd.c * Author: nobcha * Created on 2018/02/10, 18:01 */ /************************************************* MSSP i2c SCAN TEST of PIC12F1829 By nobcha all right reserved Ver 1.0 07/08/2012 for i2c peripheral TEST Ver 2.0 08/31/2012 for 1827 Ver 3.0 10/05/2014 for 1829 11/25/2014 MSSP2 is OK * 01/06/2018 MPLAB X transfered OK * 01/07/2018 PIC16F1829 MSSP2 OK * 02/10/2018 i2C LCD display PIC12F1829 + LCD + charge pumping minus volt PIN Assign RA0:LCD RS bit?RS)?RA0??? RA1:LCD EN bit (enable)?RA1??? RA2: not used T0CKI:F-in RA3:RESET_sw : MCLR RB4:MEM_sw : SW2 RB5:SDA2 MSSP2 RB6:Heart beat LED RB7:SCL2 MSSP2 RC0: not used Toggle Prescaler:CNT DISABLE RC2-5:SC1602_4bit_RC2-5 RC6: Charge pump source:CCP4 RC7: Down_sw SW3 SC1602 pin connection via 4bit mode #1 Vdd=3V #2 Vss=GND #3 LCD contrust center of 10k VOL minus V #4 RS RA0 #5 R/W GND #6 EN RA1 #11-14 DATA RC2-5 OSC INT 16MHz Development Circumstance: MPLAB X IDE V2.20 ************************************************* */ #define _XTAL_FREQ 16000000 #define PIC_CLOCK 16000000 #include <stdio.h> #include <stdlib.h> #include <htc.h> #include "lcd.h" #include "mssp2_i2c.h" #include "lcd_i2c.h" #define HEART_BEAT LATB6 #define UP_SW PORTBbits.RB4 // SW2 // CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection INT: device clock supplied to CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled) #pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is RA3) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled) #pragma config CLKOUTEN = ON // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) // proto void itostring(char , unsigned int , char* ); void mssp_init(void); unsigned char i2c_scan(unsigned char); // display data unsigned char Msg1[17] = "i2c SCAN test "; unsigned char Msg2[6] = "ADDR "; unsigned char Msg3[5] = "ack "; unsigned char Msg4[4] = " "; unsigned char Msg5[10] = " "; void main(void) { unsigned char i; /* INITIALIZE REGISTER */ OSCCON = 0b01111000; // Set 16MHz LATA = 0b00000000; // Clear TRISA = 0b00111100; // LATA INPUT RA4,5:SW,3:int,2:SW LATB = 0b00000000; // LATB RESET TRISB = 0b10110000; // LATB INPUT RB7:SCL2,5:SDA2,4:SW2 LATC = 0b00000000; // LATC RESET TRISC = 0b10000011; // LATC INPUT RC7:SW3,0,1:SHT ANSELA = 0b00000000; // All degital ANSELB = 0b00000000; ANSELC = 0b00000000; CM1CON0 = 0b00000111; // No using compalator CM2CON0 = 0b00000111; // No using compalator OPTION_REG = 0b10100100; // INTEDG 0,TOCS T0CKI 1,ToSE0,PSA TIMER0,1/32 INTCON=0; // INT off T1CON = 0; // Timer1 off // To generate minus voltage for LCD with 3V supply // CCP4 PWM initializing (83.8KHz on RB3 @16MHz) CCP4CON = 0b00001111; // use PWM mode CCPR4L = 0x0c; // duty is 50% CCPTMRS = 0; // Select TMR2 // TMR2 initilizing T2CON = 0b00000100; // POSTSCALE 1:1 ,TMR2 ON , PRESCALE 1:1 PR2 = 0x17; // resolution is 6.5bit mode TMR2ON = 1; // TMR2 start __delay_ms(200); __delay_ms(200); mssp_init(); // MSSP initialize lcd_init(); // LCD initialize continue lcd_i2c_init(); // i2c LCD initialize HEART_BEAT = 1; // LED off while(1) { __delay_ms(100); HEART_BEAT ^= 1; // Heart beat LED upset lcd_goto(0x00); // Move cursor 1st line lcd_puts(Msg1); // Display test message lcd_i2c_goto(0x00); // Move cursor 1st line lcd_i2c_puts(Msg1); // Display test message i=2; while(i){ lcd_goto(0x40); // Move cursor to 2nd line lcd_puts(Msg2); // i2c addr message lcd_i2c_goto(0x40); // Move cursor to 2nd line lcd_i2c_puts(Msg2); // i2c addr message itostring(2,i,Msg4); // convert i to ASCII lcd_puts(Msg4); // SCAN ADD lcd_i2c_puts(Msg4); if(i2c_scan(i)==0){ // If detect ack,displaying addr lcd_puts(Msg3); itostring(2,i,Msg4); lcd_puts(Msg4); lcd_i2c_puts(Msg3); lcd_i2c_puts(Msg4); while(UP_SW) ; // Waiting SW1 PUSH CHECK __delay_ms(400); } else{ lcd_puts(Msg5); lcd_i2c_puts(Msg5); } i=i+2; __delay_ms(100); HEART_BEAT ^= HEART_BEAT; // Heart beat LED upset } __delay_ms(500); // 0.5s waiting } } /*************************************** * i2c address scanning test ****************************************/ unsigned char i2c_scan(unsigned char data){ unsigned char ack_data; i2c_start(); // start condition i2c_write(data); // addr & wite mode ack_data=i2c_readack(); // if ack:0 i2c_stop(); return (ack_data); } /*************************************** * Converting 2/4 hex to ASCII ****************************************/ void itostring(char digit, unsigned int data, char *buffer) { char i; // digit:2 or 4 buffer += digit; // last data for(i=digit; i>0; i--) { // buffer--; // *buffer = (data & 0xF) + '0'; // ASCII code if(*buffer>0x39) *buffer=*buffer+7; data = data >> 4; // next hex } } /*************************************** * MSMSSP2 initialize ****************************************/ void mssp_init(void){ // Assign MSSP SDA2 & SCL2 except for RX & TX // APFCON0 = 0x80; // Assign RX on RC5 instead of RB5 // SSP2CON1 REGISTERS SSP2CON1bits.SSPEN = 1; //Enables Serial Port Mode SSP2CON1bits.SSPM3 = 1; ///////// SSP2CON1bits.SSPM2 = 0; //I2C Master Mode SSP2CON1bits.SSPM1 = 0; // clock= Fosc/(4*(SSP2ADD+1)) SSP2CON1bits.SSPM0 = 0; //////// // SSP2CON2 REGISTERS SSP2CON2 = 0x00; // SSP2CON3 REGISTERS SSP2CON3 = 0x00; // SSP2STAT REGISTERS SSP2STATbits.SMP = 1; // SLEW RATE non SSP2STATbits.CKE = 1; //SMBus Specific Inputs Enabled SSP2ADD = 0x36; //~75kHz @16MHz }
i2c接続液晶用部は次です。
// For i2c LCD(AQM1602XA-RN-GBW) // i2c LCD on PIC16F1829 mssp2 port // 2018.02.10 // OK // #define _XTAL_FREQ 16000000 #define PIC_CLOCK 16000000 #define LCD_AD 0x7C #include <htc.h> #include "lcd_i2c.h" #include "mssp2_i2c.h" void lcd_i2c_cmd(unsigned char cmd){ i2c_writeto(LCD_AD); // AQM1602XA-RN-GBW=0x7C i2c_write(0x00); // RS:0 command mode set i2c_write(cmd); // i2c_stop(); if((cmd == 0x01)||(cmd == 0x02)) __delay_ms(2); else __delay_us(40); } void lcd_i2c_data(unsigned char data1){ i2c_writeto( LCD_AD ); i2c_write(0x40); i2c_write(data1); i2c_stop(); } void lcd_i2c_goto(unsigned char cursor){ lcd_i2c_cmd(0x80 | cursor); } void lcd_i2c_puts(char* ptr){ while (*ptr !=0){ lcd_i2c_data(*ptr++); } } void lcd_i2c_init(){ lcd_i2c_cmd(0x38); __delay_us(50); lcd_i2c_cmd(0x39); __delay_us(50); lcd_i2c_cmd(0x14); __delay_us(50); lcd_i2c_cmd(0x73); __delay_us(50); lcd_i2c_cmd(0x56); __delay_us(50); lcd_i2c_cmd(0x6C); __delay_ms(250); lcd_i2c_cmd(0x38); __delay_us(50); lcd_i2c_cmd(0x01); __delay_us(50); lcd_i2c_cmd(0x0C); __delay_us(50); }
またヘッダは次になります。
/* * File: lcd_i2c.h * Author: nobcha * Created on 2018/02/10, 19:56 */ #include <htc.h> void lcd_i2c_goto(unsigned char); // Move cursor void lcd_i2c_puts(char*); void lcd_i2c_cmd(unsigned char); void lcd_i2c_data(unsigned char); void lcd_i2c_init();
色々な情報はホームページにまとめています。