Upload
others
View
4
Download
1
Embed Size (px)
Citation preview
ECE 4510/5530Microcontroller Applications
Week 5 Lab 4& Lab 5
Dr. Bradley J. BazuinAssociate Professor
Department of Electrical and Computer EngineeringCollege of Engineering and Applied Sciences
ECE 2510 2
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
MAKING SOUND
ECE 4510/5530
3
ECE 4510/5530
4
HCS12DP256
PT5
3.3 F
Buzzer
Figure 8.21 Circuit connection for a buzzer
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.
ECE 4510/5530
5
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– Go to Step 2.
ECE 4510/5530
6
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
7
#include "c:\egnu091\include\hcs12.h"#include "c:\egnu091\include\delay.c"#define HiFreq 1250#define LoFreq 5000
int delay; /* 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");
C Program for Siren Generation (1 of 2)
ECE 4510/5530
8
while(1) {delayby100ms(5); /* wait for half a second */delay = LoFreq; /* switch to low frequency tone */delayby100ms(5); /* wait for half a second */delay = HiFreq; /* switch to high frequency tone */
}return 0;
}
#pragma interrupt_handler oc5_ISRvoid oc5_ISR(void){
TC5 += delay;}
#pragma abs_address:vtimch5 // Initialize the Interrupt Vector addressvoid (*interrupt_vectors[]) (void) = {oc5_ISR}; // Assign the function pointer #pragma end_abs_address // to the ISR
C Program for Siren Generation (2 of 2)
Preferred Initialization
void init_TimerCh5(void){
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 */TIE |= BIT5; /* enable TC5 interrupt */
}
Then we have ….
int main(void){
asm(“sei");init_TimerCh5(); /* initialize channel 5*/delay = HiFreq; /* use high frequency delay count first */TC5 = TCNT + delay; /* start an OC5 operation */asm("cli");
ECE 4510/5530
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
ECE 4510/5530
11
$0.93 ea. at Digikey
Speaker
ECE 4510/5530
12
$1.10 ea. at Digikey
You may want to filter
ECE 4510/5530
13
http://homepages.wmich.edu/~bazuinb/FiltersManual_RevD.pdf
Multiple stages are needed for a good filter
ECE 4510/5530
14
Ask Dr. Bazuin for filter design notes if you need them …
Audio amplifier to drive the speaker
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
ECE 4510/5530
17
SCI data register
Receive shift register
Receive and wake up control
BAU
Dge
nera
tor
16 Data format control
Transmit control
Transmit shift register
SCI data register
Busclock
RxDInterrupt
generation
Interruptgeneration
IdleIRQ
RDRF/ORIRQ
TDREIRQ
TCIRQ
ORI
NG
IRQto CPU
TxD
Figure 9.8 HCS12 SCI block diagram
Status Register 1
Status Register 2
The HCS12 SCI Subsystem
Registers Outlined in red
SCI0 Initialization
void init_sci0(void){// BR=ECLK/(16 x BR)
SCI0BD = 156; // 24 MHz E-clock, 9600 bps desired (0.16% error)
SCI0CR1 = SCISWAI | WAKE | ILT ; //SCISWAI, wakeup to mark, idle line after stopSCI0CR1 &= ~(M | PE | PT) ; // 8-bit data, parity disabled, even paritySCI0CR2 = TE | RE; // transmitter enable, receiver enable,
// no interrupts enabled, not a break bit, not wake up}
ECE 4510/5530
18
ECE 4510/5530
19
7 6 5 4 3 2 1 0
reset: 0 0 0 0 0 0 0 0
SBR12 SBR11 SBR10 SBR90 0 0 SBR8
Figure 9.9 SCI baud rate control register
7 6 5 4 3 2 1 0
0 0 0 0 0 1 0 0
SBR4 SBR3 SBR2 SBR1SBR7 SBR6 SBR5 SBR0
(a) SCI baud rate control register high (SC0BDH/SC1BDH)
(b) SCI baud rate control register low (SC0BDL/SC1BDL)
reset:
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.
ECE 4510/5530
20
7 6 5 4 3 2 1 0
reset: 0 0 0 0 0 0 0 0
M WAKE ILT PELOOPS SCISWAI RSRC P T
Figure 9.10 SCI control register 1 (SC0CR1/SC1CR1)
LOOPS: Loop select bit 0 = loop operation disabled 1 = loop operation enabledSCISWAI: 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 bitWAKE: 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 bitPE: parity enable bit 0 = parity disabled 1 = parity enabledPT -- parity type bit (for both transmit and receive) 0 = even parity selected 1 = odd parity selected
The SCI Control Registers (1 of 2)
ECE 4510/5530
21
7 6 5 4 3 2 1 0
valueafter reset 0 0 0 0 0 0 0 0
ILIE TE RE RWUTIE TCIE RIE SBK
Figure 9.11 SCI control register 2 (SC0CR2/SC1CR2)
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 enabledRIE: Receiver full interrupt enable bit 0 = RDRF and OR interrupts disabled 1 = RDRF and OR interrupt enabledILIE: Idle line interrupt enable bit 0 = IDLE interrupt disabled 1 = IDLE interrupt enabledTE: Transmitter enable bit 0 = transmitter disabled 1 = transmitter enabledRE: Receiver enable 0 = receiver disabled 1 = receiver enabledRWU: 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.
The SCI Control Registers (2 of 2)
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 bitreturn 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 bitcontinue;
SCI0DRL = cx; // output the characterreturn 0;
}ECE 4510/5530
22
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”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 Returnputchar(0x0A); // Line Feedreturn 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 functionsstdin – makes a function call to getcharstdout – makes a function call to putchar
Name Notesgetc 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 oncegetchar has the same effects as getc(stdin)gets reads characters from stdin until a newline is encountered and stores them in its only argument
printf used to print to the standard output streamsprintf used to print to a char array (C string)
putc 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
putchar has the same effects as putc(stdout)puts outputs a character string to stdout
scanf, used to input from the standard input streamsscanf, 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++;
if (ch == '\0'){
UCA3IE &= ~UCTXIE;put_status_PC = FALSE;
}else{
UCA3TXBUF = ch;UCA3IE |= UCTXIE;put_status_PC = TRUE;
}}
ECE 4510/5530
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 interruptbreak;
case 2: // Data Received - UCRXIFGch = 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;}
break;ECE 4510/5530
29
case 4: // TX Buffer Empty - UCTXIFGch = *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 <CR>.
Creating Multi-line Status Output// Handle BPS to BPS communications events
if ((textcomm_flag) && (send_text)){ if(put_status == FALSE)
{ if(ltc_xcnt<=18){ if(ltc_xcnt<=9) {
index = ltc_xcnt;txtn=sprintf(xmit_buffer,"LTC %2.2i %8.8lX\n\r", ltc_xcnt, (long)ltc1_CV[index]);ltc_xcnt++;
}else {
index = ltc_xcnt-10;txtn=sprintf(xmit_buffer,"LTC %2.2i %8.8lX\n\r", ltc_xcnt, (long)ltc2_CV[index]);ltc_xcnt++;
} }else if (ADC_xcnt<=31){
index = ADC_xcnt;txtn=sprintf(xmit_buffer,"ADC %2.2i %8.8lX\n\r", ADC_xcnt, adc_voltage[index]);ADC_xcnt++;
}else{
txtn=sprintf(xmit_buffer,"ISH %2.2i %8.8lX\n\r", 0x00, cur_dvolt);text_sent = TRUE;textcomm_flag = FALSE;ltc_xcnt = 0;ADC_xcnt = 0;
}put_ptr = &xmit_buffer[0];BPS2BPS_put_int();put_status = TRUE;
} }ECE 4510/5530
30
Sunseeker Message Parsing// Parse Message
sscanf(test_buffer,"%s %hd %8lX",&parse_buff[0],&txt_id,&txt_hex);for(i=0;i<=4;i++){ check_ptr1 = &parse_buff[0];
check_ptr2 = &Parse_header[i][0];text_compare1 = 0x00;while(*check_ptr1 != 0x00){ text_compare1 |= (*check_ptr1++) ^ (*check_ptr2++); }if (text_compare1 == 0x00){ if(i==0)ltc[txt_id] = txt_hex;
if(i==1)adc[txt_id] = txt_hex;if(i==2)bps[txt_id] = txt_hex;if(i==3){ err[txt_id] = txt_hex;
if(bpsMODE != ERRORMODE) { batt_KILL = TRUE;
batt_ERR = 0x99;} }
if(i==4){ if(txt_id == 0x01) start_precharge = TRUE;
if(txt_id == 0x02) precharge_complete = TRUE;if(txt_id == 0x03) { if( (rx_msg_count+1) != txt_hex) rx_comm_error++;
rx_msg_count = txt_hex;comm_count--;if((comm_count<= 0) || (rx_comm_error >= 10)){ batt_KILL = TRUE;
batt_ERR = 0x99;}}}
break;}}
ECE 4510/5530
31
Double Buffers
• When operating on buffers, you may be processing them while wanting the software to continue “normal operations”.
• If part of the operation is receiving an RX buffer or filling a TX buffer, multiple RX and TX buffers are required.– This approach is often used with real-time data.
Periodic sample data is changed to longer period vector data (or even matrices of sampled data).
– When two buffers are use, they are sometimes called ping-pongbuffers … collect ping while processing pong and then collect pong while processing ping.
– A circular queue of buffers may be needed for some instances.
ECE 4510/5530
32