ECE 4510/5530 Microcontroller Applications Week 5 Lab 4& Lab 5 Dr. Bradley J. Bazuin Associate Professor Department of Electrical and Computer Engineering College of Engineering and Applied Sciences

Lab 4 & 5 Element • Hardware Development – Three terminal linear regulator – Enhanced Capture Timer (ECT) (Chap. 8) • • •

Modulus Down-Counter (time delay, periodicity) Output Compare (periodic output signals, periodicity) Input Capture (external event timing)

– Serial Communication Interface (SCI) (Chap. 9) – Relay Driver – IRQn Interrupt (Chap. 6)

• Software Development – Polling vs. Interrupts – Time of Day (register limitations) – Text buffers ECE 2510

2

MAKING SOUND

ECE 4510/5530

3

Chapter 8 Example Making Sound • A sound can be generated by creating a digital waveform with appropriate frequency and using it to drive a speaker or a buzzer. • The simplest song is a two-tone siren.

HCS12DP256 3.3 F PT5

Buzzer

Figure 8.21 Circuit connection for a buzzer

ECE 4510/5530

4

Example 8.7: Algorithm for Generating a Siren •

Step 1 – Enable an output compare channel to drive the buzzer (or speaker).



Step 2 – Start an output compare operation with a delay count equal to half the period of the siren and enable the OC interrupt.



Step 3 – Wait for the duration of the siren tone (say half a second). During the waiting period, interrupts will be requested many times by the output compare function. The interrupt service routine simply restart the output compare operation.



Step 4 – At the end of the siren tone duration, choose a different delay count for the output compare operation so that the siren sound may have a different frequency.



Step 5 – Wait for the same duration as in Step 3. During this period, many interrupts will be requested by the output compare operation.



Step 6

– ECE 4510/5530

Go to Step 2.

5

Example 8.7 Siren Generation • Write a program to generate a two-tone siren that oscillates between 300 Hz and 1200 Hz. • Solution: – Set the prescaler to TCNT to 1:8. – The delay count for the low frequency tone is (24000000  8)  300  2 = 5000. – The delay count for the high frequency tone is (24000000  8)  1200  2 = 1250.

ECE 4510/5530

6

C Program for Siren Generation (1 of 2) #include #include #define #define int

delay;

"c:\egnu091\include\hcs12.h" "c:\egnu091\include\delay.c" HiFreq 1250 LoFreq 5000 /* delay count for OC5 operation */

int main(void) { asm("cli"); TSCR1 = 0x90; /* enable TCNT and fast timer flag clear */ TSCR2 = 0x03; /* set prescaler to TCNT to 1:8 */ TIOS |= BIT5; /* enable OC5 */ TCTL1 = 0x04; /* select toggle for OC5 pin action */ delay = HiFreq; /* use high frequency delay count first */ TC5 = TCNT + delay; /* start an OC5 operation */ TIE |= BIT5; /* enable TC5 interrupt */ asm("cli"); ECE 4510/5530

7

C Program for Siren Generation (2 of 2) while(1) { delayby100ms(5); delay = LoFreq; delayby100ms(5); delay = HiFreq; } return 0;

/* wait for half a second */ /* switch to low frequency tone */ /* wait for half a second */ /* switch to high frequency tone */

}

#pragma interrupt_handler oc5_ISR void oc5_ISR(void) { TC5 += delay; } #pragma abs_address:vtimch5 // Initialize the Interrupt Vector address void (*interrupt_vectors[]) (void) = {oc5_ISR}; // Assign the function pointer #pragma end_abs_address // to the ISR ECE 4510/5530

8

Preferred Initialization void init_TimerCh5(void) { TSCR1 = 0x90; TSCR2 = 0x03; TIOS |= BIT5; TCTL1 = 0x04; TIE |= BIT5; }

/* enable TCNT and fast timer flag clear */ /* set prescaler to TCNT to 1:8 */ /* enable OC5 */ /* select toggle for OC5 pin action */ /* enable TC5 interrupt */

