1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PICマイコン MP3プレイヤーDFPlayerMini音声再生 

Last updated at Posted at 2025-11-26

シリアル通信で制御できるMP3プレイヤー

DFPlayerMini 秋月電子で購入。 SDカードの読み出し、DAコンバータ出力、アンプ出力をやってくれます。 コマンドを一つ出せば、すぐに音声ファイルを再生してくれます。 スピーカを直接接続できます。

IMG_5383.JPG

内蔵のオペアンプも、いい音を出します。

ピン配.jpg

DFPlayerMini 電源の配線

電源ラインが細いもしくは、長いと、スピーカーが発振したり、ノイズが出ます。
なので、ブレッドボードで配線する場合、VCC、GNDともに、2本のジャンパー線をつなげました。
DFPlayerMiniUSBシリアル回路図.png

上図の回路図は、パソコンとシリアル通信するときの回路です。

マイコン回路図3.png

マイコンの電源を5Vで駆動する場合は、シリアルのTX,RX線を1kΩの抵抗を介して接続、Busy端子もPchFET または、トランジスタを介して接続させます。

マイコンを3.3Vで動かすとDFPlayerの定格と合致するので、直接接続できますが、念のため、抵抗を介して配線しても、動作に問題はありません。

DFPlayerMini シリアル通信設定

baudrate:9600(固定)
Databits:8
Paritybits:なし
Stopbit:1
ハンドシェーク:なし

下図は、パソコンから、シリアル通信で、DFPlayerに指示を出した時のやり取り。
シリアルフォーマット中身.png
フォルダ指定再生コマンド(0x0F)と、再生終了レスポンス(0x3D)の中身。再生が終わるたびに、コマンド0x3Dが2回返信されてきます。

DFPlayerMini トラック番号について

トラック指定で再生されるファイルの順番は、SDカードに保存された順番です。
ファイル名と、SDカードに保存された順番は、必ずしも一致するとは限りません。
普通に、ドラッグアンドドロップで、大丈夫ですが、万一、
再生の順番がおかしいと感じたら、SDカードに保存した順番が入れ違いになっている可能性があります。

DFPlayerMini 再生ファイルのフォーマットについて

mp3、wavファイルは、ステレオでフォーマットされている必要があります。
モノラル形式で保存された場合、再生はされますが、再生終了レスポンス(0x3D)が正常に動作しません。
再生終了レスポンス(0x3D)は、通常2つ連続で返信されてきます。つまり、LeftとRightのデータが終端に到達すると、2つのレスポンスが送信されるようになっていると、想定されます。
なので、モノラルのばあい、LEFT、RIGHT双方のデータが格納されている必要があります。片方だけのファイルの場合、DFPlayerMiniが正常に動作しないと想定されます。
音声ファイルの基本構造.jpg

DFPlayerMini シリアル通信 通信フォーマット

$7 VER Len CMD Feedback para1 para2 checkSum1 checkSum2 END
7E FF 06 xx 00 xx xx xx xx EF(checksumあり10byte)
7E FF 06 xx 00 xx xx EF(checksumなし8byte)

パケット図.jpg

パケットは、チェックサムありの10バイト、なしの8バイト。どちらでも、通信できます。

バイト番号   意味
0 $S ヘッダー 0x7E 開始文字
1 VER バージョン 0xFF バージョン情報
2 Len 送信長   0x06  このバイト以降の送信数
3 CMD コマンド
4 Feedback レスポンス 0x0- 0x00:なし 0x01:あり
5 para1 パラメータ1 0x-- 上位バイト
6 para2 パラメータ2 0x-- 下位バイト
7 checkSum チェックサム1 0x-- 上位バイト
8 checkSum チェックサム2 0x-- 下位バイト
9 END フッター 0xEF 終端文字

チェックサムの計算方法
チェックサム計算方法.jpg
revisionからpara2までの6バイトを対象にします。
6バイトを単純に16ビット変数で、加算します。
それから、上記のように、XORをとりビットを反転させます。
さらに1を加算すると、2の補数になります。
6バイトの合計とチェックサムを足すと、ゼロになります。

