参考までに以下は前回のブログでのMCP23S17の初期設定のコード(コンパイラはBASCOM-AVR)です。MCP23S17と関係のある個所のみで、他の設定と処理は省略。
BASCOMを使われている方はそれほど多くないと思いますが、コピーされたい方はお使いください。CPUはATmega328PB、クロック16MHzで動作検証済みです。ソフトSPIの場合、命令語にSPI0やSPI1の様にチャンネル番号は付かないのでご注意を。ソフトSPIですからポートは変更しても問題無いはずです。変更されるときはポートの入出力設定の変更をお忘れ無く。回路図(一部抜粋)は一番下にPDFで置いてあります。
(一部訂正)config spiにおいて、Mode=0が抜けていたので追記。また、IOCONAとIOCONBは共通なのでIOCONAにのみ初期設定。(B側にあったオープンドレイン設定はA側での設定にしIOCONBの設定はコメント化。)
'SPI initialize Config Spi = Soft , Clock = Portc.1 , Dout = Porte.3 , Din = Pinc.0 , Ss = None , Mode = 0 Dim Port_data As Byte 'output data for spi Dim S_data(5) As Byte 'write data for spiout 'for MCP23S17 -------------- Dim Mcp23s17_write As Byte 'device opcode(write) Dim Mcp23s17_read As Byte 'device opcode(read) Dim Iodira_adrs As Byte Dim Iodirb_adrs As Byte Dim Ipola_adrs As Byte Dim Ipolb_adrs As Byte Dim Gpintena_adrs As Byte Dim Gpintenb_adrs As Byte Dim Defvala_adrs As Byte Dim Defvalb_adrs As Byte Dim Intcona_adrs As Byte Dim Intconb_adrs As Byte Dim Iocona_adrs As Byte Dim Ioconb_adrs As Byte Dim Gppua_adrs As Byte Dim Gppub_adrs As Byte Dim Intfa_adrs As Byte Dim Intfb_adrs As Byte Dim Intcapa_adrs As Byte Dim Intcapb_adrs As Byte Dim Gpioa_adrs As Byte Dim Gpiob_adrs As Byte Dim Olata_adrs As Byte Dim Olatb_adrs As Byte '--------------------------- Set Porte.2 'MCP23S17 /CS to high 'ポートの入出力設定 Config Portc.0 = Input 'MISO1 Config Portc.1 = Output 'SCK1 Config Porte.2 = Output 'MCP23S17 /CS Hard-SPIなら設定不要 Config Porte.3 = Output 'MOSI1 Spiinit '初期化のためのアドレスとデータの定義 Mcp23s17_write = &H40 Mcp23s17_read = &H41 Iodira_adrs = &H00 Iodirb_adrs = &H01 Ipola_adrs = &H02 Ipolb_adrs = &H03 Gpintena_adrs = &H04 Gpintenb_adrs = &H05 Defvala_adrs = &H06 Defvalb_adrs = &H07 Intcona_adrs = &H08 Intconb_adrs = &H09 Iocona_adrs = &H0A Ioconb_adrs = &H0B Gppua_adrs = &H0C Gppub_adrs = &H0D Intfa_adrs = &H0E Intfb_adrs = &H0F Intcapa_adrs = &H10 Intcapb_adrs = &H11 Gpioa_adrs = &H12 Gpiob_adrs = &H13 Olata_adrs = &H14 Olatb_adrs = &H15 '以下は処理用のサブルーチン Mcp_initial: 'Mcp23S17 ----------------------------------------------------------------------------------- 'set IOCONA S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Iocona_adrs 'set reg-adrs S_data(3) = &B00100100 'set data BANK=0 アドレス連続 シーケンシャル動作無効 オープンドレイン出力 Gosub Spiwr_sub 'set IOCONB 'S_data(1) = Mcp23s17_write 'set opcode 'S_data(2) = Ioconb_adrs 'set reg-adrs 'S_data(3) = &B00100100 'set data BANK=0 アドレス連続 シーケンシャル動作無効 オープンドレイン出力 'Gosub Spiwr_sub 'set IODIRA(全て出力) S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Iodira_adrs 'set reg-adrs S_data(3) = &B00000000 'set data Gosub Spiwr_sub 'set IODIRB(全て入力) S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Iodirb_adrs 'set reg-adrs S_data(3) = &B11111111 'set data Gosub Spiwr_sub 'set GPPUA(プルアップ無し) 'S_data(1) = Mcp23s17_write 'set opcode 'S_data(2) = Gppua_adrs 'set reg-adrs 'S_data(3) = &B00000000 'set data 'Gosub Spiwr_sub 'Set Gppub(プルアップ無し) S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Gppub_adrs 'set reg-adrs S_data(3) = &B00000000 'set data Gosub Spiwr_sub 'set GPINTENA 'S_data(1) = Mcp23s17_write 'set opcode 'S_data(2) = Gpintena_adrs 'set reg-adrs 'S_data(3) = &B00000000 'set data 状態変化割り込み無効 Gosub Spiwr_sub 'set DEFVALA 'S_data(1) = Mcp23s17_write 'set opcode 'S_data(2) = Defvala_adrs 'set reg-adrs 'S_data(3) = &B00000000 'set data 'Gosub Spiwr_sub 'set DEFVALB(プルアップなので全て1) S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Defvalb_adrs 'set reg-adrs S_data(3) = &B11111111 'set data fault状態と反対の論理に設定(=全て1) Gosub Spiwr_sub 'set INTCONA 'S_data(1) = Mcp23s17_write 'set opcode 'S_data(2) = Intcona_adrs 'set reg-adrs 'S_data(3) = &B00000000 'set data 'Gosub Spiwr_sub 'set INTCONB (全て入力) S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Intconb_adrs 'set reg-adrs S_data(3) = &B11111111 'set data 全てのビットでDEFBALBレジスタと比較 Gosub Spiwr_sub 'set GPINTENB(状態変化割り込み有効) S_data(1) = Mcp23s17_write 'set opcode S_data(2) = Gpintenb_adrs 'set reg-adrs S_data(3) = &B11111111 'set data 状態変化割り込み有効 Gosub Spiwr_sub Port_data = 0 'DATA output Gosub Spiout_sub 'GPA 出力全てLow Waitus 10 Return Spiwr_sub: Reset Porte.2 'CS-low Waitus 1 Spiout S_data(1) , 3 '3byte write Waitus 5 Set Porte.2 'CS-high Return Spird_sub: Reset Porte.2 'CS-low Waitus 1 Spiin S_data(1) , 3 '3byte write Waitus 5 Set Porte.2 'CS-high Return Spiout_sub: 'MCP23S17-0(Lower) S_data(1) = Mcp23s17_write 'set adrs (&H40) S_data(2) = Olata_adrs 'set olata adrs (&H12) S_data(3) = Port_data 'set byte data Gosub Spiwr_sub Return
CPUとMCP23S17の接続(全体回路図からの一部抜粋)はこちら。リセットは4.3VのリセットICをCPUとエキスパンダに使っています。どちらにもパワーオンリセット機能がありますが、共通にしないと起動のタイミングが揃わない可能性があるためにリセットICを使った方が確実です。