Jump to content

DanAndDusty

Members
  • Content Count

    134
  • Joined

  • Last visited

  • Days Won

    1

Reputation Activity

  1. Like
    DanAndDusty got a reaction from FrankT in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
  2. Like
    DanAndDusty got a reaction from gventurini in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
  3. Like
    DanAndDusty got a reaction from johnnyb in Strange problem: LED1 and LED2 react differently to same code   
    Hi Potatochan,
     
    looking at your code the problem you have is not to do with the for loop (which you are using as a software delay) but with the fact that your port isn't in a "known state"..  In pseudo code you have....
     
    Put the WatchDogTimer on hold.. (Tell the watch dog.. Go on hold. If you don't do this your 430 will reset regularly)
    Tell the 430 that in Port 1 bits 0 and 6 are used for output.
    Loop forever    
        Toggle bit 6 of port 1      If the LED on bit 6 is on turn it off, if its off turn it on    
        count to 5000                Counting is purely as a delay    
        Toggle bit 0 of port 1      As with the other toggle.. but for the other LED
    Continue the loop
     
    As you can see.. all the interactions with P1OUT are dependent on what was there before.  You noticed them in sync and not in sync not because of what I was looping to, but because of what they were on before.
     
    Im guessing you run the code (maybe stepping through) then edited the number, re-uploaded and run the code.  Depending on where you stopped the code the LEDs could have been on or off semi randomly.  The solution is to put the port into a known state.  After the line that sets P1DIR your problem would be solved if you put in P1OUT = 0; Which says take every bit low.
     
    As to the counting loop being optimised out as pabigot said.. think about when you played Hide and Seek as a child.. (Im hoping this game is universal ) The game starts with 1 child counting to a number maybe 100.  This was purely to give a delay before they started hunting.  Now some children counted slow and some counted fast, and some were clever and thought that the counting achieved nothing and could be optimised to "1, 2, skip a few, 99 100".
     
    The compiler when in release mode can optimise your code and decide "That counting achieves nothing so I can safely ignore it".. so your code behaves differently in release mode from debug mode.  The solution here is to use __delay_cycles(xx) where xx is the number of cycles to pause.  At 1MHz using __delay_cycles(1000000) will always wait 1 second, __delay_cycles(100000) will always delay 1/10th of a second.  I can't remember the default speed of the 430 I think its either 1MHz or 1.1MHz.. I always set the clock to one of the calibrated speeds at the sametime as I put the WDT in hold mode.  The lines to do this are....
     
    BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; // Set DCO step and modulation    
    The way I would have written your code would be....
     
    #include <msp430.h> #define LED_RED BIT0 // The Red LED is on P1.0 #define LED_GREEN BIT6 // Green LED is P1.6 void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; // Tell the 430 to run at a calibrated DCOCTL = CALDCO_1MHZ; // Clk speed of 1MHz P1DIR = LED_RED + LED_GREEN; // We want outputs on Red and Green LEDs only P1OUT = 0; // Start with both LEDs off while(1) { P1OUT ^= LED_GREEN; // Toggle state of the green LED __delay_cycles(500000); // Delay for 1/2 a second (clock is at a known 1MHz) P1OUT ^= LED_RED; // Toggle the red LED } }  
    I think this code would do what you want.  Things to notice are...
     
    1) The #defines at the top.  These tell the compiler "Whenver you see LED_RED in the code replace it with BIT0". BIT0 is itself a #define for 0x1, BIT6 is a #define for 0x40.  These take a little longer than using 0x41 instead of LED_RED + LED_GREEN, but this delay is done by the compiler on your PC before the code gets to your 430.  So the 430 gets the exact same code as with what you had written and so runs with exactly the same efficiency, but for someone reading your code it is obvious which LED is being toggled at which line.
     
    2) Setting the clock to calibrated speeds.  The 430 has a very flexible clocking system that run run the CPU at almost any speed upto 16MHz, the devices have certain speeds calibrated into them at the factory, i.e. the MSP430G2553 has 1MHz, 8MHz and 16MHz if I remember correctly.  We are saying run at a known speed of 1MHz.  If you wanted 16MHz use CALBC1_16MHZ and CALDCO_16MHZ.  If you did this though you would have to alter your __delay_cycles line to __delay_cycles(8000000) for a 1/2 second delay.
     
    3) Changing your for(;; ;-) to while(1).. This one is personal taste.  Each says "Loop forever".  Personally I think the while(1) is easier to understand but many many other people prefer the for(; ;-) method so you will see both in examples round the net.
     
    I meant this as a quick response and got carried away as usual..  I hope it helped.
     
    Dan
     
    P.S. One further thing to add.  Putting the CPU into a known good state is a good practice to get into.  For example when you start using interrupts each interrupt has an interrupt flag that says this interrupt has occured.  Good practice says to always clear this flag before enabling the interrupt.  It is a good habit to get into and saves much hair pulling, keyboard bashing later on (I know.. I learned this one the hard way)
  4. Like
    DanAndDusty got a reaction from opcode in Increase stack on Stellaris in CCS   
    There is indeed. I'm on my phone at the moment so I can't check where. But its in the project properties, arm linker sections. I think by default its set to 256 bytes. I usually set it to 2048 bytes as a minimum.
  5. Like
    DanAndDusty got a reaction from bluehash in Increase stack on Stellaris in CCS   
    There is indeed. I'm on my phone at the moment so I can't check where. But its in the project properties, arm linker sections. I think by default its set to 256 bytes. I usually set it to 2048 bytes as a minimum.
  6. Like
    DanAndDusty got a reaction from GeekDoc in Strange problem: LED1 and LED2 react differently to same code   
    Hi Potatochan,
     
    looking at your code the problem you have is not to do with the for loop (which you are using as a software delay) but with the fact that your port isn't in a "known state"..  In pseudo code you have....
     
    Put the WatchDogTimer on hold.. (Tell the watch dog.. Go on hold. If you don't do this your 430 will reset regularly)
    Tell the 430 that in Port 1 bits 0 and 6 are used for output.
    Loop forever    
        Toggle bit 6 of port 1      If the LED on bit 6 is on turn it off, if its off turn it on    
        count to 5000                Counting is purely as a delay    
        Toggle bit 0 of port 1      As with the other toggle.. but for the other LED
    Continue the loop
     
    As you can see.. all the interactions with P1OUT are dependent on what was there before.  You noticed them in sync and not in sync not because of what I was looping to, but because of what they were on before.
     
    Im guessing you run the code (maybe stepping through) then edited the number, re-uploaded and run the code.  Depending on where you stopped the code the LEDs could have been on or off semi randomly.  The solution is to put the port into a known state.  After the line that sets P1DIR your problem would be solved if you put in P1OUT = 0; Which says take every bit low.
     
    As to the counting loop being optimised out as pabigot said.. think about when you played Hide and Seek as a child.. (Im hoping this game is universal ) The game starts with 1 child counting to a number maybe 100.  This was purely to give a delay before they started hunting.  Now some children counted slow and some counted fast, and some were clever and thought that the counting achieved nothing and could be optimised to "1, 2, skip a few, 99 100".
     
    The compiler when in release mode can optimise your code and decide "That counting achieves nothing so I can safely ignore it".. so your code behaves differently in release mode from debug mode.  The solution here is to use __delay_cycles(xx) where xx is the number of cycles to pause.  At 1MHz using __delay_cycles(1000000) will always wait 1 second, __delay_cycles(100000) will always delay 1/10th of a second.  I can't remember the default speed of the 430 I think its either 1MHz or 1.1MHz.. I always set the clock to one of the calibrated speeds at the sametime as I put the WDT in hold mode.  The lines to do this are....
     
    BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; // Set DCO step and modulation    
    The way I would have written your code would be....
     
    #include <msp430.h> #define LED_RED BIT0 // The Red LED is on P1.0 #define LED_GREEN BIT6 // Green LED is P1.6 void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; // Tell the 430 to run at a calibrated DCOCTL = CALDCO_1MHZ; // Clk speed of 1MHz P1DIR = LED_RED + LED_GREEN; // We want outputs on Red and Green LEDs only P1OUT = 0; // Start with both LEDs off while(1) { P1OUT ^= LED_GREEN; // Toggle state of the green LED __delay_cycles(500000); // Delay for 1/2 a second (clock is at a known 1MHz) P1OUT ^= LED_RED; // Toggle the red LED } }  
    I think this code would do what you want.  Things to notice are...
     
    1) The #defines at the top.  These tell the compiler "Whenver you see LED_RED in the code replace it with BIT0". BIT0 is itself a #define for 0x1, BIT6 is a #define for 0x40.  These take a little longer than using 0x41 instead of LED_RED + LED_GREEN, but this delay is done by the compiler on your PC before the code gets to your 430.  So the 430 gets the exact same code as with what you had written and so runs with exactly the same efficiency, but for someone reading your code it is obvious which LED is being toggled at which line.
     
    2) Setting the clock to calibrated speeds.  The 430 has a very flexible clocking system that run run the CPU at almost any speed upto 16MHz, the devices have certain speeds calibrated into them at the factory, i.e. the MSP430G2553 has 1MHz, 8MHz and 16MHz if I remember correctly.  We are saying run at a known speed of 1MHz.  If you wanted 16MHz use CALBC1_16MHZ and CALDCO_16MHZ.  If you did this though you would have to alter your __delay_cycles line to __delay_cycles(8000000) for a 1/2 second delay.
     
    3) Changing your for(;; ;-) to while(1).. This one is personal taste.  Each says "Loop forever".  Personally I think the while(1) is easier to understand but many many other people prefer the for(; ;-) method so you will see both in examples round the net.
     
    I meant this as a quick response and got carried away as usual..  I hope it helped.
     
    Dan
     
    P.S. One further thing to add.  Putting the CPU into a known good state is a good practice to get into.  For example when you start using interrupts each interrupt has an interrupt flag that says this interrupt has occured.  Good practice says to always clear this flag before enabling the interrupt.  It is a good habit to get into and saves much hair pulling, keyboard bashing later on (I know.. I learned this one the hard way)
  7. Like
    DanAndDusty got a reaction from Newtonn2 in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
  8. Like
    DanAndDusty got a reaction from vicvelcro in Strange problem: LED1 and LED2 react differently to same code   
    Hi Potatochan,
     
    looking at your code the problem you have is not to do with the for loop (which you are using as a software delay) but with the fact that your port isn't in a "known state"..  In pseudo code you have....
     
    Put the WatchDogTimer on hold.. (Tell the watch dog.. Go on hold. If you don't do this your 430 will reset regularly)
    Tell the 430 that in Port 1 bits 0 and 6 are used for output.
    Loop forever    
        Toggle bit 6 of port 1      If the LED on bit 6 is on turn it off, if its off turn it on    
        count to 5000                Counting is purely as a delay    
        Toggle bit 0 of port 1      As with the other toggle.. but for the other LED
    Continue the loop
     
    As you can see.. all the interactions with P1OUT are dependent on what was there before.  You noticed them in sync and not in sync not because of what I was looping to, but because of what they were on before.
     
    Im guessing you run the code (maybe stepping through) then edited the number, re-uploaded and run the code.  Depending on where you stopped the code the LEDs could have been on or off semi randomly.  The solution is to put the port into a known state.  After the line that sets P1DIR your problem would be solved if you put in P1OUT = 0; Which says take every bit low.
     
    As to the counting loop being optimised out as pabigot said.. think about when you played Hide and Seek as a child.. (Im hoping this game is universal ) The game starts with 1 child counting to a number maybe 100.  This was purely to give a delay before they started hunting.  Now some children counted slow and some counted fast, and some were clever and thought that the counting achieved nothing and could be optimised to "1, 2, skip a few, 99 100".
     
    The compiler when in release mode can optimise your code and decide "That counting achieves nothing so I can safely ignore it".. so your code behaves differently in release mode from debug mode.  The solution here is to use __delay_cycles(xx) where xx is the number of cycles to pause.  At 1MHz using __delay_cycles(1000000) will always wait 1 second, __delay_cycles(100000) will always delay 1/10th of a second.  I can't remember the default speed of the 430 I think its either 1MHz or 1.1MHz.. I always set the clock to one of the calibrated speeds at the sametime as I put the WDT in hold mode.  The lines to do this are....
     
    BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; // Set DCO step and modulation    
    The way I would have written your code would be....
     
    #include <msp430.h> #define LED_RED BIT0 // The Red LED is on P1.0 #define LED_GREEN BIT6 // Green LED is P1.6 void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; // Tell the 430 to run at a calibrated DCOCTL = CALDCO_1MHZ; // Clk speed of 1MHz P1DIR = LED_RED + LED_GREEN; // We want outputs on Red and Green LEDs only P1OUT = 0; // Start with both LEDs off while(1) { P1OUT ^= LED_GREEN; // Toggle state of the green LED __delay_cycles(500000); // Delay for 1/2 a second (clock is at a known 1MHz) P1OUT ^= LED_RED; // Toggle the red LED } }  
    I think this code would do what you want.  Things to notice are...
     
    1) The #defines at the top.  These tell the compiler "Whenver you see LED_RED in the code replace it with BIT0". BIT0 is itself a #define for 0x1, BIT6 is a #define for 0x40.  These take a little longer than using 0x41 instead of LED_RED + LED_GREEN, but this delay is done by the compiler on your PC before the code gets to your 430.  So the 430 gets the exact same code as with what you had written and so runs with exactly the same efficiency, but for someone reading your code it is obvious which LED is being toggled at which line.
     
    2) Setting the clock to calibrated speeds.  The 430 has a very flexible clocking system that run run the CPU at almost any speed upto 16MHz, the devices have certain speeds calibrated into them at the factory, i.e. the MSP430G2553 has 1MHz, 8MHz and 16MHz if I remember correctly.  We are saying run at a known speed of 1MHz.  If you wanted 16MHz use CALBC1_16MHZ and CALDCO_16MHZ.  If you did this though you would have to alter your __delay_cycles line to __delay_cycles(8000000) for a 1/2 second delay.
     
    3) Changing your for(;; ;-) to while(1).. This one is personal taste.  Each says "Loop forever".  Personally I think the while(1) is easier to understand but many many other people prefer the for(; ;-) method so you will see both in examples round the net.
     
    I meant this as a quick response and got carried away as usual..  I hope it helped.
     
    Dan
     
    P.S. One further thing to add.  Putting the CPU into a known good state is a good practice to get into.  For example when you start using interrupts each interrupt has an interrupt flag that says this interrupt has occured.  Good practice says to always clear this flag before enabling the interrupt.  It is a good habit to get into and saves much hair pulling, keyboard bashing later on (I know.. I learned this one the hard way)
  9. Like
    DanAndDusty got a reaction from rpgdonkey in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
  10. Like
    DanAndDusty got a reaction from mbeals in ADC10 Speed tests using hardware UART   
    Hi all,
     
    Here is a little snippet of code I wrote to test the speed of the ADC10 at a variety of settings, and also to discover just how easy using the hardware UART turned out to be. I used the 2553 as it has a hardware UART.
     
    It sets the MCLK to a variety of speeds (I used CCS to read the calibration constants in the flash and coded them into the program). Then counts the number of samples that can be taken in 1 second using all the possible values for the SHT bits.
     
    The details are then written out to the UART at 9600 so I can see how speed affects the number of samples per second. To verify that the SHT settings are sufficient I also display the max/min readings taken. I had a potentiometer connected VCC/GND to pin P1.4 (INCH4).. Testing with different resistors between the POT and INCH4 I found that it wasn't until about 10K ohms that the ADC couldn't read the max Voltage at the fastest SHT settings.
     
    These are the readings I got

    Using Speed 1MHz Using ADC10SHT_0 (x4) There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,030 samples per sec - readings range from [1,018] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] Using ADC10SHT_1 (x8) There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,018] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] There were 15,031 samples per sec - readings range from [1,020] to [1,023] Using ADC10SHT_2 (x16) There were 15,030 samples per sec - readings range from [1,018] to [1,023] There were 15,030 samples per sec - readings range from [1,019] to [1,023] There were 15,030 samples per sec - readings range from [1,018] to [1,023] There were 15,031 samples per sec - readings range from [1,018] to [1,023] There were 15,030 samples per sec - readings range from [1,018] to [1,023] Using ADC10SHT_3 (x64) There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] There were 15,030 samples per sec - readings range from [1,017] to [1,023] Using Speed 8MHz Using ADC10SHT_0 (x4) There were 120,640 samples per sec - readings range from [1,018] to [1,023] There were 120,408 samples per sec - readings range from [1,018] to [1,023] There were 120,308 samples per sec - readings range from [1,018] to [1,023] There were 120,420 samples per sec - readings range from [1,018] to [1,023] There were 119,489 samples per sec - readings range from [1,018] to [1,023] Using ADC10SHT_1 (x8) There were 122,614 samples per sec - readings range from [1,017] to [1,023] There were 122,614 samples per sec - readings range from [1,017] to [1,023] There were 122,615 samples per sec - readings range from [1,017] to [1,023] There were 122,615 samples per sec - readings range from [1,017] to [1,023] There were 122,614 samples per sec - readings range from [1,017] to [1,023] Using ADC10SHT_2 (x16) There were 113,886 samples per sec - readings range from [1,016] to [1,023] There were 113,886 samples per sec - readings range from [1,017] to [1,023] There were 113,885 samples per sec - readings range from [1,016] to [1,023] There were 113,885 samples per sec - readings range from [1,016] to [1,023] There were 113,885 samples per sec - readings range from [1,016] to [1,023] Using ADC10SHT_3 (x64) There were 50,897 samples per sec - readings range from [1,015] to [1,023] There were 50,897 samples per sec - readings range from [1,013] to [1,023] There were 50,897 samples per sec - readings range from [1,013] to [1,023] There were 50,896 samples per sec - readings range from [1,016] to [1,023] There were 50,897 samples per sec - readings range from [1,012] to [1,023] Using Speed 12MHz Using ADC10SHT_0 (x4) There were 184,092 samples per sec - readings range from [1,013] to [1,023] There were 184,092 samples per sec - readings range from [1,013] to [1,023] There were 184,092 samples per sec - readings range from [1,012] to [1,023] There were 184,092 samples per sec - readings range from [1,013] to [1,023] There were 184,092 samples per sec - readings range from [1,013] to [1,023] Using ADC10SHT_1 (x8) There were 159,657 samples per sec - readings range from [1,013] to [1,023] There were 159,658 samples per sec - readings range from [1,013] to [1,023] There were 159,658 samples per sec - readings range from [1,013] to [1,023] There were 159,657 samples per sec - readings range from [1,013] to [1,023] There were 159,657 samples per sec - readings range from [1,013] to [1,023] Using ADC10SHT_2 (x16) There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] There were 123,543 samples per sec - readings range from [1,014] to [1,023] Using ADC10SHT_3 (x64) There were 52,702 samples per sec - readings range from [1,014] to [1,023] There were 52,722 samples per sec - readings range from [1,013] to [1,023] There were 52,708 samples per sec - readings range from [1,012] to [1,023] There were 52,702 samples per sec - readings range from [1,011] to [1,023] There were 52,709 samples per sec - readings range from [1,013] to [1,023] Using Speed 16MHz Using ADC10SHT_0 (x4) There were 203,974 samples per sec - readings range from [1,016] to [1,023] There were 203,979 samples per sec - readings range from [1,016] to [1,023] There were 204,158 samples per sec - readings range from [1,016] to [1,023] There were 204,059 samples per sec - readings range from [1,016] to [1,023] There were 204,135 samples per sec - readings range from [1,016] to [1,023] Using ADC10SHT_1 (x8) There were 171,828 samples per sec - readings range from [1,007] to [1,023] There were 171,828 samples per sec - readings range from [1,006] to [1,023] There were 171,828 samples per sec - readings range from [1,007] to [1,023] There were 171,828 samples per sec - readings range from [1,006] to [1,023] There were 171,828 samples per sec - readings range from [1,006] to [1,023] Using ADC10SHT_2 (x16) There were 131,106 samples per sec - readings range from [1,013] to [1,023] There were 131,185 samples per sec - readings range from [1,013] to [1,023] There were 131,061 samples per sec - readings range from [1,013] to [1,023] There were 131,128 samples per sec - readings range from [1,013] to [1,023] There were 131,135 samples per sec - readings range from [1,012] to [1,023] Using ADC10SHT_3 (x64) There were 54,328 samples per sec - readings range from [1,014] to [1,023] There were 54,336 samples per sec - readings range from [1,009] to [1,023] There were 54,326 samples per sec - readings range from [1,014] to [1,023] There were 54,324 samples per sec - readings range from [1,010] to [1,023] There were 54,332 samples per sec - readings range from [1,015] to [1,023]
     
    And here is the code

    /* ****************************************************************************************** * * * * * ADC-SpeedTest - This program samples the ADC at high speed using a variety of * * * settings for Sample & Hold Times and CPU clock speed * * * * * * While doing this it keeps track of the highest/lowest readings * * * (to ensure that the SHT values are sufficient to capture * * * the full range. * * * * * * Once readings are taken they are written out using the hardware * * * UART at 9600,8,1,none * * * * * ****************************************************************************************** */ #include volatile unsigned long samples = 0; // How many samples have we had? volatile int timer_ticks = 0; // How many timer ticks have we had? volatile long max_reading=0; // Whats the highest reading we have had? volatile long min_reading=1023; // Whats the lowest reading we have had? int cur_sht = 0; // What SHT are we using now? int sht_count = 0; // How many runs at this SHT have we had? int cur_speed = 0; // What speed are we running at? const unsigned SHT_vals[] = { ADC10SHT_0,ADC10SHT_1,ADC10SHT_2,ADC10SHT_3 // What values do we need for each of the SHTs? }; const char *SHT_strs[] = { // Descriptive Strings for the SHTs "ADC10SHT_0 (x4)", "ADC10SHT_1 (x8)", "ADC10SHT_2 (x16)", "ADC10SHT_3 (x64)" }; const char *SPEEDS_STR[] = { // Descriptive strings for the processor speeds "1MHz","8MHz","12MHz","16MHz" }; const char SPEEDS_UCABR0[] = { // Values to use for UCABR0 for each proc speed (9600 baudrate) 104, 0x41, 0xE2, 0x82 }; const char SPEEDS_UCABR1[] = { // Values to use for each UCABR1 0, 0x03, 0x04, 0x06 }; const int SPEEDS_CCR[] = { // CCR Values to use for each proc speed (to trigger at 1/1000th sec) 1000-1, 8000-1, 12000-1,16000-1 }; const char SPEEDS_BCS[] = { // BCS Values to use for each processor speed (Grabbed from the calib section of the flash) 0x86, 0x8D, 0x8E, 0x8F }; const char SPEEDS_DCO[] = { // DCO values to use for each processor speed (Grabbed from the calib section of the flash) 0xD6, 0x94, 0x9D, 0x95 }; void serial_puts(const char *); // Put a string (NULL Terminated) out via the UART void serial_putch(char); // put a single char out via the UART void serial_putl(long); // Write a long number as ascii out via the UART void show_sht(void); // Write the SHT settings out of the serial port void show_speed(void); // Write the CPU Speed settings out of the serial port void set_speed(void); // Set the processor speed and associated variables void main(void) { WDTCTL = WDTPW + WDTHOLD; // Hold the WDT BCSCTL1 = CALBC1_16MHZ; // Set the CPU to 16MHz DCOCTL = CALDCO_16MHZ; ADC10CTL0 &= ~ENC; // Disable ADC conversion (Can't configure if enabled) ADC10CTL0 = SREF_0 | ADC10SHT_0 | ADC10ON | ADC10IE; // GND to Vcc, 4 x ADC10CLK Ticks, ADC on, Enable Interrupt ADC10CTL1 = INCH_4 | SHS_0 | ADC10DIV_0 | ADC10SSEL_0 | CONSEQ_0; // ADC Chan 4, ADC10 SC, /1 CLK, ADC10 OSC, Sing Chan/Sing Conv P1SEL = BIT1 + BIT2; // Enable P1.1, P1.2 as Hardware UART P1SEL2 = BIT1 + BIT2; UCA0CTL1 |= UCSSEL_2; // UART clocked from SMCLK UCA0BR0 = 0x82; // 16,000,000/9600 = 0x682 UCA0BR1 = 0x06; UCA0MCTL = UCBRS0; // No modulation UCA0CTL1 &= ~UCSWRST; // reset usci CCTL0 = CCIE; // Enable interrupts on Timer TACTL = TASSEL_2 | ID_0 | MC_1; // SMCLK, /1, Up to CCR0 CCR0 = 16000 - 1; // One Thousandth of a second set_speed(); // Set clock speed, baudrate divisors etc show_speed(); // Send speed details to UART show_sht(); // Send SHT details to UART while(1) { min_reading = 1023; // Clear min/max readings max_reading = 0; samples = 0; // And counters timer_ticks = 0; TACTL |= TACLR; // Reset the timer CCTL0 |= CCIE; // Enable timer interrupts ADC10CTL0 |= ENC | ADC10SC; // Enable ADC and Start conversion _bis_SR_register(CPUOFF | GIE); // Pause CPU and enable interrupts ADC10CTL0 &= ~ENC; // Turn off the encoder CCTL0 &= ~ CCIE; // Disable interrupts while(ADC10CTL1 & ADC10BUSY); // While til pending ADC done ADC10CTL0 &= ~ADC10IFG; // Ensure pending ifgs are cleared serial_puts(" There were "); serial_putl(samples); serial_puts(" samples per sec - readings range from ["); serial_putl(min_reading); serial_puts("] to ["); serial_putl(max_reading); serial_puts("]\n\r"); if(++sht_count == 5) { // Take readings for 5 seconds per Speed/SHT combo sht_count = 0; cur_sht++; if(cur_sht == 4) { // There are 4 SHT settings per speed cur_sht = 0; cur_speed++; if(cur_speed == 4) { // And we have 4 speeds cur_speed = 0; } set_speed(); // Set speed details show_speed(); // Show the details } show_sht(); // Show the SHT settings ADC10CTL0 = SREF_0 | SHT_vals[cur_sht] | ADC10ON | ADC10IE; // Setup ADC10 } } } /* ********************************************************************************************** * * * set_speed(void) - Sets the DCO/BCS registers so MCLK is desired speed, * * UART baudrate divisors for 9600 * * CCR0 so ticks are 1/1000 seconds * * NOTE: Must pause to allow the clocks to settle down * * * * ********************************************************************************************** */ void set_speed(void) { BCSCTL1 = SPEEDS_BCS[cur_speed]; // Set MCLK to desired speed DCOCTL = SPEEDS_DCO[cur_speed]; UCA0BR0 = SPEEDS_UCABR0[cur_speed]; // set bitrate divisors depending on speed UCA0BR1 = SPEEDS_UCABR1[cur_speed]; CCR0 = SPEEDS_CCR[cur_speed]; // And CCR so each tick is 1/1000 seconds __delay_cycles(20000); // Wait for clocks etc to settle down } /* ********************************************************************************************** * * show_sht(void) - Writes out description of the SHT settings to the UART * * ********************************************************************************************** */ void show_sht(void) { serial_puts(" Using "); serial_puts(SHT_strs[cur_sht]); serial_puts("\n\r"); } /* ********************************************************************************************** * * show_speed(void)- Writes out description of the CPU speed settings to the UART * * ********************************************************************************************** */ void show_speed(void) { serial_puts("Using Speed "); serial_puts(SPEEDS_STR[cur_speed]); serial_puts("\n\r"); } /* ********************************************************************************************** * * serial_putl(long val) - Writes out a long number as ASCII through the UART * * * For ease of reading the numbers there are ',' chars * * * written out as thou separators * * * Leading 0s are skipped * * * * * * NOTE:- At the moment all numbers are assumed to be +ve (can't have a -ve number of * * * readings so not needed in this project * * * * * ********************************************************************************************** */ void serial_putl(long val) { long digit; char ch; char had_digit = 0; digit = 1000000; // Allow for upto 1M Samples per sec while(digit >0 ) { ch = val / digit; if(had_digit && (digit == 100000 || digit == 100)) { serial_putch(','); // If a digit has been written then put a thou sep } if(ch >0 || had_digit || digit == 1) { // Skip 0s if not had a char left and not on units serial_putch('0' + ch); had_digit = 1; } val -= digit * ch; digit /= 10; } } /* ********************************************************************************************** * * * * * serial_puts(const char *ptr) - Writes out a NULL terminated string through the UART* * * * * ********************************************************************************************** */ void serial_puts(const char *ptr) { while(*ptr) { // Go until we are at the NULL serial_putch(*(ptr++)); // put out the single char } } /* ********************************************************************************************** * * * * * serial_putch(char c) - Writes out a single ASCII char through the UART * * * * * ********************************************************************************************** */ void serial_putch(char c) { while ( !(IFG2 & UCA0TXIFG) ) // Wait if there is a transmission ongoing ; UCA0TXBUF = c; // Put the char into the UART TX buffer } /* ********************************************************************************************** * * * * * ADC_ISR(void) - ISR for when the ADC has completed a conversion * * * It keeps track of the min and max readings * * * And keeps track of the number of readings taken * * * * * ********************************************************************************************** */ #pragma vector=ADC10_VECTOR __interrupt void ADC_ISR(void) { ADC10CTL0 |= ADC10SC; // Start Conversion as soon as possible here if(ADC10MEM > max_reading) { max_reading = ADC10MEM; // Keep track of highest reading } if(ADC10MEM < min_reading) { min_reading = ADC10MEM; // And the minimum } samples++; // And bump the number of reaings } /* ********************************************************************************************** * * * * * TIMERA_ISR(void) - ISR for the timer CCR0 * * * simple routine.. keeps track of the number of ticks * * * All ticks should be 1/1000 sec * * * When 1000 ticks have happened the CPU is re-enabled so the * * * details can be sent out of the UART * * * * * ********************************************************************************************** */ #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMERA_ISR(void) { timer_ticks++; // Bump the count if(timer_ticks == 1000) { __bic_SR_register_on_exit(CPUOFF + GIE); // After 1000 ticks re-enable the processor } }
     
    I hope someone finds this snippet useful
     
    Dan
  11. Like
    DanAndDusty got a reaction from sirri in Launchpad Rev 1.4 RXD TXD jumpers ?   
    You can do it with 2 female to female jumper wires. I soldered wires across 2 lots of 2 female headers making a 2x2 block with wires soldered across. This is neat and unobtrusive.
     
    The only non solder job I can think of though is 2 crossed f2f jumper wires.
     
    Have a great Christmas.
     
    Dan
     
    Sent from my GT-I8160 using Tapatalk 2
     
     
  12. Like
    DanAndDusty got a reaction from abecedarian in i2c HD44780 LCD Booster Shield   
    Yup. That's the one I was thinking of. Thanks for doing the link hunting.
     
    Sent from my GT-I8160 using Tapatalk 2
     
     
  13. Like
    DanAndDusty reacted to abecedarian in i2c HD44780 LCD Booster Shield   
    I believe the thread is this: http://forum.43oh.com/topic/211-flashing-the-missing-dco-calibration-constants/
  14. Like
    DanAndDusty got a reaction from dlejob in Very Basic HD44780 driver for Stellaris LaunchPad   
    I don't have one of these LCDs but at the top he says Full port B used.. So I would read those as GPIO_PIN_1 is PB1 and so on..
  15. Like
    DanAndDusty got a reaction from SergK in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
  16. Like
    DanAndDusty reacted to JWoodrell in Advice on MOSFETs please.   
    as big as that FDT439N is, it may as well be though hole, is feet line up nearly perfectly on a standard prototype board, just solder its feet down, solder on a jumper wire for your breadboard and boom instant through hole (use big enough wire for the amperage though)

  17. Like
    DanAndDusty got a reaction from GeekDoc in CCS type-ahead   
    Not sure of a way of doing it automatically.. But if you press it pops up the chooser for the matching variables/functions.
  18. Like
    DanAndDusty reacted to RobG in Advice on MOSFETs please.   
    For the 3A, you can use FDT439N. See here.
  19. Like
    DanAndDusty reacted to oPossum in Advice on MOSFETs please.   
    Not as many parts in thru-hole as there are in SMD. IRL540 or IRLZ44 would work if you are running the MSP430 from at least a 3.3V supply. Use a 47 to 220 ohm gate resistor to ensure it doesn't oscillate.
  20. Like
    DanAndDusty got a reaction from bluehash in CCS type-ahead   
    Not sure of a way of doing it automatically.. But if you press it pops up the chooser for the matching variables/functions.
  21. Like
    DanAndDusty got a reaction from CorB in SOLVED: SPI on C2000 launchpad   
    Hey CorB, looks like we have been working on the same project. Ive also written some code (needs tidying still but will post when Im happy) to drive these LCDs. As Ive been using mine for the $4.30 booster pack using Hardware SPI wasn't an option for me so I was bit banging too. As there was ADC pins used I also used your code for setting GPIO pins.. lol..
     
    Given the extra ram on the C2000 I think it should be possible to code up a reasonable graphics library (add to buffer and then chuck out the whole buffer to the LCD).
     
    Anyways.. Thanks for the GPIO lib.. made things a lot easier to get my head around.
     
    Dan
  22. Like
    DanAndDusty got a reaction from msptest6 in SOLVED :Code issues: automated setting of GPADIR for GPIOpins >15 problematic   
    I don't have access to my dev terminal here at the moment.. But I seem to remember hitting something similar on a different processor a while ago. Does it work if you cast the 1? I.E.
     

    GpioCtrlRegs.GPADIR.all |= ((unsigned long)1<<pinNumber);
  23. Like
    DanAndDusty got a reaction from CorB in SOLVED :Code issues: automated setting of GPADIR for GPIOpins >15 problematic   
    I don't have access to my dev terminal here at the moment.. But I seem to remember hitting something similar on a different processor a while ago. Does it work if you cast the 1? I.E.
     

    GpioCtrlRegs.GPADIR.all |= ((unsigned long)1<<pinNumber);
  24. Like
    DanAndDusty reacted to spirilis in G2452 USI errata   
    Anyone encounter this? http://www.ti.com/lit/er/slaz072/slaz072.pdf
    USI5:
    USI Module
     
    Function:
    SPI master generates one additional clock after module reset
    Description Initializing the USI in SPI MASTER mode with the USICKPH bit set generates one
    additional clock pulse than defined by the value in the USICNTx bits on the SCLK pin
    during the first data transfer after module reset. For example, if the USICNTx bits hold
    the value eight, nine clock pulses are generated on the SCLK pin for the first transfer
    only.
     
    Workaround:
    Load USICNTx with a count of N
  25. Like
    DanAndDusty got a reaction from GeekDoc in Setting pins??!   
    You are correct on the P1DIR and P2DIR.. however your value to use in the register is incorrect.
     
    Basically the register is a bit mask for ALL the pins on the port.
     
    These following lines all do the same and set P2.4 to be output...
     

    P2DIR = 0x10; P2DIR = 16; P2DIR = BIT4;
     
    P2.4 is the 5th pin along (numbering starts at 0).. The mask in binary is therefore 00010000. In decimal this is 16 which is 10 in hexadecimal and BIT4 is defined in the device header file as one of these values. Personally I find the BIT4 varient easier to understand.
     
    The mask being built up this way makes more sense when you need more than one pin for output. For example if pins P2.0 and P2.4 were needed for output.. the mask in binary would be.... 00010001. In decimal this is 17 and in hex is 0x11. So setting P2.0 and P2.4 for output could be done with any one of these following lines..
     

    P2DIR = 0x11; P2DIR = 17; P2DIR = BIT0 + BIT4;
     
    From looking at this you can see that using the BIT0 and BIT4 variant is much easier to understand.
     
    Hope this helps...
     
    Dan
×
×
  • Create New...