DFPlayerMini 設定コマンド群 (返信なし)

最もよく使うコマンド群です。

コマンド送信フォーマット
7E FF 06 CMD 00 para1 para2 xx xx EF (10byte)
7E FF 06 CMD 00 para1 para2 EF (8byte)
※チェックサムはなくても、OK。

CMD 機能 パラメータ(2byte) 内容
0x01 Next -
0x02 Previous -
0x03 Specify Track 0-2999 再生:トラック番号
0x04 IncreaseVolume 音量+
0x05 DecreaseVolume 音量ー
0x06 SpecifyVoluem 0-30 音量設定
0x07 SpecifyEQ 0-5 Normal/Pop/Jazz/Classic/Base
0x08 PlayMode 0-3 リピート、シングル再生設定
0x09 PlaySource 0-4 再生デバイス設定
0x0A StanbyMode スタンバイ設定
0x0B NormalWorking ?
0x0C ResetModue リセット
0x0D PlayBack 再生
0x0E Pause 一時停止
0x0F Specify folder 01-99,001-255 再生:フォルダ、トラック指定
0x10 VolumeAdjust ?
0x11 RepeatPlay ?
0x16 Stop 停止

基本3コマンド.jpg

DFPlayerMini 再生終了レスポンス

再生終了時に、DFPlayerから返信されるパケットです。
コマンド0x3DはSDカードでの終了を意味します。
トラック番号は、ファイル名ではなく、SDカードに登録された順番になります。

受信:7E FF 06 3D 00 para1 para2 xx xx EF (10byte)

CMD パラメータ 内容
0x3D トラック番号 再生終了

DFPlayerMini エラーレスポンス

コマンドの内容にエラーがあった場合のFDPlayerが送信する返信パケット
受信:7E FF 06 40 00 00 00 xx xx EF (10byte)

CMD パラメータ1 パラメータ1
0x40 エラーコード1  エラーコード2

エラーコード

エラーコード1 エラーコード2 内容
0x00 0x00 Module busy
0x00 0x01 ?
0x00 0x02 ?

DFPlayerMini Queryコマンド(質問コマンド、返信あり)

DFPlayer内の設定やステータスを読むためのクエリーコマンド群です。

コマンド送信(0x4E) フォルダ内のトラック数をしらべる

7E FF 06 4E 00 00 para1 xx xx EF (10byte)
7E FF 06 4E 00 00 para1 EF (8byte)
para1にフォルダ番号を指定

レスポンス
7E FF 06 4E 00 para1 para2 xx xx EF (10byte)

CMD パラメータ1 パラメータ1 内容
0x4E 上位バイト 下位バイト トラック数

コマンド送信(0x4F) ルートのフォルダ数を調べる

7E FF 06 4F 00 00 00 xx xx EF (10byte)
7E FF 06 4F 00 00 00 EF (8byte)

レスポンス
7E FF 06 4F 00 para1 para2 xx xx EF (10byte)

CMD パラメータ1 パラメータ1 内容
0x4F 上位バイト 下位バイト SDカードのフォルダ数

DFPlayerMini ドライバーコード

DFPlayerMiniの初期化処理は、まったくありません。ただし、音量がデフォルトで、MAX30になっているので、音量を起動時に下げておく必要があります。あとは、再生コマンドを送信すれば、音声を再生できます。

初期化再生フロー.jpg

チェックサムは、パケットのrevisionからpara2までの6バイトを単純に加算した後、その値を2の補数に変換します。それがチェックサムになります。

PICマイコンの電源は、3.3V。
DFPlayerMiniの電源も、3.3V。
PICマイコンのRB3に、DFPlayerのBusy端子を接続しています。
Busy端子はアクティブロー出力で、Lowのときは再生中。Highのときは、停止中です。
このBusy信号をポーリングして、つぎの曲の再生コマンドを送信します。

PIC16F1827ピン配

