Jump to content
43oh

BlackAngel

Members
  • Content Count

    0
  • Joined

  • Last visited

Reputation Activity

  1. Like
    BlackAngel reacted to bluehash in 2018   
    Hello Everyone,
    I would like to wish all of our members and visitors a wonderful new year. Thank you for contributing and answering posts. 
    Keep posting and wish you all the best.
  2. Like
    BlackAngel reacted to RogueGeek in Code to Read/Write 24LC256 I2C EEPROM on MSP430G2553   
    Hello,
     
    I've been lurking here for well over a year and finally figured I should post something.
     
    I've been learning to use the USCI I2C interface on the on MSP430G2553 and came up with this code for talking to the 24LC256 chip.
     
    The code implements single/multibyte read/write routines for the 24LC256 EEPROM.  
    It should work on the 24LC512 without modification and on other 24LCxx family chips with minimal modification to the addressing.
     
    I have probably broken numerous coding rules and best practices, there is no error checking to speak of, and nothing has timeouts. So use at your own risk.
     
    I also have screen captures from the logic analyzer showing the SCL/SDA timings.  If anyone is interested, please let me know and I'll post them.
     
    Comments are welcome and appreciated.
    Thanks
     
    Brian
    //************************************************************************************* // MSP430G2553 24LC256/512 I2C Interface // Brian McClure NZ8D // first.lastname@gmail.com // July 2014 // /********************************************************************************************/ /* Include */ /********************************************************************************************/ #include "msp430g2553.h" /********************************************************************************************/ /* I2C Definitions */ /********************************************************************************************/ //I2C Port Definitions #define i2cAddress 0x50 //Address GPIO Address //USCI I2C PIN Definition #define SDA_PIN BIT7 //Bit 7 USCI Port 1(SDA) #define SCL_PIN BIT6 //Bit 6 USCI Port 1(SCL) /********************************************************************************************/ /* UART Function Definitions */ /********************************************************************************************/ void UART_puts(char * s); void UART_outdec(long data, unsigned char ndigits); /********************************************************************************************/ /* I2C Function Definitions */ /********************************************************************************************/ void I2C_Write_EEProm(unsigned char slave_address, unsigned int register_address, char * data, unsigned char DataLength ); void I2C_Read_EEProm(unsigned char slave_address, unsigned int memory_address, char * data, unsigned char DataLength ); /********************************************************************************************/ /* Misc Function Definitions */ /********************************************************************************************/ void delay_ms(unsigned int delay); //Delay /********************************************************************************************/ /* Main */ /********************************************************************************************/ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_16MHZ; //set DCO to 16Mhz DCOCTL = CALDCO_16MHZ; // make sure to update the Delay_ms function if the DCO is changed //UART Initial P1SEL = BIT1 + BIT2; // P1.1 = RX pin, P1.2=TX pin P1SEL2 = BIT1 + BIT2 ; // P1SEL and P1SEL2 = 11--- Secondary peripheral module function is selected. UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 69; // 16MHz 230400 UCA0BR1 = 0; // 16MHz 230400 UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt //USCI_I2C_Init P1SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0 P1SEL2|= SDA_PIN + SCL_PIN; UCB0CTL1 = UCSWRST; // Enable SW reset, HOLD USCB in a reset state UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, MODE 3 = I2C, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 72; // Set I2C master speed 72 gives approx 200Khz clock at 16Mhz UCB0BR1 = 0; // Set I2C master speed UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UART_puts("Starting...\r\n"); //output to UART to indicate the program is running __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enable while (1){ } } void UART_puts(char * s) { while (*s) { while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = *s++; } } void UART_outdec(long data, unsigned char ndigits){ //UART_outdec modified/hacked to properly handle negative numbers. unsigned char sign, s[15]; //I copied this from a TI example or the 40oh forum, but I'm not sure of the original author. unsigned int i; sign = 0x00; if(data < 0) { sign='-'; data = -data; } i = 0; do { s[i++] = data % 10 + '0'; //adds the value of data least sig digit to ascii value of '0' if(i == ndigits) { s[i++]='.'; } } while( (data /= 10) > 0); if (i < ndigits) //fixes loss of leading 0 in fractional portion when number of digits is less than length of data { do { s[i++]='0'; } while (ndigits > i) ; s[i++]='.'; } if (sign == '-') //if value is negative then include the '-' sign { s[i] = sign; } else { //if value is positive then reduce 'i' counter by 1 to prevent the do loop from trying to output a sign character. i--; } do { while (!(IFG2 & UCA0TXIFG)); UCA0TXBUF = s[i]; } while(i--); } void delay_ms(unsigned int delay) { while (delay--) { __delay_cycles(16000); //1ms = 1000 cycles per 1Mhz clock freq. } } void I2C_Read_EEProm(unsigned char slave_address, unsigned int memory_address, char * data, unsigned char DataLength ) { //Reading from a 24LCxxx series is much easier then writing. Reading doesn't have to be done in 64 byte pages. /* * Todo: * 1. add checks to make sure write does not exceed maximum length of EEprom * 2. check for valid memory_address * */ int rLoop = 0; //loop counter while (UCB0STAT & UCBBUSY); //wait for USCI B0 bus to be inactive UCB0I2CSA = slave_address; //set SLAVE address UCB0CTL1 |= UCTR + UCTXSTT; //set USCI to be I2C TX, send start condition UCB0TXBUF = (memory_address & 0x7F00) >> 8; //transfer memory_address MSB while (UCB0CTL1 & UCTXSTT); // waiting for slave address to transfer while ((IFG2 & UCB0TXIFG) != UCB0TXIFG); //wait for TX IFG to clear UCB0TXBUF = (memory_address & 0x00FF); //transfer memory_address LSB while ((IFG2 & UCB0TXIFG) != UCB0TXIFG); //wait for TX IFG to clear UCB0CTL1 &= ~UCTR; //set USCI to be RECEIVER UCB0CTL1 |= UCTXSTT; //send restart while (UCB0CTL1 & UCTXSTT); // wait until I2C STT is sent for (rLoop=0; rLoop<DataLength; rLoop++) //receive loop { while ((IFG2 & UCB0RXIFG) != UCB0RXIFG); //wait for RX buffer to have data data[rLoop] = UCB0RXBUF; //Move rvcd data of or USCI buffer. This also clears the UCB0RXIFG flag if (rLoop == DataLength-2) //NACK and STOP must be send before the last byte is read from the buffer. //if not the CPU will read an extra byte. { UCB0CTL1 |= UCTXNACK; //generate a NACK UCB0CTL1 |= UCTXSTP; //generate a stop condition } } } void I2C_Write_EEProm(unsigned char slave_address, unsigned int memory_address, char * data, unsigned char DataLength ) { /* * Todo: * 1. add checks to make sure write does not exceed maximum length of EEprom * 2. check for valid memory_address * */ int NumPages = (DataLength)/64 ; //Count of full 64 byte pages, 0 means the data is less than a full 64 byte page int PartialPageBytes = DataLength % 64; //this is the number of bytes remaining that do not make up a full page int address = 0; //EEprom memory starting address, this is different from the I2C slave address int NP =1; //loop counter to iterate though pages of memory int offset = 0; int offsetlimit = 0; if (PartialPageBytes > 0) { NumPages++; //if we have left over bytes that do not make up a full page, this will add a page to handle those bytes. } __disable_interrupt(); //prevent interrupts from messing with the I2C functions while (UCB0STAT & UCBBUSY); //wait for USCI B0 bus to be inactive UCB0I2CSA = slave_address; //set SLAVE address for (NP=1; NP<=NumPages; NP++) { address = ((NP-1) * 64) + memory_address; //this is the full page start address UCB0CTL1 |= UCTR + UCTXSTT; //set USCI to be I2C TX, send start condition UCB0TXBUF = (address & 0x7F00) >> 8; //transferring memory_address MSB while (UCB0CTL1 & UCTXSTT); // waiting for slave address was transferred while ((IFG2 & UCB0TXIFG) != UCB0TXIFG); //wait for TX IFG to clear UCB0TXBUF = (address & 0x00FF); //transferring memory_address LSB while ((IFG2 & UCB0TXIFG) != UCB0TXIFG); //wait for TX IFG to clear offsetlimit = 63; //set the offset limit to 63 if ((NP == NumPages) && (PartialPageBytes > 0)) //if we are preparing to send the last/partial page { offsetlimit = PartialPageBytes-1; //set the offset limit to the number of partial page bytes } for (offset=0; offset <=offsetlimit; offset++) { UCB0TXBUF = data[((NP-1)*64)+offset]; //send data. //UART_outdec(offset,0); while ((IFG2 & UCB0TXIFG) != UCB0TXIFG); //wait for TX IFG to clear } UCB0CTL1 |= UCTXSTP; // set I2C stop condition while ((UCB0STAT & UCSTPIFG) == UCSTPIFG); //wait for Stop condition to be set //delay while the EEPROM completed its write cycle. //It would be better to use NACK polling here as described in the datasheet. delay_ms(6); //24LC256 has a max page write time of 5ms, so we will wait 6ms to be sure } UART_puts("Done...\r\n"); __enable_interrupt(); } // ----------------------------------------------------------------------------- // Interrupt Handlers // ----------------------------------------------------------------------------- #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) char RxChar = 0x00; //char used to receive serial data RxChar = UCA0RXBUF; // copy the RX buffer into RxChar char buf[4] = {0}; //i2c received data buffer //void I2C_Write_EEProm(unsigned char slave_address, unsigned int memory_address, char * data, unsigned char DataLength ) I2C_Write_EEProm(i2cAddress,0x00,"ABCDEFGHIJKLMNOP",15); //void I2C_Read_EEProm(unsigned char slave_address, unsigned int memory_address, char * data, unsigned char DataLength ) I2C_Read_EEProm(i2cAddress,0x05,buf,5); //reads three bytes starting at memory location 0x05 and returns the data into 'buf' UART_puts("READING: \r\n"); UART_puts(buf); UART_puts("\r\n"); __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enable } //end UART RCV ISR
  3. Like
    BlackAngel reacted to zeke in Console with One-Wire Temperature on MSP430F5529 LP   
    Hi Guys,
     
    This has been on my bucket list for a while.
     
    I've put together a CCS6 project that gives the user a serial console to the MSP430 with the ability to read a DS18B20 sensor by issuing a serial command.
     
    Here's a copy-paste of some of my interactions on the console:
    ************************************************************************************* * CommandConsole Ver:0.1 Released by:RandomElectrons.com Built:Sep 22 2014 16:33:28 * ************************************************************************************* h ******************************************************************************* B,b: Banner command C,c: Clear screen command H,h: Help command M,m: Memory command R,r: Reset command S,s: Sensitivity command T,t: Temperature command V,v: Version command ******************************************************************************* OK t? T=254 raw decimal counts T=15.87'C OK t? T=213 raw decimal counts T=-13.31'C OK T? T=29 raw decimal counts T=-1.81'C OK T? T=9 raw decimal counts T=-0.56'C OK T? T=6 raw decimal counts T=0.37'C OK T? T=242 raw decimal counts T=15.12'C OK B? T=440 raw decimal counts T=27.50'C OK I have also uploaded my CCS6 project as a zip file.
     
    As the pictures suggest, I have created this on an F5529 LaunchPad board.
     
    The DS18B20 is wired up in 3-Wire mode and is connected to P1.4 of the LP and read with the typical bit-banging method. 
     
    I have wired in an adafruit ftdi friend onto P3.3 and P3.4 for USART to the PC operation.
     
    I use the Terminal inside of CCS6 to interact with the system.
    -->View-->Other-->Terminal-->OK
     
    The console portion of this project was inspired by and adapted from http://www.adnbr.co.uk/articles/parsing-simple-usart-commands
     
    Comments are welcomed.
     


    RE_OneWireOnF5529LP.zip
  4. Like
    BlackAngel reacted to chibiace in Nokia 5110 LCD ADC Graph   
    Hey, here is a little piece of code i cobbled together so that i could visualize my adc input and get a value reading along with it.
     


     
     
    when the line reaches the end of the screen it starts again from the beginning and erases the old line, which was the simplest way i could think of doing it
     
    the communication is bitbang and works on msp430g2231 and barely fits on there, tips on how to slim down my flashed code size would be very welcome.
     
    thanks to other members on this forum whom i borrowed small bits and pieces from.
     
    very fun to adjust the delays and amount of samples to see sine waves appear from a floating input pin.
     

     
    main.c:
    #include "msp430g2231.h" /* Program for MSP430G2231 to display a Graph,ADC and Voltage on a Nokia 5110 Lcd _____ VCC -| M G |- GND SCLK -| S 2 |- NC DIN -| P 2 |- NC DC -| 4 3 |- TEST CE -| 3 1 |- RESET RST -| 0 |- NC LED -|_____|- ADC */ //Define Pins for LCD + Backlight LED and ADC #define SCLK BIT0 #define DIN BIT1 #define DC BIT2 #define CE BIT3 #define RST BIT4 #define LED BIT5 #define ADC BIT6 //Font for ADC and Voltage Display static const char font[][5] = { {0x40, 0x5f, 0x51, 0x5f, 0x40} //0 ,{0x40, 0x40, 0x40, 0x5f, 0x40} //1 ,{0x40, 0x5d, 0x55, 0x57, 0x40} //2 ,{0x40, 0x55, 0x55, 0x5f, 0x40} //3 ,{0x40, 0x47, 0x44, 0x5f, 0x40} //4 ,{0x40, 0x57, 0x55, 0x5d, 0x40} //5 ,{0x40, 0x5f, 0x55, 0x5d, 0x40} //6 ,{0x40, 0x41, 0x41, 0x5f, 0x40} //7 ,{0x40, 0x5f, 0x55, 0x5f, 0x40} //8 ,{0x40, 0x47, 0x45, 0x5f, 0x40} //9 ,{0x40, 0x5e, 0x45, 0x5e, 0x40} //A ,{0x40, 0x5f, 0x51, 0x4e, 0x40} //D ,{0x40, 0x5f, 0x51, 0x51, 0x40} //C ,{0x40, 0x4f, 0x50, 0x4f, 0x40} //V }; const int write = 1; const int instruction = 0; void init(void); void clear(void); void shift(unsigned int, unsigned char); void cha(unsigned int ch); int main(void) { //Change me to suit. unsigned int samples = 5; unsigned int sampledelay = 1200; unsigned int loopdelay = 60000; //delay cycles unsigned int supplyvoltage = 3600; //mV //Int Hell int e;int i;unsigned int b=0b00000001;unsigned int j=0;int h;unsigned int l=5; //Arduino Value Map long map(long x, long in_min, long in_max, long out_min, long out_max) {return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;} //Disable Watchdog Timer WDTCTL = WDTPW + WDTHOLD; //Pin Directions P1DIR |= SCLK+DIN+DC+CE+RST+LED;; P1OUT |= LED; //ADC Setup Channel 2, ADC10CLK/4 ADC10CTL1 = INCH_6 + ADC10DIV_3 ; //Vcc & Vss as reference ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE; ADC10AE0 |= ADC; ADC10CTL0 |= ENC + ADC10SC; init(); clear(); //Set Cursor shift(instruction, 0x40 | 0); shift(instruction, 0x80 | 0); //Draw Font cha(10); //A cha(11); //D cha(12); //C shift(write, 0x4A); //: for(e=0;e<34;e++){shift(write, 0x40);} //_____ cha(13); //V: shift(write, 0x4A); //: for(e=0;e<32;e++){shift(write, 0x40);} //_____ //Main Program Loop while(1){ //ADC Read e=0; for(i=0;i<samples;i++){ ADC10CTL0 |= ADC10SC; while(ADC10CTL1 & ADC10BUSY); e=e+ADC10MEM; __delay_cycles(sampledelay); } e=e/samples; //Map ADC to graph e=map(ADC10MEM,0,1023,0,40); //Write ADC and Voltage values shift(instruction, 0x40 | 0); shift(instruction, 0x80 | 20); cha((ADC10MEM)/1000%10); cha((ADC10MEM)/100%10); cha((ADC10MEM)/10%10); cha((ADC10MEM)%10); shift(instruction, 0x80 | 60); h=(long)ADC10MEM*supplyvoltage/1023; cha(h/1000); shift(write, 0x50); //decimal point cha(h/100%10); cha(h/10%10); cha(h/1%10); //Clear lines shift(instruction, 0x40 | 1);shift(instruction, 0x80 | j);shift(write, 0x00); shift(instruction, 0x40 | 2);shift(instruction, 0x80 | j);shift(write, 0x00); shift(instruction, 0x40 | 3);shift(instruction, 0x80 | j);shift(write, 0x00); shift(instruction, 0x40 | 4);shift(instruction, 0x80 | j);shift(write, 0x00); shift(instruction, 0x40 | 5);shift(instruction, 0x80 | j);shift(write, 0x00); //Drawable values for graph if (e<=40) {     if (!e) e=1;     e = 40-e;     b = 1<<(e%8);     l = (e/8)+1; } //Set cursor at write point and write shift(instruction, 0x40 | l); shift(instruction, 0x80 | j); shift(write,; //"Scrolling" j++; if(j==85){j=0;} //Loop Delay __delay_cycles(loopdelay); }} //Clears the whole display void clear(){ int e; for(e=0;e<588;e++){shift(write,0x00);}} //Draws Font void cha(unsigned int ch){ int e; for(e = 0; e < 5; e++) { shift(write, font[ch][e]);} } void init(void){ P1OUT &= ~SCLK+DIN+DC+CE+RST; __delay_cycles(50000); P1OUT |= RST; P1OUT &= ~CE; //Sets up the display, your settings may vary: shift(instruction, 0x21); shift(instruction, 0xC5); shift(instruction, 0x12); shift(instruction, 0x20); shift(instruction, 0x09); shift(instruction, 0x0C); P1OUT |= CE; } //Serial Communication with LCD void shift(unsigned int mode, unsigned char byte){ if (mode==instruction){P1OUT &= ~DC;} else if(mode==write){P1OUT |= DC;} P1OUT &= ~CE; unsigned char i; for(i=0;i<=7;i++){ P1OUT &= ~SCLK; if(byte>127){P1OUT |= DIN;} else if(byte<128){P1OUT &= ~DIN;} P1OUT |= SCLK; byte = byte<<1; } P1OUT |= CE; }
  5. Like
    BlackAngel reacted to username in DAC GUI V2   
    Hey all,
     
    Round 2: This extends the peripherals of the MSP430 to a UART based ascii AT command set. For example, send "AT+GET_ADC" over the USB->Serial bridge to get all the ADC values returned. Since I released my first GUI there have been a couple others like it. You will find that this version's strength is that the underlying C driver set is my personal driver set which is quite powerful XD . I then wrote a C# GUI as a wrapper around this command set.
     
    Features Implemented: Digital IO, Analog I, PWM, SPI

     
    PWM Example:

     
    Steps to use:
    1. Download code & .exe file here: https://github.com/NateZimmer/ICBM
    2. Import C code into CCSV5.1 (haven't tested with other versions) and flash to launchpad.
    3. Ensure UART jumpers on the MSP430 Launchpad are set to Hardware based UART on a msp430g2553 launchpad Rev 1.5
    4. Run GUI and connect to launchpad.
    5. Enjoy!
     
    Skip to 10:35 for setup instructions:
     
     


     
    Todo:
    Implement DCO Calibration for better CLK accuracy
    Implement I2C
    Implement Graphing/Logging
    Implement more flexible spi chip select features
     
    Please let me know if this does not work for you
×
×
  • Create New...