Then we have …. int main(void) { asm(“sei"); init_TimerCh5(); delay = HiFreq; TC5 = TCNT + delay; asm("cli"); ECE 4510/5530

/* initialize channel 5*/ /* use high frequency delay count first */ /* start an OC5 operation */

9

A Better Way – Audio Amp

ECE 4510/5530

10

LM386 • Input gain control using potentiometer • Device Gain control 20-200 with feedback RC • Drives an 8 ohm speaker

$0.93 ea. at Digikey ECE 4510/5530

11

Speaker

$1.10 ea. at Digikey

ECE 4510/5530

12

You may want to filter

http://homepages.wmich.edu/~bazuinb/FiltersManual_RevD.pdf

ECE 4510/5530

13

Multiple stages are needed for a good filter Ask Dr. Bazuin for filter design notes if you need them …

ECE 4510/5530

Audio amplifier to drive the speaker

14

TEXT PROCESSING

ECE 4510/5530

15

The SCI0 Port to the PC • Built in functions to make it connect with the PC – All you need is code …

• Standard PC to modem cable – Not a null modem cable

• Textbook DVD – And on-line material provided by Dr. Bazuin

ECE 4510/5530

16

The HCS12 SCI Subsystem Registers Outlined in red

SCI data register Receive shift register

RxD

Interrupt generation

Idle IRQ RDRF/OR IRQ

Bus clock

BAUD generator

Receive and wake up control

16

O R I N G

Data format control

IRQ to CPU

Transmit control Transmit shift register

Interrupt generation

TDRE IRQ

Status Register 1

TC IRQ

Status Register 2

SCI data register TxD Figure 9.8 HCS12 SCI block diagram

ECE 4510/5530

17

SCI0 Initialization void init_sci0(void) { // BR=ECLK/(16 x BR) SCI0BD = 156; SCI0CR1 = SCISWAI | WAKE | ILT ; SCI0CR1 &= ~(M | PE | PT) ; SCI0CR2 = TE | RE;

// 24 MHz E-clock, 9600 bps desired (0.16% error) //SCISWAI, wakeup to mark, idle line after stop // 8-bit data, parity disabled, even parity // transmitter enable, receiver enable, // no interrupts enabled, not a break bit, not wake up

}

ECE 4510/5530

18

Baud Rate Generation (1 of 2) • The HCS12 SCI module uses a 13-bit counter to generate this clock signal. • The baud rate generator divides down the E clock to derive the clock signal for reception and transmission. • The user writes an appropriate value into the SCIxBDH and SCIxBDL (x = 0 or 1) register pair to set the baud rate.

reset:

7

6

5

4

3

2

1

0

0

0

0

SBR12

SBR11

SBR10

SBR9

SBR8

0

0

0

0

0

0

0

0

(a) SCI baud rate control register high (SC0BDH/SC1BDH)

reset:

7

6

5

4

3

2

1

0

SBR7

SBR6

SBR5

SBR4

SBR3

SBR2

SBR1

SBR0

0

0

0

0

0

1

0

0

(b) SCI baud rate control register low (SC0BDL/SC1BDL)

ECE 4510/5530

Figure 9.9 SCI baud rate control register

19

The SCI Control Registers (1 of 2) 7

6

LOOPS SCISWAI

reset:

ECE 4510/5530

0

0

5

4

3

2

1

0

RSRC

M

WAKE

ILT

PE

PT

0

0

0

0

0

0

LOOPS: Loop select bit 0 = loop operation disabled 1 = loop operation enabled SCISWAI: SCI stop in wait mode 0 = SCI enabled in wait mode. 1 = SCI disabled in wait mode. RSRC: Receiver source bit When LOOPS = 1, the RSRC bit determines the source for the receiver shift register 0 = receiver input connected to the transmitter internally (not TxD pin). 1 = receiver input connected extrenally to the transmitted (TxD pin) M: Data format mode bit 0 = one start bit, eight data bits, one stop bit 1 = one start bit, nine data bits, one stop bit WAKE: Wakeup condition bit 0 = idle line wakeup 1 = address mark wakeup (last data bit set) ILT: Idle line type bit 0 = idle character bit count begins after start bit 1 = idle character bit count begins after the stop bit PE: parity enable bit 0 = parity disabled 1 = parity enabled PT -- parity type bit (for both transmit and receive) 0 = even parity selected 1 = odd parity selected Figure 9.10 SCI controlregister 1 (SC0CR1/SC1CR1)

20

The SCI Control Registers (2 of 2) value after reset

ECE 4510/5530

7

6

5

4

3

2

1

0

TIE

TCIE

RIE

ILIE

TE

RE

RWU

SBK

0

0

0

0

0

0

0

0

TIE: Transmit interrupt enable bit 0 = TDRE interrupt disabled 1 = TDRE interrupt enabled. TCIE: Transmit complete interrupt enable bit 0 = TC interrupt disabled 1 = TC interrupt enabled RIE: Receiver full interrupt enable bit 0 = RDRF and OR interrupts disabled 1 = RDRF and OR interrupt enabled ILIE: Idle line interrupt enable bit 0 = IDLE interrupt disabled 1 = IDLE interrupt enabled TE: Transmitter enable bit 0 = transmitter disabled 1 = transmitter enabled RE: Receiver enable 0 = receiver disabled 1 = receiver enabled RWU: Receiver wakeup bit 0 = normal SCI receiver 1 = enables the wakeup function and inhibits further receiver interrupts. Normally, hardware wakes up the receiver by automatically clearing this bit. SBK: Send break bit 0 = no break characters 1 = generate a break code, at least 10 or 11 contiguous 0s. As long as SBK remains set, the transmitter sends 0s. Figure 9.11 SCI control register 2 (SC0CR2/SC1CR2)

21

Getchar and Putchar /******************************************************************/ /* The following function uses polling method to read a character */ /* from SCI0 port. */ /******************************************************************/ int getchar(void) { while(!(SCI0SR1 & RDRF)); // poll the status bit return SCI0DRL; // read and return the value }

/*****************************************************************/ /* The following function uses the polling method to output a */ /* character to the SCI0 port. */ /*****************************************************************/ int putchar(char cx) { while(!(SCI0SR1 & TDRE)) )); // poll the status bit continue; SCI0DRL = cx; // output the character return 0; } ECE 4510/5530

Get and Put are unique to every microcontroller. (registers and status bits) They are called by C standard I/O routines. See text files “stdio.c” 22 Or better yet stdio_hcs.c from Dr. Bazuin

Output to a new line /*******************************************************************/ /* The following function outputs a carriage return and a linefeed */ /* to move the cursor to the first column of the next row. */ /*******************************************************************/ int newline(void) { putchar(0x0D); // Carriage Return putchar(0x0A); // Line Feed return 0; }

ECE 4510/5530

23

Reading Into a Buffer /******************************************************************/ /* The following function reads a string from the SCI0 port by */ /* calling the getchar function until the CR character is reached */ /******************************************************************/ int getstr(char *ptr) { while (1) { *ptr = getchar(); if (*ptr == 0x0D){ *ptr = 0; return 0; } else ptr++; } return 0; }

ECE 4510/5530

24

Using the stdio library Input-output manipulation functions stdin – makes a function call to getchar stdout – makes a function call to putchar Name getc getchar gets

Notes reads and returns a character from a given stream and advances the file position indicator; it is allowed to be a macro with the same effects as fgetc, except that it may evaluate the stream more than once has the same effects as getc(stdin) reads characters from stdin until a newline is encountered and stores them in its only argument

printf sprintf

used to print to the standard output stream used to print to a char array (C string)

putc putchar puts

writes and returns a character to a stream and advances the file position indicator for it; equivalent to fputc, except that a macro version may evaluate the stream more than once has the same effects as putc(stdout) outputs a character string to stdout

scanf, sscanf,

used to input from the standard input stream used to input from a char array (e.g., a C string)

ECE 4510/5530

25

Character String Buffers • Memory space allocated for ASCII text string data. – Functions can operate on string buffers instead of “standard I/O”

• Separate the operation of string generation or interpretation from string output and input! – Generate to a string buffer with no polling delays! sprintf instead of printf – Read/operate on a received string buffer with no polling delays! sscanf instead of scanf – Change how characters are read and written using SCI0 from polling to interrupts!

ECE 4510/5530

26

Sunseeker Text Strings //public declarations constants static char RS232Cmd[5] = "+++\r\0"; static char RS232_Test1[13] = "Sunseeker \n\r\0"; static char RS232_Test2[9] = "2012. \n\r\0"; static char Parse_header[6][5] = {"LTC \0","ADC \0","ISH \0","ERR \0","BPS \0","BPC \0"}; char test_buffer[60]; char test_buffer_PC[60]; char xmit_buffer[60]; char xmit_buffer_PC[60]; char parse_buff[8];

ECE 4510/5530

27

Sunseeker Put String Interrupt Start void BPS2PC_put_int(void) { extern char *putPC_ptr; extern char put_status_PC; char ch; ch = *putPC_ptr++;

ECE 4510/5530

if (ch == '\0') { UCA3IE &= ~UCTXIE; put_status_PC = FALSE; } else { UCA3TXBUF = ch; UCA3IE |= UCTXIE; put_status_PC = TRUE; } }

28

Sunseeker ISR /* * BPS2PC Interrupt Service Routine */ #pragma vector=USCI_A3_VECTOR __interrupt void USCI_A3_ISR(void) { extern char *putPC_ptr, *getPC_ptr; extern char put_status_PC, get_status_PC, BPS2PC_RX_flag; char ch; switch(__even_in_range(UCA3IV,16)) { case 0: // Vector 0 - no interrupt break; case 2: // Data Received - UCRXIFG ch = UCA3RXBUF; *getPC_ptr++ = ch; if (ch == 0x0D){ *getPC_ptr = 0; getPC_ptr = &test_buffer_PC[0]; BPS2PC_RX_flag = TRUE; get_status_PC = FALSE; } else { get_status_PC = TRUE; } ECE break; 4510/5530

case 4: // TX Buffer Empty - UCTXIFG ch = *putPC_ptr++; if (ch == '\0') { UCA3IE &= ~UCTXIE; put_status_PC = FALSE; } else { UCA3TXBUF = ch; } break; default: break; } }

String Pointers Used. Check for TX string null and RX string .

29

Creating Multi-line Status Output // Handle BPS to BPS communications events if ((textcomm_flag) && (send_text)) { if(put_status == FALSE) { if(ltc_xcnt