pin name 機能 説明 pin name 機能 説明
17 RA0 IO入力 スイッチ 6 RB0
18 RA1 7 RB1 MSSP1 I2C1 SDA1
1 RA2 8 RB2 USART RX
2 RA3 9 RB3 Busy信号 DFPlayer
3 RA4 10 RB4 MSSP1 I2C1 SCK1
7 RA5 /MCLR 11 RB5 USART TX
15 RA6 12 RB6 ICSCLK 書き込み線
16 RA7 13 RB7 ICSDAT 書き込み線

マイコン回路図.png

DFPlayer.h
/* 
 * File:   DFPlayer.h
 * Author: h
 *
 * Created on 2025/11/20, 9:21
 */

#ifndef DFPLAYER_H
#define	DFPLAYER_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <xc.h>    
    
//コマンド
#define CMD_Next            0x01
#define CMD_Previous        0x02
#define CMD_SpecifyTrack    0x03 //0-2999
#define CMD_IncVolume       0x04        
#define CMD_DecVolume       0x05
#define CMD_SpecifyVol      0x06 //0-30
#define CMD_SpecifyEQ       0x07 //Normal/Pop/Rock/Jazz/Classic/Base
#define CMD_SpecifyPlayMode     0x08 //Repeat/folder repeat/single repeat/random
#define CMD_SpecifyPlaySouce    0x09 //0:U 1:TF
#define CMD_EnterStanby     0x0A
#define CMD_NormalWorking   0x0B
#define CMD_Reset           0x0C
#define CMD_PlayBack        0x0D
#define CMD_Pause           0x0E
#define CMD_SpecifyFolder   0x0F //1-10(need to set by user)
#define CMD_VolumeAdjust    0x10
#define CMD_RepetPlay       0x11 1:start repeat 0:stop play
#define CMD_Stop            0x16
#define CMD_Q_FileNumber    0x4E
#define CMD_Q_FolderNumber   0x4F
    
//チェックサム用    
typedef struct
{
    uint8_t high;//7バイト目
    uint8_t low;//8バイト目
}_DFPlayer_checkSum;

/*
 * 送信データセット用構造体
 *コマンドフォーマット
 *[0][1][2][3] [4] [5]  [6]   [7]  [8]  [9]
 * 7E FF 06 CMD 00 parm1 para2 chs1 chs2 EF
 */
typedef union
{
    struct{
        uint8_t header;    //0バイト目
        uint8_t version;   //1バイト目
        uint8_t length;    //2バイト目
        uint8_t cmd;       //3バイト目
        uint8_t feedBack;  //4バイト目
        uint8_t para1;     //5バイト目
        uint8_t para2;     //6バイト目
        _DFPlayer_checkSum checkSum; //7,8バイト目
        uint8_t fotter;    //9バイト目
    };
    uint8_t txData[10];//送信バッファ
}_DFPlayer_txData;

typedef struct
{
    uint8_t maxTrackNumber;     //総トラック数(指定フォルダ内)
    uint8_t maxFolderNumber;    //総フォルダ数
}_DFPlayerData;

extern _DFPlayerData DFPlayerData;
extern _DFPlayer_txData DFPlayer;

//DFPlayer制御関数
extern void DFPlayerInitialize(void);
extern void DFPlayerCalcCheckSum(void);
extern void DFPlayerSendCommand(uint8_t cmd, uint8_t para_high, uint8_t para_low);
//コマンド
extern void DFPlayerStop(void); //再生停止(0x16)
extern void DFPlayerQueryMaxTrackNumber(uint8_t folderNumber);//ファイル数(0x4E)
extern void DFPlayerQueryMaxFolderNumber(void); //フォルダ数(0x4F)


#ifdef	__cplusplus
}
#endif

#endif	/* DFPLAYER_H */
DFPlayer.c
#include "DFPlayer.h"
#include "Peripheral.h"
#include "LCDdriver.h"

_DFPlayerData DFPlayerData;
_DFPlayer_txData DFPlayer;

