Forum: Mikrocontroller und Digitale Elektronik MCP23S17 ansteuern


von Alex E. (alex_e)


Lesenswert?

Hallo,

hab nun schon alles durchgeschaut und bekomme es nicht hin.

MCP23S17 ist an SPI angeschlossem und SS an PB0(µC), Reset auf Vcc.
Adress-Pins am MCP sind offen, liegen im Low-Pegel(gemessen).
Sollte aber beim ersten ansteuern erstmal egal sein, da IOCON.HAEN auf 0 
nach POR liegt.

hab dem atmega324PA mit 3.3V im einsatz...

Verwende folgenden Code(aus einem anderen Thread):
1
#include <avr/io.h>
2
#include <stdio.h>
3
#include <avr/interrupt.h>
4
#include <avr/eeprom.h>
5
#include <avr/delay.h>
6
#include <string.h>
7
#include "MCP23S17.h"
8
9
void conf_mcp_send(uint8_t addr,uint8_t art,uint8_t pa,uint8_t pb)
10
{
11
  cli();
12
  //uint8_t send_addr;
13
  //send_addr=addr && 0b111;
14
  //addr= send_addr<<1;
15
  MCP_CS_ON();
16
  _delay_us(50);   
17
  SPI_WRITE(((addr )<<1) | 0x40);
18
  SPI_WAIT();
19
  SPI_WRITE(art);
20
  SPI_WAIT();
21
  SPI_WRITE(pa);
22
  SPI_WAIT();
23
  SPI_WRITE(pb);
24
  SPI_WAIT();     
25
  MCP_CS_OFF();
26
  _delay_us(2);
27
}     
28
29
void mcp_send(uint8_t addr,uint8_t pa,uint8_t pb)
30
{
31
  cli();
32
   //uint8_t send_addr;
33
   //send_addr=addr && 0b111;
34
   //addr= send_addr<<1;
35
    MCP_CS_ON();
36
  //_delay_us(20);      
37
   SPI_WRITE((addr <<1) | 0x40);
38
   SPI_WAIT();
39
   SPI_WRITE(0x12);
40
   SPI_WAIT();
41
   SPI_WRITE(pa);
42
   SPI_WAIT();
43
   SPI_WRITE(pb);
44
SPI_WAIT(); 
45
//_delay_us(20);
46
   MCP_CS_OFF();
47
_delay_us(2);   
48
49
     }
50
   
51
int mcp_rec(uint8_t addr)
52
    {
53
  cli();
54
  uint8_t timeout;
55
  uint8_t by;
56
  uint8_t bx;
57
  MCP_CS_ON();
58
//_delay_us(20);      
59
  SPI_WRITE((addr <<1) | 0x41);
60
  SPI_WAIT();
61
  SPI_WRITE(0x12);
62
  SPI_WAIT();
63
   
64
  timeout=255;
65
 
66
    //wait for response
67
    do
68
  {
69
    SPI_WRITE(DUMMY_WRITE);
70
    SPI_WAIT();
71
    by=SPI_DATA_REGISTER;
72
    timeout--;
73
    if(timeout==0) break; // no response
74
  } while(by==DUMMY_WRITE);
75
  
76
  do
77
  {
78
    SPI_WRITE(DUMMY_WRITE);
79
    SPI_WAIT();
80
    bx=SPI_DATA_REGISTER;
81
    timeout--;
82
    if(timeout==0) break; // no response
83
  } while(bx==DUMMY_WRITE);
84
  MCP_CS_OFF();
85
_delay_us(2);    
86
   
87
  return by | bx<<8; 
88
   
89
  }    
90
   
91
void mcp_int_on()
92
{
93
  cli();
94
   conf_mcp_send(3,MCP_GPINTEN,0XFF,0XFF);  
95
   conf_mcp_send(3,MCP_DEFVAL,0X00,0X00);
96
}
97
   
