Jump to content
43oh

New take on ADC -> LCD


Recommended Posts

This is pretty much same as this ADC -> LCD, but with functions written in asm, conversion is much faster now. LCD is connected with 3 wires, just like here.

 

adc_lcd.h

#ifndef ADC_LCD_H_
#define ADC_LCD_H_

#define DATAPIN BIT6
#define CLOCKPIN BIT5
#define ENABLEPIN BIT4

#define sendData(data) send(data, 1)
#define sendInstruction(data) send(data, 0)
#define initDisplay() sendInstruction(0x3C); sendInstruction(0x0C); clearDisplay(); sendInstruction(0x06)
#define clearDisplay() sendInstruction(0x01); _delay_cycles(2000)

#endif /*ADC_LCD_H_*/

 

adc_lcd.c

#include "msp430g2231.h"
#include "adc_lcd.h"

const char addressMap[4] = {
                              0x80, 0x88, 0xC0, 0xC8
                          };

void binaryToASCIIScale(unsigned int n, unsigned char * digits, unsigned int scale);
void sendChars(unsigned char chars[], unsigned char length);
void send(unsigned char data, unsigned char registerSelect);

unsigned char d[4][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};

void sendDataArray(unsigned char data[], char length);

char charIndex = 0;
char valueIndex = 0;

int values[4] = {0,0,0,0};

void main(void) {
   WDTCTL = WDTPW + WDTHOLD;

   BCSCTL1 = CALBC1_1MHZ;
   DCOCTL = CALDCO_1MHZ;

   P1OUT &= ~(CLOCKPIN + DATAPIN);
   P1OUT |= ENABLEPIN;
   P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN;

   initDisplay();

   ADC10CTL1 = INCH_3 + CONSEQ_1;
   ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
   ADC10DTC1 = 0x04;
   ADC10AE0 |= 0x0F;

   TACTL = TASSEL_2 + MC_1 + ID_3;

   while(1) {
       ADC10SA = (unsigned int)values;
       ADC10CTL0 |= ENC + ADC10SC;

       _bis_SR_register(LPM0_bits + GIE);
       CCTL0 &= ~CCIE;

       valueIndex = 0;
       while(valueIndex < 4) {
           unsigned int binary = values[valueIndex];
           sendInstruction(addressMap[valueIndex]);
           binaryToASCIIScale(binary, d[valueIndex], 3);
           sendChars(d[valueIndex], 5);
           valueIndex++;
       }
   }
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
   CCR0 = 25000;
   CCTL0 = CCIE;
}

// Timer A0 interrupt service routine
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void) {
   _bic_SR_register_on_exit(LPM0_bits);
}

 

send.asm

.cdecls C, LIST, "msp430g2231.h"
.cdecls C, LIST, "adc_lcd.h"
.global sendChars
.global send

sendChars:						
push R13					
push R12					
scl:							
tst	2(SP)					
jz en0						
mov		#1, R13				
mov		0(SP), R12			
mov.b	0(R12), R12			
call #send					
dec 2(SP)					
inc 0(SP)					
jmp scl						
en0:							
add	#4, SP					
ret							
send:							
mov	#8, R15					
sndLoop:						
bic.b #DATAPIN, &P1OUT		
rla.b R12					
jnc clk1					
bis.b #DATAPIN, &P1OUT		
clk1:							
bis.b #CLOCKPIN, &P1OUT		 
bic.b #CLOCKPIN, &P1OUT		
dec R15						
jnz sndLoop					
bic.b #DATAPIN, &P1OUT		
tst R13						
jz en1						
bis.b #DATAPIN, &P1OUT		
en1:							
bic.b #ENABLEPIN, &P1OUT	
bis.b #ENABLEPIN, &P1OUT	
ret							

 

convert.asm

.global binaryToASCIIScale

binaryToASCIIScale:
clr		R15
rla		R12
rla		R12
rla		R12
rla		R12
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
rla		R12
dadd	R15, R15
mov.b	R15, 3(R13)
swpb	R15
mov.b	R15, 1(R13)
rra		R15
rra		R15
rra		R15
rra		R15
mov.b	R15, 0(R13)
swpb	R15
	mov.b	R15, 2(R13)