/**
 * 関数名:DFPlayerInitialize
 * 初期化関数
 * 使用上特別に設定することはなし。
 * 音量は、MAX30がデフォルトなので、下げる。
 */
void DFPlayerInitialize(void)
{
    //コマンドパケットのセット(定型部分を先にセット)
    DFPlayer.header = 0x7E;
    DFPlayer.version = 0xFF;
    DFPlayer.feedBack = 0x00;
    DFPlayer.length = 6;
    DFPlayer.fotter = 0xEF;
    
    //起動待機 ------------------------------
    __delay_ms(1000);
    //音量設定コマンド (0x06)-----------------
    DFPlayerSendCommand(CMD_SpecifyVol,0x00,0x19);
    __delay_ms(100);
}

/**
 * 関数名:DFPlayerCalcCheckSum
 * チェックサムを求める
 * Versionからpara2まで、
 * 単純加算後、2の補数として計算する。
 */
void DFPlayerCalcCheckSum(void)
{
    uint8_t i;
    uint16_t buf; 
    
    buf=0;
    for(i=1; i<=6; i++)
    {
        buf+=DFPlayer.txData[i];
    }
    //2の補数にする。
    buf =buf^0xFFFF;
    buf+=1;
    DFPlayer.checkSum.high = (uint8_t)(buf>>8);
    DFPlayer.checkSum.low = (uint8_t)(buf&0x00FF); 
}

/**
 * 関数名:DFPlayerSendCommand
 * コマンド送信
 * 定型部分は、初期化関数でセットしてある。
 * @param cmd コマンド
 * @param para_high パラメータ上位バイト
 * @param para_low パラメータ下位バイト
 */
void DFPlayerSendCommand(uint8_t cmd, uint8_t para_high, uint8_t para_low)
{
    uint8_t i;
    
    DFPlayer.cmd=cmd;          //コマンドのセット
    DFPlayer.para1 = para_high;//パラメータ1のセット
    DFPlayer.para2 = para_low; //パラメータ2のセット
    DFPlayerCalcCheckSum();//チェックサムの計算とデータセット
    for(i=0; i<=9; i++)
    {
        putch(DFPlayer.txData[i]);//パケット10バイトの送信
    }
}

//コマンド群-----------------------------------------------------
/**
 * 関数名:DFPlayerStop
 * 再生停止コマンド
 */
void DFPlayerStop()
{
    DFPlayerSendCommand(CMD_Stop,0x00,0x00);
}

/**
 * 関数名:DFPlayerQueryMaxTrackNumber
 * 指定したフォルダ内のファイル数を読みだす。
 * @param folderNumber 検索するフォルダ番号01-99
 */
void DFPlayerQueryMaxTrackNumber(uint8_t folderNumber)
{
    uint8_t length=0;//sprint用
    uint8_t txt[3];//LCD用
    
    DFPlayerData.maxTrackNumber=0x00;
    DFPlayerSendCommand(CMD_Q_FileNumber,0x00,folderNumber);
    //レスポンス待機開始。
    RCSTAbits.CREN=1;
    PIE1bits.RCIE=1;  
    while(!usart.rxCompleted);
    if(usart.rxBuf[3]==CMD_Q_FileNumber)
    {//受信成功
        length = sprintf(txt,"%02d",usart.rxBuf[6]);
        LCD_Printf(LcdDeviceAdd,txt,length,0x8C);
        DFPlayerData.maxTrackNumber=usart.rxBuf[6];
    }
    RCSTAbits.CREN=1;
    PIE1bits.RCIE=1;
    usart.rxCompleted=false;
    usart.length=0;
}

/**
 * 関数名:DFPlayerQueryMaxFolderNumber
 * ルートにあるフォルダの数を取得
 * 隠れファイルが一つあるので、マイナス1する。
 */