98
void initmcp(uint8_t addr)
99
{
100
  cli();
101
  // SPCR SPI Controlregister
102
  // SPIE=0; //No SPI Interrupt
103
  // SPE=1;  //SPI Enable
104
  // DORD=0; //Send MSB first
105
  // MSTR=1; //I am the master !
106
  // CPOL=0; //SCK low if IDLE
107
  // CPHA=0; //SPI Mode 0
108
  // SPR1=1; //SPI Clock = f/128 = 125kHz @16MHz Clock
109
  // SPR0=1; //or f/64 if SPI2X = 1 in SPSR register
110
  
111
  
112
  SPI_CTRL_REGISTER = (1<<SPE0) | (1<<MSTR0) | (1<<SPR00) | (1<<SPR10);
113
114
  // SPSR SPI Statusregister
115
  // SPI2X=0; // No double speed
116
  _delay_ms(1);
117
  /*Teste*******/
118
  //conf_mcp_send(addr,MCP_IOCON,0b00000000,0b00000000);
119
  conf_mcp_send(addr,MCP_IODIR, 0xf8, 0xff);
120
  conf_mcp_send(addr,MCP_GPPU,0XFF,0XFF);
121
  mcp_send(addr,0x07,0x00);
122
  /******************************/
123
  
124
  //conf_mcp_send(1,MCP_IODIR,0X00,0X00);
125
   //
126
  //conf_mcp_send(2,MCP_IOCON,0x40,0x40);
127
  //conf_mcp_send(2,MCP_IODIR,0X00,0X00);   
128
   //
129
  //conf_mcp_send(0,MCP_IOCON,0b01000000,0b01000000);
130
  //conf_mcp_send(3,MCP_IODIR,0XFF,0XFF);   
131
  //conf_mcp_send(3,MCP_IPOL,0XFF,0XFF);  
132
  //conf_mcp_send(0,MCP_GPPU,0XFF,0X00);
133
   
134
  /*EIMSK = (1<<INT2);
135
  EIFR = (1<<INTF2);
136
  EICRA |=(0<<ISC20);
137
  EICRA |=(0<<ISC21);
138
139
140
141
/* Move interrupts to Boot Flash section */
142
}
1
#ifndef MCP23S17_H_
2
#define MCP23S17_H_
3
4
//Deklaration MCP Register
5
/*
6
' MCP23S17 Register  RO=ReadOnly
7
' Adresse 00 01  IODIR   Richtung Port a/b 0=Output 1=Input
8
' Adresse 02 03  IPOL    Polarität 1=umgekehrt
9
' Adresse 04 05  GPINTEN Interrupt aktivieren 1=an 0=aus
10
' Adresse 06 07  DEFVAL  Vergleichsregister für Interrupt
11
' Adresse 08 09  INTCON  1=PIN<->DEFVAL 0=PIN neu <->PIN alt
12
' Adresse 0A 0B  IOCON   Configuration
13
' Adresse 0C 0D  GPPU    PullUp 1=aktiv 0= aus
14
' Adresse 0E 0F  INRF    Interrupt Flag register RO
15
' Adresse 10 11  INTCAP  Interrupt Capture Register RO
16
' Adresse 12 13  GPIO    Port Werte RW
17
' Adresse 14 14  OLAT    Output Latch Register
18
*/
19
#define MCP_IODIR    0x00
20
#define MCP_IPOL    0x02
21
#define MCP_GPINTEN    0x04
22
#define MCP_DEFVAL    0x06
23
#define MCP_INTCON    0x08
24
#define MCP_IOCON    0x0A
25
#define MCP_GPPU    0x0C
26
#define MCP_INRF    0x0E
27
#define MCP_INTCAP    0x10
28
#define MCP_GPIO    0x12
29
#define MCP_OLAT    0x14
30
31
#define DUMMY_WRITE    (uint8_t)(0xFF)
32
// Port definition
33
#define MCP_CS_BIT    0  
34
#define MCP_CS_PORT    PORTB   
35
#define MCP_CS_DDR    DDRB   
36
37
//#define MCP_RESET_BIT  0  
38
//#define MCP_RESET_PORT   PORTB   
39
//#define MCP_RESET_DDR   DDRB   
40
41
#define MCP_INTERRUPT_BIT    2  
42
#define MCP_INTERRUPT_PORT    PORTB   
43
#define MCP_INTERRUPT_DDR    DDRB   
44
45
#ifndef cbi
46
 #define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
47
#endif
48
#ifndef sbi
49
 #define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
50
#endif
51
52
#define MCP_CS_INIT()   { cbi(MCP_INTERRUPT_DDR,MCP_INTERRUPT_BIT); \
53
            sbi(MCP_CS_PORT,MCP_CS_BIT); \
54
            sbi(MCP_CS_DDR,MCP_CS_BIT);/*/
55
            sbi(MCP_RESET_PORT,MCP_RESET_BIT); /
56
            sbi(MCP_RESET_DDR,MCP_RESET_BIT);*/ }
57
58
#define MCP_CS_ON()   cbi(MCP_CS_PORT,MCP_CS_BIT);
59
#define MCP_CS_OFF()   sbi(MCP_CS_PORT,MCP_CS_BIT);
60
61
//#define MCP_RESET_ON()    cbi(MCP_RESET_PORT,MCP_RESET_BIT);
62
//#define MCP_RESET_OFF()   sbi(MCP_RESET_PORT,MCP_RESET_BIT);
63
64
 #define SPI_CTRL_REGISTER    SPCR0
65
 #define SPI_STATUS_REGISTER  SPSR0
66
 #define SPI_DATA_REGISTER    SPDR0
67
 #define SPI_STATUS_IF_BIT    SPIF0
68
69
 #define SPI_WRITE(a)     { SPI_DATA_REGISTER=(a); }
70
 #define SPI_WAIT()     { while(! ( SPI_STATUS_REGISTER & (1<<SPI_STATUS_IF_BIT) ) ); }
71
72
void conf_mcp_send(uint8_t addr,uint8_t art,uint8_t pa,uint8_t pb);
73
void mcp_send(uint8_t addr,uint8_t pa,uint8_t pb);
74
int mcp_rec(uint8_t addr);
75
void mcp_int_on();
76
void initmcp(uint8_t addr);
77
78
#endif /* MCP23S17_H_ */

Vielen Dank für hilfreiche Tipps;-)

von holger (Gast)


Lesenswert?

1
    //wait for response
2
    do
3
  {
4
    SPI_WRITE(DUMMY_WRITE);
5
    SPI_WAIT();
6
    by=SPI_DATA_REGISTER;
7
    timeout--;
8
    if(timeout==0) break; // no response
9
  } while(by==DUMMY_WRITE);

Kommt mir bekannt vor;)
Nur mal zum Verständnis: Der MCP23S17 ist keine
SD Karte!

von Alex E. (alex_e)


Lesenswert?

ja, es wurde ein teil einer sdcard-implementierung genutzt.

ich benutz aber momentan nur die Funktion initmcp(0);
Sollte dann ja gerade meine Adresspins ansteuerung, geht aber nicht;-(

von Alex E. (alex_e)


Lesenswert?

Sorry Jungs...

eine Zeile hat das Problem gelöst;-)

DDRB |= (1<<PINB0);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.