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?

PIC16F1827 ブレッドボード配線3 <I2C通信>

Last updated at Posted at 2024-09-12

PIC16F1827を使用したI2C通信回路をブレッドボード上に組む。

前回は、PORTBのRB1,RB2をシリアル通信の送受信端子に設定して、USBシリアル機に配線しました。

今回は、この回路をすこし変更して、I2C通信回路を増設します。

IMG_4940.JPG

16ビットIOエキスパンダーMCP23017を通信相手にI2C通信を行います。
IMG_4942.JPG

回路図

PIC16F1827_I2C回路図.jpg
プルアップ抵抗は10kΩ、LEDはチップ型で、抵抗値は、青1kΩ、緑2.2kΩ。

I2Cデバイス IOエキスパンダーMCP23017
MCP23017datasheet.png

スレーブアドレスは、15,16,17番ピンで指定します。今回は、15番をプルダウン。
16番、17番ピンをプルアップして、8ビットアドレスを0x4Cに設定しています。

16F1827のI2Cモジュールの使用端子は、固定されています。

PORTB RB1: I2C1モジュール SDA1(データ線)
PORTB RB4: I2C1モジュール SCL1(クロック線)

I2C1モジュールに割り当てられたこの2つのピンを、移動させることはできません。
シリアル通信のように、ピン割り当てを変更できません。

前回のシリアル通信でRB1をRx端子として使用したので、このままではI2C1とピン割り当てが、バッティング(butting,競合)してしまいます。

というわけで、
オルタネータピン機能で、シリアル通信端子Rx、Txの位置を移動させています。

ポートの初期化
void Port_Init(void)
{
    TRISA=0x00;
    ANSELA=0x00;
    TRISB=0x04;     //RX:RB2
    ANSELB=0x00;
    PORTA=0x00;
    PORTB=0x00;  
    //Altanative Pin Selective
    APFCON0bits.RXDTSEL=1;  //RX:RB2
    APFCON1bits.TXCKSEL=1;  //TX:RB5
    //I2Cpin
    TRISBbits.TRISB1=1;
    TRISBbits.TRISB4=1;
}

下記の表にあるとおり、割り付けました。

ペリフェラル 端子名 割り付けピン
USART Rx RB2 APFCON0レジスタで指定移動
USART Tx RB5 APFCON1レジスタで指定移動
I2C1 SDA1 RB1 I2C1使用時固定
I2C1 SCL1 RB4 I2C1使用時固定

このポート初期化で、シリアル通信とI2Cを同時使用できるようになります。

※PICマイコンのI2Cの端子は、TRISレジスタで入力に初期化しておきます。

I2C MSSP1モジュール コード

I2C_MSSP1.h

#ifndef I2C_MSSP1_H
#define	I2C_MSSP1_H
#include <xc.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

#define _XTAL_FREQ  16000000

#ifdef	__cplusplus
extern "C" {
#endif
//-----------------------------------------------
#define I2C1_Ack   0//SSP1CON2.ACKDT master:receive mode
#define I2C1_NoAck 1//SSP1CON2.ACKDT master:receive mode
extern void I2C1_Reg_Init(void);
extern bool I2C1_Start(void);
extern bool I2C1_ReStart(void);
extern bool I2C1_Stop(void);
extern bool I2C1_Tx_Buffer_Write(uint8_t _byte_data);
extern uint8_t I2C1_Rx_Buffer_Read(void);
extern bool I2C1_Wait_Ack(void);
extern bool I2C1_Send_Ack(uint8_t _Ack_Nack);
extern bool I2C1_CheckIdle(void);
extern bool I2C1_ClearSSPxIF(void);
//------------------------------------------------
//-----------------------------------------------
extern bool I2C1_b1Write(uint8_t _device_add, uint8_t _data);
extern uint8_t I2C1_b2Write(uint8_t _device_add, uint8_t _data1, uint8_t _data2);
extern uint8_t I2C1_DataBuffer[10];
extern bool I2C1_bnWrite(uint8_t _device_add, uint8_t *_data, uint8_t _len);
extern uint8_t I2C1_b1Read(uint8_t _device, uint8_t _data1);
extern uint16_t I2C1_b2Read(uint8_t _device_add, uint8_t _data1);
extern bool I2C1_bnRead(uint8_t _device_add, uint8_t _data1,uint8_t _len);
//-----------------------------------------------
#ifdef	__cplusplus
}
#endif

