close

256320.jpg

此篇使用MCU I2C功能來完成, 程式部分是以Microchip MCU例子,但觀念可以用在其他廠牌MCU,只要改變週遭IO配置就可以,

1. I2C程式

.h部份

#define SCL1_RB8()                             TRISBbits.TRISB8 = 1;  
#define SDA1_RB9()                             TRISBbits.TRISB9 = 1;  

#define I2C1_InterruptEnable()              IEC1bits.MI2C1IE = true;
#define I2C1_InterruptDisable()             IEC1bits.MI2C1IE = false;
#define I2C1_InterruptFlagClear()          IFS1bits.MI2C1IF = false;
#define I2C1_InterruptPriority                IPC4bits.MI2C1IP

/* I2C1 Master初始化 */
void I2C1_Master_Init(void);

/* I2C1 Master Set Clear */
void I2C1_Master_SetClear(void);

/* I2C1 Start */
void I2C1_Start(uint8_t address);

/* I2C1 Stop */
void I2C1_Stop(void);

/* I2C1 Write */
void I2C1_Write(uint8_t data);

/* I2C1 Read Ack */
uint8_t I2C1_Read_Ack(void);

/* I2C1 Read Nack */
uint8_t I2C1_Read_Nack(void);

.c部份

/*
Name: I2C1 Master初始化
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void I2C1_Master_Init(void){
    
    I2C1_Master_SetClear();                                 
    
    SCL1_RB8();                                           
    SDA1_RB9();                                           
       
    /* I2CxCON Set */
    I2C1CONbits.SMEN = 0;                                 
    I2C1CONbits.DISSLW = 0;                              
    I2C1CONbits.A10M = 0;                                 
    I2C1CONbits.IPMIEN = 0;                                
    I2C1CONbits.I2CSIDL = 0;                           
    I2C1CONbits.I2CEN = 1;                               
   
    /* Baud Rate Set */
    I2C1_BRG = 395;                                        
}

/*
Name: I2C1 Master Set Clear 
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void I2C1_Master_SetClear(void){
    
    I2C1CON = 0x0000;   
    I2C1STAT = 0x0000; 
}

/*
Name: I2C1 Start
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void I2C1_Start(uint8_t address){
    
    I2C1CONbits.SEN  = true;                                                    
    while(I2C1CONbits.SEN==true);                                             
    I2C1TRN = address;                                                           
    while(I2C1STATbits.TBF==true || I2C1STATbits.TRSTAT==true);                 
    while(I2C1STATbits.ACKSTAT==true);                                            
}

/*
Name: I2C1 Stop
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void I2C1_Stop(void){
    
    I2C1CONbits.PEN = true;       
    while(I2C1CONbits.PEN==true); 
}

/*
Name: I2C1 Write
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void I2C1_Write(uint8_t data){
    
    I2C1TRN = data;                                                               
    while(I2C1STATbits.TBF==true || I2C1STATbits.TRSTAT==true);                    
    while(I2C1STATbits.ACKSTAT==true);                                         
}

/*
Name: I2C1 Read Ack
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
uint8_t I2C1_Read_Ack(void){
    uint8_t data=NULL;
    
    I2C1CONbits.RCEN = true;               
    while(I2C1CONbits.RCEN==true);         
    data = I2C1RCV;                      
    I2C1CONbits.ACKDT = false;              
    I2C1CONbits.ACKEN = true;             
    while(I2C1CONbits.ACKEN==true);      
    
    return data;
}

/*
Name: I2C1 Read Nack
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
uint8_t I2C1_Read_Nack(void){
    uint8_t data=NULL;
    
    I2C1CONbits.RCEN = true;               
    while(I2C1CONbits.RCEN==true);          
    data = I2C1RCV;                      
    I2C1CONbits.ACKDT = true;             
    I2C1CONbits.ACKEN = true;             
    while(I2C1CONbits.ACKEN==true);         
    I2C1CONbits.ACKDT = false;             
    
    return data;
}

2. FM24CL16B程式

.h部份

#define FM24CL16B_SLAVE_ADDRESS 0xA0
#define FM24CL16B_Length 20

/*
Name: FM24CL16B Global Variable
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
typedef struct{  
    uint8_t address;
    uint8_t writeData[FM24CL16B_Length];
    uint8_t readData[FM24CL16B_Length];
    uint16_t length;
} _FM24CL16B_Type;
/* 結構變數FM24CL16B */
extern _FM24CL16B_Type FM24CL16B;

/* FM24CL16B初始化 */
void FM24CL16B_Init(void);

/* FM24CL16B資料寫入 */
void FM24CL16B_WriteData(uint8_t addressServe, uint8_t address, uint8_t *writeData, uint16_t length);

/* FM24CL16B資料讀取 */
void FM24CL16B_ReadData(uint8_t addressServe, uint8_t address, uint8_t *readData, uint16_t length);

.c部份

/* 結構變數FM24CL16B */
_FM24CL16B_Type FM24CL16B;

/*
Name: FM24CL16B初始化
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void FM24CL16B_Init(void){
    
    I2C1_Master_Init(); 
}

/*
Name: FM24CL16B資料寫入
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void FM24CL16B_WriteData(uint8_t addressServe, uint8_t address, uint8_t *writeData, uint16_t length){
    uint16_t i=0;
    
    I2C1_Start(addressServe);      
    I2C1_Write(address);           
    /* I2C1 Write Data */
    for(i=0; i<length; i++){
       I2C1_Write(*(writeData + i));
    }
    I2C1_Stop();                    
}

/*
Name: FM24CL16B資料讀取
Version: V1.0
Author: Michael Cheng
Created Date: 
Updated Data: N/A
Description:

Updated Record:

*/
void FM24CL16B_ReadData(uint8_t addressServe, uint8_t address, uint8_t *readData, uint16_t length){
    uint16_t i=0;  
    
    I2C1_Start(addressServe);                
    I2C1_Write(address);                        
    I2C1_Stop();                                
    
    I2C1_Start(addressServe+0x01);           
    for(i=0; i<(length-1); i++){
        *(readData + i) = I2C1_Read_Ack();     
    }
    *(readData + length-1) = I2C1_Read_Nack(); 
}

3. main部份

FM24CL16B_WriteData(FM24CL16B_SLAVE_ADDRESS, 0x00, (uint8_t*)"123456", 6);
delay_ms(100);
FM24CL16B_ReadData(FM24CL16B_SLAVE_ADDRESS, 0x00, FM24CL16B.readData, 6);   

2.JPG

 

arrow
arrow
    文章標籤
    MCU GPIO UART EEPROM
    全站熱搜

    鄭智遠 發表在 痞客邦 留言(0) 人氣()