and		#0x0F0F, 0(R13)
and		#0x0F0F, 2(R13)
add.b	#0x30, 3(R13)
tst.b	0(R13)
jnz l10
cmp	#3, R14
jge l10
mov.b	#0x20, 0(R13)
tst.b	1(R13)
jnz l20
cmp	#2, R14
jge l20
mov.b	#0x20, 1(R13)
tst.b	2(R13)
jnz l30
cmp	#1, R14
jge l30
mov.b	#0x20, 2(R13)
jmp l40
l10:
add.b	#0x30, 0(R13)
l20:
add.b	#0x30, 1(R13)
l30:
add.b	#0x30, 2(R13)
l40:
tst	R14
jz l80
dec R14
mov.b	3(R13), 4(R13)
tst	R14
jnz l50
mov.b	#0x2E, 3(R13)
jmp l90
l50:
dec R14
mov.b	2(R13), 3(R13)
tst	R14
jnz l60
mov.b	#0x2E, 2(R13)
jmp l90
l60:
dec R14
mov.b	1(R13), 2(R13)
tst	R14
jnz l70
mov.b	#0x2E, 1(R13)
jmp l90
l70:
dec R14
mov.b	0(R13), 1(R13)
mov.b	#0x2E, 0(R13)
jmp l90
l80:
mov.b	3(R13), 4(R13)
mov.b	2(R13), 3(R13)
mov.b	1(R13), 2(R13)
mov.b	0(R13), 1(R13)
mov.b	#0x20, 0(R13)
l90:
   ret

Link to post
Share on other sites

Hi Rob,

 

Studying your code is difficult (for me) when it doesn't include comments. Could I impose to ask you if my interpretation (below) is correct, please?

 

TIA... Regards, Mike

 

;
void sendChars:                  
       push    R13             ; push "length" param
       push    R12             ; push *string address
scl:                     
       tst     2(SP)           ; length == 0?
       jz      en0             ; yes, branch, else
       mov     #1, R13         ; RS = 1
       mov     0(SP), R12      ; copy *string to R12
       mov.b   0(R12), R12     ; copy string char to R12
       call    #send           ; send char
       dec     2(SP)           ; decrement "length"
       inc     0(SP)           ; increment *string address
       jmp     scl             ; loop
en0:
       add     #4, SP          ; fix stack pointer              
       ret                     ;

Link to post
Share on other sites

You see, you don't need comments, you are right on the money :)

I know, I know, sorry about that, it was late and I figured I will add them later.

 

I made some improvements to the © code, now you can set precision as well.

 

Different precision, same scale

 

Different scale, same precision

 

#include "msp430g2231.h"
#include "adc_lcd.h"

const char addressMap[4] = {
                              0x85, 0x8D, 0xC5, 0xCD
                          };

void binaryToASCIIScale(unsigned int n, unsigned char * digits, unsigned int scale);
void sendChars(unsigned char chars[], unsigned char length);
void send(unsigned char data, unsigned char registerSelect);

unsigned char d[4][6] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}};
unsigned const char precision[4] = {5,5,5,5};
unsigned const char scale[4] = {3,3,3,3};

void sendDataArray(unsigned char data[], char length);

char charIndex = 0;
char valueIndex = 0;

int values[4] = {0,0,0,0};

void main(void) {
   WDTCTL = WDTPW + WDTHOLD;

   BCSCTL1 = CALBC1_1MHZ;
   DCOCTL = CALDCO_1MHZ;

   P1OUT &= ~(CLOCKPIN + DATAPIN);
   P1OUT |= ENABLEPIN;
   P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN;

   initDisplay();

   ADC10CTL1 = INCH_3 + CONSEQ_1;
   ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
   ADC10DTC1 = 0x04;
   ADC10AE0 |= 0x0F;

   TACTL = TASSEL_2 + MC_1 + ID_3;

   while(1) {
       ADC10SA = (unsigned int)values;
       ADC10CTL0 |= ENC + ADC10SC;

       _bis_SR_register(LPM0_bits + GIE);
       CCTL0 &= ~CCIE;

       valueIndex = 0;
       while(valueIndex < 4) {
           unsigned int binary = values[valueIndex];
           sendInstruction(addressMap[valueIndex]-precision[valueIndex]);
           binaryToASCIIScale(binary, d[valueIndex], scale[valueIndex]);
           sendChars(d[valueIndex], precision[valueIndex]);
           valueIndex++;
       }
   }
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
   CCR0 = 25000;
   CCTL0 = CCIE;
}

// Timer A0 interrupt service routine
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void) {
   _bic_SR_register_on_exit(LPM0_bits);
}

Link to post
Share on other sites
  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...