#endif	/* I2C_MSSP1_H */

スレーブアドレスの指定は、8ビットにしています。

今回のIOエキスパンダーMCP23017だと、0x4Cを引数に代入します。

I2CのR/Wビットは、この0x4Cの最下位ビットをセット、クリアして使用します。

I2C_MSSP1.c
#include "I2C_MSSP1.h"


uint8_t I2C1_DataBuffer[10];//読取りバッファ

//--------------------------------------------
//I2C1 MSSP1初期化
//--------------------------------------------
void I2C1_Reg_Init(void)
{
    SSP1STAT=0xC0;
    SSP1CON1=0x38;
    SSP1CON3=0x00;
    //SSP1ADD=0x50;//Fosc=16Mhz Fclock=50kHz
    //SSP1ADD=0x27;//Fosc=16MHz Fclock=100kHz
    SSP1ADD=0x09;//Fosc=16MHz Fclock=400kHz
    PIE1bits.SSP1IE=0;
}

//--------------------------------------------
//I2C1 MSSP1スタートコンディション発令
//--------------------------------------------
bool I2C1_Start(void)
{
    if(!I2C1_CheckIdle()) return false;
    SSP1CON2bits.SEN=1;
    if(!I2C1_ClearSSPxIF())return false;
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    return true;
}

//--------------------------------------------
//I2C1 MSSP1リスタートコンディション発令
//--------------------------------------------
bool I2C1_ReStart(void)
{
     //restart
    if(!I2C1_CheckIdle()) return false;
    SSP1CON2bits.RSEN=1;
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    return true;
    
}

//--------------------------------------------
//I2C1 MSSP1ストップコンディション発令
//--------------------------------------------
bool I2C1_Stop(void)
{
     if(!I2C1_CheckIdle()) return false;
    SSP1CON2bits.PEN=1;
    if(!I2C1_ClearSSPxIF())return false;
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    return true;
}

//--------------------------------------------
//I2C1 MSSP1 送信バッファ書込み
//--------------------------------------------
bool I2C1_Tx_Buffer_Write(uint8_t _byte_data)
{
    if(!I2C1_CheckIdle()) return false;
    SSP1BUF=_byte_data;
    if(!I2C1_ClearSSPxIF())return false;
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    return true;
}

//--------------------------------------------
//I2C1 MSSP1 受信バッファ読み出し
//--------------------------------------------
uint8_t I2C1_Rx_Buffer_Read(void)
{
    uint8_t ret, cnt;
    ret=0xFF;
    cnt=0;
    if(!I2C1_CheckIdle()) return false;
    SSP1CON2bits.RCEN=1;
    while(!SSP1STATbits.BF){
        __delay_us(3);
        cnt++;
        if(cnt==100)return false;
    }
    if(!I2C1_CheckIdle()) return false;
    ret = SSP1BUF;
    if(!I2C1_ClearSSPxIF())return false;
    return ret;
}

//--------------------------------------------
//I2C1 MSSP1 ACK確認
//--------------------------------------------
bool I2C1_Wait_Ack(void)
{
    //while(SSP1CON2bits.ACKSTAT);
    if(SSP1CON2bits.ACKSTAT)
    {
        return false;//error
        
    }else
    {
        return true;//success
    }
}