void DFPlayerQueryMaxFolderNumber(void)
{
    uint8_t length=0;
    uint8_t txt[3];
    
    DFPlayerData.maxFolderNumber=0x00;
    DFPlayerSendCommand(CMD_Q_FolderNumber,0x00,0x00);
    //レスポンス待機開始。
    RCSTAbits.CREN=1;
    PIE1bits.RCIE=1;  
    while(!usart.rxCompleted);
    if(usart.rxBuf[3]==CMD_Q_FolderNumber)
    {//受信成功
        length = sprintf(txt,"%02d",usart.rxBuf[6]);
        LCD_Printf(LcdDeviceAdd,txt,length,0x8C);
        DFPlayerData.maxFolderNumber=usart.rxBuf[6]-1;//隠れファイル-1
    }
    RCSTAbits.CREN=1;
    PIE1bits.RCIE=1;
    usart.rxCompleted=false;
    usart.length=0;
}
main.c

// PIC16F1827 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#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 MCLR)
#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 enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#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 = ON       // PLL Enable (4x PLL enabled)
#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 DEBUG = ON       // In-Circuit Debugger Mode (In-Circuit Debugger enabled, ICSPCLK and ICSPDAT are dedicated to the debugger)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdlib.h>
#include <stdio.h>
#include "Interrupt.h"
#include "Peripheral.h"
#include "I2C_MSSP1.h"
#include "LCDdriver.h"
#include "DFPlayer.h"


void Oscillator_Init(void);
void Port_Init(void);

uint8_t txt[20];//LCD用

void main(void)
{    
    uint8_t length;//sprint用
    uint8_t trackNumber,folderNumber;
    
    //MCU初期化
    Oscillator_Init();
    Port_Init(); 
    //Peripheral initializing
    USART_INIT();//USART初期化
    I2C1_Reg_Init();//MSSP1初期化
    LCD_Init(LcdDeviceAdd);//LCD初期化
    //LCD初期化後は、I2Cの速度を上げる
    //SSP1ADD=0x13;  //Fosc=32MHz Fclock=400kHz
    SSP1ADD=0x09;//Fosc=32MHz Fclock=800kHz
    
    //DFPlayer初期化
    DFPlayerInitialize();
    DFPlayerData.maxTrackNumber=3; //総トラック数(特定フォルダ内)
    DFPlayerData.maxFolderNumber=3;//総フォルダ数
    folderNumber=1;//フォルダ番号カウンタ
    trackNumber=1;//トラック番号カウンタ
    //LCD表示
    LCD_Printf(LcdDeviceAdd,"Folder:",7,0x80);
    LCD_Printf(LcdDeviceAdd,"PlayNumber:",11,0xC0);
    //割り込み許可
    Interrupt_START();
 
//例:総フォルダ数、総トラック数を取得する関数    
//#define EN1    
#ifdef EN1 
    //SDカードのルートにある総フォルダ数の取得
    DFPlayerQueryMaxFolderNumber();
    while(PORTAbits.RA0==1);
    __delay_ms(300);
    //フォルダ01にあるトラック数の取得
    DFPlayerQueryMaxTrackNumber(1);
    while(PORTAbits.RA0==1);
    __delay_ms(300);
#endif    
    while(1)
    {
        //USART 受信割り込み処理
        if(usart.rxCompleted)
        {
            LATAbits.LATA2=~LATAbits.LATA2;
            //レスポンスの内容を表示。
            usart.rxCompleted=false;
            usart.length=0;
        }

        //再生コマンド処理 RB3にDFPlayerのBusy端子がつながっています。
        if(PORTBbits.RB3==1)//再生停止中。Busy信号:1 再生中:0
        {
            //再生コマンド送信
            DFPlayerSendCommand(CMD_SpecifyFolder, folderNumber, trackNumber);
            //LCDに再生場所を表示     
            length = sprintf(txt,"%02d",folderNumber);
            LCD_Printf(LcdDeviceAdd,txt,length,0x87);   
            
            length = sprintf(txt,"%03d",trackNumber);
            LCD_Printf(LcdDeviceAdd,txt,length,0xCB);   
            //フォルダ番号とファイル番号のカウント
            trackNumber++;
            if(trackNumber>DFPlayerData.maxTrackNumber)
            {
                trackNumber=1;
                folderNumber++;
                if(folderNumber>DFPlayerData.maxFolderNumber)
                {
                    folderNumber=1;
                }
            }

            while(PORTBbits.RB3==1);
            RCSTAbits.CREN=1;
            PIE1bits.RCIE=1;                
        }
       
        
    }
    return;
}

