По просьбе одного из моих читателей, публикую информацию о том, как работать с этим чудным дисплейчиком. В интернете уже достаточно подробно описано то, как с ним работать программно, поэтому повторяться я не буду, опишу здесь только пример отображения информации на индикаторе от встроенного в msp430g2553 датчика температуры и АЦП (будем показывать напряжение питания)

Схема подключения очень проста:


Наш файл определений будет выглядеть вот так:


#ifndef HD44780_H_
#define HD44780_H_

#define LCM_DIR P1DIR
#define LCM_OUT P1OUT

// Определяем карту соответствия пинов индикатора контроллеру
// Для простоты зададим соответствие пинов номерам выводов порта 4,5,6,7

#define LCM_PIN_RS BIT0 // P1.0
#define LCM_PIN_EN BIT1 // P1.1
#define LCM_PIN_D7 BIT7 // P1.7
#define LCM_PIN_D6 BIT6 // P1.6
#define LCM_PIN_D5 BIT5 // P1.5
#define LCM_PIN_D4 BIT4 // P1.4

#define LCM_PIN_MASK ((LCM_PIN_RS | LCM_PIN_EN | LCM_PIN_D7 | LCM_PIN_D6 | LCM_PIN_D5 | LCM_PIN_D4))

#define FALSE 0
#define TRUE 1

void HD44780_SetPosition(char Row, char Col);
void HD44780_Clear_Screen();
void HD44780_Init(void);
void HD44780_PrintStr(char *Text);
void HD44780_outdec(long data, unsigned char ndigits);

#endif /* HD44780_H_ */

Индикатор по схеме работает в 4-битном режиме, и согласно даташиту, его прежде всего необходимо настроить на этот режим. Инициализируем индикатор:

void HD44780_Init(void)
{

// Устанавливаем порты МК на вывод
// и выдаём на них логический ноль

LCM_DIR |= LCM_PIN_MASK;
LCM_OUT &= ~(LCM_PIN_MASK);
// Ждём пока индикатор инициализирует сам себя
// Помним, что МК включается гораздо быстрее индикатора

__delay_cycles(100000);
// Инициализация индикатора
// 1. установка 4-битного режима обмена

LCM_OUT &= ~LCM_PIN_RS;
LCM_OUT &= ~LCM_PIN_EN;

LCM_OUT = 0x20;
HD44780_Pulse();

// Снова отправляем команду режима 4-бит
// (согласно спецификации)

HD44780_SendByte(0x28, FALSE);
// 2. Включаем дисплей, мигание курсора включено

HD44780_SendByte(0x0E, FALSE);
// 3. режим автоматического перемещения курсора

HD44780_SendByte(0x06, FALSE);
}

Получение данных от встроенного АЦП возьмём из стандартного примера для launchpad:

 

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

InitializeLcm();

ClearLcmScreen();
LcmSetCursorPosition(0,0);
PrintStr("Temp Voltage");

//Initialize DCO
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
{
while(1); // If calibration constants erased
// do not load, trap CPU!!
}
BCSCTL1 = CALBC1_1MHZ; // Set DCO
DCOCTL = CALDCO_1MHZ;

//Initialize ADC
measmode = MEASTEMP;
ADC10CTL1 = INCH_10 + ADC10DIV_3 + SHS_1; // Temp Sensor ADC10CLK/4
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
TACCR0 = 30; // Delay to allow Ref to settle
TACCTL0 |= CCIE; // Compare-mode interrupt
TACTL = TASSEL_2 + MC_1; // TACLK = SMCLK, Up mode
__bis_SR_register(CPUOFF + GIE); // LPM0, TA0_ISR will force exit
TACCTL0 &= ~CCIE; // Disable timer Interrupt

BCSCTL3 |= LFXT1S_2; // ACLK = VLO
TACCR0 = 6000; //
TACCTL1 = OUTMOD_3; // TACCR1 set/reset
TACCR1 = 3000; // TACCR1 PWM Duty Cycle
//TACCTL0 |= CCIE; // Compare-mode interrupt
TACTL = TASSEL_1 + MC_1; // TACLK = ACLK, Up mode

ADC10CTL0 |= ENC;
while(1) {
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled

switch (measmode) {
case MEASTEMP :
temp = ADC10MEM;
IntDegC = ((temp - 687) * 4225) / 1024;
LcmSetCursorPosition(1,0);
HD44780_outdec(IntDegC,1);
PrintStr("C");
measmode = MEASVDD;
break;
case MEASVDD:
volt = ADC10MEM;
IntVoltmV = volt * 5000 / 1024;
LcmSetCursorPosition(1,7);
HD44780_outdec(IntVoltmV,3);
PrintStr("V");
measmode = MEASTEMP;
break;
}
__no_operation(); // SET BREAKPOINT HERE
}
}

 

Используем прерывания по таймеру для пробуждения процессора и переключения режимов измерения напряжения/температуры:


// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
ADC10CTL0 &= ~ENC; // ADC10 disable
switch (measmode) {
case MEASTEMP:
//temp = ADC10MEM;
ADC10CTL1 = INCH_11 + ADC10DIV_3 + SHS_1;
ADC10CTL0 |= REF2_5V;
break;
case MEASVDD:
//volt = ADC10MEM;
ADC10CTL1 = INCH_10 + ADC10DIV_3 + SHS_1;
ADC10CTL0 &= ~REF2_5V;
break;
}
ADC10CTL0 |= ENC;
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void TA0_ISR(void)
{
//TACTL = 0; // Clear Timer_A control registers
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
//ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
//ADC10CTL0 |= ENC;
}

Описывать подробно всю программу здесь не вижу смысла, так как она очень подробно описана в комментариях, я всего лишь слепил библиотеку для hd44780 и стандартный пример из комплекта launchpad. После прошивки программы в память МК должная получиться вот такая картинка:

С периодом около 1 секунды происходит процесс переключения режимов измерения и данные на индикаторе обновляются:

Скачать пример программы