Jump to content
43oh

maelli01

Members
  • Content Count

    48
  • Joined

  • Last visited

  • Days Won

    16

Reputation Activity

  1. Like
    maelli01 got a reaction from MichelKohler in 3phase variable speed motor drive   
    Hi there
    Here is my 3phase variable speed motor drive booster pack

    This has been in my mind for some years, but I always thought that a 3phase variable speed inverter drive is
    beyond my humble hobbyist scope. Too complicated for my old 8-bit mind ;-)

    Such a inverter contains:
    6 high voltage FETs or IGBTs, 6 gatedrives, at least one DSP, a protection concept,
    all the software to create the 3-phase PWM, dead time control.....

    Still that was for quite some time on my long-term "to do" list, with no chance to actually materialize it,
    not enough time, too many other things to do.

    When playing around with the PWM module of the TM4C123 I found out that creating a 3phase PWM
    signal with this module is actually pretty easy.
    Combined that with an integrated Power Module such as the FSB50550 (Fairchild).



    So here it is: a booster pack for the Tiva Launchpad which drives big-ass 3phase motors.

    The booster pack contains the following:
    - the FSB50550 power module (6 FETs 500V 1.4Ohm, Gatedrivers, Bootstrap diodes, Temp sensor)
    - snubber capacitor
    Power supply: everything is powered from one DC source, 20V or (much) more.
    - 15V switchmode power supply from the high voltage side, built around a LNK304, for the FSB50550
    - 3.3V switchmode power supply from the 15V to power the Launchpad, built around a LT1376
    Measurement:
    - Passive voltage dividier to measure the input voltage
    - Sense resistor and LM339 comparator for overcurrent detection
    Display:
    - Nokia 5110 display
    Potentiometer for motor speed and direction


    The software is based on Energia using Tiva Ware function calls for all the PWM stuff.
    It is still work in progress, very basic and at the moment consists of:

    - calculate the sinwave lookup table at startup
    - PWM initialisation (PWM set to 15625 Hz, deadtime 1us, sync on)
    - a timer interrupt run every 10uSecs, do update the 3 PWD duty cycles
    - ADC measurement of temperature, voltage, current (moving average)
    - fault interrupt

    The main program is very short, the display is updated twice a second and the modulation factor is calculated
    out of the potentiometer speed setting and the applied DC voltage.
    Sudden changes in motor frequency are limited in the software, to prevent the motor to feed back energy and cause
    overvoltage.

    The motor on the picture is a 1/2hp, 900rpm, 6-pole motor, 12 kg of Italian steel and copper, probably 50 years old.
    For playing around, I apply about 50% of rated volt/hz, so current and maximum torque is reduced.
    Currently I use my dual 35V 4A lab supply, series connected, as a power source.
     
    here is the code:
    //simple 3phase frequency converter //27.9.2014 by maelli #define dots 192 //dots per halfhave, must be divisible with 3 #define period 5120 //80Mhz/5120 = 15625 switching frequency #define dt 80 //deadtime 80Mhz / 80 = 1uS #define PART_TM4C123GH6PM #include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_sysctl.h" #include "inc/hw_types.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "driverlib/pwm.h" #include "LCD_5110.h" #include "inc/tm4c123gh6pm.h" LCD_5110 myScreen (33,37,36,35,34,38,17); char celsius[3]={0x7f,'C',0x00}; uint16_t a,dire=0,modu,tensec; uint32_t timecount,sintable[dots]; volatile int32_t irqcount,timeset; volatile uint32_t temperature, voltage, current, poti; void setup(){ myScreen.begin(); myScreen.setBacklight(0); myScreen.text(0, 0, "3ph Converter"); for(int i=0;i<dots;i++) sintable[i]=sinf((i*3.14159)/dots)*(period/2-dt); unsigned long ulPeriod; unsigned int Hz = 10000; // interupt frequency in Hz ulPeriod = (SysCtlClockGet() / Hz); initTimer(); charge_gdu(); ROM_TimerLoadSet(TIMER0_BASE, TIMER_A,ulPeriod -1); initPWM(); } void loop(){ if (irqcount>499) { //20x per sec irqcount-=500; int32_t fsoll=732*(poti-16384); int32_t diff=fsoll-timeset; if (diff>0){ if (diff>150000) timeset+=150000; else timeset=fsoll; } else { if (diff<-150000) timeset-=150000; else timeset=fsoll; } modu=abs(timeset)/voltage/16; if (modu<(32000/voltage)) modu=32000/voltage; if (modu>256) modu=256; tensec++; if (tensec==10) { //2x per sec we display something tensec=0; myScreen.text(0, 1, mkstrg((temperature-325)/24,2)); myScreen.text(2, 1, celsius); myScreen.text(5, 1, mkstrg((voltage)/23,3)); myScreen.text(8, 1, "Volt"); myScreen.text(0, 2, mkstrg(abs(timeset)/322122,2)); myScreen.text(2, 2, "."); myScreen.text(3, 2, mkstrg(abs((timeset/32212)%10),1)); myScreen.text(4, 2, "Hz"); myScreen.text(7, 2, mkstrg(current,4)); myScreen.text(11, 2, "mA"); if (timeset<0) myScreen.text(0, 3, "links "); else myScreen.text(0, 3, "rechts"); } } } String mkstrg(int d,uint8_t l){ char display[l+1]; int q=1; display[l]=0; for (uint8_t a=l;a;a--){ display[a-1]=0x30+(d%(q*10))/q; q*=10; } return display; } void initTimer(){ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // 32 bits Timer TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0Isr); // Registering isr ROM_TimerEnable(TIMER0_BASE, TIMER_A); ROM_IntEnable(INT_TIMER0A); ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); } void charge_gdu(){ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 ); ROM_GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_0,GPIO_STRENGTH_4MA,GPIO_PIN_TYPE_STD); GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_7); //alle 3 oberen ausschalten HWREG(GPIO_PORTA_BASE + (GPIO_PIN_7 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_1); HWREG(GPIO_PORTD_BASE + (GPIO_PIN_1 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3); HWREG(GPIO_PORTF_BASE + (GPIO_PIN_3 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); //auch die 2 letzten aus HWREG(GPIO_PORTD_BASE + (GPIO_PIN_0 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2); HWREG(GPIO_PORTF_BASE + (GPIO_PIN_2 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_6); //den ersten unteren ein HWREG(GPIO_PORTA_BASE + (GPIO_PIN_6 << 2)) = GPIO_PIN_6; delay(1); HWREG(GPIO_PORTD_BASE + (GPIO_PIN_0 << 2)) = GPIO_PIN_0; delay(1); HWREG(GPIO_PORTF_BASE + (GPIO_PIN_2 << 2)) = GPIO_PIN_2; delay(1); } void initPWM(){ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); //The Tiva Launchpad has two PWM modules (0 and 1). We are using 1 ROM_GPIOPinConfigure(GPIO_PD0_M1PWM0); ROM_GPIOPinConfigure(GPIO_PD1_M1PWM1); ROM_GPIOPinConfigure(GPIO_PA6_M1PWM2); ROM_GPIOPinConfigure(GPIO_PA7_M1PWM3); ROM_GPIOPinConfigure(GPIO_PF2_M1PWM6); ROM_GPIOPinConfigure(GPIO_PF3_M1PWM7); ROM_GPIOPinConfigure(GPIO_PF4_M1FAULT0); ROM_GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 ); ROM_GPIOPinTypePWM(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7 ); ROM_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4); PWM1_0_FLTSEN_R =3; //PWM fault inverted see page 1169 GPIO_PORTF_PUR_R=0x10; //weak pullup for Pin 4 ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC | PWM_GEN_MODE_FAULT_LEGACY); ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC | PWM_GEN_MODE_FAULT_LEGACY); ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC | PWM_GEN_MODE_FAULT_LEGACY); ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, period); ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, period); ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, period); ROM_PWMDeadBandEnable(PWM1_BASE, PWM_GEN_0, dt,dt); ROM_PWMDeadBandEnable(PWM1_BASE, PWM_GEN_1, dt,dt); ROM_PWMDeadBandEnable(PWM1_BASE, PWM_GEN_3, dt,dt); ROM_PWMSyncTimeBase(PWM1_BASE,PWM_GEN_0_BIT |PWM_GEN_1_BIT|PWM_GEN_3_BIT); ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_0); ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_1); ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_3); delay(1); PWMFaultIntRegister(PWM1_BASE, oh_shit); ROM_PWMIntEnable(PWM1_BASE,PWM_INT_FAULT0); ROM_PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM1_BASE | PWM_OUT_2_BIT | PWM_OUT_3_BIT |PWM_OUT_6_BIT | PWM_OUT_7_BIT, true); } void Timer0Isr(void) { //10000x per second ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt irqcount++; timecount+=timeset; // 1 Hz is 192x256*256*256/10000=322122.5 if (timecount> 0xEFFFFFFF) timecount+=0xC0000000; if (timecount> 0xBFFFFFFF) timecount-=0xC0000000;; a=timecount>>16; a=a/(16384/(dots/3*2)); //a immer kleiner 2*dots: C000 *dots/3*2/ 4000= 12 *dots/3*2/4= 2*dots if (a<dots)ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0,period/2+sintable[a]*modu/256); else ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0,period/2-sintable[a-dots]*modu/256); a=a+dots*2/3; if (a>=2*dots) a-=2*dots; if (a<dots)ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2,period/2+sintable[a]*modu/256); else ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2,period/2-sintable[a-dots]*modu/256); a=a+dots*2/3; if (a>=2*dots) a-=2*dots; if (a<dots)ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,period/2+sintable[a]*modu/256); else ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,period/2-sintable[a-dots]*modu/256); ROM_PWMSyncUpdate(PWM1_BASE,PWM_GEN_0_BIT |PWM_GEN_1_BIT|PWM_GEN_3_BIT); switch(irqcount%10){ case 0: temperature=(temperature*127+analogRead(26))/128; break; case 1: voltage=(voltage*31+analogRead(27)*3)/32; break; case 2: current=(current*127+analogRead(25)*8)/128; break; case 3: poti=(poti*127+analogRead(28)*8)/128; break; } } void oh_shit(void) { //in case of severe overcurrent we shut down! ROM_PWMFaultIntClearExt(PWM1_BASE,PWM_INT_FAULT0); ROM_PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM1_BASE | PWM_OUT_2_BIT | PWM_OUT_3_BIT |PWM_OUT_6_BIT | PWM_OUT_7_BIT, false); }  



  2. Like
    maelli01 got a reaction from spirilis in 3phase variable speed motor drive   
    Hi there
    Here is my 3phase variable speed motor drive booster pack

    This has been in my mind for some years, but I always thought that a 3phase variable speed inverter drive is
    beyond my humble hobbyist scope. Too complicated for my old 8-bit mind ;-)

    Such a inverter contains:
    6 high voltage FETs or IGBTs, 6 gatedrives, at least one DSP, a protection concept,
    all the software to create the 3-phase PWM, dead time control.....

    Still that was for quite some time on my long-term "to do" list, with no chance to actually materialize it,
    not enough time, too many other things to do.

    When playing around with the PWM module of the TM4C123 I found out that creating a 3phase PWM
    signal with this module is actually pretty easy.
    Combined that with an integrated Power Module such as the FSB50550 (Fairchild).



    So here it is: a booster pack for the Tiva Launchpad which drives big-ass 3phase motors.

    The booster pack contains the following:
    - the FSB50550 power module (6 FETs 500V 1.4Ohm, Gatedrivers, Bootstrap diodes, Temp sensor)
    - snubber capacitor
    Power supply: everything is powered from one DC source, 20V or (much) more.
    - 15V switchmode power supply from the high voltage side, built around a LNK304, for the FSB50550
    - 3.3V switchmode power supply from the 15V to power the Launchpad, built around a LT1376
    Measurement:
    - Passive voltage dividier to measure the input voltage
    - Sense resistor and LM339 comparator for overcurrent detection
    Display:
    - Nokia 5110 display
    Potentiometer for motor speed and direction


    The software is based on Energia using Tiva Ware function calls for all the PWM stuff.
    It is still work in progress, very basic and at the moment consists of:

    - calculate the sinwave lookup table at startup
    - PWM initialisation (PWM set to 15625 Hz, deadtime 1us, sync on)
    - a timer interrupt run every 10uSecs, do update the 3 PWD duty cycles
    - ADC measurement of temperature, voltage, current (moving average)
    - fault interrupt

    The main program is very short, the display is updated twice a second and the modulation factor is calculated
    out of the potentiometer speed setting and the applied DC voltage.
    Sudden changes in motor frequency are limited in the software, to prevent the motor to feed back energy and cause
    overvoltage.

    The motor on the picture is a 1/2hp, 900rpm, 6-pole motor, 12 kg of Italian steel and copper, probably 50 years old.
    For playing around, I apply about 50% of rated volt/hz, so current and maximum torque is reduced.
    Currently I use my dual 35V 4A lab supply, series connected, as a power source.
     
    here is the code:
    //simple 3phase frequency converter //27.9.2014 by maelli #define dots 192 //dots per halfhave, must be divisible with 3 #define period 5120 //80Mhz/5120 = 15625 switching frequency #define dt 80 //deadtime 80Mhz / 80 = 1uS #define PART_TM4C123GH6PM #include <stdint.h> #include <stdbool.h> #include "inc/hw_ints.h" #include "inc/hw_sysctl.h" #include "inc/hw_types.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/timer.h" #include "driverlib/pwm.h" #include "LCD_5110.h" #include "inc/tm4c123gh6pm.h" LCD_5110 myScreen (33,37,36,35,34,38,17); char celsius[3]={0x7f,'C',0x00}; uint16_t a,dire=0,modu,tensec; uint32_t timecount,sintable[dots]; volatile int32_t irqcount,timeset; volatile uint32_t temperature, voltage, current, poti; void setup(){ myScreen.begin(); myScreen.setBacklight(0); myScreen.text(0, 0, "3ph Converter"); for(int i=0;i<dots;i++) sintable[i]=sinf((i*3.14159)/dots)*(period/2-dt); unsigned long ulPeriod; unsigned int Hz = 10000; // interupt frequency in Hz ulPeriod = (SysCtlClockGet() / Hz); initTimer(); charge_gdu(); ROM_TimerLoadSet(TIMER0_BASE, TIMER_A,ulPeriod -1); initPWM(); } void loop(){ if (irqcount>499) { //20x per sec irqcount-=500; int32_t fsoll=732*(poti-16384); int32_t diff=fsoll-timeset; if (diff>0){ if (diff>150000) timeset+=150000; else timeset=fsoll; } else { if (diff<-150000) timeset-=150000; else timeset=fsoll; } modu=abs(timeset)/voltage/16; if (modu<(32000/voltage)) modu=32000/voltage; if (modu>256) modu=256; tensec++; if (tensec==10) { //2x per sec we display something tensec=0; myScreen.text(0, 1, mkstrg((temperature-325)/24,2)); myScreen.text(2, 1, celsius); myScreen.text(5, 1, mkstrg((voltage)/23,3)); myScreen.text(8, 1, "Volt"); myScreen.text(0, 2, mkstrg(abs(timeset)/322122,2)); myScreen.text(2, 2, "."); myScreen.text(3, 2, mkstrg(abs((timeset/32212)%10),1)); myScreen.text(4, 2, "Hz"); myScreen.text(7, 2, mkstrg(current,4)); myScreen.text(11, 2, "mA"); if (timeset<0) myScreen.text(0, 3, "links "); else myScreen.text(0, 3, "rechts"); } } } String mkstrg(int d,uint8_t l){ char display[l+1]; int q=1; display[l]=0; for (uint8_t a=l;a;a--){ display[a-1]=0x30+(d%(q*10))/q; q*=10; } return display; } void initTimer(){ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); // 32 bits Timer TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0Isr); // Registering isr ROM_TimerEnable(TIMER0_BASE, TIMER_A); ROM_IntEnable(INT_TIMER0A); ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); } void charge_gdu(){ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 ); ROM_GPIOPadConfigSet(GPIO_PORTF_BASE,GPIO_PIN_0,GPIO_STRENGTH_4MA,GPIO_PIN_TYPE_STD); GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_7); //alle 3 oberen ausschalten HWREG(GPIO_PORTA_BASE + (GPIO_PIN_7 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_1); HWREG(GPIO_PORTD_BASE + (GPIO_PIN_1 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3); HWREG(GPIO_PORTF_BASE + (GPIO_PIN_3 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0); //auch die 2 letzten aus HWREG(GPIO_PORTD_BASE + (GPIO_PIN_0 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2); HWREG(GPIO_PORTF_BASE + (GPIO_PIN_2 << 2)) = 0; GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_6); //den ersten unteren ein HWREG(GPIO_PORTA_BASE + (GPIO_PIN_6 << 2)) = GPIO_PIN_6; delay(1); HWREG(GPIO_PORTD_BASE + (GPIO_PIN_0 << 2)) = GPIO_PIN_0; delay(1); HWREG(GPIO_PORTF_BASE + (GPIO_PIN_2 << 2)) = GPIO_PIN_2; delay(1); } void initPWM(){ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); //The Tiva Launchpad has two PWM modules (0 and 1). We are using 1 ROM_GPIOPinConfigure(GPIO_PD0_M1PWM0); ROM_GPIOPinConfigure(GPIO_PD1_M1PWM1); ROM_GPIOPinConfigure(GPIO_PA6_M1PWM2); ROM_GPIOPinConfigure(GPIO_PA7_M1PWM3); ROM_GPIOPinConfigure(GPIO_PF2_M1PWM6); ROM_GPIOPinConfigure(GPIO_PF3_M1PWM7); ROM_GPIOPinConfigure(GPIO_PF4_M1FAULT0); ROM_GPIOPinTypePWM(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 ); ROM_GPIOPinTypePWM(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7 ); ROM_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4); PWM1_0_FLTSEN_R =3; //PWM fault inverted see page 1169 GPIO_PORTF_PUR_R=0x10; //weak pullup for Pin 4 ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_0, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC | PWM_GEN_MODE_FAULT_LEGACY); ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC | PWM_GEN_MODE_FAULT_LEGACY); ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_SYNC | PWM_GEN_MODE_FAULT_LEGACY); ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_0, period); ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, period); ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, period); ROM_PWMDeadBandEnable(PWM1_BASE, PWM_GEN_0, dt,dt); ROM_PWMDeadBandEnable(PWM1_BASE, PWM_GEN_1, dt,dt); ROM_PWMDeadBandEnable(PWM1_BASE, PWM_GEN_3, dt,dt); ROM_PWMSyncTimeBase(PWM1_BASE,PWM_GEN_0_BIT |PWM_GEN_1_BIT|PWM_GEN_3_BIT); ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_0); ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_1); ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_3); delay(1); PWMFaultIntRegister(PWM1_BASE, oh_shit); ROM_PWMIntEnable(PWM1_BASE,PWM_INT_FAULT0); ROM_PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM1_BASE | PWM_OUT_2_BIT | PWM_OUT_3_BIT |PWM_OUT_6_BIT | PWM_OUT_7_BIT, true); } void Timer0Isr(void) { //10000x per second ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt irqcount++; timecount+=timeset; // 1 Hz is 192x256*256*256/10000=322122.5 if (timecount> 0xEFFFFFFF) timecount+=0xC0000000; if (timecount> 0xBFFFFFFF) timecount-=0xC0000000;; a=timecount>>16; a=a/(16384/(dots/3*2)); //a immer kleiner 2*dots: C000 *dots/3*2/ 4000= 12 *dots/3*2/4= 2*dots if (a<dots)ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0,period/2+sintable[a]*modu/256); else ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_0,period/2-sintable[a-dots]*modu/256); a=a+dots*2/3; if (a>=2*dots) a-=2*dots; if (a<dots)ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2,period/2+sintable[a]*modu/256); else ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2,period/2-sintable[a-dots]*modu/256); a=a+dots*2/3; if (a>=2*dots) a-=2*dots; if (a<dots)ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,period/2+sintable[a]*modu/256); else ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,period/2-sintable[a-dots]*modu/256); ROM_PWMSyncUpdate(PWM1_BASE,PWM_GEN_0_BIT |PWM_GEN_1_BIT|PWM_GEN_3_BIT); switch(irqcount%10){ case 0: temperature=(temperature*127+analogRead(26))/128; break; case 1: voltage=(voltage*31+analogRead(27)*3)/32; break; case 2: current=(current*127+analogRead(25)*8)/128; break; case 3: poti=(poti*127+analogRead(28)*8)/128; break; } } void oh_shit(void) { //in case of severe overcurrent we shut down! ROM_PWMFaultIntClearExt(PWM1_BASE,PWM_INT_FAULT0); ROM_PWMOutputState(PWM1_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM1_BASE | PWM_OUT_2_BIT | PWM_OUT_3_BIT |PWM_OUT_6_BIT | PWM_OUT_7_BIT, false); }  



  3. Like
    maelli01 got a reaction from cde in input protection diodes, interesting video on eevblog   
    power an msp430 without power pins ;-)
     
    http://www.eevblog.com/2015/12/18/eevblog-831-power-a-micro-with-no-power-pin/
  4. Like
    maelli01 got a reaction from energia in watchdog   
    converted the watchdog example from Tivaware into Energia.
    it should explain itself...
    I tested this with the connected launchpad TM4C1294
     
    5 blinks, resets itself, 5 blinks, on and on....
    /* 6.11.2015 Watchdog example */ #define LED RED_LED #include <stdint.h> #include <stdbool.h> #include "driverlib/sysctl.h" #include "driverlib/watchdog.h" unsigned long oldmillis; unsigned int timeout; void setup() { pinMode(LED, OUTPUT); SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG0); WatchdogReloadSet(WATCHDOG0_BASE,120000000); WatchdogResetEnable(WATCHDOG0_BASE); } // the loop routine runs over and over again forever: void loop() { if (millis()>(oldmillis+500)){ oldmillis=millis(); digitalWrite(LED, HIGH); delay(100); digitalWrite(LED, LOW); timeout++; WatchdogReloadSet(WATCHDOG0_BASE,120000000); //feed the dog, food for a second ;-) // simulated software crash: dog will not be fed any longer, causing a reset if (timeout>5){ while(1); } } }
  5. Like
    maelli01 got a reaction from gsutton in Products using MSP430   
    Bike light follow-up: reverse engineering time!
     
    here is my almost complete circuit diagram.
     
    IC1 is a voltage regulator: 2.5V, exact type I could not find out. Only the MSP runs on the regulated voltage, all the rest runs from the raw battery voltage.
     
    Voltage divider R2 1M / R3 330K measure the battery voltage (some microamps get lost here)
     
    LED2 and 3 are indicator (red/green)
     
    LED1 is the power led
     
    PWM is 20kHz, coming from pin 11 of the MSP.
    Main switch is a Si4562, N and P channel 20V 5A mosfet. Inductor is 100uH.
    Instead of using only the upper fet, they alternately switch on the upper / lower FET, avoiding one diode voltage drop, increasing effiency.
    The circuitry around IC3 (a weird CMOS 4572) creates a small dead time (less than a microsecond) to avoid cross-conduction.
    Note the resistors in the signal path ;-) 
     
    They managed to regulate the LED current without a shunt resistor. Took me some time to find out how:
    The voltage across the inductor is low-pass filtered, R14 390k / C4 0.1u, then fed into the MSP. Of course the DC-part of the inductor voltage depends on the current flow.
    Pretty clever. The regulation is rather slow (ramp-up of current is so slow it is actually visible).
     
    The circuitry around Q8 and Q9 takes care of the battery charge turn on/off. Input is from a wall-wart adaptor which is 500mA constant current type.
    R10/R11 tell the MSP that external voltage is present.
     
     

  6. Like
    maelli01 got a reaction from tripwire in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  7. Like
    maelli01 got a reaction from spirilis in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  8. Like
    maelli01 got a reaction from L.R.A in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  9. Like
    maelli01 got a reaction from Frida in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  10. Like
    maelli01 got a reaction from Fmilburn in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  11. Like
    maelli01 got a reaction from cubeberg in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  12. Like
    maelli01 got a reaction from yosh in Christmas tree blinky thing   
    Last year my daughter (she was almost 7 back then) got interesting in soldering.
    So I let het solder stuff together, no function whatsoever. It did not last long, until she wanted to solder something that "does something". 
     
    So I took the challenge and designed this christmas tree.
     
    - FR2 board, copper artwork by me, other side by my daughter. (cheap FR2 is better for using felt tip pens.. almost like paper)
    - G2553, all 16pins to simple LEDs, various colours
    - simple discrete regulator (another led+ transistor) for more or less 3V
    - powered by USB
    - mostly through-hole (soldered by a 7 year old), some SMD (where I helped)
    - programmed in Energia
     
     
    merry christmas!



  13. Like
    maelli01 got a reaction from bluehash in Products using MSP430   
    Bike light follow-up: reverse engineering time!
     
    here is my almost complete circuit diagram.
     
    IC1 is a voltage regulator: 2.5V, exact type I could not find out. Only the MSP runs on the regulated voltage, all the rest runs from the raw battery voltage.
     
    Voltage divider R2 1M / R3 330K measure the battery voltage (some microamps get lost here)
     
    LED2 and 3 are indicator (red/green)
     
    LED1 is the power led
     
    PWM is 20kHz, coming from pin 11 of the MSP.
    Main switch is a Si4562, N and P channel 20V 5A mosfet. Inductor is 100uH.
    Instead of using only the upper fet, they alternately switch on the upper / lower FET, avoiding one diode voltage drop, increasing effiency.
    The circuitry around IC3 (a weird CMOS 4572) creates a small dead time (less than a microsecond) to avoid cross-conduction.
    Note the resistors in the signal path ;-) 
     
    They managed to regulate the LED current without a shunt resistor. Took me some time to find out how:
    The voltage across the inductor is low-pass filtered, R14 390k / C4 0.1u, then fed into the MSP. Of course the DC-part of the inductor voltage depends on the current flow.
    Pretty clever. The regulation is rather slow (ramp-up of current is so slow it is actually visible).
     
    The circuitry around Q8 and Q9 takes care of the battery charge turn on/off. Input is from a wall-wart adaptor which is 500mA constant current type.
    R10/R11 tell the MSP that external voltage is present.
     
     

  14. Like
    maelli01 got a reaction from tripwire in input protection diodes, interesting video on eevblog   
    power an msp430 without power pins ;-)
     
    http://www.eevblog.com/2015/12/18/eevblog-831-power-a-micro-with-no-power-pin/
  15. Like
    maelli01 got a reaction from pneumatics in Products using MSP430   
    My high tech, German street legal, bicycle light failed. Corrosion on the battery contacts, one day it worked, the other not.

    So I cracked the damn thing open. Solid build quality, waterproof,  but not built to be repairable.

    As far as I remember, I bought it back in 2006.

    So what is inside:  An MSP430F1122, doing all the business:

    -         Battery charge termination (four AA NIMH)
    -         Two LED intensity levels PWM
    -         2 color status led (blink duty cycle would indicate remaining charge)
    -         Pushbutton, long for on/off, short for low/high
     
    The electronics still works fine, but would need a lot of duct tape to make it a cycle light again :-(
     

     
     
     
  16. Like
    maelli01 got a reaction from bluehash in Products using MSP430   
    It is was a Busch & M
  17. Like
    maelli01 got a reaction from bluehash in Products using MSP430   
    My high tech, German street legal, bicycle light failed. Corrosion on the battery contacts, one day it worked, the other not.

    So I cracked the damn thing open. Solid build quality, waterproof,  but not built to be repairable.

    As far as I remember, I bought it back in 2006.

    So what is inside:  An MSP430F1122, doing all the business:

    -         Battery charge termination (four AA NIMH)
    -         Two LED intensity levels PWM
    -         2 color status led (blink duty cycle would indicate remaining charge)
    -         Pushbutton, long for on/off, short for low/high
     
    The electronics still works fine, but would need a lot of duct tape to make it a cycle light again :-(
     

     
     
     
  18. Like
    maelli01 got a reaction from CorB in watchdog   
    converted the watchdog example from Tivaware into Energia.
    it should explain itself...
    I tested this with the connected launchpad TM4C1294
     
    5 blinks, resets itself, 5 blinks, on and on....
    /* 6.11.2015 Watchdog example */ #define LED RED_LED #include <stdint.h> #include <stdbool.h> #include "driverlib/sysctl.h" #include "driverlib/watchdog.h" unsigned long oldmillis; unsigned int timeout; void setup() { pinMode(LED, OUTPUT); SysCtlPeripheralEnable(SYSCTL_PERIPH_WDOG0); WatchdogReloadSet(WATCHDOG0_BASE,120000000); WatchdogResetEnable(WATCHDOG0_BASE); } // the loop routine runs over and over again forever: void loop() { if (millis()>(oldmillis+500)){ oldmillis=millis(); digitalWrite(LED, HIGH); delay(100); digitalWrite(LED, LOW); timeout++; WatchdogReloadSet(WATCHDOG0_BASE,120000000); //feed the dog, food for a second ;-) // simulated software crash: dog will not be fed any longer, causing a reset if (timeout>5){ while(1); } } }
  19. Like
    maelli01 reacted to dubnet in TM4C1294 ethernet library crashes   
    I experimented with mine using Exosite and had issues similar to what is discussed in the TI E2E thread referenced below.  With the patch referenced late in the thread it did improve but I ended up putting it aside, deciding to wait until the stability issues were more fully addressed over time.
     
    http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/p/358842/1296816#1296816
     
    For further reading you may want to visit http://e2e.ti.com/support/microcontrollers/tiva_arm/  and type:  connected Launchpad in the search field.  Although not specifically addressing use of this Launchpad under Energia, perhaps it could be helpful.
  20. Like
    maelli01 reacted to tripwire in Cannot get TI-RTOS to work, not exen the examples   
    Does the file pwmled_pem4f.h exist at the path listed above?
     
    If it does exist then maybe try setting up a new CCS workspace at a path with no spaces in the name. I've had trouble with that in TI's software before...
  21. Like
    maelli01 got a reaction from greeeg in Tiny Chip-on-glass LCD with ST7565 controller   
    Connected one of those
     
    http://www.newhavendisplay.com/lcd-chiponglass-128-x-32-c-3_113.html
     
    to the launchpad. These are really tiny chip-on-glass LCD displays. The visible area is 8 x 32mm.
     

     
    More tricky than the software is the hardware: in order to work, I had to connect nine 1uF ceramic caps
    to the display (I guess that with the chip-on-glass display it is not possible to integrate the caps into he display).
     
    Made a small,hand etched, one sided PCB, to accomodate the caps and to change from the weird 1.5mm connector
    pitch to a 2.54 one.
     

     
    6502 for size comparison only ;-)
     
    RobG's Nokia software helped me to get the hardware SPI right. Software-SPI, works as well, advantage is the free choice 
    of the pins, but more processor time is wasted for the display.
     
    I measured 85uA, with the example clock program (Display + MSP in LPM3), without backlight. So power-wise this 
    fits perfectly with the MSP. 
    Official working voltage is 2.7-3.3V. The 3.6V of the LP are the maximum rating for the display. 
     
    The backlight is already bright enough for me with 2mA. So switching the backlight on/offwith an extra pin would be easy.
    #include "msp430g2553.h" const unsigned char font5x8[][5] ={ { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ { 0x62, 0x64, 0x08, 0x13, 0x23 }, // % { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ { 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ { 0x04, 0x08, 0x10, 0x20, 0x40 }, // / { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f { 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i { 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o { 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p { 0x18, 0x24, 0x24, 0x18, 0xFC }, // q { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x { 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y { 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z { 0x08, 0x36, 0x41, 0x41, 0x00 }, // { { 0x00, 0x00, 0x7F, 0x00, 0x00 }, // | { 0x41, 0x41, 0x36, 0x08, 0x00 }, // } { 0x02, 0x04, 0x02, 0x01, 0x02 } // ~ }; unsigned char hour=12, min, sec,j; void clearline(unsigned char); void clearall(void); void print( char* s); void gotoXy(unsigned char , unsigned char); void printc(unsigned char r); void sendData(unsigned char data); void sendCmd(unsigned char cmd); //lcd connected to port 0 #define A0 BIT2 #define CS BIT3 #define SCK BIT5 #define SDA BIT7 #define RST BIT6 void main(void) { WDTCTL = WDT_ADLY_1000; // WDT 1sec, ACLK, interval timer IE1 |= WDTIE; // Enable WDT interrupt BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR = 0b11101100; P1REN = 0b00010011; P2REN = 0b00111111; P1SEL |=SCK + SDA; P1SEL2|=SCK + SDA; UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 0x01; // 1:1 UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // clear SW P1OUT &= ~RST; __delay_cycles(1000); P1OUT |= RST; P1OUT &=~A0; P1OUT &=~CS; //Initialize LCD display //see http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf for command set sendCmd(0xA1); //ADC select reverse mode sendCmd(0xA2); // 1/7 bias sendCmd(0x2F); //VC on, VR on, VF on sendCmd(0x21); //resistor ratio 3.5 sendCmd(0x81); //set contrast sendCmd(0x27); //adjust this number to get the best contrast sendCmd(0xAF); //now turn it on! clearall(); gotoXy(0,20); print("MSP430G2553 LCD"); gotoXy(1,35); print("2015-05-22"); while (1){ sec++; if (sec==60){ sec=0; clearline(2); min++; if (min==60){ min=0; hour++; if (hour==24) hour=0; } } gotoXy(3,40); printc((hour/10%10)+48); printc((hour%10)+48); printc(':'); printc((min/10%10)+48); printc((min%10)+48); printc(':'); printc((sec/10%10)+48); printc((sec%10)+48); gotoXy(2,sec); print("Hello World!"); __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt } } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ __bic_SR_register_on_exit(CPUOFF); // wake up } void clearall(void){ unsigned char i; for(i = 0; i<4 ; i++) clearline(i); } void clearline(unsigned char line){ unsigned char j; sendCmd(0xB0 | line); //sets page(row) sendCmd(0x10); //sets column address(MSB) to 0 for each page(row) sendCmd(0x04); //sets Column address(LSB) start, for this display 4 for(j=0;j<128;j++) {sendData(0x00);} } void sendData(unsigned char data){ P1OUT |=A0; UCB0TXBUF = data; while(!(IFG2 & UCB0TXIFG)); } void sendCmd(unsigned char cmd){ P1OUT &=~A0; UCB0TXBUF = cmd; while(!(IFG2 & UCB0TXIFG)); } void gotoXy(unsigned char x,unsigned char y){ y+=4; //this display does not show first four lines sendCmd(0xB0|(x & 0x03)); sendCmd(0x10|((y>>4))); sendCmd(0x00|(y & 0x0F)); } void print(char* s){ while(*s) printc(*s++); } void printc(unsigned char r){ unsigned char i; sendData(0); for (i=0;i<5;i++) sendData(font5x8[r-32][i] ); }
  22. Like
    maelli01 reacted to RobG in MSP432 toggle a bit using bit banding?   
    Don't use BIT0, you have to use bit #, so BIT0 is 0.
    BITBAND_PERI(P1OUT,0)=1; BITBAND_PERI(P1OUT,0)=0;
  23. Like
    maelli01 got a reaction from bluehash in Tiny Chip-on-glass LCD with ST7565 controller   
    Connected one of those
     
    http://www.newhavendisplay.com/lcd-chiponglass-128-x-32-c-3_113.html
     
    to the launchpad. These are really tiny chip-on-glass LCD displays. The visible area is 8 x 32mm.
     

     
    More tricky than the software is the hardware: in order to work, I had to connect nine 1uF ceramic caps
    to the display (I guess that with the chip-on-glass display it is not possible to integrate the caps into he display).
     
    Made a small,hand etched, one sided PCB, to accomodate the caps and to change from the weird 1.5mm connector
    pitch to a 2.54 one.
     

     
    6502 for size comparison only ;-)
     
    RobG's Nokia software helped me to get the hardware SPI right. Software-SPI, works as well, advantage is the free choice 
    of the pins, but more processor time is wasted for the display.
     
    I measured 85uA, with the example clock program (Display + MSP in LPM3), without backlight. So power-wise this 
    fits perfectly with the MSP. 
    Official working voltage is 2.7-3.3V. The 3.6V of the LP are the maximum rating for the display. 
     
    The backlight is already bright enough for me with 2mA. So switching the backlight on/offwith an extra pin would be easy.
    #include "msp430g2553.h" const unsigned char font5x8[][5] ={ { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ { 0x62, 0x64, 0x08, 0x13, 0x23 }, // % { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ { 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ { 0x04, 0x08, 0x10, 0x20, 0x40 }, // / { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f { 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i { 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o { 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p { 0x18, 0x24, 0x24, 0x18, 0xFC }, // q { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x { 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y { 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z { 0x08, 0x36, 0x41, 0x41, 0x00 }, // { { 0x00, 0x00, 0x7F, 0x00, 0x00 }, // | { 0x41, 0x41, 0x36, 0x08, 0x00 }, // } { 0x02, 0x04, 0x02, 0x01, 0x02 } // ~ }; unsigned char hour=12, min, sec,j; void clearline(unsigned char); void clearall(void); void print( char* s); void gotoXy(unsigned char , unsigned char); void printc(unsigned char r); void sendData(unsigned char data); void sendCmd(unsigned char cmd); //lcd connected to port 0 #define A0 BIT2 #define CS BIT3 #define SCK BIT5 #define SDA BIT7 #define RST BIT6 void main(void) { WDTCTL = WDT_ADLY_1000; // WDT 1sec, ACLK, interval timer IE1 |= WDTIE; // Enable WDT interrupt BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR = 0b11101100; P1REN = 0b00010011; P2REN = 0b00111111; P1SEL |=SCK + SDA; P1SEL2|=SCK + SDA; UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 0x01; // 1:1 UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // clear SW P1OUT &= ~RST; __delay_cycles(1000); P1OUT |= RST; P1OUT &=~A0; P1OUT &=~CS; //Initialize LCD display //see http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf for command set sendCmd(0xA1); //ADC select reverse mode sendCmd(0xA2); // 1/7 bias sendCmd(0x2F); //VC on, VR on, VF on sendCmd(0x21); //resistor ratio 3.5 sendCmd(0x81); //set contrast sendCmd(0x27); //adjust this number to get the best contrast sendCmd(0xAF); //now turn it on! clearall(); gotoXy(0,20); print("MSP430G2553 LCD"); gotoXy(1,35); print("2015-05-22"); while (1){ sec++; if (sec==60){ sec=0; clearline(2); min++; if (min==60){ min=0; hour++; if (hour==24) hour=0; } } gotoXy(3,40); printc((hour/10%10)+48); printc((hour%10)+48); printc(':'); printc((min/10%10)+48); printc((min%10)+48); printc(':'); printc((sec/10%10)+48); printc((sec%10)+48); gotoXy(2,sec); print("Hello World!"); __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt } } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ __bic_SR_register_on_exit(CPUOFF); // wake up } void clearall(void){ unsigned char i; for(i = 0; i<4 ; i++) clearline(i); } void clearline(unsigned char line){ unsigned char j; sendCmd(0xB0 | line); //sets page(row) sendCmd(0x10); //sets column address(MSB) to 0 for each page(row) sendCmd(0x04); //sets Column address(LSB) start, for this display 4 for(j=0;j<128;j++) {sendData(0x00);} } void sendData(unsigned char data){ P1OUT |=A0; UCB0TXBUF = data; while(!(IFG2 & UCB0TXIFG)); } void sendCmd(unsigned char cmd){ P1OUT &=~A0; UCB0TXBUF = cmd; while(!(IFG2 & UCB0TXIFG)); } void gotoXy(unsigned char x,unsigned char y){ y+=4; //this display does not show first four lines sendCmd(0xB0|(x & 0x03)); sendCmd(0x10|((y>>4))); sendCmd(0x00|(y & 0x0F)); } void print(char* s){ while(*s) printc(*s++); } void printc(unsigned char r){ unsigned char i; sendData(0); for (i=0;i<5;i++) sendData(font5x8[r-32][i] ); }
  24. Like
    maelli01 got a reaction from tripwire in Tiny Chip-on-glass LCD with ST7565 controller   
    Connected one of those
     
    http://www.newhavendisplay.com/lcd-chiponglass-128-x-32-c-3_113.html
     
    to the launchpad. These are really tiny chip-on-glass LCD displays. The visible area is 8 x 32mm.
     

     
    More tricky than the software is the hardware: in order to work, I had to connect nine 1uF ceramic caps
    to the display (I guess that with the chip-on-glass display it is not possible to integrate the caps into he display).
     
    Made a small,hand etched, one sided PCB, to accomodate the caps and to change from the weird 1.5mm connector
    pitch to a 2.54 one.
     

     
    6502 for size comparison only ;-)
     
    RobG's Nokia software helped me to get the hardware SPI right. Software-SPI, works as well, advantage is the free choice 
    of the pins, but more processor time is wasted for the display.
     
    I measured 85uA, with the example clock program (Display + MSP in LPM3), without backlight. So power-wise this 
    fits perfectly with the MSP. 
    Official working voltage is 2.7-3.3V. The 3.6V of the LP are the maximum rating for the display. 
     
    The backlight is already bright enough for me with 2mA. So switching the backlight on/offwith an extra pin would be easy.
    #include "msp430g2553.h" const unsigned char font5x8[][5] ={ { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ { 0x62, 0x64, 0x08, 0x13, 0x23 }, // % { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ { 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ { 0x04, 0x08, 0x10, 0x20, 0x40 }, // / { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f { 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i { 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o { 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p { 0x18, 0x24, 0x24, 0x18, 0xFC }, // q { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x { 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y { 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z { 0x08, 0x36, 0x41, 0x41, 0x00 }, // { { 0x00, 0x00, 0x7F, 0x00, 0x00 }, // | { 0x41, 0x41, 0x36, 0x08, 0x00 }, // } { 0x02, 0x04, 0x02, 0x01, 0x02 } // ~ }; unsigned char hour=12, min, sec,j; void clearline(unsigned char); void clearall(void); void print( char* s); void gotoXy(unsigned char , unsigned char); void printc(unsigned char r); void sendData(unsigned char data); void sendCmd(unsigned char cmd); //lcd connected to port 0 #define A0 BIT2 #define CS BIT3 #define SCK BIT5 #define SDA BIT7 #define RST BIT6 void main(void) { WDTCTL = WDT_ADLY_1000; // WDT 1sec, ACLK, interval timer IE1 |= WDTIE; // Enable WDT interrupt BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR = 0b11101100; P1REN = 0b00010011; P2REN = 0b00111111; P1SEL |=SCK + SDA; P1SEL2|=SCK + SDA; UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 0x01; // 1:1 UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // clear SW P1OUT &= ~RST; __delay_cycles(1000); P1OUT |= RST; P1OUT &=~A0; P1OUT &=~CS; //Initialize LCD display //see http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf for command set sendCmd(0xA1); //ADC select reverse mode sendCmd(0xA2); // 1/7 bias sendCmd(0x2F); //VC on, VR on, VF on sendCmd(0x21); //resistor ratio 3.5 sendCmd(0x81); //set contrast sendCmd(0x27); //adjust this number to get the best contrast sendCmd(0xAF); //now turn it on! clearall(); gotoXy(0,20); print("MSP430G2553 LCD"); gotoXy(1,35); print("2015-05-22"); while (1){ sec++; if (sec==60){ sec=0; clearline(2); min++; if (min==60){ min=0; hour++; if (hour==24) hour=0; } } gotoXy(3,40); printc((hour/10%10)+48); printc((hour%10)+48); printc(':'); printc((min/10%10)+48); printc((min%10)+48); printc(':'); printc((sec/10%10)+48); printc((sec%10)+48); gotoXy(2,sec); print("Hello World!"); __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt } } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ __bic_SR_register_on_exit(CPUOFF); // wake up } void clearall(void){ unsigned char i; for(i = 0; i<4 ; i++) clearline(i); } void clearline(unsigned char line){ unsigned char j; sendCmd(0xB0 | line); //sets page(row) sendCmd(0x10); //sets column address(MSB) to 0 for each page(row) sendCmd(0x04); //sets Column address(LSB) start, for this display 4 for(j=0;j<128;j++) {sendData(0x00);} } void sendData(unsigned char data){ P1OUT |=A0; UCB0TXBUF = data; while(!(IFG2 & UCB0TXIFG)); } void sendCmd(unsigned char cmd){ P1OUT &=~A0; UCB0TXBUF = cmd; while(!(IFG2 & UCB0TXIFG)); } void gotoXy(unsigned char x,unsigned char y){ y+=4; //this display does not show first four lines sendCmd(0xB0|(x & 0x03)); sendCmd(0x10|((y>>4))); sendCmd(0x00|(y & 0x0F)); } void print(char* s){ while(*s) printc(*s++); } void printc(unsigned char r){ unsigned char i; sendData(0); for (i=0;i<5;i++) sendData(font5x8[r-32][i] ); }
  25. Like
    maelli01 got a reaction from cubeberg in Tiny Chip-on-glass LCD with ST7565 controller   
    Connected one of those
     
    http://www.newhavendisplay.com/lcd-chiponglass-128-x-32-c-3_113.html
     
    to the launchpad. These are really tiny chip-on-glass LCD displays. The visible area is 8 x 32mm.
     

     
    More tricky than the software is the hardware: in order to work, I had to connect nine 1uF ceramic caps
    to the display (I guess that with the chip-on-glass display it is not possible to integrate the caps into he display).
     
    Made a small,hand etched, one sided PCB, to accomodate the caps and to change from the weird 1.5mm connector
    pitch to a 2.54 one.
     

     
    6502 for size comparison only ;-)
     
    RobG's Nokia software helped me to get the hardware SPI right. Software-SPI, works as well, advantage is the free choice 
    of the pins, but more processor time is wasted for the display.
     
    I measured 85uA, with the example clock program (Display + MSP in LPM3), without backlight. So power-wise this 
    fits perfectly with the MSP. 
    Official working voltage is 2.7-3.3V. The 3.6V of the LP are the maximum rating for the display. 
     
    The backlight is already bright enough for me with 2mA. So switching the backlight on/offwith an extra pin would be easy.
    #include "msp430g2553.h" const unsigned char font5x8[][5] ={ { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ { 0x62, 0x64, 0x08, 0x13, 0x23 }, // % { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , { 0x08, 0x08, 0x08, 0x08, 0x08 }, // - { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ { 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ { 0x04, 0x08, 0x10, 0x20, 0x40 }, // / { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f { 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i { 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o { 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p { 0x18, 0x24, 0x24, 0x18, 0xFC }, // q { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x { 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y { 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z { 0x08, 0x36, 0x41, 0x41, 0x00 }, // { { 0x00, 0x00, 0x7F, 0x00, 0x00 }, // | { 0x41, 0x41, 0x36, 0x08, 0x00 }, // } { 0x02, 0x04, 0x02, 0x01, 0x02 } // ~ }; unsigned char hour=12, min, sec,j; void clearline(unsigned char); void clearall(void); void print( char* s); void gotoXy(unsigned char , unsigned char); void printc(unsigned char r); void sendData(unsigned char data); void sendCmd(unsigned char cmd); //lcd connected to port 0 #define A0 BIT2 #define CS BIT3 #define SCK BIT5 #define SDA BIT7 #define RST BIT6 void main(void) { WDTCTL = WDT_ADLY_1000; // WDT 1sec, ACLK, interval timer IE1 |= WDTIE; // Enable WDT interrupt BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR = 0b11101100; P1REN = 0b00010011; P2REN = 0b00111111; P1SEL |=SCK + SDA; P1SEL2|=SCK + SDA; UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 0x01; // 1:1 UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // clear SW P1OUT &= ~RST; __delay_cycles(1000); P1OUT |= RST; P1OUT &=~A0; P1OUT &=~CS; //Initialize LCD display //see http://www.newhavendisplay.com/specs/NHD-C12832A1Z-FSRGB-FBW-3V.pdf for command set sendCmd(0xA1); //ADC select reverse mode sendCmd(0xA2); // 1/7 bias sendCmd(0x2F); //VC on, VR on, VF on sendCmd(0x21); //resistor ratio 3.5 sendCmd(0x81); //set contrast sendCmd(0x27); //adjust this number to get the best contrast sendCmd(0xAF); //now turn it on! clearall(); gotoXy(0,20); print("MSP430G2553 LCD"); gotoXy(1,35); print("2015-05-22"); while (1){ sec++; if (sec==60){ sec=0; clearline(2); min++; if (min==60){ min=0; hour++; if (hour==24) hour=0; } } gotoXy(3,40); printc((hour/10%10)+48); printc((hour%10)+48); printc(':'); printc((min/10%10)+48); printc((min%10)+48); printc(':'); printc((sec/10%10)+48); printc((sec%10)+48); gotoXy(2,sec); print("Hello World!"); __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt } } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void){ __bic_SR_register_on_exit(CPUOFF); // wake up } void clearall(void){ unsigned char i; for(i = 0; i<4 ; i++) clearline(i); } void clearline(unsigned char line){ unsigned char j; sendCmd(0xB0 | line); //sets page(row) sendCmd(0x10); //sets column address(MSB) to 0 for each page(row) sendCmd(0x04); //sets Column address(LSB) start, for this display 4 for(j=0;j<128;j++) {sendData(0x00);} } void sendData(unsigned char data){ P1OUT |=A0; UCB0TXBUF = data; while(!(IFG2 & UCB0TXIFG)); } void sendCmd(unsigned char cmd){ P1OUT &=~A0; UCB0TXBUF = cmd; while(!(IFG2 & UCB0TXIFG)); } void gotoXy(unsigned char x,unsigned char y){ y+=4; //this display does not show first four lines sendCmd(0xB0|(x & 0x03)); sendCmd(0x10|((y>>4))); sendCmd(0x00|(y & 0x0F)); } void print(char* s){ while(*s) printc(*s++); } void printc(unsigned char r){ unsigned char i; sendData(0); for (i=0;i<5;i++) sendData(font5x8[r-32][i] ); }
×
×
  • Create New...