Jump to content
43oh

A/D input voltage output USI to 7X10 LED


Recommended Posts

Hi, first post to project forums. Let me know if my forum conduct is incorrect!

 

Programmed the MSP430G2231 to A/D an input voltage and output via USI to serial-parallel shift reigsters connected to 7X10 LED matrix.

 

My code description is: Iterate through 7 rows. For a given row shift data in bitwise from USI SDO MSB first, latch in and output. Then row next and repeat.

 

I ran my code using CCS and step through gets stuck on delay...

 

Also, My SDO output is on P1.6. LED2 is on but I didn't program this. Sup?

 

#include  "msp430g2231.h"

#define CLOCK BIT0; //reference bit for clock
#define OE BIT1; //output enable
#define LATCHR BIT2; // Row latch-> 1.2
#define LATCHC BIT3; // Column Latch -> 1.3


void pulseClock ( void );
void delay ( unsigned int );

void main(void)
{
//Intitialize registers
 P1DIR |= OE;
 P1DIR |= LATCHR;
 P1DIR |= LATCHC;// Set P1.1,P1.2,P1.3 to output direction
 ADC10CTL1 = INCH_7; //Input P1.7, single conversion
 ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE; //Relative to VREF 1.5, 16CLKs SHT


USICTL0 = USIPE6 + USIPE5 + USIMST + USIGE;// P1.6 and P1.5 set, MSBFIRST I am assuming 8-bit to 16-bit reuires MSB zero padding
USICTL1 = USIIE; //Interrupt enabled, most options are for I2C
USICKCTL = USISSEL_4;//Action on input clock high, USISWCLK is initialized to 0
USICNT = USI16B + 0x10; //16-bit SR mode, INITIAL CONDITION 16 bit countdown decrement during operation must reset

int i;
int k;

while(1)
{ 
if( i == 7)
{i = 0;}

// Begin row count envelope
 for( i = 0; i < 7; i++)
  {
P1OUT &= ~LATCHC;
P1OUT &= ~LATCHR;//initialize latches
USICTL0 = USIOE; //Enable USI output
    if(i == 0) //initilize row register with 0x1h;
     { 
       USISR |= CLOCK; //Prepare USISR with 0x1h 

         while(USIIFG != 0) //flag set when USICNT = 0
          {
             USISR |= CLOCK; //Prepare USISR with 0x1h 
			for( k = 0; k < 16; k++) //send each bit via clock iteration
              	{
                 pulseClock();
                 delay(50); //3.125ms delay
             	}
		USICNT |= 0x10; //reload SR counter
           P1OUT |= LATCHR;
           P1OUT &= ~LATCHR; // Pulse the row register latch pin to write
  		}
     }
    else
     {   
     USISR = BIT0 << i; //shift next row + 1
   	for( k = 0; k < 16; k++) //send each bit via clock iteration
              {
                 pulseClock();
                 delay(50); //3.125ms delay
              }
  			USICNT |= 0x10; //reload SR counter
           P1OUT |= LATCHR;
           P1OUT &= ~LATCHR; // Pulse the row register latch pin to write
     }
//Begin ADC
USICTL0 = ~USIOE; //disable USI output
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
USISR = ADC10MEM; //move ADC output to shift register buffer
ADC10CTL0 |= ~(ENC + ADC10SC); 
USICTL0 = USIOE; //Enable USI output
 			for( k = 0; k < 16; k++) //send col register via clock iteration
              {
                 pulseClock();
                 delay(50); //3.125ms delay
              }
 			USICNT |= 0x10; //reload SR counter
           P1OUT |= LATCHC;
           P1OUT &= ~LATCHC;// Pulse the column register latch pin to write
		P1OUT |= OE; //toggle OE for both row and col register
		P1OUT &= ~OE;// Clear OE off
  }
}
}  
void pulseClock( void )
{
 USICKCTL |= USISWCLK;
 USICKCTL ^= USISWCLK; //remember OR sets to 1 XOR sets to 0
}

void delay(unsigned int ms)
{
while (ms--)
   {
       __delay_cycles(1000); // set for 16Mhz change it to 1000 for 1 Mhz
   }
}

 

DVM.txt

 

Thanks for your attention colleagues!

Link to post
Share on other sites

A little more information... What shift register are you using? I use the 2 - 74HC595 to get 16 bits.

 

In my matrix configuration I use the same for 8X8 as I would for 8X7.

 

Maybe I do it screw ball or backwards..... but I shift out column then row out.

 

I set the Latch pin Low, then clock in pin low bit, put data bit at input, then clock pin goes high shifting in that bit. I repeat it 16 times, then set the Latch pin high.

 

MSB ---------- LSB

 

00010000 01010101

Column Row

 

Note I depending on if your using Common cathode or Common anode and the driving logic.. your address data for the column could also look like this.... 11101111 where zero selects which column is displayed. The same goes for your data, depending on if you need a 1 or 0 to turn on the led.

 

 

Then I get the next column data and repeat the above steps.

 

If you like check out my dot matrix code.....

Link to post
Share on other sites

Hey thanks for responding

 

So I am using 3 Toshiba Tc4094 Shift registers: 1 chip for 7 rows 2 chips for 10 columns. I finalized the schematic today and totally spaced on bringing it home, i will post it tomorrow. Here's the chip pin spec and general function...

 

post-2457-135135500305_thumb.jpg

 

It looks like these chips are using like a C2MOS logic in a transmission gate dynamic latch structure, not sure though wierd symbol...

 