//--------------------------------------------
//I2C1 MSSP1 ACK送信
//--------------------------------------------
bool I2C1_Send_Ack(uint8_t _Ack_Nack)
{
    if(!I2C1_CheckIdle()) return false;
    SSP1CON2bits.ACKDT=_Ack_Nack;
    SSP1CON2bits.ACKEN=1;   
    if(!I2C1_ClearSSPxIF())return false;
    return true;
}

//--------------------------------------------
//I2C1 MSSP1 アイドリングチェック
//--------------------------------------------
bool I2C1_CheckIdle(void)
{
    uint8_t cnt=0;
    while(SSP1STATbits.R_nW || SSP1CON2 & 0x1F)
    {
    /*    __delay_us(2);
        cnt++;
        if(cnt==100) 
            return false;*/
    };//MSSP1 is idle mode
    return true;
}

//--------------------------------------------
//I2C1 MSSP1 SSP1IFフラグクリア
//--------------------------------------------
bool I2C1_ClearSSPxIF(void)
{
    uint8_t cnt=0;
    while(!PIR1bits.SSP1IF)
    {
    /*    __delay_us(2);
        cnt++;
        if(cnt==100)
            return false;*/
    };
    PIR1bits.SSP1IF=0;
    return true;
}


//-----------------------------------------------------------------


//----------------------------------------------------
//  I2C1 MSSP1 1バイト送信
//_device_add:I2Cスレーブアドレス
//_data:送信データ
//----------------------------------------------------
bool I2C1_b1Write(uint8_t _device_add, uint8_t _data)
{  
    //start condition
    I2C1_Start();
    //send device address
    I2C1_Tx_Buffer_Write(_device_add);
    if(!I2C1_Wait_Ack())
        return false;
    //send data
    I2C1_Tx_Buffer_Write(_data);
    if(!I2C1_Wait_Ack())
        return false;
    //Stop condition
    I2C1_Stop();
    return true;
}

//----------------------------------------------------
//  I2C1 MSSP1 2バイト送信
//_device_add:I2Cスレーブアドレス
//_data1:送信データ
//_data2:送信データ
//----------------------------------------------------
uint8_t I2C1_b2Write(uint8_t _device_add, uint8_t _data1, uint8_t _data2)
{
    //start condition
    I2C1_Start();
    //send device address
    I2C1_Tx_Buffer_Write(_device_add);
    if(!I2C1_Wait_Ack())
    {
        return 0xF1;
        //return false;
    }
    //send data
    I2C1_Tx_Buffer_Write(_data1);
    if(!I2C1_Wait_Ack())
    {    
        return 0xF2;
        //return false;
    }
        //send data
    I2C1_Tx_Buffer_Write(_data2);
    if(!I2C1_Wait_Ack())
    {
        return 0xF3;
        //return false;
    }
    //Stop condition
    I2C1_Stop();
    return true;
}

//----------------------------------------------------
//  I2C1 MSSP1 nバイト送信
//_device_add:I2Cスレーブアドレス
//_data:送信データ先頭アドレス
//_len:送信長
//----------------------------------------------------
bool I2C1_bnWrite(uint8_t _device_add, uint8_t *_data, uint8_t _len)
{
    //start condition
    I2C1_Start();
    //send device address
    I2C1_Tx_Buffer_Write(_device_add);
     if(!I2C1_Wait_Ack())
        return false;
    //send data
    do{
        I2C1_Tx_Buffer_Write(*_data);
        if(!I2C1_Wait_Ack())
        return false;
        _data++;
    }while(--_len);
    //Stop condition
    I2C1_Stop();
    return true;
}

