JH7UBCブログ

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

PIC16F18326 MCC ADCテスト

2024-01-21 15:20:18 | MPLAB X MCC
 PIC16F18326のADCのテストをします。
 環境は、MPLAB X(v6.15) XC8(v2.45) MCC(v5.3.7)です。 

 PIC16F18326は、ADCを11ch使えます。各チャンネルと対応ポートの関係は次のようになっています。
 チャンネル番号  アナログポート I/Oポート
    0       ANA0     RA0
    1       ANA1     RA1
    2       ANA2     RA2
    3       -
    4       ANA4     RA4
    5       ANA5     RA5
   6~15      -
   16       ANC0     RC0
   17       ANC1     RC1
   18       ANC2     RC2
   19       ANC3     RC3
   20       ANC4     RC4
   21       ANC5     RC5

 ch1(RC1)を使って、入力電圧をボリュームで変化させ、ADCの値をシリアル通信で出力し、Tera Termで表示します。
 回路図です。ICSPでPICKit3で書き込みます。


 MPLAB Xでprojectを作成し、MCCを立ち上げ、各種設定をします。
 まず、systemモジュールでクロックを設定します。下のように4MHzとしました。


 ADCモジュールを導入し、Result Alignmentをrifhtに設定します。他はデフォルトのままです。



 EUSARTモジュールを導入します。設定は特にせず、デフォルトのままです。Baud Rateは9600bpsです。

 pinモジュールです。ADCの入力はANC1(RC1)で、EUSARTのTXがRC4、RXがRC5です。

 1secごとにADCの値を送信するプログラムです。
--------------------------------------------------------------------------
/*
 * PIC16F18326 MCC ADC test
 * 2024.01.20
 * JH7UBC Keiji Hata
*/

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

void putch(uint8_t ch)
{
      EUSART_Write(ch);
}

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

     int data = 0;
     uint8_t channel = 17;//ANC1 RC1
     while (1)
    {
         data = ADC_GetConversion(channel);
         printf("channel %2d = ",channel);
         printf("%4d\r\n",data);
         __delay_ms(1000);
    }
}
--------------------------------------------------------------------------
 purch()関数を定義して、printf()関数を使って送信します。
 Project PropatiesでC StandardをC90にします。

 ブレッドボードです。


 VRを回して、電圧を変えて、ADCの値を表示させました。


 10bitのADCですので、値は0~1023の間で変化します。

PIC16F18326 MCC PWMテスト(ICSP)

2024-01-20 14:17:59 | MPLAB X MCC
 PIC16F18326のPWMのテストをします。
 環境は、MPLAB X(v6.15) XC8(v2.45) MCC(v5.3.7)です。 

 テストした回路です。ライターはPICKit3を使い、ICSPでテストをしました。



 MPLAB Xでprojectを作成し、MCCを立ち上げ、各種設定をします。

 まず、system moduleでクロックの設定をします。下のように設定し、クロック4MHzとしました。


 PIC16F18326ではPWM5とPWM6を使用できます。今回は、PWM5を使うことにして、PWM5を導入します。また、PWM5でタイマーとしてTimer2を使いますので、TMR2も導入します。



 TMR2で、PWMの周波数を設定します。今回、下のように設定し周波数は1KHzとしました。


 この状態で、GenerateしてMCCを閉じ、main.cを最小限の状態で、buildして、ICSPでPICに書き込みます。
----------------------------------------------------
#include "mcc_generated_files/mcc.h"
void main(void)
{
     // initialize the device
     SYSTEM_Initialize();
     while (1)
    {
    }
}
----------------------------------------------------
 プログラムには何も書いていないのですが、MCCで設定したとおり、1KHz,Duty Cycle 50%のPWM出力が得られました。


 Duty比を変えるには、PWM5_LoadDutyValue()関数を使います。
 PWM5モジュールの中で、Duty0 Cycle50%の時、PWMDC Valueが499ですから、Duty Cycle 20%のPWMを得るには、main()の中で、PWM5_LoadDutyValue(200);とします。その時の波形です。


 これは、PWM Polarity active_hiの状態です。MCCでPWM5モジュールでPWM Polarity active_loにすると次のようになります。


 PIC16F18326では、PWMの出力をRA3を除くすべてのポートに出力することができます。ポートの指定は、MCCで設定できます。また、複数のポートに出力することもできます。

 LEDの明るさをPWMで明るくなったり暗くなったりするプログラムです。
