Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <msp430.h>
- #include <stdint.h>
- #include <stdio.h>
- // Variables para la LCD:
- typedef unsigned char byte;
- #define Enable_LCD 0x04
- #define iluminacion_LCD 0x08
- #define comando_LCD 0x00
- #define dato_LCD 0x01
- #define LCD_PCF8574_ADDRESS 0x27 // Slave address poniendo A0,A1,A2 = 1
- // Variables para el ADC:
- volatile uint8_t buffer_lleno = 0;
- uint16_t valor_promedio_A0 = 0; // Variable that stores average value of A0
- uint16_t valor_promedio_A1 = 0; // Variable that stores average value of A1
- uint8_t *PTxData; // Pointer to TX
- uint8_t TXByteCtr; // Counter of bytes send
- uint16_t volatile contador_milisegundos;
- void Inicializacion_Relojes(void)
- {
- __bis_SR_register(SCG0); // Disable the FLL control loop
- UCSCTL0 = 0x0000;
- UCSCTL1 = DCORSEL_5;
- UCSCTL2 = FLLD_0 | 487;
- // (N + 1) * (FLLRef/n) = Fdcomsp430
- // (487 + 1) * (32768/1) = 16MHz
- UCSCTL3 = 0; // FLL SELREF = XT1CLK y divisor de FLL = 1 (FLLREFDIV = FLLREFCLK/1)
- UCSCTL4 |= SELA_0 | SELS_4 | SELM_4; // Tomamos ACLK = XT1CLK (Cuarzo externo de 2^15 bits); SMCLK = MCLK = DCOCLKDIV (DCO interno de 16 MHz)
- // UCSCTL5 |= DIVA_0 | DIVS_0;
- __bic_SR_register(SCG0); // Enable the FLL control loop
- }
- void USCIB1_init()
- {
- P4SEL |= BIT2 | BIT1; // P4.1 --> UCB1SDA
- // P4.2 --> UCB1SCL
- UCB1CTL1 |= UCSWRST;
- UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // UCMST: Master; UCMODE_3: Modulo USCI como I2C; UCSYNC: Modo Sincrono
- UCB1CTL1 |= (UCSSEL_2 | UCSWRST); // UCSSEL_2: SMCLK; UCSWRST: Usci sigue en estado Reset
- UCB1BR0 = 160; // fSCL = SMCLK(16MHz)/160 = 100kHz
- UCB1BR1 = 0;
- UCB1CTL1 &= ~UCSWRST;
- UCB1IE |= UCTXIE;
- }
- void delay_ms(uint16_t tiempo_milisegundos)
- {
- contador_milisegundos = 0;
- TA1CTL |= MC_1; UP MODE
- TA1CCTL0 |= CCIE;
- while(contador_milisegundos < tiempo_milisegundos);
- TA1CTL |= MC_0; // STOP MODE
- }
- void init_TimerA1_ms(void)
- { // Timer for counting every ms for delay_ms
- TA1CCR0 = 16000-1;
- TA1CTL |= TASSEL_2 | MC_0; // Reloj SMCLK, Frecuencia: 16 MHz. Modo Stop.
- }
- // Funcion para configurar el ADC:
- void ConfiguracionADC(void){
- P6SEL |= BIT0 | BIT1; // enable P6.0 y P6.1 as A/D channels
- ADC12CTL0 |= ADC12SHT0_5 | ADC12MSC | ADC12ON; // ADC12ON: enable el ADC; ADC12SHT0_5: 64 sample cycles del S & H
- ADC12CTL1 |= ADC12SSEL_3 | ADC12DIV_7 | ADC12CONSEQ_3 | ADC12SHP; // ADC12SSEL_3: SMCLK; ADC12DIV_7: Preescalador de 8; ADC12CONSEQ_3: Repeat-Sequence-of-Channels Mode
- ADC12MCTL0 |= ADC12SREF_0 | ADC12INCH_0; // ADC12SREF_0: VR+ = AVcc+ and VR- = AVss ; ADC12INCH_0: Canal A0
- ADC12MCTL1 |= ADC12SREF_0 | ADC12INCH_1 | ADC12EOS; // ADC12INCH_1: Canal A1; ADC12EOS: end of sequence
- ADC12CTL0 |= ADC12ENC; // ADC12ENC: enable conversion
- ADC12IE |= BIT1; // enable ADC12IFG.1
- }
- void I2C_send(byte addr, byte *buffer, byte numero_datos)
- {
- UCB1I2CSA = addr;
- PTxData = buffer;
- TXByteCtr = numero_datos;
- UCB1CTL1 |= (UCTR | UCTXSTT);
- __bis_SR_register(LPM0_bits + GIE);
- __no_operation();
- while(UCB1CTL1 & UCTXSTP);
- }
- void lcd_send_nibble_cmd(byte dato)
- {
- byte buffer[2];
- byte dato_I2C_H;
- dato_I2C_H = dato & 0xF0;
- buffer[0] = dato_I2C_H | iluminacion_LCD | Enable_LCD | comando_LCD;
- buffer[1] = dato_I2C_H | iluminacion_LCD | comando_LCD;
- I2C_send(LCD_PCF8574_ADDRESS, buffer, 2);
- }
- void lcd_send_byte_data(byte dato)
- {
- byte buffer[4];
- byte dato_I2C_H, dato_I2C_L;
- dato_I2C_H = dato & 0xF0;
- dato_I2C_L = (dato << 4) & 0xF0;
- buffer[0] = dato_I2C_H | iluminacion_LCD | Enable_LCD | dato_LCD;
- buffer[1] = dato_I2C_H | iluminacion_LCD | dato_LCD;
- buffer[2] = dato_I2C_L | iluminacion_LCD | Enable_LCD | dato_LCD;
- buffer[3] = dato_I2C_L | iluminacion_LCD | dato_LCD;
- I2C_send(LCD_PCF8574_ADDRESS, buffer, 4);
- }
- void lcd_send_byte_cmd(byte dato)
- {
- byte buffer[4];
- byte dato_I2C_H, dato_I2C_L;
- dato_I2C_H = dato & 0xF0;
- dato_I2C_L = (dato << 4) & 0xF0;
- buffer[0] = dato_I2C_H | iluminacion_LCD | Enable_LCD | comando_LCD;
- buffer[1] = dato_I2C_H | iluminacion_LCD | comando_LCD;
- buffer[2] = dato_I2C_L | iluminacion_LCD | Enable_LCD | comando_LCD;
- buffer[3] = dato_I2C_L | iluminacion_LCD | comando_LCD;
- I2C_send(LCD_PCF8574_ADDRESS, buffer, 4);
- }
- void init_LCD_PCF8574(void)
- {
- delay_ms(20);
- lcd_send_nibble_cmd(0x30);
- delay_ms(5);
- lcd_send_nibble_cmd(0x30);
- delay_ms(1);
- lcd_send_nibble_cmd(0x30);
- delay_ms(5);
- lcd_send_nibble_cmd(0x20); // data bus of 4 bits
- delay_ms(1);
- lcd_send_byte_cmd(0x28);
- delay_ms(1);
- lcd_send_byte_cmd(0x08); // Display off, Cursor off, Blink off
- delay_ms(1);
- lcd_send_byte_cmd(0x01); // Clear Screen, Cursor Home
- delay_ms(2);
- lcd_send_byte_cmd(0x06); // Entry mode set; I/D=1: Incremento;
- delay_ms(10);
- lcd_send_byte_cmd(0x0D); // Display ON, Cursor ON, Cursor Blink
- delay_ms(10);
- }
- void lcd_setCursor(byte fila, byte columna)
- {
- byte address;
- if (fila == 0){ // first row
- address = 0;
- }
- else address = 0x40; // Second row
- address |= columna; // Para tener 0x00 + Columna (Fila1)
- // Para tener 0x40 + Columna (Fila2)
- lcd_send_byte_data(0x80 | address); // Set DDRAM Address
- delay_ms(2);
- }
- void lcd_print(char *string, uint8_t fila, uint8_t columna)
- {
- uint8_t tamaño;
- lcd_setCursor(fila,columna);
- while(*string != '\0')
- {
- lcd_send_byte_data(*string++); // write the character on the LCD
- tamaño++;
- if(tamaño > (16-columna))
- {
- lcd_send_byte_cmd(0x18); // Display shift to left
- delay_ms(300); // delay to see how characters are shifted
- }
- }
- delay_ms(2);
- }
- void borrar_pantalla(void)
- {
- lcd_send_byte_cmd(0x01); // clear display
- delay_ms(2);
- lcd_send_byte_cmd(0x02); // Return Home
- delay_ms(2);
- }
- void main(void)
- {
- char datos_A0[4], datos_A1[4];
- WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
- Inicializacion_Relojes();
- USCIB1_init();
- init_TimerA1_ms();
- __enable_interrupt();
- init_LCD_PCF8574();
- borrar_pantalla(); // delete anything that could appear in the display, for clearing it
- lcd_print("Hello Worlddddddddddddddd!",0,0); // Message to show that LCD display seems to work fine
- delay_ms(1000);
- borrar_pantalla();
- ConfiguracionADC();
- delay_ms(300); // wait for stabilize voltage reference
- ADC12CTL0 |= ADC12SC; // ADC12SC: begins the conversion
- __bis_SR_register(LPM0_bits + GIE);
- while(1){
- if (buffer_lleno == 1){
- sprintf(datos_A0,"valor ADC_A0=%d",valor_promedio_A0);
- sprintf(datos_A1,"valor ADC_A1=%d",valor_promedio_A1);
- lcd_print(datos_A0,0,4); // In row 0 of the LCD i put the A1 average value
- lcd_print(datos_A1,1,4); // In row 1 of the LCD i put the A1 average value
- valor_promedio_A0 = 0; // Reset value of A0
- valor_promedio_A1 = 0; // Reset value of A1
- buffer_lleno = 0;
- ADC12CTL0 |= ADC12ENC; // enable ADC
- }
- }
- }
- #pragma vector=TIMER1_A0_VECTOR
- __interrupt void timer1_A0_ISR(void){
- contador_milisegundos++;
- TA1CCTL0 &= ~CCIFG;
- }
- #pragma vector = USCI_B1_VECTOR
- __interrupt void usci_b1_isr(void)
- {
- switch(__even_in_range(UCB1IV,12))
- {
- case 0: break; // Vector 0: No interrupts
- case 2: break; // Vector 2: ALIFG
- case 4: break; // Vector 4: NACKIFG
- case 6: break; // Vector 6: STTIFG
- case 8: break; // Vector 8: STPIFG
- case 10: break; // Vector 10: RXIFG
- case 12: // Vector 12: TXIFG
- if (TXByteCtr) // Check TX byte counter
- {
- UCB1TXBUF = *PTxData++; // Load TX buffer
- TXByteCtr--; // Decrement TX byte counter
- }
- else
- {
- UCB1CTL1 |= UCTXSTP; // I2C stop condition
- UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
- __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
- }
- default: break;
- }
- }
- #pragma vector=ADC12_VECTOR
- __interrupt void ADC12ISR (void)
- {
- static unsigned int index = 0;
- switch(__even_in_range(ADC12IV,34))
- {
- case 0: break; // Vector 0: No interrupt
- case 2: break; // Vector 2: ADC overflow
- case 4: break; // Vector 4: ADC timing overflow
- case 6: break;
- case 8: // Vector 8: ADC12IFG1
- valor_promedio_A0 += ADC12MEM0;
- valor_promedio_A1 += ADC12MEM1;
- index++;
- if (index == 8){
- buffer_lleno = 1;
- valor_promedio_A0 >>= 3; // To divide by 8 to take the average value cause i had measured 8 samples.
- valor_promedio_A1 >>= 3;
- index = 0;
- ADC12CTL0 &= ~ADC12ENC; // Deshabilitamos el ADC
- }
- break;
- case 10: break; // Vector 10: ADC12IFG2
- case 12: break; // Vector 12: ADC12IFG3
- case 14: break; // Vector 14: ADC12IFG4
- case 16: break; // Vector 16: ADC12IFG5
- case 18: break; // Vector 18: ADC12IFG6
- case 20: break; // Vector 20: ADC12IFG7
- case 22: break; // Vector 22: ADC12IFG8
- case 24: break; // Vector 24: ADC12IFG9
- case 26: break; // Vector 26: ADC12IFG10
- case 28: break; // Vector 28: ADC12IFG11
- case 30: break; // Vector 30: ADC12IFG12
- case 32: break; // Vector 32: ADC12IFG13
- case 34: break; // Vector 34: ADC12IFG14
- default: break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement