CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Problems with interrupts on MCP23S17

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

Problems with interrupts on MCP23S17
PostPosted: Wed Aug 24, 2016 10:39 pm     Reply with quote

Hi everybody:)
I having a problems with interrupts on MCP23S17.
In my project, i used 4 MCP23S17 (address: 0->3) to check short or open of wireharness.
The testing steps are set output( logic 0) one pin and read input of another pins, if detected pins have a logic 0 (same level with pin output) I'll get into a array, convert to strings and sent to PC.
But when tried on circuit, when i set output for 1 pin, if I used a 1 wire (flat wire) for connect to another pin, the interrupts will occurred (although another side of wire not connect to GND), so that I think maybe an errors in my config or terrible reason is noisy in my circuit.
In my circuit, all of signal lines for SPI com and interrupt pins have a 4.7k pullup resistors, and all of IO pins of MCP23S17 were protected by TVS diode array.
I'm using PIC18F26K22 and CCS C ver 5.058.
If everybody have a same problem, pls share me a way to fix it.
Thanks you.

1. Schematic
https://drive.google.com/file/d/0Bz215_lkn4g-VkZ4R3NJVmdtMkU/view?usp=sharing

2. Code
-- Init
Code:

void IO_INIT(){   // Just 1 call spread to all devices
   output_high(IO_CS_PIN);
   output_drive(IO_CS_PIN);
   IO_WRITE_REGISTER(dev0, 0x0A, 0xA8);

}


-- set config one output pins and another pins input
Code:

      if(check_cmd_pc==1)
      {
         check_cmd_pc=0;
         if(str_cmd_pc1[0]=='S' && str_cmd_pc1[1]=='P' && str_cmd_pc1[2]=='_' && str_cmd_pc1[3]=='C' && str_cmd_pc1[6]=='_')  // $SP_C01_01#
         {
         
            id_card= ((str_cmd_pc1[4] - 0x30)*10) + (str_cmd_pc1[5] - 0x30);
            id_pin = ((str_cmd_pc1[7] - 0x30)*10) + (str_cmd_pc1[8] - 0x30);
           
            init_checking();

           
            if(id_pin<=16)      {   dev_num= dev0; pin_num= map_pin[id_pin];     tris_num= ~( map_tris[id_pin]);    }
            else if(id_pin<=32) {   dev_num= dev1; pin_num= map_pin[id_pin-16];  tris_num= ~( map_tris[id_pin-16]); }
            else if(id_pin<=48) {   dev_num= dev2; pin_num= map_pin[id_pin-32];  tris_num= ~( map_tris[id_pin-32]); }
            else if(id_pin<=64) {   dev_num= dev3; pin_num= map_pin[id_pin-48];  tris_num= ~( map_tris[id_pin-48]); }
           
            fprintf(PC, "\r\n Id card: %u", id_card);
            fprintf(PC, "\r\n Id pin : %u", id_pin);
            fprintf(PC, "\r\n dev_num:%u",  dev_num);
            fprintf(PC, "\r\n pin_num :0x%X",  pin_num);
            fprintf(PC, "\r\n tris_num:0x%X",  tris_num);
           
            if(( id_pin % 2)==0)
            {
               IO_WRITE_REGISTER(dev_num, IODIRA,   tris_num);    // set tris a
               IO_WRITE_REGISTER(dev_num, GPINTENA, tris_num);    // enable interrupts
               IO_WRITE_REGISTER(dev_num, DEFVALA,  tris_num);    // set default value for compare
               IO_WRITE_REGISTER(dev_num, INTCONA,  tris_num);    // set interrupt pin compare value 
//!               IO_WRITE_REGISTER(dev_num, GPPUA,    tris_num);
            }
           
            else
            {
               IO_WRITE_REGISTER(dev_num, IODIRB,   tris_num);    // set tris b
               IO_WRITE_REGISTER(dev_num, GPINTENB, tris_num);    // enable interrupts
               IO_WRITE_REGISTER(dev_num, DEFVALB,  tris_num);    // set default value for compare
               IO_WRITE_REGISTER(dev_num, INTCONB,  tris_num);    // set interrupt pin compare value
//!               IO_WRITE_REGISTER(dev_num, GPPUB,    tris_num);
            }
           
            for(dev_num=0; dev_num<=6; dev_num=dev_num+2)         // reset all interrupt
            {
//!               IO_READ_REGISTER( dev_num,GPIOA);
//!               IO_READ_REGISTER( dev_num,GPIOB);
               IO_READ_REGISTER( dev_num,INTCAPA);
               IO_READ_REGISTER( dev_num,INTCAPB);
            }           
           
           
            IO_OUTPUT_BIT( dev_num, pin_num, 0 );     // send output pin
         }
      }

_________________
Begin Begin Begin !!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 25, 2016 5:40 pm     Reply with quote

You apparently have some problem with a ribbon cable. You should put
a scope on the problem pins and make a test program to send signals
on your problem pins. Look at the waveforms. Are they correct ?

You can greatly reduce crosstalk between signals on a flat ribbon cable
by putting a ground wire between all signal wires. Example:

1 Ground
2 Signal
3 Ground
4 Signal
5 Ground
6 Signal
7 Ground
etc.

Of course, this method requires 2x as many pins on the flat ribbon cable.


Also, there may be an impedance mismatch resulting in distorted
waveforms. This is commonly fixed or reduced by adding a 30 ohm
series resistor between the driver IC and the flat ribbon cable connector.
Some other resistor value may be better. You can find it by experimenting.
tienchuan



Joined: 25 Aug 2009
Posts: 175

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Aug 26, 2016 3:13 am     Reply with quote

Thanks for your helping.
Yes, I tried with your suggestion, used oscilloscope to test a fixed input pin, and don't see a low level appearance on this pin, but interrupts occurred.
And about resister buffer between connector and TVS array IC, you can reference schematic. I think with resistor value is 220 ohm, it enough for limit current of output pin MCP23S17.
If don't haven't a way, I'll change all of input to pull down resistor and using high level for active level.
Do you think a good solution in this case?
Thanks you.
_________________
Begin Begin Begin !!!
temtronic



Joined: 01 Jul 2010
Posts: 9134
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Aug 26, 2016 5:03 am     Reply with quote

First I would make test code for only ONE of the 23S17 chips. You've got a LOT of 'math' and 'logic' to set/test/report ALL 4 chips and ir may not be correct.
Also I don't see a 23S17 'init()' function where all the registers of the device are setup. There may be 'timing' issues either with the device themselves or the SPI communications( you don't show the actual 'driver..)
I'd start with a 'simple' set/reset all 16 bits in sequence,say 250ms apart and confirm using LEDs+Rs that each pin is functional. Then code 1 pin for output, the rest input, 'toggle' the output pin and manually connect it to the others. The program should show you which pin is 'active'.
Finally, once that all works THEN configure the interrupt registers for ONE device and confirm it works. I see there are 2 modes, IOC and mask, so you'll need to test both ways.

I know this is a lot of 'small' programs to code/compile and test but you need to confirm in small steps that both hardware and software is working properly. Once a plan of attack is made, it should only be 1/2 days labour and you'll KNOW what's happening as opposed to spending 3-4 days trying this, changing that and getting no where.

I can see a couple applications for that chip already so I better order a tube soon !

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group