------------------------------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
     // initialize the device
     SYSTEM_Initialize();
     while (1)
    {
         for(int i=0;i<1000;i++){
             PWM5_LoadDutyValue(i);
             __delay_ms(1);
         }
         for(int i=1000;i>0;i--){
             PWM5_LoadDutyValue(i);
             __delay_ms(1);
         }
    }
}
------------------------------------------------------------
ブレッドボードです。ICSPでプログラムを書き込み、PICの電源は、PICKit3から供給しています。



PIC16F18326 MCC シリアル通信テスト

2024-01-18 17:07:47 | MPLAB X MCC
 PIC16F18326のシリアル通信のテストをします。
 環境は、MPLAB X(v6.15) XC8(v2.45) MCC(v5.3.7)です。

 テストする回路です。パソコンとの通信には、秋月電子のUSBシリアル変換モジュールFT-234を使います。電源もこのモジュールから供給します。


 MPLAB Xでprojectを作成し、MCCを立ち上げ、各種設定をします。

 まず、system moduleでクロックの設定をします。下のように設定し、クロック4MHzとしました。


 シリアル通信を行うために、EUSARTモジュールを導入します。
 設定は特に行わず、デフォルトのままです。通信速度は9600bpsです。


 pin moduleです。特に設定はしません。RC4がTXにRC5がRXピンになります。


 テストプログラムです。