Am i correct in assuimg that I can transfer the 10-bit ADC10MEM contents to USISR by just setting them equal? The CPU will just zero pad the ADC10MEM MSB?

 

Pretty much all of the LED matrix example I have investigated along the way have used GPI/O to shift-out-by-toggle from some known dataset. I am trying to shift variable A/D contents out after single converion. Is it even possible to shift ADC10MEM register contents out serially by just toggling a pin? I havent found anything that these register are bit-addressable....

 

Nice job on your scroller btw, I have been having a really hard time finding a multicolor ribbon like that :(

Link to post
Share on other sites

Yeah, trying to recycle parts :x I have hooked up NMOS transistors to assist with the current. The shift registers are only trigger their gates. It should be clear in the schemo, when i post it :oops: But Vdd is 5V because it's being fed directly with the MSP430, any higher and it demands more from the feed.

Link to post
Share on other sites

The ACD10MEM the numbers are padded to zero about the 10th bit.

 

Just looking at the 4094 logic most if it is enable high...

 

Output Enable = Logic high or supply.

 

Strobe (latch) = Low is the data is latched.

 

Clock looks like data is shifted in on the low to high change.

 

I think someone has used the SPI to serial out the data to the shift registers, I have not worked with it yet.

 

I just manually shift out the data, so I can use any port as a serial out port. Also can use any word bit size...

 

Rainbow ribbon - Digi-key...

 

 

 

Hey thanks for responding

 

So I am using 3 Toshiba Tc4094 Shift registers: 1 chip for 7 rows 2 chips for 10 columns. I finalized the schematic today and totally spaced on bringing it home, i will post it tomorrow. Here's the chip pin spec and general function...

 

[attachment=0]TC4094.JPG[/attachment]

 

It looks like these chips are using like a C2MOS logic in a transmission gate dynamic latch structure, not sure though wierd symbol...

 

Am i correct in assuimg that I can transfer the 10-bit ADC10MEM contents to USISR by just setting them equal? The CPU will just zero pad the ADC10MEM MSB?

 

Pretty much all of the LED matrix example I have investigated along the way have used GPI/O to shift-out-by-toggle from some known dataset. I am trying to shift variable A/D contents out after single converion. Is it even possible to shift ADC10MEM register contents out serially by just toggling a pin? I havent found anything that these register are bit-addressable....

 

Nice job on your scroller btw, I have been having a really hard time finding a multicolor ribbon like that :(

Link to post
Share on other sites

Good catch on the latch nexus, totally wrote my latch sequence in the wrong order.

 

Using SPI is not really the tricky part its more of getting the ADC to run smoothly with the SPI. And I am still not 100% that movign ADC10MEM to USI Shift register (USISR) is done with the following USISR = ADC10MEM because....

 

post-2457-135135500373_thumb.jpg

 

So it looks like to access anything outside of the ADC block, I have to use ADC10SA (start address in memory). But the addressing mode section says that the CPU has a "Register Mode" and simply moves register contents to another with the assembly mov function (which its equiavlent is '=' in C?)

 

Heres is my schematic for fun

 

output.pdf

 

The confusion is just beginning!!! I appreciate everyones patience

Link to post
Share on other sites

If you use single channel single conversion then you don't need to worry about ADC10SA, but one thing I don't understand is why are you sending raw ADC value to shift registers without converting it to something readable? No multiplexing either, is this intentional?

Link to post
Share on other sites

Nice, tahnks Rob.

 

This more of a visual experiment. I am "filling-up" the display with binary then reset and repeat, each row a new sample. So I thought it would look cool to see how the display pattern changes as the input voltage changes. Although i can't convert binary quickly the display would be much more lively in conveying dynamic measurements than a 7-segment.

 

Multiplexing the ADC results?

Link to post
Share on other sites

Some code I wrote up but not posted is displaying a Bar graph or Dot graph on the matrix display.

 

Yes multiplexing the ADC output on the display... you could create a slowly changing graph of the temperature or voltage change on your display in Bar or Dot form.

 

Look at my scrolling matrix code, with simple changes, you could set a sample rate for the ADC. The older data scrolls off the screen as the new data sample comes in.

 

Create a simple Oscilloscope....

 

 

Just throwing some stuff out there....

Link to post
Share on other sites

nexus that is a swell idea and i see that Rob agrees with you, but i was really wanting to "real-time" it :(. I simplified this code enough to where this should totally work. Though..... currently the interrupt is acting like The Terminator

 

Well i should also say that i know that mine wont be any easier to read, but if the data is side scrolling then i definately wont be able to pick out a when a constant voltage is present. On mine it would display as the same binary voltage on every row. Yours would look pretty cool as the voltage is varying though, like a roaring river of red!

Link to post
Share on other sites

Still pulling my hair out. I want to abandon the whole interrupt idea but its is the most effective.

 

While i am in debug:

 

-software hops into interrupt when expected

-then exits after performing commands i have inside the ISR

-returns to the point where the interrupt occured

-steps one line down, a line that would not trigger interrupt

-jumps back into interrupt

 

The USI interrupt can be turns on when a 5 bits of a register value has been decremented to zero. Flag is turned off by inserting value > 0 into 5-bits portion of same register.

 

USICTL1 |= (USIIE|~(USIIFG)); //both the USIIE AND GIE will high for the interrupt service request

USICNT |= 16; // re-load counter to reset flag

 

which is more than necessary right?

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...