BASCOMでMCP23S17を制御

BASCOM-AVRでI/OエキスパンダIC MCP23S17を制御しました。(atMega328 clock=16MHz)

SSをCPU直結ではなくトランジスタを1段入れ反転しての制御としました。
(AVRからH出力で、/CS が有効)

hard SPIで、Interrupt=on, Noss=1に設定し、送信後割り込みで/CSをクリアしようとしたところ割り込み先から戻ってこないという動作が見られたので以下のようにsoft-spiに変更しました。

AVRの使い方でプログラマを接続した時の誤動作を防ぐためにSPIラインに大きめの抵抗(6K以上)を入れるようにとされていますが、この場合には波形整形をしてやらないと「なまった波形」のため正常な設定をしない可能性がありますから注意が必要です。今回は抵抗値を1Kにしましたが支障なく書き込みができています。

Config Spi = Soft , Clock = Portb.5 , Dout = Portb.3 , Din = Pinb.4 , Ss = None

Config Portb.2 = Output ‘/CS
Config Portb.3 = Output   ‘MOSI (SI)
Config Portb.4 = Input   ‘MISO
Config Portb.5 = Output ‘SCK (SCK)
 
 ’変数の定義は省略(Byte形式)
Spiinit

 ’初期化のためのアドレスとデータの定義
Op_code = &H40
Iocona_adrs = &H0A
Iocona_data = &H20
Ioconb_adrs = &H0B
Ioconb_data = &H20
Iodira_adrs = &H00
Iodira_data = &H00
Iodirb_adrs = &H01
Iodirb_data = &H00
Gpioa_adrs = &H12
Gpiob_adrs = &H13

Mcp_initial:
‘set IOCONA(seqopのみセット sequential operation enabled)
S_data(1) = Op_code ‘set opcode
S_data(2) = Iocona_adrs ‘set reg-adrs
S_data(3) = Iocona_data ‘set data

Set Portb.2 ‘/CS on
Spiout S_data(1) , 3 ‘3byte write
Reset Portb.2 ‘/CS off
Waitus 5 ‘delay 5us(次のデータとの間のウエイトが必要)

‘set IOCONB(seqopのみセット sequential operation enabled)
S_data(1) = Op_code ‘set opcode
S_data(2) = Ioconb_adrs ‘set reg-adrs
S_data(3) = Ioconb_data ‘set data

Set Portb.2 ‘/CS on
Spiout S_data(1) , 3 ‘3byte write
Reset Portb.2 ‘/CS off
Waitus 5 ‘delay 5us(次のデータとの間のウエイトが必要)

‘set IODIRA(全て出力)
S_data(1) = Op_code ‘set opcode
S_data(2) = Iodira_adrs ‘set reg-adrs
S_data(3) = Iodira_data ‘set data

Set Portb.2 ‘/CS on
Spiout S_data(1) , 3 ‘3byte write
Reset Portb.2 ‘/CS off
Waitus 5 ‘delay 5us(次のデータとの間のウエイトが必要)

‘set IODIRB(全て出力)
S_data(1) = Op_code ‘set opcode
S_data(2) = Iodirb_adrs ‘set reg-adrs
S_data(3) = Iodirb_data ‘set data

Set Portb.2 ‘/CS on
Spiout S_data(1) , 3 ‘3byte write
Reset Portb.2 ‘/CS off
Waitus 5 ‘delay 5us(次のデータとの間のウエイトが必要)

Return

‘初期設定ここまで(割り込み等未使用 全出力)

‘データ出力
’10bitのデータをPort_data (word)に設定し
Gosub Spiout_sub

‘データ出力ルーチン
Spiout_sub:

H_byte = Port_data And &H300 ‘set High-byte data(2bit)
L_byte = Port_data And &HFF ‘set Low-byte data(8bit)

H_byte = H_byte / &H100 ‘shift 8-bit right High-byte data

‘IOCONでsequentialを設定してあるので、ポートAとポートBは連続して出力(送信) 合計8×4=32bit
S_data(1) = Op_code ‘set adrs (40H)
S_data(2) = Gpioa_adrs ‘set gpioa adrs (12H)
S_data(3) = L_byte ‘set High-byte data
S_data(4) = H_byte ‘set High-byte data

‘op-code,reg-adrs,data(A),data(B)

‘spi出力
Set Portb.2 ‘/CS on
Spiout S_data(1) , 4
Reset Portb.2 ‘/CS off

Return

注)上記で出力が10bitとなっているのは仕様が10bit出力のI/Oボードであるからです。
Port_dataに16bitのデータをセットし、H_byte = Port_data And &H300 を H_byte = Port_data And &HFF00 に変更すれば、全体で16bitの出力ができます。