//外付けセラロック8MHzを使用Fosc=8*4=32MHz
void Oscillator_Init(void)
{
    OSCCONbits.SPLLEN=1;
    //OSCCONbits.IRCF=0b1110;//8Mhz
    OSCCONbits.SCS=0b00;// Clock determined by FOSC<2:0> 
}

void Port_Init(void)
{
    TRISA=0x01;     //ボタン入力
    ANSELA=0x00;
    
    TRISB=0x08;     //RB3:DFPlayer Busy信号入力
    ANSELB=0x00;
    PORTA=0x00;
    PORTB=0x00;  
    //Altanative Pin Selective
    APFCON0bits.RXDTSEL=1;  //RX:RB2
    APFCON1bits.TXCKSEL=1;  //TX:RB5
    TRISBbits.TRISB2=1;
    //I2Cinitialize
    TRISBbits.TRISB1=1;     //RB1
    TRISBbits.TRISB4=1;     //RB4
}


interrput.h
#ifndef INTERRUPT_H
#define	INTERRUPT_H

#ifdef	__cplusplus
extern "C" {
#endif
    
    extern void __interrupt()isr();



#ifdef	__cplusplus
}
#endif

#endif	/* INTERRUPT_H */

interrupt.c
#include <pic16f1827.h>
#include "Peripheral.h"
#include "Interrupt.h"
#include "I2C_MSSP1_Slave.h"

void __interrupt()isr()
{
    uint8_t ch;
    uint8_t temp;
   
    //USART受信割り込み処理
    if(PIE1bits.RCIE==1 &&  PIR1bits.RCIF)
    {
        LATAbits.LATA1=~LATAbits.LATA1;
        PIR1bits.RCIF=0;
        //USART error check-----------------------
        if(RCSTAbits.OERR)
        {
            RCSTAbits.CREN=0;
            RCSTAbits.CREN=1;
        }
        if(RCSTAbits.FERR)
                temp=RCREG;
        //受信バッファから取り出し-------------------
        ch =(uint8_t)getch();
        usart.rxBuf[usart.length++]=ch;
        //-----------------------------------
        if(usart.length>=rxLength)
        {//受信バッファが満杯。
            usart.length=0;
            usart.rxCompleted=true;
            RCSTAbits.CREN=0;
            PIE1bits.RCIE=0;           
        }
        //受信完了
        if(ch==0xEF && usart.length==0x0A)
        {//終端文字の受信
            usart.rxCompleted=true;
            RCSTAbits.CREN=0;
            PIE1bits.RCIE=0;
        }
       
    }
  
}
Peripheral.h

#ifndef PERIPHERAL_H
#define	PERIPHERAL_H

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

#define _XTAL_FREQ 32000000