//----------------------------------------------------
//  I2C1 MSSP1 1バイト受信
//_device_add:I2Cスレーブアドレス
//_data1:送信データ
//戻り値:受信バイトデータ
//----------------------------------------------------
uint8_t I2C1_b1Read(uint8_t _device_add, uint8_t _data1)
{
    uint8_t ret;
    //Start Condition
    I2C1_Start();
     //send device address
    I2C1_Tx_Buffer_Write(_device_add);
     if(!I2C1_Wait_Ack())
        return false;
    //send data
    I2C1_Tx_Buffer_Write(_data1);
     if(!I2C1_Wait_Ack())
        return false;
    //restart
    I2C1_ReStart();
      //send device address
    I2C1_Tx_Buffer_Write(_device_add|0x01);
     if(!I2C1_Wait_Ack())
        return false;
    //recieve data
    ret=I2C1_Rx_Buffer_Read();
    //send Nack
    I2C1_Send_Ack(I2C1_NoAck);
    //Stop Condition
    I2C1_Stop();
    return ret;
}

//----------------------------------------------------
//  I2C1 MSSP1 2バイト受信
//_device_add:I2Cスレーブアドレス
//_data1:送信データ
//戻り値:2バイトデータ
//----------------------------------------------------
uint16_t I2C1_b2Read(uint8_t _device_add, uint8_t _data1)
{
    uint16_t ret;
    //Start Condition
    I2C1_Start();
     //send device address
    I2C1_Tx_Buffer_Write(_device_add);
     if(!I2C1_Wait_Ack())
        return false;
    //send data
    I2C1_Tx_Buffer_Write(_data1);
     if(!I2C1_Wait_Ack())
        return false;
    //restart
    I2C1_ReStart();
    //send device address
    I2C1_Tx_Buffer_Write(_device_add|0x01);
     if(!I2C1_Wait_Ack())
        return false;
    //recieve data
    ret=I2C1_Rx_Buffer_Read();
    ret<<=8;
    //send Ack
    I2C1_Send_Ack(I2C1_Ack);
    //recieve data
    ret|=I2C1_Rx_Buffer_Read();
    //send Nack
    I2C1_Send_Ack(I2C1_NoAck);
    //Stop Condition
    I2C1_Stop();
    return ret;
}

//----------------------------------------------------
//  I2C1 MSSP1 nバイト受信
//_device_add:I2Cスレーブアドレス
//_data1:送信データ
//_len:受信長
//戻り値:受信の成否
//----------------------------------------------------
bool I2C1_bnRead(uint8_t _device_add, uint8_t _data1,uint8_t _len)
{
    uint8_t index=0;
    
    //Start Condition
    I2C1_Start();
     //send device address
    I2C1_Tx_Buffer_Write(_device_add);
     if(!I2C1_Wait_Ack())
        return false;
    //send data
    I2C1_Tx_Buffer_Write(_data1);
     if(!I2C1_Wait_Ack())
        return false;
    //restart
    I2C1_ReStart();
      //send device address
    I2C1_Tx_Buffer_Write(_device_add|0x01);
     if(!I2C1_Wait_Ack())
        return false;
    //recieve data
    do{
        I2C1_DataBuffer[index++]=I2C1_Rx_Buffer_Read();
        if(_len!=1)
        {
            I2C1_Send_Ack(I2C1_Ack);
        }
        _len--;
    }while(_len!=0);
    //send Nack
    I2C1_Send_Ack(I2C1_NoAck);
    //Stop Condition
    I2C1_Stop();
    return true;
}
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 FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on 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 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 = ON       // 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 = ON       // 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 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"

#define _XTAL_FREQ  16000000

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

