# TCA9548A_1對8選擇I2C輸出IC [TCA9548A datasheet](https://www.ti.com/lit/ds/symlink/tca9548a.pdf?ts=1612232898480&ref_url=https%253A%252F%252Fwww.google.com%252F) ###### tags:`datasheet` `PIC16F18854` `TCA9548A` <style> .red {color:red;} </style> ## IC封裝與腳位  \  A2 A1 A1是用來決定ID的 \ RESET輸入low,可從bus故障狀態中恢復,並取消選擇所有通道。 RESET輸入必須通過上拉電阻連接到VCC。 ## 寫入控制暫存器  要使用的組設為1,可以一次設多個組 <!-- ## 使用方式 ### 接線方式 畫張圖拉 --> ### 要來寫程式了喔 #### WRITE  #### READ  <!--還沒用到--> ### 程式說明 :::spoiler ### 大家都要有的初始化 ```c= void init(void){ PMD_Initialize(); PIN_MANAGER_Initialize(); OSCILLATOR_Initialize(); } void OSCILLATOR_Initialize(void){ // NOSC HFINTOSC; NDIV 1; OSCCON1 = 0x60; // CSWHOLD may proceed; SOSCPWR Low power; OSCCON3 = 0x00; // MFOEN disabled; LFOEN disabled; ADOEN disabled; SOSCEN disabled; EXTOEN disabled; HFOEN disabled; OSCEN = 0x00; // HFFRQ 4_MHz; OSCFRQ = 0x02; // HFTUN 0; OSCTUNE = 0x00; } void PMD_Initialize(void){ // CLKRMD CLKR enabled; SYSCMD SYSCLK enabled; SCANMD SCANNER enabled; FVRMD FVR enabled; IOCMD IOC enabled; CRCMD CRC enabled; NVMMD NVM enabled; PMD0 = 0x00; // TMR0MD TMR0 enabled; TMR1MD TMR1 enabled; TMR4MD TMR4 enabled; TMR5MD TMR5 enabled; TMR2MD TMR2 enabled; TMR3MD TMR3 enabled; NCOMD DDS(NCO) enabled; TMR6MD TMR6 enabled; PMD1 = 0x00; // ZCDMD ZCD enabled; DACMD DAC enabled; CMP1MD CMP1 enabled; ADCMD ADC enabled; CMP2MD CMP2 enabled; PMD2 = 0x00; // CCP2MD CCP2 enabled; CCP1MD CCP1 enabled; CCP4MD CCP4 enabled; CCP3MD CCP3 enabled; CCP5MD CCP5 enabled; PWM6MD PWM6 enabled; PWM7MD PWM7 enabled; PMD3 = 0x00; // CWG3MD CWG3 enabled; CWG2MD CWG2 enabled; CWG1MD CWG1 enabled; MSSP1MD MSSP1 enabled; UART1MD EUSART enabled; MSSP2MD MSSP2 enabled; PMD4 = 0x00; // DSMMD DSM enabled; CLC3MD CLC3 enabled; CLC4MD CLC4 enabled; SMT1MD SMT1 enabled; SMT2MD SMT2 enabled; CLC1MD CLC1 enabled; CLC2MD CLC2 enabled; PMD5 = 0x00; } void PIN_MANAGER_Initialize(void){ /** LATx registers */ LATA = 0x00; LATB = 0x00; LATC = 0x00; /** TRISx registers */ TRISA = 0x00; TRISB = 0xFF; TRISC = 0xFF; /** ANSELx registers */ ANSELC = 0xE7;//RC3 RC4設為數位 ANSELB = 0xFF; ANSELA = 0x00;//PORTA 設為數位 /** WPUx registers */ WPUE = 0x00; WPUB = 0x00; WPUA = 0x00; WPUC = 0x00; /** ODx registers */ ODCONA = 0x00; ODCONB = 0x00; ODCONC = 0x00; /** SLRCONx registers */ SLRCONA = 0xFF; SLRCONB = 0xFF; SLRCONC = 0xFF; /** INLVLx registers */ INLVLA = 0x00; INLVLB = 0xFF; INLVLC = 0xFF; INLVLE = 0x08; //智能SDA和SCL兩隻腳 SSP1CLKPPS = 0x13; //RC3->MSSP1:SCL1; RC3PPS = 0x14; //RC3->MSSP1:SCL1; RC4PPS = 0x15; //RC4->MSSP1:SDA1; SSP1DATPPS = 0x14; //RC4->MSSP1:SDA1; } ``` ### Master #### master暫存器設定 ```c= void master_init(void){ INTCONbits.GIE = 0;//中斷不智能 INTCONbits.PEIE = 0;//中斷不智能 PIR3bits.SSP1IF = 1;//等待傳輸 PIR3bits.BCL1IF = 1;//未檢測到衝突 PIE3bits.SSP1IE = 0;//不允許中斷 PIE3bits.BCL1IE = 0;//衝突不允許中斷 SSP1CON1=0x28; //智能SDA和SCL兩隻腳與設定為I2C master模式 SSP1CON2=0x00; SSP1CON3=0x00; SSP1STAT=0x00; SSP1BUF =0x00; SSP1STATbits.SMP=1; //1 =在標準速度模式(100 kHz和1 MHz)下禁用slew rate control SSP1STATbits.CKE=1; //1 =智能輸入邏輯,以使閾值符合SMBus規範 SSP1ADD=0x06; //100k Hz=0x06 數字越高頻率越慢 SSP1MSK=0xFF; //理論上這個在master應該是沒有用的,但還是讓她都為1乖一點 RA3=1; //可以用來看這個時候轉換成master了 } ``` #### wait ```c= void I2C_Master_Wait(){ while ((SSP1STAT & 0x04) || (SSP1CON2 & 0x1F));//確認有發起start後再動作 } ``` #### start ```c= void I2C_Master_Start(){ I2C_Master_Wait(); SSP1CON2bits.SEN = 1; //start } ``` #### stop ```c= void I2C_Master_Stop(){ I2C_Master_Wait(); SSP1CON2bits.PEN = 1; //stop } ``` #### 寫入 ```c= void I2C_Master_Write(uint8_t data){ I2C_Master_Wait(); SSP1BUF = data; //將要傳送的data放進要經由I2C傳出的buffer裡 while(!PIR3bits.SSP1IF); // 等待bus上空閒 PIR3bits.SSP1IF = 0; //傳輸完成之後會為1,要用軟體回歸0,代表做完事了 } ``` #### 讀取 ```c= uint8_t I2C_Master_Read(uint8_t get){//get=0代表所有讀取資料完畢後會回傳nack(通常都是這個) //get=1代表所有讀取資料完畢後會回傳nack uint8_t temp; // 用來儲存讀取的資料的變數 I2C_Master_Wait(); SSP1CON2bits.RCEN = 1; //智能I2C的接收模式 I2C_Master_Wait(); temp = SSP1BUF; //將buffer收到的資料放進用來存取的變數裡 I2C_Master_Wait(); SSP1CON2bits.ACKDT = (get)?0:1;//get=1時,ack_data=NACK(0) //get=0時,ack_data=ACK(1) SSP1CON2bits.ACKEN = 1; //回傳ack_data給發送端 return temp; //引用I2C_Master_Read(uint8_t get)這行函式可得到讀取的資料 } ``` ::: #### restart ```c= void I2C_Master_RepeatedStart(){ I2C_Master_Wait(); SSP1CON2bits.RSEN = 1; //restart } ``` #### main ```c= #define SLAVE_ADD 0x70 //tca9548a的id #define VOLTADE_ADD 0x68 //後面那顆ic的id void main(void) { init(); I2C_Master_Start(); I2C_Master_Write((SLAVE_ADD << 1)|0); //傳tca9548a的id要寫 I2C_Master_Write(0x01); //寫入之後要用的是0通道 I2C_Master_Stop(); I2C_Master_Start(); I2C_Master_Write((SLAVE_ADD << 1)|0); I2C_Master_RepeatedStart(); //因為之後一定還會再接一個透過i2c的ic,所以必須restart,後面那顆 ic才會知道接下來的那個byte是他要判定的id I2C_Master_Write((VOLTADE_ADD << 1)|0); //傳後面那顆ic的id要寫 I2C_Master_Write(0x80);//寫給後面那顆ic的值 I2C_Master_Stop(); ``` :::danger ## 注意 restart很重要,因為i2c只會判定start後面的那一個byte為id,bus上的所有裝置在與自己的id比較,如果正確就做後面的事 <!--應該要再加東西--> :::
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up