---------------------------------------------------------------------
/*
 * PIC16F18326 MCC Serial com. test
 * 2024.01.18
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"

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

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

     uint8_t data;
     int i = 0;
     while (1)
    {
         data = EUSART_Read();
         printf("%3d ",i);
         EUSART_Write(data);
         printf("\r\n");
         i++;
    }
}
---------------------------------------------------------------------

 putch()関数を定義しましたので、printf()関数を使うことができます。
 今回、C standardがC99のままでもエラーは出ませんでした。

 ブレッドボードです。

 パソコンでTeraTermを立ち上げて、9600bpsで通信を行います。

 0からカウントアップされる数字が表示され、キーボードから入力された文字が表示されます。


PIC16F18326 MCC I2C LCD1602表示テスト

2024-01-14 19:45:34 | MPLAB X MCC
 こちら喜多方市熱塩加納町は、1月12日に降った雪が15cmほど積もっています。近くにある日本で一番すいているスキー場「三ノ倉スキー場」が営業を再開しました。

 雪が降ると、なんだか落ち着くようなきがします。炬燵にあたってPICの勉強を再開しました。PIC18Fシリーズの勉強は一旦棚上げして、PIC16F18326の各種テストをします。このPICは、秋月電子でまだ250円で入手でき、サイズ、機能からもコスパの良いPICだと思います。

 PIC16F18326では、AQM0802AとOLEDの表示テストを既にしていますので、定番のI2C LCD1602の表示テストをします。

 回路図です。I2Cのプルアップ抵抗は、LCD1602に内蔵されているので付けていません。


 MPLAB X(v6.15を使いました)とXC8(v2.45)でprojectを作成し、MCCを立ち上げます。
 MCCで各種の設定をします。まず、System moduleでクロックを設定します。今回は下のように設定し、クロックは4MHzです。

 

 I2Cを使いますので、MSSP1 moduleを導入し、次のように設定しました。
 I2C Clockは100KHzです。割り込みを使いますので、Interrupt Drivenにチェックを入れます。


 Interrupt moduleを次のように設定しました。



 これでGenerateし、MCCを終了します。
 生成されたソースリストmain.cを次のように編集しました。
 内容は、これまで当ブログやJH7UBCホームぺージで発表したものと同じです。
---------------------------------------------------------------------------------
/*
 * PIC16F18326 MCC I2C LCD1602 test
 * 2024.1.13
 * JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.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){
I2C1_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,cursol 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);
}
}

//文字列の表示
void LCD_str(char *str){
while(*str)
LCD_write(*str++,LCD_CHR); //pointer increment
}

//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();
     char msg[] = "Hello World!";
     LCD_str(msg);
     int count = 0;
     while (1){
         LCD_cursor(2,1);
         printf("%3d",count);
         count++;
         __delay_ms(1000);
     }
}
---------------------------------------------------------------------------------
 printf()関数を使っていますので、このままコンパイル(build)するとエラーがでますので、project propertiesを開き、XC8 Global OptionsのC StandardをC90に変更します。
 PICKit3でPICに書き込み、ブレッドボードでテストしました。
 1行目に「Hell World!」が表示され、2行目に数字がカウントアップされました。





PIC16F1827 MCC TMR2 割込みテスト

2023-03-19 20:13:06 | MPLAB X MCC
 久しぶりにPICの記事です。

 PIC16F1827を使って、MPLAB X+ XC8 + MCCという環境で周波数カウンタを作ってみようと思っています。その準備段階でPC16F1827のTMR2割込みのテストをします。具体的には、TMR2で0.5s(500ms)ごとに割込みを発生させ、LEDを点滅させてみます。なお、MPLAB XはV6.00をXC8はv2.40を使っています。

 回路図です。LEDは、RA2に接続します。


 プロジェクトを作成してからMCCで各種の設定を行います。
 まず、Syatem moduleの設定です。
 クロックは、内部クロック4MHzとしました。Low-voltage Programming Enableはチェックを外しておきます。RA2はoutputに設定します。


 TMR2(8bit timer)を導入して設定します。設定の前にTMR2の構造を見ておきます。

 TMR2のクロックソースは、Fosc/4です。今回Fosc=4MHzですから1MHz(1us)がTMR2に入ります。
 Prescalerは、1:1~1:64の間で設定できます。今回は1:4としました。TR2には、250KHz(4us)が入ります。PR2(プリセットレジスタ 8bit)とPostscalerを設定することによりTMR2出力の周期を設定することができます。
 MCCでは、Postsaclerの分周比とTimer Periodを設定すれば自動的にPR2の値が設定されます。(PR2は8bitのため設定できる周期の範囲が表示されます)今回は、Postscaler 1:10 とし、Timer Period10msとしました。


 更に、Softwear Setting で、50倍して、Callback Function Rateを500msとしたました。

 Interrupts moduleの設定です。
 Single ISR interruptとTMR2 のEnableにチェックを入れます。



 MCCの設定は以上です。Generateして各種cファイルを生成します。

 main.cです。
 Global InterruptsとPeripheral Interruptsを有効にします。
 RA2に接続したLEDは最初消しておき、TMR2をスタートさせます。
----------------------------------------------------------------------------------
#include "mcc_generated_files/mcc.h"
void main(void)
{
     // initialize the device
     SYSTEM_Initialize();

     // Enable the Global Interrupts
     INTERRUPT_GlobalInterruptEnable();

     // Enable the Peripheral Interrupts
     INTERRUPT_PeripheralInterruptEnable();

     LATA2 = 0;
     TMR2_StartTimer();//TMR2 start
     while (1)
    {
    }
}
----------------------------------------------------------------------------------

 さて、TMR2割込みがあった時の処理ルーチンはどこに書いたら良いのでしょうか。簡単には分からずあれこれやってもうまくいかず、分かるまで丸1日かかってしまいました。各cファイルをよく読めばわかるのですが、英文なので・・・・

 timer.cファイルの中のTMR2_CallBack()関数の中に処理を書きます。
 今回は、RA2に接続したLEDを点滅させるだけなので、LATA2を反転させる式 LATA2 = 1 - LATA2;を書き込みました。
----------------------------------------------------------------------------------
void TMR2_CallBack(void)
{
    LATA2 = 1 - LATA2;
     // Add your custom callback code here
     // this code executes every TMR2_INTERRUPT_TICKER_FACTOR periods of TMR2
     if(TMR2_InterruptHandler)
    {
         TMR2_InterruptHandler();
    }
}
----------------------------------------------------------------------------------
 これで、コンパイル書き込みをしました。RA2に接続したLEDが0.5秒ごとに点滅しました。

 MCCを利用したTMR割込みの例をネットで探したのですが、あまり見つけることができす、四苦八苦でした。これからMCCを利用してタイマー割込みをやってみようという方の参考になれば幸いです。