void main(void)
{    
    uint8_t val=0x55;
    //Basic Hard Initialize
    Oscillator_Init();
    Port_Init(); 
    //Peripheral 
    Timer0_INIT();
    USART_INIT();
    I2C1_Reg_Init();//I2C初期化
    //IOex:MCP23017初期化
    I2C1_b2Write(0x4C,0x0A,0x00);//コンフィグ
    I2C1_b2Write(0x4C,0x00,0x00);//PortA IOdirection
    I2C1_b2Write(0x4C,0x01,0x00);//PortB IOdirection
    //割り込み許可
    Interrupt_START();
    
    while(1)
    {
        //USART interrupt processing
        if(usart.rxCompleted)
        {
            usart.rxCompleted=false;
            printf("%s\n",usart.rxBuf);
            usart.length=0;
            PIE1bits.RCIE=1;
        }
        
        //Timer0 interrupt processing
        if(tm0.up)
        {
            tm0.up=false;
            LATBbits.LATB0=~LATBbits.LATB0;
            I2C1_b2Write(0x4C,0x14,val);//IOex:PortA
            I2C1_b2Write(0x4C,0x15,val);//IOex:PortB
            if(val==0x55)
                val=0xAA;
            else
                val=0x55;
            INTCONbits.TMR0IE=1;
        }        
    }
    return;
}

void Oscillator_Init(void)
{
    OSCCONbits.SPLLEN=0;
    OSCCONbits.IRCF=0b1111;//16Mhz
    OSCCONbits.SCS=0b10;//InternalOscillator
}

void Port_Init(void)
{
    TRISA=0x00;
    ANSELA=0x00;
    TRISB=0x04;     //RX:RB2
    ANSELB=0x00;
    PORTA=0x00;
    PORTB=0x00;  
    //Altanative Pin Selective
    APFCON0bits.RXDTSEL=1;  //RX:RB2
    APFCON1bits.TXCKSEL=1;  //TX:RB5
    //I2Cpin
    TRISBbits.TRISB1=1;
    TRISBbits.TRISB4=1;
}


Periperal.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 16000000

#ifdef	__cplusplus
extern "C" {
#endif

//**************************************************//    
//   USART 
//**************************************************//    
//#define BAUDRATE 19200
#define BAUDRATE 115200  
#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 30
typedef struct {
    uint8_t length;
    uint8_t rxBuf[30];
    bool rxCompleted;
}_usart;    
extern _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 Interrupt_START(void);

#ifdef	__cplusplus
}
#endif

#endif	/* MYLIB_H */


Peripheral.c
#include <pic16f1827.h>

#include "Peripheral.h"

/*-----------------------------------------
 *USART
 *-----------------------------------------*/
_usart usart;
_rx rx;
void USART_INIT(void)
{
    uint8_t buf;
    unsigned int brg;
    //SPBRG value set
    brg = SET_SPBRG_DATA1;
    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 | 0x24;
    //RX-------------------------------------
    //RCSTA  SPEN:1 RX9:0 CREN:1
    buf =RCSTA & 0x2F;
    RCSTA =buf | 0x90;
    //BAUR RATE CONTROL REGISTER
    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(uint8_t byte)
{
    while(!PIR1bits.TXIF)continue;
    TXREG=byte;
}

uint8_t 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:16
    T2CONbits.T2CKPS=0b11;//PSC 1:16
    T2CONbits.TMR2ON=1;
    PR2=0xFA;//1ms matching.
    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;
}

Interrupt.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"

void __interrupt()isr()
{
    uint8_t ch;
    
    //USART受信割り込み処理
    if(PIE1bits.RCIE==1 &&  PIR1bits.RCIF)
    {
        PIR1bits.RCIF=0;
        ch = getch();
        usart.rxBuf[usart.length++]=ch;
        if(usart.length>=rxLength)
        {
            usart.length=0;
        }
        if(ch==0x0A)
        {//CR,LF受信
            usart.rxCompleted=true;
            usart.rxBuf[usart.length-2]=0x00;
            PIE1bits.RCIE=0;
        }
    }
    
    //Timer0割り込み処理
    if(INTCONbits.TMR0IE==1 && INTCONbits.TMR0IF )
    {
        INTCONbits.TMR0IF=0;
        tm0.cnt++;
        if(tm0.cnt==50)
        {
            tm0.cnt=0;
            INTCONbits.TMR0IE=0;
            tm0.up=true;
        }
        TMR0=0x63;
    }

}


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?