I'm very confused as to why I can't get 3 GPIO's to work as desired.
I'm trying to program 3 external shift registers. The control lines are Clk, Latch, Output Enable and Data In. I've implemented a ~240Hz timer to cycle between 4 16-bit values to be sent to the shift registers. Everything works except the 3 data inputs. The actual failure is the bit shifting and mask of each of the 16-bits of the 3 data in variables.
I'm including my code and an analyzer trace (uc32 pins directly to a Saleae logic analyzer).
I'd appreciate anyone that could shed some light.
Thanks!
Test.pde
/*
To turn on any given channel, set the pin LOW.
To turn off, set the pin HIGH. The higher the analogWrite level,
the lower the brightness.
This example code is in the public domain.
*/
#define __32MX340F512H__ 1
period = TICKS_PER_SECOND / frequency;
T3CONCLR = Tx_ON; /* Turn the timer off */
T3CON = Tx_PS_1_8; /* Set the prescaler */
TMR3 = 0; /* Clear the counter */
PR3 = period; /* Set the period */
T3CONSET = Tx_ON; /* Turn the timer on */
}
void setup()
{
// Initialize serial communications:
Serial.begin(115200);
Serial.println("hello");
// Set all used outputs to open-drain
ODCDSET = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
ODCFSET = E3 | CTR1 | CTR0;
ODCGSET = E0 | E1 | E2;
// Set all used outputs to a low
LATDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
LATFCLR = E3 | CTR1 | CTR0;
LATGCLR = E0 | E1 | E2;
// Set all Analogue pins to digitial
AD1PCFG = 0xffff;
// Set LED Control outputs to normal TTL, not open-drain
ODCDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
ODCFCLR = E3 | CTR1 | CTR0;
ODCGCLR = E0 | E1 | E2;
// set LED control pins as outputs
TRISDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
TRISFCLR = E3 | CTR1 | CTR0;
TRISGCLR = E0 | E1 | E2;
// Disable the interrupt-on-change for IO pins
CNCONCLR = 0xe000;
switch ( eCount ) {
case 0:
digitalWrite( PIN_E0, HIGH );
break;
case 1:
digitalWrite( PIN_E1, HIGH );
break;
case 2:
digitalWrite( PIN_E2, HIGH );
break;
case 3:
digitalWrite( PIN_E3, HIGH );
break;
default:
break;
}
Question
bgetz
I'm very confused as to why I can't get 3 GPIO's to work as desired.
I'm trying to program 3 external shift registers. The control lines are Clk, Latch, Output Enable and Data In. I've implemented a ~240Hz timer to cycle between 4 16-bit values to be sent to the shift registers. Everything works except the 3 data inputs. The actual failure is the bit shifting and mask of each of the 16-bits of the 3 data in variables.
I'm including my code and an analyzer trace (uc32 pins directly to a Saleae logic analyzer).
I'd appreciate anyone that could shed some light.
Thanks!
Test.pde
/*
To turn on any given channel, set the pin LOW.
To turn off, set the pin HIGH. The higher the analogWrite level,
the lower the brightness.
This example code is in the public domain.
*/
#define __32MX340F512H__ 1
#include <p32xxxx.h>
#include <plib.h>
#define CLK 0x0400 // D10
#define Ou1 0x0080 // D07
#define Ou2 0x0040 // D06
#define Ou3 0x0020 // D05
#define OE 0x0010 // D04
#define LE 0x0008 // D03
#define E0 0x0040 // G06
#define E1 0x0080 // G07
#define E2 0x0100 // G08
#define E3 0x0040 // F06
#define INDCTR 0x0800 // D11
#define CTR1 0x0020 // F5
#define CTR0 0x0010 // F4
#define PIN_CLK 8
#define PIN_Ou1 37
#define PIN_Ou2 36
#define PIN_Ou3 34
#define PIN_OE 10
#define PIN_LE 9
#define PIN_E0 13
#define PIN_E1 12
#define PIN_E2 11
#define PIN_E3 38
#define PIN_CTR1 40
#define PIN_CTR0 39
#define PIN_INDCTR 35
#define CPU_HZ 80000000
#define TICKS_PER_SECOND (CPU_HZ / 2)
#define Tx_ON 0x8000
#define Tx_PS_1_8 (3 << 4)
#define Tx_SOURCE_INT 0
volatile uint32_t counter = 0;
volatile uint32_t intHit = 0;
volatile uint32_t eCount = 0;
volatile uint32_t OutA1[4] = { 0xaaaa, 0x5555, 0x9999, 0x6666 };
volatile uint32_t OutA2[4] = { 0x5555, 0x9999, 0x6666, 0xaaaa };
volatile uint32_t OutA3[4] = { 0x9999, 0x6666, 0xaaaa, 0x5555 };
/* Define the Interrupt Service Routine (ISR) */
void __attribute__((interrupt)) myISR() {
++counter;
if ( counter == 4 )
counter = 0;
intHit = 1;
if ( counter & 0x01 )
LATFSET = CTR0;
else
LATFCLR = CTR0;
if ( counter & 0x02 )
LATFSET = CTR1;
else
LATFCLR = CTR1;
LATDSET = INDCTR;
_nop();
LATDCLR = INDCTR;
clearIntFlag(_TIMER_3_IRQ);
}
/* start_timer_3 */
void start_timer_3( uint32_t frequency ) {
uint32_t period;
period = TICKS_PER_SECOND / frequency;
T3CONCLR = Tx_ON; /* Turn the timer off */
T3CON = Tx_PS_1_8; /* Set the prescaler */
TMR3 = 0; /* Clear the counter */
PR3 = period; /* Set the period */
T3CONSET = Tx_ON; /* Turn the timer on */
}
void setup()
{
// Initialize serial communications:
Serial.begin(115200);
Serial.println("hello");
// Set all used outputs to open-drain
ODCDSET = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
ODCFSET = E3 | CTR1 | CTR0;
ODCGSET = E0 | E1 | E2;
// Set all used outputs to a low
LATDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
LATFCLR = E3 | CTR1 | CTR0;
LATGCLR = E0 | E1 | E2;
// Set all Analogue pins to digitial
AD1PCFG = 0xffff;
// Set LED Control outputs to normal TTL, not open-drain
ODCDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
ODCFCLR = E3 | CTR1 | CTR0;
ODCGCLR = E0 | E1 | E2;
// set LED control pins as outputs
TRISDCLR = CLK | Ou1 | Ou2 | Ou3 | OE | LE | INDCTR;
TRISFCLR = E3 | CTR1 | CTR0;
TRISGCLR = E0 | E1 | E2;
// Disable the interrupt-on-change for IO pins
CNCONCLR = 0xe000;
// Set OE to high
LATDSET = OE;
counter = 8;
intHit = 0;
start_timer_3( 60 * 4 ); /* 240 Hz */
setIntVector( _TIMER_3_VECTOR, myISR );
setIntPriority( _TIMER_3_VECTOR, 4, 0 );
clearIntFlag( _TIMER_3_IRQ );
setIntEnable( _TIMER_3_IRQ );
}
void loop()
{
int i, j;
int to1, to2, to3;
if ( intHit ) {
eCount = counter & 0x03;
/* Make sure CLK and LE are low */
digitalWrite( PIN_CLK, LOW );
digitalWrite( PIN_LE, LOW );
/* Make sure OE is hi */
digitalWrite( PIN_OE, HIGH );
/* Prepare the Out Data lines by setting them LOW */
digitalWrite( PIN_Ou1, LOW );
digitalWrite( PIN_Ou2, LOW );
digitalWrite( PIN_Ou3, LOW );
to1 = OutA1[eCount];
to2 = OutA2[eCount];
to3 = OutA3[eCount];
for ( i = 0; i < 16; i++ ) {
/* Test Red */
if ( to1 & 0x01 ) {
digitalWrite( PIN_Ou1, HIGH );
}
/* Test Green */
if ( to2 & 0x01 ) {
digitalWrite( PIN_Ou2, HIGH );
}
/* Test Blue */
if ( to3 & 0x01 ) {
digitalWrite( PIN_Ou3, HIGH );
}
/* Toggle CLK */
digitalWrite( PIN_CLK, HIGH );
digitalWrite( PIN_CLK, LOW );
to1 = to1 >> 1;
to2 = to2 >> 1;
to3 = to3 >> 1;
}
/* Toggle LE, then set OE low */
digitalWrite( PIN_LE, HIGH );
digitalWrite( PIN_LE, LOW );
digitalWrite( PIN_OE, LOW );
digitalWrite( PIN_E0, LOW );
digitalWrite( PIN_E1, LOW );
digitalWrite( PIN_E2, LOW );
digitalWrite( PIN_E3, LOW );
switch ( eCount ) {
case 0:
digitalWrite( PIN_E0, HIGH );
break;
case 1:
digitalWrite( PIN_E1, HIGH );
break;
case 2:
digitalWrite( PIN_E2, HIGH );
break;
case 3:
digitalWrite( PIN_E3, HIGH );
break;
default:
break;
}
intHit = 0;
}
}
Link to comment
Share on other sites
1 answer to this question
Recommended Posts
Archived
This topic is now archived and is closed to further replies.