#ifdef	__cplusplus
extern "C" {
#endif

//**************************************************//    
//   USART 
//**************************************************//    
#define BAUDRATE 9600
//#define BAUDRATE 115200  
#define SET_SPBRG_DATA2  (((unsigned int)((_XTAL_FREQ/64)/BAUDRATE))-1)
#define SET_SPBRG_DATA  (((unsigned int)((_XTAL_FREQ/16)/BAUDRATE))-1)
#define SET_SPBRG_DATA1 (((unsigned int)((_XTAL_FREQ/4)/BAUDRATE))-1)    
extern void USART_INIT(void);
//extern void putch(uint8_t byte);
//extern uint8_t getch(void);
#define rxLength 11
typedef struct {
    uint8_t length;
    uint8_t rxBuf[60];
    bool rxCompleted;
}_usart;    
extern volatile _usart usart;

#define rxBuffer_length 30
typedef struct{
    uint8_t ch;
    uint8_t Buffer[rxBuffer_length];
    uint8_t index;
    uint8_t Completed;
}_rx;
extern _rx rx;

//************************************************//
//Timer0 8bits timer
//************************************************//
#define T0_UP 1
#define T0_STOP 0
typedef struct{
    bool up;
    uint16_t cnt;
}_tm0;    
extern _tm0 tm0;

//************************************************//
//Timer1
//************************************************//
#define T1_UP 1
#define T1_STOP 0
typedef struct{
    bool up;
    uint16_t cnt;
}_tm;    
extern _tm tm1;

//************************************************//
//ADC
//************************************************//
#define ADC_Sampling_Num 10    
typedef struct{
    uint8_t Ch;
    uint16_t val;
    bool    Completed;
    uint16_t data[ADC_Sampling_Num+1];
    uint8_t index;
    uint16_t RMS;
    int32_t cal;
}_ADC;
extern _ADC ADC;

extern void Timer0_INIT(void);
extern void Timer1_INIT(void); 
extern void Timer2_INIT(void);
extern void Timer4_INIT(void);
extern void Timer6_INIT(void);
extern void Interrupt_START(void);
extern void ADC_INIT(void);
extern void CCP1_PWM_Init(void);
extern void CCP2_PWM_Init(void);
extern void CCP3_PWM_Init(void);
extern void CCP4_PWM_Init(void);
#ifdef	__cplusplus
}
#endif

#endif	/* MYLIB_H */
peripheral.c

#include "Peripheral.h"

/*-----------------------------------------
 *USART
 *-----------------------------------------*/
volatile _usart usart;
_rx rx;
void USART_INIT(void)
{
    uint8_t buf;
    unsigned int brg;
    //SPBRG value set
    brg = SET_SPBRG_DATA2;
    SP1BRGL =(unsigned char) brg;
    SP1BRGH =(unsigned char) (brg>>8); 
    //TX-------------------------------------
    TXREG=0x00;
    //TXSTA SYNC:1 BRGH:1 TXEN:1 TX9:0
    buf =TXSTA & 0x83;
    TXSTA = buf | 0x20;
    //TXSTA = buf | 0x24;
    //RX-------------------------------------
    //RCSTA  SPEN:1 RX9:0 CREN:1
    buf =RCSTA & 0x2F;
    RCSTA =buf | 0x90;
    //BAUR RATE CONTROL REGISTER
    BAUDCON = 0x00;
    //BAUDCON = 0x08;
    //if interrupt is desired, TXIE set(PIE1)
    PIE1bits.TXIE=0;//disable
    //if interrupts are desired, RCIE set(PIE1)
    PIE1bits.RCIE=1;//enable
    
    usart.length=0;
    usart.rxCompleted=false;
}

void putch(char byte)
{
    while(!PIR1bits.TXIF)continue;
    TXREG=byte;
}

int getch(void)
{
    while(!PIR1bits.RCIF){};
    return RCREG;
}



/*---------------------------------------------------
 Timer0     8bits Timer 
 ---------------------------------------------------*/
_tm0 tm0;
void Timer0_INIT(void)
{
    OPTION_REGbits.TMR0CS = 0;  //ClockSource:Fosc/4
    OPTION_REGbits.PSA = 0;     //assingned to the Timer0
    OPTION_REGbits.PS = 0b111;  //1:256
    TMR0=0x63;  //Fosc:32Mhz interval time 10ms
    INTCONbits.T0IE = 1;
    tm0.cnt=0;
}


/*---------------------------------------------------
 Timer1
 ---------------------------------------------------*/
 _tm tm1;
void Timer1_INIT(void)
{
    TMR1L=0x0B;//16MHz 1ms PSC:1:8
    TMR1H=0xFE;
    T1CON=0x31;    
    T1GCON=0x00;
    PIE1bits.TMR1IE=1;
    tm1.up=T0_STOP;
    tm1.cnt=0x0000;
}

