JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

PIC16F1455 MCC USB Serial 変換テスト

2023-10-03 20:18:45 | PIC16F1455
 しばらくTiny402の勉強をしてきましたが、ここで、PIC16F1455の勉強に戻ることにします。目的はPIC16F1455でUSBシリアル変換を行うことです。うまくいけば、Arduinoに使ったり、Tiny402の書き込み用に使ったりしたいと思います。

 PIC16F1455を使ったUSBシリアル変換の記事はWeb上には多くなく、「elchika」というサイトの「Arduinoにも使えるUSBシリアル変換器」という記事のプログラムでテストをしました。

 MPLAB XからPICへの書き込みと書き込んだプログラムのテストには、前に作成したPIC16F1455開発ボード を使います。開発ボードの記事は、こちら

 テストをした回路図です。PICKit3での書き込み時は、右下のソケットに`PICKit3を接続します。書き込みが終了したら、右上と左下のコネクタにUSBケーブルを接続し、それらをパソコン本体に接続し、TeraTermで通信できるかどうかテストします。


 MPLAB Xでプロジェクトを作成し、elchikaサイトに掲載されているとおりMCCの設定を行いました。generateして、main.cに掲載されているプログラムリストをコピペし、コンパイル、書き込みを行いました。問題なく書き込むことができました。ボーレートは115200bps固定です。

 PICKit3を外して、回路図右上のコネクタにUSBケーブルを接続し、パソコン本体のUSBポートに接続しました。自動的にドライバがインストールされ、COM4として認識されました。

 PIC16F1455のシリアルポートには、FT-234を接続しました。パソコン本体にUSB接続するとCOM5として設定されました。TeraTermを2つ立ち上げ、しれぞれシリアルポートをCOM4とCOM5に、速度を115200bpsに設定して相互に通信できるかどうかテストしました。


 結果は、相互通信ができました。

 USBケーブルが接続された開発ボードです。elchikaさんのプログラムですと、RC2に1が出力されるため、RC2に接続したLEDが点灯のままになります。


 DTR信号が送られるのかCTESTWINびCW送信機能でてすとしましたが、NGでした。そもそもelchikaさんの記事に
「USB_device_CDC.cを書き換えます。下の画像のように117行目のUART_DTRにPORTCbits.RC3を設定してください 」
とあるのですが、現在のバージョンのUSB_device_CDC.c には、該当の箇所がなく、書き換えることができませんでした。

 今回のテストで、テキストの送受信は確認しましたが、DTR信号を出すことができませんでした。もう少し勉強してみます。ただ、DTR信号が出なくてもTiny402への書き込みはできますので、そちらを先にテストしてみようと思います。

PIC16F1455 MCC I2C LCD1602 テスト

2023-07-07 20:48:36 | PIC16F1455
 MPLAB X XC8 MCC環境で、PIC16F1455におけるI2C接続LCD1602の表示テストをします。

 PIC16F1455開発ボードにI2C接続のピンを増設し、ここにLCD1602を接続します。(プルアップ抵抗はLCD1602側についていますので、ボード上には付けていません。)


 projectを作成し、MCCの設定をします。

 まず、System Moduleの設定です。
 クロックは、16MHzとしました。PLLは使いません。Clock Deviderも使いません。MSSPモジュールを導入し、I2Cに設定すると自動的にI2CのSCLがRC0に、SDAがRC1にセットされます。


 Pin Moduleです。


 MSSP Moduleの設定です。
 I2C Masterに設定し、I2C Clockは100KHzとしました。


 I2Cで割込みを使いますので、Interrupt Moduleで割込みにチェックを入れます。

 この設定でGenerateします。

 テストしたプログラムです。
 プログラム自体はこれまで何度も使ったものですが、若干注意点があります。
 まず、printf()関数を使うために、stdio.hをincludeします。
 このままだとコンパイル時にエラーが出ますので、project propertiesを開き、XC8 Global OptionsでC standardをC90に設定します
-----------------------------------------------------
/*
 * PIC16F1455 MCC I2C LCD1602 TEST
 * 2023.07.07
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c_master_example.h"
#include <stdio.h>

#define I2C_LCD_addr 0x27
#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

//I2C LCDに1byteのdataを書き込む
void I2C_write_data(uint8_t data){
     I2C_Write1ByteRegister(I2C_LCD_addr, (data | LCD_EN | LCD_BL),(data | LCD_BL));
     __delay_us(100);
}

//I2C LCDにコマンドまたは文字を送る
void LCD_write(uint8_t data, uint8_t mode){
     //上位4bitを送る
     I2C_write_data((data & 0xF0) | mode);
     //下位4bitを送る
     I2C_write_data(((data << 4) & 0xF0) | mode);
}

//I2C LCD 初期化
void LCD_init(){
     __delay_ms(40);
     LCD_write(0x33,LCD_CMD);//8bit mode set 2?
     LCD_write(0x32,LCD_CMD);//8bit mode set 1?,4bit mode set
     LCD_write(0x06,LCD_CMD);//Entry mode set
     LCD_write(0x0C,LCD_CMD);//display ON,cursor OFF,blink OFF
     LCD_write(0x28,LCD_CMD);//Function set 4bit mode,2line
     LCD_write(0x01,LCD_CMD);//Clear display
     __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(uint8_t x,uint8_t y){
     if(y == 0){
     LCD_write(LCD_LINE1 + x,LCD_CMD);
    }
     if(y == 1){
     LCD_write(LCD_LINE2 + x,LCD_CMD);
    }
}

//1文字表示
void putch(char ch){
     LCD_write(ch,LCD_CHR);
}

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     // Enable the Global Interrupts
     INTERRUPT_GlobalInterruptEnable();

     // Enable the Peripheral Interrupts
     INTERRUPT_PeripheralInterruptEnable();
     LCD_init();
     LCD_home();
     printf("PIC16F1455");
     uint8_t count = 0;

     while (1)
    {
         LCD_cursor(1,1);
         printf("%3d",count);
         count ++;
         __delay_ms(1000);
    }
}
-----------------------------------------------------

 PIX16D1455への書き込みが終わったらPICKit3を外し、LCD1602を接続して、電源を入れます。1行目にPIC16F1455と表示され、2行目にcountの値が1秒ごとにカウントアップされます。



PIC16F1455 MCC シリアル通信テスト

2023-07-02 19:02:37 | PIC16F1455
 PIC16F1455でシリアル通信のテストをします。

 回路は、PIC16F1455開発ボードを使います。回路図です。


 projectを作成し、MCCの設定をします。

 System Moduleの設定をします。
 クロックは16MHzにしました。


 EUSARTモジュールを導入します。
 自動的にRC5がRX(input)に、RC4がTX(output)に設定されます。
 設定はデフォルトのままにして、Baud Rateは9600bpsです。


 これでGenerateして、次の簡単なエコーバックプログラムをコンパイル書き込みをしてテストします。
-----------------------------------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     uint8_t data;
      while (1)
    {
          data = EUSART_Read();
          EUSART_Write(data);
    }
}
-----------------------------------------------------------------
 FT-234をパソコンに接続し、通信ソフトTera Termを立ち上げて、送った文字が返ってくるかどうか確認します。



キーボードで打ったとおりの文字が返ってきました。OKです。


 送受信できることが確認できましたので、次に文字列をPICからTeraTermに送ってみます。
 プログラムです。
------------------------------------------------------------------
#include "mcc_generated_files/mcc.h"

//文字列の送信
void Send_str(char *str)
{
     while(*str)
    {
         EUSART_Write(*str++);
    }
}

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();
     char msg[]="PIC16F1455 TEST\r\n";

      while (1)
    {
          Send_str(msg);
          __delay_ms(1000);
    }
}
------------------------------------------------------------------
 1秒ごとに「PIC16F1455 TEST」がTeraTermに表示されます。
 \r\nはエスケープシーケンスで、\rがキャリジリターン、\nがニューラインです。

 さらに文字列や数値を簡単に文字として送信するために、printf()を使えるようにすると、次のようなプログラムになります。
 2行目に#include <stdio.h>を追加します。
 1文字出力関数 putch()を定義します。
--------------------------------------------------------------
#include "mcc_generated_files/mcc.h"
#include <stdio.h>

//1文字送信
void putch(char ch)
{
     EUSART_Write(ch);
}

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     uint8_t count=0;
      while (1)
    {
          printf("count = ");
          printf("%3d\r\n",count);
          count++;
          __delay_ms(1000);
    }
}
--------------------------------------------------------------
このプログラムで下のようにTeraTermに1秒ごとにcountの値がアカウントアップされて表示されます。



PIC16F1455 MCC PWMテスト

2023-07-01 19:12:42 | PIC16F1455
 PIC16F1455のPWMのテストをします。
 このPICは2つPWMを持っていて、出力先は次のようになっています。

 PWM1 → RC5固定
 PWM2 → RC3またはRA5(デフォルトはRC3でAFPCONで変更できる)

 テスト回路はLED点滅の時と同じPIC16F1455開発ボードです。


 今回は、PWM2を使いRC3(赤色LEDが接続されている)に出力します。

 projectを作成し、MCCの設定を行います。

 まず、System Moduleでクロックを設定します。
 INTOSC,FOSC,4MHz_HFに設定し、PLLは使いません。Clock dividerも使いませんので4MHzで動作させます。
 割込みは使いません。
 
 PWM2モジュールを導入し、RC3をoutputに指定します。

 PWM2モジュールの設定です。
 TimerはデフォルトのTimer2とします。
 Duty Cycle 50%のときPWMDC Valueは249です。これはメモしておきます。

 Timer2(TMR2)モジュールを導入し設定します。
 Prescaler 1:4,Postscaler 1:4とし、Timer Period を2msとしました。
 この設定が上のPWMモジュールに反映され、
 PWM Period = 500us
 PWM Frequency = 2kHz
 となりました。


 この設定でGenerateして、次のmainプログラムをコンパイル、書き込みをして出力される波形を見てみます。
--------------------------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();
     while (1)
    {
    }
}
--------------------------------------------------------
 プログラムには何も書いていないのですが、既にMCCのPWMモジュールでPWM Period 500us,duty cycle 50%に設定しています。
 RC3にPico scopeを接続して見てみると確かに設定どおりの波形が出力されました。


 duty cycleを変更する場合は、
 PWM2_LoadDutyValue(uint16_t dutyValue);
 という関数を使います。
 dutyValue=249のときduty cycle 50%ですので、
 PWM2_LoadDutyValue(125);
 とするとduty cycle 25%のPWMが出力されます。


 次に、LEDを明るくしたり暗くしたりを繰り返すプログラムを試してみました。
----------------------------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     while (1)
    {
         for(uint16_t i=0 ;i<=500;i++){
             PWM2_LoadDutyValue(i);
             __delay_ms(5);
         }
         for(uint16_t i=500;i>0;i--){
             PWM2_LoadDutyValue(i);
              __delay_ms(5);
         }
    }
}
----------------------------------------------------------

 RC3に接続した赤色LEDが、明るくなったり暗くなったりを繰り返しました。

PIC16F1455 MCC LED点滅

2023-07-01 08:08:43 | PIC16F1455
 MPLAB X(v6.00) + XC8(v2.40) + MCC(v5.1.17)環境で、LED点滅のテストをします。使うのは前の記事で紹介したPIC16F1455開発ボードです。回路図です。

 
 Projectを作成してからMCCの設定をします。
 System Moduleの設定です。
 INTOSCを選び内蔵のクロック16MHzを使います。
 PLLは使いません。Clock Dividerも使いません。
 Pin Managerで、RC2とRC3をoutputに設定します。
 割込みは使いません。
 

 これでGerarateします。
 RC2の青色LEDとRC3の赤色LEDを交互に点灯させるプログラムです。
---------------------------------------------------------------
#include "mcc_generated_files/mcc.h"

#define R_LED LATC3
#define B_LED LATC2
void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     while (1)
    {
         B_LED = 1;
         R_LED = 0;
         __delay_ms(500);
         B_LED = 0;
         R_LED = 1;
         __delay_ms(500);
    }
}
------------------------------------------------------
 交互に点滅しました。(電源はUSBからとっています)

 PIC16F1455は、USB用のクロック48MHzを生成するために下の図のように若干複雑になっています。