/*-------------------------------------------
Timer2
--------------------------------------------*/
void Timer2_INIT(void)
{
    T2CONbits.T2OUTPS=0b0000;//post sc 1:1
    T2CONbits.T2CKPS=0b00;//PSC 1:1
    T2CONbits.TMR2ON=1;
    PR2=0x50;//10us matching. Fosc=32Mhz
    TMR2=0;
    PIR1bits.TMR2IF=0;
    PIE1bits.TMR2IE=1;
}

/*---------------------------------------------------
 Timer4
 ---------------------------------------------------*/
void Timer4_INIT(void)
{
    T4CONbits.T4OUTPS=0b1111;//1:16 Postscaler
    TMR4=0;
    T4CONbits.T4CKPS=0b01;//prescle1:4
    PR4=0x4B;
    PIE3bits.TMR4IE=1;
    PIR3bits.TMR4IF=0;
    T4CONbits.TMR4ON=1;
}

/*---------------------------------------------------
 Timer6
 ---------------------------------------------------*/
void Timer6_INIT(void)
{
    T6CONbits.T6OUTPS=0b0000;//1:16 Postscaler
    T6CONbits.T6CKPS=0b11;//prescle1:16
    T6CONbits.TMR6ON=1;
    PR6=0xFA;
    TMR6=0;
    PIR3bits.TMR6IF=0;
    PIE3bits.TMR6IE=1;
}
//interrupt start
void Interrupt_START(void)
{
    INTCONbits.PEIE=1;
    INTCONbits.GIE=1;
}
/*---------------------------------------------------
 AD converter
 -------------------------------------------------------*/
_ADC ADC;
void ADC_INIT(void)
{
    uint8_t buf;
    
    //1.Configure PortA
    buf=TRISA;
    TRISA=buf|0x01;
    ANSELA|=0x01;
  
    //2.Configure the ADC module
    ADCON1bits.ADFM=1;      //Right justified.
    ADCON1bits.ADCS=0b101;  //FOSC/16  Select ADC conversion clock
    ADCON1bits.ADNREF=0;    //Vref-:AVss Configure voltage referrence 
    ADCON1bits.ADPREF=0b00; //Vref+ is connected to Vdd.
    ADCON0bits.CHS=0x00;    //RA0:Select ADC input channel
    
    //Turn on ADC module
    ADCON0bits.ADON=1;
    PIR1bits.ADIF=0;
    PIE1bits.ADIE=1;
    
    //ADC struct data initialize
    ADC.index=0;
    ADC.cal=0;
    ADC.Completed=false;
    
  
}

/*----------------------------------------------*/
//PWM
/*-----------------------------------------------*/

//RB0
void CCP1_PWM_Init(void)
{
    CCP1CONbits.CCP1M=0b1100;//PWMmode
    CCPTMRSbits.C1TSEL0=0b00;//Timer2 in PWM mode
    CCPR1L=0x00;
    TRISB0=0;
    APFCON0bits.CCP1SEL=1;//RB0
}

//RA7
void CCP2_PWM_Init(void)
{
    CCP2CONbits.CCP2M=0b1100;//PWMmode
    CCPTMRSbits.C2TSEL0=0b00;//Timer2 in PWM mode
    CCPR2L=0x00;
    TRISA7=0;
    APFCON0bits.CCP2SEL=1;//RA7
}

//RA3
void CCP3_PWM_Init(void)
{
    CCP3CONbits.CCP3M=0b1100;//PWMmode
    CCPTMRSbits.C3TSEL0=0b00;//Timer2in PWM mode
    CCPR3L=0x00;
    TRISA3=0;
}

//RA4
void CCP4_PWM_Init(void)
{
    CCP4CONbits.CCP4M=0b1100;//PWMmode
    CCPTMRSbits.C4TSEL0=0b00;//Timer2in PWM mode
    CCPR4L=0x00;
    TRISA4=0;
}

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?