XC878 Easy Kit: Playing music using the CAPCOM6 module using the SDCC Compiler

Cookery Book, V2.0, May 2010
AP08082
XC878
Playing music using the CAPCOM6 module.
Using DAvE (Code Generator) and
DAvE Bench (Open Platform for Free Tools:
IDE, Compiler, Debugger, Utility Tools)
Microcontrollers
Edition 2010-06-21
Published by
Infineon Technologies AG
81726 München, Germany
© Infineon Technologies AG 2010.
All Rights Reserved.
LEGAL DISCLAIMER
THE INFORMATION GIVEN IN THIS APPLICATION NOTE IS GIVEN AS A HINT FOR THE
IMPLEMENTATION OF THE INFINEON TECHNOLOGIES COMPONENT ONLY AND SHALL NOT BE
REGARDED AS ANY DESCRIPTION OR WARRANTY OF A CERTAIN FUNCTIONALITY, CONDITION OR
QUALITY OF THE INFINEON TECHNOLOGIES COMPONENT. THE RECIPIENT OF THIS APPLICATION
NOTE MUST VERIFY ANY FUNCTION DESCRIBED HEREIN IN THE REAL APPLICATION. INFINEON
TECHNOLOGIES HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND LIABILITIES OF ANY KIND
(INCLUDING WITHOUT LIMITATION WARRANTIES OF NON-INFRINGEMENT OF INTELLECTUAL
PROPERTY RIGHTS OF ANY THIRD PARTY) WITH RESPECT TO ANY AND ALL INFORMATION GIVEN
IN THIS APPLICATION NOTE.
Information
For further information on technology, delivery terms and conditions and prices please contact your nearest
Infineon Technologies Office (www.infineon.com).
Warnings
Due to technical requirements components may contain dangerous substances. For information on the types
in question please contact your nearest Infineon Technologies Office.
Infineon Technologies Components may only be used in life-support devices or systems with the express
written approval of Infineon Technologies, if a failure of such components can reasonably be expected to
cause the failure of that life-support device or system, or to affect the safety or effectiveness of that device or
system. Life support devices or systems are intended to be implanted in the human body, or to support
and/or maintain and sustain and/or protect human life. If they fail, it is reasonable to assume that the health
of the user or other persons may be endangered.
AP08082
XC878 Starter-Kit Playing Music
AP08048
Revision History:
2010-05
Previous Version:
none
Page
V2.0
Subjects (major changes since last revision)
We Listen to Your Comments
Any information within this document that you feel is wrong, unclear or missing at all?
Your feedback will help us to continuously improve the quality of this document.
Please send your proposal (including a reference to this document) to:
[email protected]
Application Note
3
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Table of Contents
Page
Note: Table of Contents see page 8 and page 9.
Introduction:
This “Application Note / Appnote” is a Hands On Training / Cookery Book / step-by-step book.
It will help inexperienced users to get familiar with the CAPCOM 6 module.
This step-by-step book is a follow-up to AP08081!
The purpose of this document is to gain know-how of the possibilities offered by the CAPCOM 6 /
CCU6 module for PWM generation.
Note:
The style used in this document focuses on working through this material as fast and easily as
possible. That means there are full screenshots instead of dialog-window-screenshots; extensive use
of colours and page breaks; and listed source-code is not formatted to ease copy & paste.
Have fun and enjoy the CAPCOM 6 module!
Note:
In case you want to start with the CCU6 from scratch (generating Asymmetrical/Edge-Aligned
PWM signals or Symmetrical/Center-Aligned PWM signals) we suggest taking a look at AP08068.
Note:
Additionally, there is a step-by-step book (AP16109) focusing on BLDC-Motors available, which
can be used for all 8/16 and 32 bit microcontrollers equipped with the CAPCOM 6 module.
To get the most out of the CAPCOM 6 module this additional Cookery Book is the icing on the
cake of all available functionalities (modes) offered by this module (e.g. Multi-Channel Mode, Hall
Sensor Mode).
Application Note
4
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
5
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CAPCOM 6 Block Diagram – general use (Source: Product Marketing)
CAPCOM 6 Block Diagram – BLDC use (Source: Product Marketing)
Application Note
6
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CAPCOM 6 Block Diagram (Source: User’s Manual)
Note:
Just by comparing the different sources of the CAPCOM 6 Module Block Diagrams
[Capture/Compare Unit 6 (CCU6)], you should be able to get a picture of the module and to answer
some of your initial questions.
Application Note
7
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
“Cookery-book“
For your first programming example for the CCU6:
Your
program:
Chapter/
Step
*** Recipes ***
1.)
Do the XC878 Cookery Book
2.)
Playing music
2.1)
Configuring and Reconfiguring the DAvE Project Settings
2.2)
Open the DAvE Bench project and insert code
2.3)
See and hear the result; using the Debugger
Application Note
8
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Appendix:
*** Recipes ***
Chapter/
Step
3.)
Appendix: about music (note length, note frequency)
4.)
Appendix: CAPCOM6 / CCU6 use to create note length and note frequency
5.)
Appendix: songs used
Feedback:
6.)
Thanks To
7.)
Feedback
Application Note
9
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
1.) Do the XC878 Cookery Book:
Note:
It is necessary to follow all instructions in the XC878 Cookery Book (AP08081) step by step, as
this is the basis for all instructions which will follow later.
Note:
In the following steps of this document we will expand the “Hello World Application” (Application
Note AP08081) with the requirements for PWM generation.
Application Note
10
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
2.) Asymmetrical / Edge-Aligned PWM generation:
Single Shot Mode: Timer12 (note length),
Modulation: Timer13 (note frequency),
Playing music
Application Note
11
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
Port_3 pins used by our PWM module:
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Duty Cycle [%] (purpose, modulated by)
100 (note length, Timer_12)
100 (note length, Timer_12)
100 (note length, Timer_12) + 50 (note frequency, Timer_13)
50 (note frequency, Timer_13)
Port_3 pins used as GPIO:
Port Lines
P3.1
P3.6
Function
Show start of next note
use: „program running signal“
Comment
Toggled via Software
Toggled via Timer_0 ISR
Port 3:
Pin
P3.0
CC60
CCU6-Channel
CCU6-Channel-0
Modulated by
Modulated by T12
P3.1
P3.2
CC61
--CCU6-Channel-1
Software
Modulated by T12
P3.3
P3.4
CC62
--CCU6-Channel-2
--Modulated by T12 + T13
---
CC63
----CCU6-Channel-3
P3.5
P3.6
P3.7
Application Note
Software
Modulated by T13
12
Purpose
show note length
duty cycle = 100 %
only for measurement
start of next note
show note length
duty cycle = 100 %
only for measurement
--Music Output:
note length
modulated by
note frequency
--running signal
note frequency
duty cycle = 50 %
only for measurement
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
2.1) Configuring and Reconfiguring the DAvE Project Settings:
Let’s Get Started:
Configuring and Reconfiguring
the DAvE Project Settings:
Application Note
13
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Start the program generator DAvE and open your XC878.dav DAvE project:
View - Project Window (Closes the Project Window)
View - Command Window (Closes the Command Window)
File
Open
Location: C:\XC8xx\XC878
Filename: XC878.dav
Click Open
Application Note
14
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
15
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Changing the Memory Model:
Note
(Release Notes; DAvE Bench for XC800; SDCC Tool chain for XC800; List of Limitations and
Deviations; List of known Issues):
Floats are enabled in large memory model only due to code size limitation. So, print routines
like printf(), sprintf() etc., will output <NO_FLOAT> when floats are used with these routines
in small and medium memory models.
! Because we are going to use float variables in this programming example we have to change the
Memory Model from small to large.
Printf does not work on XC878 16FF
! Therefore we are going to use other print formats like printf_small() and printf_fast_f().
Application Note
16
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
File – Project Settings
Click Yes
Application Note
17
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
General: Compiler Settings: Memory Model: select Large
Exit this dialog now by clicking
Application Note
the close button.
18
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Reconfiguration of Port 3:
The (re)configuration window/dialog can be opened by clicking the specific block/module (Port).
Application Note
19
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Ports: click “Configure Port 3”
Application Note
20
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Port 3: Port Function: untick to unselect " Use P3.0 to free GPIO pin P3.0 for CCU6 use
Port 3: Port Function: untick to unselect " Use P3.2 to free GPIO pin P3.2 for CCU6 use
Port 3: Port Function: untick to unselect " Use P3.4 to free GPIO pin P3.4 for CCU6 use
Port 3: Port Function: untick to unselect " Use P3.7 to free GPIO pin P3.7 for CCU6 use
Port 3: Port Function: tick/check # Use P3.1 as general IO - Port Direction: click/check $ Out
Port 3: Port Function: tick/check # Use P3.3 as general IO - Port Direction: click/check $ Out
Port 3: Port Function: tick/check # Use P3.5 as general IO - Port Direction: click/check $ Out
Port 3: Port Function: tick/check # Use P3.6 as general IO - Port Direction: click/check $ Out
Application Note
21
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
Port_3 pins used by our PWM module:
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Duty Cycle [%] (purpose, modulated by)
100 (note length, Timer_12)
100 (note length, Timer_12)
100 (note length, Timer_12) + 50 (note frequency, Timer_13)
50 (note frequency, Timer_13)
Port_3 pins used as GPIO:
Port Lines
P3.1
P3.6
Function
Show start of next note
use: „program running signal“
Comment
Toggled via Software
Toggled via Timer_0 ISR
Port 3:
Pin
P3.0
P3.1
P3.2
P3.3
P3.4
P3.5
P3.6
P3.7
CC60
CCU6-Channel
CCU6-Channel-0
Modulated by
Modulated by T12
CC61
--CCU6-Channel-1
Software
Modulated by T12
CC62
--CCU6-Channel-2
--Modulated by T12 + T13
CC63
----CCU6-Channel-3
--Software
Modulated by T13
Application Note
22
Purpose
show note length
duty cycle = 100 %
only for measurement
start of next note
show note length
duty cycle = 100 %
only for measurement
--Music Output:
note length
modulated by
note frequency
--running signal
note frequency
duty cycle = 50 %
only for measurement
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Pull Device: (do nothing)
Application Note
23
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Parameters: (do nothing)
Application Note
24
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Notes: Insert Notes: If you wish, you can insert your comments here.
Exit this dialog now by clicking
the close button.
Exit this dialog now by clicking
the close button.
Application Note
25
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Configuration of the CAPCOM 6 module:
The configuration window/dialog can be opened by clicking the specific block/module
(CAPCOM6).
Application Note
26
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Module Clock: CCU6 Disable Flag: click/check $ Enable module
CCU6: Module Clock: Input Clock: click $ FCLK runs at the same frequency as PCLK
Application Note
27
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Pin Control 1: (do nothing)
Application Note
28
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Pin Control 2: Control of Pin CC60: click $ Use pin CC60 (P3.0) as output
CCU6: Pin Control 2: Control of Pin CC61: click $ Use pin CC61 (P3.2) as output
CCU6: Pin Control 2: Control of Pin CC62: click $ Use pin CC62 (P3.4) as output
CCU6: Pin Control 2: Control of Pin COUT63: click $ Use pin COUT63 (P3.7) as output
Remember:
Port_3 pins used by our PWM module:
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Application Note
Duty Cycle [%] (purpose, modulated by)
100 (note length, Timer_12)
100 (note length, Timer_12)
100 (note length, Timer_12) + 50 (note frequency, Timer_13)
50 (note frequency, Timer_13)
29
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
Application Note
30
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Timer 12: “note length”:
CCU6: Timer 12: Input Selection (T12CLK): choose fclk / 8 ! Resolution = 85,333 µs *1
CCU6: Timer 12: T12 Single Shot Control: tick % Enable single shot mode (T12SSC)
CCU6: Timer 12: T12 Operating Mode: click/check $ Edge aligned mode: count up
CCU6: T12: Interrupt Control of Timer 12: tick % Enable interrupt for T12 period match
*1
*1: See next page !!!
Timer 12 Resolution = 11,719 kHz / 85,333 µs
<<< !!! click here to see more information about music !!! >>>
Application Note
31
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
Unfortunately bit T12PRE is not available in the DAvE dialog.
Source: User’s Manual:
The input clock for timer T12 can be from fCCU6 to a maximum of fCCU6/128 and is configured by bit
field T12CLK. In order to support higher clock frequencies, an additional prescaler factor of
1/256 can be enabled for the prescaler of T12 if bit T12PRE = 1.
*1:
Timer 12 Resolution:
24 MHz / 256 (T12PRE=1, done by software) / 8 = 11,719 kHz ! Resolution = 85,333 µs
Application Note
32
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Timer 13: ”note frequency”:
CCU6: Timer T13: Input Selection: Input selection select fclk/2 (Resolution: 83,333 ns)
CCU6: Timer T13: Timer 13 Start Control: click # Start T13 after initialization (T13RS)
<<< !!! click here to see more information about music !!! >>>
Application Note
33
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Multi Channel: (do nothing)
Application Note
34
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: click Configure Channel 0
Note:
Port pins used by our PWM module (not available as GPIO pins):
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Application Note
Channel
Channel 0
Channel 1
Channel 2
Channel 3
Duty Cycle [%]
100 (T12)
100 (T12)
100 (T12)+50 (T13)
50 (T13)
35
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
Application Note
36
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 0:
Mode Selection: Mode Selection for Capture / Compare Channel 0: click $ Compare mode 1
Application Note
37
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 0: Modulation Control for CC60:
T12 Modulation Control for CC60: tick % Enable T12 modulation for CC60
Application Note
38
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 0: Modulation Control for COUT60: (do nothing)
Application Note
39
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 0: Control: (do nothing)
Exit this dialog now by clicking
Application Note
the close button.
40
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: click Configure Channel 1
Note:
Port pins used by our PWM module (not available as GPIO pins):
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Application Note
Channel
Channel 0
Channel 1
Channel 2
Channel 3
Duty Cycle [%]
100 (T12)
100 (T12)
100 (T12)+50 (T13)
50 (T13)
41
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 1:
Mode Selection: Mode Selection for Capture / Compare Channel 1: click $ Compare mode 1
Application Note
42
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 1: Modulation Control for CC61:
T12 Modulation Control for CC61: tick % Enable T12 modulation for CC61
Application Note
43
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 1:
Modulation Control for COUT61: (do nothing)
Application Note
44
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 1: Control: (do nothing)
Exit this dialog now by clicking
Application Note
the close button.
45
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: click Configure Channel 2
Note:
Port pins used by our PWM module (not available as GPIO pins):
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Application Note
Channel
Channel 0
Channel 1
Channel 2
Channel 3
Duty Cycle [%]
100 (T12)
100 (T12)
100 (T12)+50 (T13)
50 (T13)
46
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 2:
Mode Selection: Mode Selection for Capture / Compare Channel 2: click $ Compare mode 1
Application Note
47
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 2: Modulation Control for CC62:
T12 Modulation Control for CC62: tick % Enable T12 modulation for CC62
CCU6: Channels: Configure Channel 2: Modulation Control for CC62:
T13 Modulation Control for CC62: tick % Enable T13 modulation for CC62
Application Note
48
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 2: Modulation Control for COUT62: (do nothing)
Application Note
49
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 2: Control: (do nothing)
Exit this dialog now by clicking
Application Note
the close button.
50
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: click Configure Channel 3
Remember:
Port pins used by our PWM module (not available as GPIO pins):
Port Lines
P3.0
P3.2
P3.4
P3.7
Signal
CC60_0
CC61_0
CC62_0
COUT63_0
Application Note
Channel
Channel 0
Channel 1
Channel 2
Channel 3
Duty Cycle [%]
100 (T12)
100 (T12)
100 (T12)+50 (T13)
50 (T13)
51
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Channels: Configure Channel 3: Control: Compare Timer 13 Output Control:
tick % Enable alternate output function COUT63 for the PWM signal generated by T13
Exit this dialog now by clicking
Application Note
the close button.
52
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Trap / Interrupt Control: click Interrupt Configuration
Application Note
53
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Trap / Interrupt Control: Interrupt Configuration:
Interrupt Control 1: Interrupt Control: tick % Enable interrupt node 2
Click Yes
Application Note
54
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Trap / Interrupt Control: Interrupt Configuration:
Interrupt Control 2: (do nothing)
Exit this dialog now by clicking
Application Note
the close button.
55
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Interrupts: change CCU6 Interrupt Node 2 from Priority 0, Level 13 to Priority 2, Level 13
Priority
Level
Level
Level
Level
Priority 2, Level 13
Application Note
56
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Functions: Initialization Function: tick % CCU6_vInit
CCU6: Functions: Function Library (Part 1): tick % CCU6_vStartTmr
CCU6: Functions: Function Library (Part 1): tick % CCU6_vStopTmr
CCU6: Functions: Function Library (Part 1): tick % CCU6_vSetTmrPeriod
CCU6: Functions: Function Library (Part 3): tick % CCU6_vEnableShadowTransfer
CCU6: Functions: Function Library (Part 3): tick % CCU6_vLoadChannelShadowRegister
*1
Note (*1):
The CCU6 ISR
void SHINT_viXINTR12Isr(void) interrupt XINTR12INT {}
will be generated in the SHARED_INT.C file.
Application Note
57
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Parameters: (do nothing)
Application Note
58
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
CCU6: Notes: If you wish, you can insert your comments here.
Exit this dialog now by clicking
Application Note
the close button.
59
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Generate Code:
File - Generate Code
or
click
DAvE will show you all the files he has generated
(File Viewer opens automatically):
Application Note
60
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
New: SHARED_INT.C, SHARED_INT.H
New: CC6.C, CC6.H
Close DAvE: File – Exit
Application Note
Save changes?
click Yes
61
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
2.2) Open the DAvE Bench project and insert code:
Start DAvE Bench and open your XC878 Project:
Click OK
Application Note
62
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
63
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Mouse position: C/C++ Projects, XC878 [Active - Debug]: click right mouse button
click Refresh
Application Note
64
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
New!
New!
Application Note
65
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Project – Rebuild Active Project
or: click
Application Note
66
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
No Errors!
Application Note
67
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Check/Change the Memory Model:
Project – Active Project Properties
Application Note
68
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Tool Settings: Global Options: Memory Model: check Large
Click OK
Note:
(Release Notes; DAvE Bench for XC800; SDCC Tool chain for XC800):
Floats are enabled in large memory model only due to code size limitation.
So, print routines like printf(), sprintf() etc., will output <NO_FLOAT> when floats are used
with these routines in small and medium memory models.
! Because we are going to use float variables in this programming example we have to use the
Large Memory Model.
Application Note
69
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Insert your application specific program:
Note:
DAvE doesn’t change code which is inserted between ‘// USER CODE BEGIN’ and ‘//
USER CODE END’. Therefore, whenever adding code to DAvE’s generated code, write it
between ‘// USER CODE BEGIN’ and ‘// USER CODE END’.
If you wish to change DAvE´s generated code or add code outside these ‘USER CODE’
sections you will have to insert/modify your changes each time after letting DAvE
regenerate code!
Application Note
70
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click Main.h and change the Defines from:
#define OFF 0
#define ON 1
#define LED_ON 0xFF
#define LED_OFF 0x00
to:
#define OFF 0
#define ON 1
#define LED_ON 1
#define LED_OFF 0
Application Note
71
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click T01.C and change code from:
++ Timer_0_interrupt_counter;
if(RS232_wait)
RS232_wait--; // 183 * Timer_0-overflow = 183 * 5461,333 µs = 0,9994
if(Timer_0_interrupt_counter==183) // 183 * Timer_0-overflow = 183*5461,333µs = 0,9994s
{
Timer_0_interrupt_counter=0;
if (blinking)
{
P3_DATA = P3_DATA^0xFF;
}
}
to:
++ Timer_0_interrupt_counter;
if(RS232_wait)
RS232_wait--; // 183 * Timer_0-overflow = 183 * 5461,333 µs = 0,9994
if(Timer_0_interrupt_counter==183) // 183 * Timer_0-overflow = 183*5461,333µs = 0,9994s
{
Timer_0_interrupt_counter=0;
if (blinking)
{
IO_vTogglePin(P3_6);
}
}
Application Note
72
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
The LED on IO_Port_3.6 will be blinking
with a frequency of about 1 second.
Application Note
73
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and change Global Variable menu
from:
code char menu[] =
"\n\n\n"
"1 ... LEDs P3 ON\n"
"2 ... LEDs P3 OFF\n"
"3 ... LEDs P3 blinking\n"
"\n";
to:
code char menu[] =
"\n\n\n"
"a ... play: Maus am Mars\n"
"b ... play: Yesterday\n"
"c ... play: Frere Jacques / Lazy John / Bruder Jakob\n"
"d ... play: Happy birthday\n"
"e ... play: Take Me Home, Country Roads\n"
"f ... play: Es tanzt ein Bi-ba-butzemann\n"
"g ... play: Ich geh mit meiner Laterne\n"
"h ... play: The little drummer boy\n"
"i ... play: Hey, Pippi Langstrumpf\n"
"j ... play: Stille Nacht, heilige Nacht\n"
"k ... play: Junge komm bald wieder\n"
"l ... play: Lili Marleen\n"
"m ... play: musical scale / chromatic scale / for testing purpose / Tonleiter\n"
"z ... back to main menu (anytime)\n"
"\n";
Application Note
74
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
75
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and delete Global Variables message1, message2 and message3
from:
code char message1[] =
"\n*** LEDs P3 ON ***\n";
code char message2[] =
"\n*** LEDs P3 OFF ***\n";
code char message3[] =
"\n*** LEDs P3 BLINKING ***\n";
to:
Application Note
76
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and change function ”char input (void)”:
from
char input (void)
{
char in=' ';
do
{
printf_small(question);
while (!RI);
RI=0;
in = SBUF;
}while (in!='1' && in!= '2' && in != '3');
return in;
}
to
char input (void)
{
char in=' ';
do
{
printf(question);
while (!RI);
RI=0;
in = SBUF;
}while ( !(in>='a'&&in<='m') );
return in;
}
Application Note
77
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
78
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and extend/change [ “switch/case” in void main (void) ] :
from:
switch (select)
{
case '1': blinking=OFF, P3_DATA=LED_ON, printf_small(message1); break;
case '2': blinking=OFF, P3_DATA=LED_OFF, printf_small(message2); break;
case '3': blinking=ON, printf_small(message3); break;
}
to:
switch (select)
{
case 'a': ++next_song_a,
case 'b': ++next_song_b,
case 'c': ++next_song_c,
case 'd': ++next_song_d,
case 'e': ++next_song_e,
case 'f': ++next_song_f,
case 'g': ++next_song_g,
case 'h': ++next_song_h,
case 'i': ++next_song_i,
case 'j': ++next_song_j,
case 'k': ++next_song_k,
case 'l': ++next_song_l,
case 'm': ++next_song_m,
}
Application Note
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
play_song();
79
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
80
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and insert Global Variables:
//music:
/*
Construction of the music data:
===============================
created by Christan Perschl (www.perschl.at)
extended by Wilhelm Brezovits
C,D,E,F,G,A,H: play note
+: the + raises its note a semitone: Cis, Dis, Eis, Fis, Gis,
Ais, His
-: the – lowers its note a semitone: Ces, Des, Es, Fes, Ges, As,
Hes
Lx : Change note length
(x = 1,2,4,8,16 -> 1=whole-note, 2=half-note, 4=quarternote, ...)
Px : play rest
(x = 1,2,4,8,16 -> 1=whole-rest, 2=half-rest, 4=quarterrest, ...)
Ox : Change octave (x = 0,1,2,3)
. : Extend preceding note by half of its value
Tx : Change tempo (x = 72 ... 199 Beats per Minute)
Additional functionality:
=========================
OL : activate octave LOW
ON : deactivate octave LOW = activate octave normal
Note:
Be aware that not every song sounds good on a descant recorder.
*/
unsigned int T13_values[] =
{45802,43309,40816,38590,36364,34383,32389,30612,28943,27273,25782,24291,200};
// Timer-T13-periods(frequency) of the notes
// [0]=c',[1]=cis',[2]=d’,[3]=dis',[4]=e',[5]=f',
// [6]=fis',[7]=g',[8]=gis',[9]=a',[10]=ais',[11]=h',
// [12]=<Frequency for rest>
unsigned int length_of_a_whole_note = 23438;
// Default-length of a whole-note with tempo 120
Note:
The notes C,D,E,F,G,A,H are named C,D,E,F,G,A,B in other countries.
In this document we stick to the German names.
Application Note
81
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
82
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and insert Global Variables (”songstrings”):
//Songs:
// Maus am Mars (song a) :
code unsigned char
songa[]="T120O0L4FL8AL4O1C.O0L8FEGL2O1CO0P4P8L4EL8GO1L4C.O0L8EFAL2O1CP4
P8O0L4FL8AO1L4C.O0L8FH-O1L4DFL8FEDDCO0HO1CDCO0H-GL2F.";
// Yesterday (song b) :
code unsigned char
songb[]="T120O0L8GL16FL2F.P4L8AHO1C+DEFL4EL8DL2D.P8L8DDCO0H-AGL4HL8AL4A.L4GFL8AL2GL8DL4FL8AL2AAAL4O1DEFL8EDL4E.L8DL4CEFCO0HAL8GL16FL2F.P4L8AHO1C+DEFL4EL8DL2D.P8L8DDCO0H-AGL4HL8AL4A.L4GFL8AL2GL8DL4FL8AL2A";
// Bruder Jakob (song c) :
code unsigned char songc[]="T120O0L4FGAFFGAFAH-O1L2CO0L4AH-O1L2CL8CDCO0L8HL4AFO1L8CDCO0L8H-L4AFFCL2FL4FCL2F";
// Happy birthday (song d) :
code unsigned char
songd[]="T120O0L8DDL4EDGL2F+L8DDL4EDAL2GL8DDL4O1DO0HL8GGL4F+L4EO1L8C
CO0L4HGAL2G";
// Take Me Home, Country Roads (song e):
code unsigned char
songe[]="T199O0L4DDE.L2D.P2L4EL8DL4EL2G.P2L8AL4A.L4H.L2A.L4EEEDL8EL4GL1GP
1L4DDE.L2D.L4EGGHL1HL4AAAAH.L2A.L4EGGAL2G.L4GAL1HL8HAL4GL1AL4HAL1G
L4HO1L4DL1EL4EEDO0L1HL8HAGAL1HL8HAL4GL1GL4GAL1G";
// Es tanzt ein Bi-ba-butzemann (song f):
code unsigned char
songf[]="T199O0L8DGGO1DDO0HHGGAADDL4GP8L8DGGO1DDO0HHGGAADDL4GP8L8
HAHO1CO0AHO1CDO0L8HAHO1CO0AHO1CDO0DGGO1DDO0HHGGAADDL4G";
// Ich geh mit meiner Laterne (song g):
code unsigned char
songg[]="T120O0L8CL4FL8FAFAO1L4C.O0L4AL8FG.L16GL8GGAGL4F.P4O0L8CL4FL8FA
FAO1L4C.O0L4AL8FG.L16GL8GGAGL4F.P4O0L8AO1L4CO0L8AL4FL8AO1L4CO0L8AL4F
L8FGGGGAGL4FP4.O0L8AO1L4CO0L8AL4FL8AO1L4CO0L8AL4FL8FGGGGAGL4FP4.";
// The little drummer boy (song h):
code unsigned char
songh[]="T120P2O0L2D.L4EL2F+L4F+L4F+L8GF+L4GL2F+P2L4DDEF+L4F+L4F+L4F+L8G
F+L4GL2F+P2L4EF+L4GAAAHL8AGL4F+L2EP2L4EF+L4GAAAHO1L8CO0L8HL4AL2GL8
HAL4GL2F+L8AGL4F+L2EP1L2D.L4EL4F+F+F+F+L8GF+L4GL2F+P1L8EDL4EL2D";
// Hey, Pippi Langstrumpf (song i):
code unsigned char
songi[]="T180OLL4AONO0L4DF+DL2EL8GF+EDL4C+EOLAONO0L4C+L2DF+OLL4AONO
0L4DF+DL2EL8GF+EDL4C+EOLL4AONO0L4C+DP4P2OLL4AONO0L4DF+DL2EL8GF+ED
L4C+EOLAONO0L4C+L2DF+OLL4AONO0L4DF+DL2EL8GF+EDL4C+EOLL4AONO0L4C+
DP4P2O0L2F+L4F+F+L2GL4GL8GF+L4EL8EEL4EL8EDL4C+DEP4L2F+L4F+F+L2GL4GF+
Application Note
83
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
EEDC+DP4L2F+GAH.O1L4DC+O0L4HAGL2AO1L4C+O0L4HAGF+L2G.L4HAGF+EL2F+GL
4AF+GAL2H.O1L4DC+O0L4HAGL2A.O1L4C+O0L4HAGF+L2G.L4HAGF+EL2F+EDP2";
// Stille Nacht, heilige Nacht (song j):
code unsigned char
songj[]="T72O0L8G.L16AL8GL4E.L8G.L16AL8GL4E.O1L4DL8DO0L4H.O1L4CL8CO0L4G.L
4AL8AO1L8C.O0L16HL8AL8G.L16AL8GL4E.L4AL8AO1L8C.O0L16HL8AL8G.L16AL8GL4
E.O1L4DL8DL8F.L16DO0L8HO1L4C.L4E.L8C.O0L16GL8EL8G.L16FL8DL1C.";
// Junge komm bald wieder (song k):
code unsigned char
songk[]="T120O0L4DDL8C+L8DL4EL4D.OLL8HONO0L4EL4D.OLL8HONO0L2C.L4EEL8D+
L8EL4F+L4E.L8EL4GL4F+L4EL2D.L4GGGEL2CL4GF+L4EL2D.L4F+L4F+.L8EL4EL2DL4E
L4D.L8COLL2H.ONO0L4DDL8C+L8DL4EL4D.OLL8HONO0L4EL4D.OLL8HONO0L2C.L4E
EL8D+L8EL4F+L4E.L8EL4GF+L4AL2GP8L8DDDDDDDDDL4DP8L8DL8D+L8DDDDDL8D
+L8DL4DP8L8DL8EEEEEEL2GP8L8EL1DP8L8DL8EEEL4E.P8L8GGGF+L8GL1A.";
// Lili Marleen (song l):
code unsigned char
songl[]="T120O0L4EL8E.L16FL4GL4EL8F.L16FL8F.O1L16CO0L2HL8D.L16DL8D.L16EL4FL
8F.L16GL8H.L16AL8G.L16FL4E.L8CL4AL8H.O1L16CO0L4HL4AL4AL4GL4H.L8AL4GL4FL
4A.L8GL4FEL4G.L8EL4G.L8FL4FO1L4DL2CP4O0L4EL4G.L8FL4FOLL4HONO0L2C.";
// musical scale / chromatic scale / for testing purpose / Tonleiter (song m) :
code unsigned char
songm[]="T120O0L4CC+DD+EFF+GG+AA+HO1CC+DD+EFF+GG+AA+HO2CC+DD+EFF+G
G+AA+HO3CC+DD+EFF+GG+AA+HP4O0L8CC+DD+EFF+GG+AA+HO1CC+DD+EFF+GG+
AA+HO2CC+DD+EFF+GG+AA+HO3CC+DD+EFF+GG+AA+HP8O0L16CC+DD+EFF+GG+A
A+HO1CC+DD+EFF+GG+AA+HO2CC+DD+EFF+GG+AA+HO3CC+DD+EFF+GG+AA+HP16
";
unsigned char xdata song[MAX_SONG_LENGTH];
Application Note
84
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
85
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.H and insert Define:
#define MAX_SONG_LENGTH 400
Application Note
86
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and insert Global Variables:
// default values for global variables - will be overwritten before use:
volatile unsigned int xdata note=12;
volatile unsigned int xdata octave=1;
volatile unsigned int xdata current_note_length=23438;
volatile unsigned int xdata old_note_length=23438;
volatile unsigned int xdata tempo=120; // 120 beats/minute
volatile unsigned int pos=0; // current note
unsigned int max=0; // song length
// song counters:
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
unsigned int
xdata
xdata
xdata
xdata
xdata
xdata
xdata
xdata
xdata
xdata
xdata
xdata
xdata
next_song_a=0;
next_song_b=0;
next_song_c=0;
next_song_d=0;
next_song_e=0;
next_song_f=0;
next_song_g=0;
next_song_h=0;
next_song_i=0;
next_song_j=0;
next_song_k=0;
next_song_l=0;
next_song_m=0;
//
//
//
//
//
//
//
//
//
//
//
//
//
song
song
song
song
song
song
song
song
song
song
song
song
song
counter
counter
counter
counter
counter
counter
counter
counter
counter
counter
counter
counter
counter
song
song
song
song
song
song
song
song
song
song
song
song
song
a
b
c
d
e
f
g
h
i
j
k
l
m
volatile bit OctaveLOW=OFF;
Application Note
87
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
88
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
In the following code sequence
CCU6_ISSL = CCU6_ISSL | 0x80
we have to access/set the ST12PM bit (Set Timer 12 Period-Match Flag).
The ST12PM bit is located in the ISSL register (Capture/Compare Interrupt Status Set Register
Low).
Application Note
89
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
The ISSL register (Capture/Compare Interrupt Status Set Register Low) is located in Page 2.
Note (Source: User’s Manual):
The CCU6 SFRs are located in the standard memory area (RMAP = 0) and are organized into 4
pages. The CCU6_PAGE register contains the page value and the page control information.
Therefore, we can use the following code sequence:
// start CAPCOM 6 - Timer T12 – ISR the first time:
SFR_PAGE(_cc2,noSST); // CCU6_PAGE = Page 2 !!!
// Access the module SFR :
CCU6_ISSL = CCU6_ISSL | 0x80; // set ST12PM -> Set-Timer-T12-Period-Match-Flag
Application Note
90
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note: Memory Organization:
From 8052/XC866:
to XC878:
Application Note
91
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Address Extension:
Note:
In the XC800 architecture, the Special Function Registers (SFRs) occupy the direct internal data
memory space in the range 80H to FFH. However, the 128-Byte-SFR range is less than the total
number of registers required and therefore address extension mechanisms are used to increase the
number of addressable SFRs. The address extension mechanisms are:
.) Mapping
.) Paging
Application Note
92
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Address Extension by Mapping:
Note (Source: User’s Manual):
The SFR area is extended into two portions: the standard (non-mapped) SFR area and the mapped
SFR area. Each portion supports the same address range 80H to FFH, extending the number of
addressable SFRs to 256 Bytes.
The extended address range is not directly controlled by the CPU instruction itself, but is derived
from bit RMAP in the system control register SYSCON0.
To access SFRs in the mapped area, bit RMAP in SFR SYSCON0 must be set.
The SFRs in the standard area can be accessed by clearing bit RMAP.
As long as bit RMAP is set, the mapped SFR area can be accessed. This bit is not cleared
automatically by hardware. Thus, before standard/mapped registers are accessed, bit RMAP must
be cleared/set, respectively, by software.
Application Note
93
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Address Extension by Paging:
Note (Source: User’s Manual):
Address extension is further performed at the module level by paging. With the address extension
by mapping, the XC8xx has a 256-SFR address range. However, this is still less than the total
number of SFRs needed by the on-chip peripherals.
To meet this requirement, some peripherals (Parallel Ports, Analog-to-Digital Converter,
Capture/Compare Unit 6, System Control Registers) have a built-in local address extension
mechanism for increasing the number of addressable SFRs. The extended address range is not
directly controlled by the CPU instruction itself, but is derived from bit field PAGE in the module
page register MOD_PAGE. Hence, the bit field PAGE must be programmed before accessing the
SFRs of the target module. Each module may contain a different number of pages and a different
number of SFRs per page, depending on the specific requirement.
Besides setting the correct RMAP bit value to select the SFR area, the user must also ensure that a
valid PAGE is selected to target the desired SFRs.
Note (Source: Application Note AP08053):
It should be noted that each peripheral that supports paging has its own page register.
Application Note
94
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
We can see the PAGE SFR definition in the MAIN.H file:
Application Note
95
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Additionally, there are useful macros available with which we can easily handle the Address
Extension by Paging during interrupt using the Storage Containers:
Application Note
96
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Address Extension (via Mapping and Paging) with respect to the Interrupt System
using Storage Containers:
Note (Source: Application Note AP08053):
There could be six interrupt priorities.
These priorities, with 6 being the highest, are as follows:
Interrupt Priority:
6
5
4
3
2
1
NMI
Interrupt Priority 3
Interrupt Priority 2
Interrupt Priority 1
Interrupt Priority 0
Main
Main refers to routines that run prior to any interrupt and can be interrupted by any interrupt.
Each interrupt source can be programmed to any of the four interrupt priorities (0-3).
An interrupt that is currently being serviced can only be interrupted by a higher priority interrupt,
but not by another interrupt of the same or lower priority.
Hence, an interrupt of the highest priority cannot be interrupted by any other interrupt.
In any case, the NMI always has the highest priority (above priority 3) and its priority cannot be
programmed.
The XC800 architecture provides an efficient mechanism to save and modify the current page
setting without using the stack.
This paging mechanism contains 4 storage containers for the save and restore action.
Application Note
97
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
For any of the six interrupt priorities, the storage number should be unique for each priority to avoid
being overwritten by a different storage number when it is interrupted by a higher priority interrupt
that is accessing the same module.
Users must also ensure that the storage numbers within the ISRs are changed accordingly when the
interrupt priorities are changed.
The main routine should not use a storage container.
This leaves us with five interrupt priorities and four storage containers.
If all priorities are used in an application, then not every interrupt priority can have its own storage
container. A workaround is to make use of the stack as the extended storage container.
The ISR may also call functions that could modify page registers. If these functions are shared by
ISRs of different priority levels, then these functions can be interrupted. It is therefore necessary to
save and restore the page registers that are modified in these functions. In such cases, the stack
should be used as a storage container.
In summary:
• All the page registers modified in an ISR must be saved.
• The storage container should be unique for each interrupt priority.
• The storage numbers within the ISRs must be changed accordingly when the interrupt priorities
are changed.
• No storage container is necessary for the main level.
• Stack can be used as an extended storage container.
• Page registers modified in functions called by the ISRs should use the stack as the storage
container if the functions are shared by different interrupt priorities.
Application Note
98
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
As you can see in the screenshots below,
DAvE uses Storage Container 0 for Interrupt Priority 0:
SAVE to ST0
RESTORE from ST0
Application Note
99
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
As you can see in the screenshots below,
DAvE uses Storage Container 1 for Interrupt Priority 1:
SAVE to ST1
RESTORE from ST1
Application Note
100
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
As you can see in the screenshots below,
DAvE uses Storage Container 2 for Interrupt Priority 2:
SAVE to ST2
RESTORE from ST2
Application Note
101
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
As you can see in the screenshots below,
DAvE uses Storage Container 3 for Interrupt Priority 3:
SAVE to ST3
RESTORE from ST3
Application Note
102
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
In addition to the User’s Manual, we suggest reading Application Note AP08053 for a better
understanding of address extension via Mapping or Paging – especially if interrupts occur:
Application Note
103
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and insert function “ play_song() ” - [ after function “input()” ]:
void play_song(void)
{
max=0;
if (next_song_a && ((sizeof(songa)-1)< MAX_SONG_LENGTH) )
strcpy(song,songa), max=(sizeof(songa))-1, --next_song_a,
printf_small("\nplaying: Maus am Mars\n");
if (next_song_b && ((sizeof(songb)-1)< MAX_SONG_LENGTH) )
strcpy(song,songb), max=(sizeof(songb))-1, --next_song_b,
printf_small("\nplaying: Yesterday\n");
if (next_song_c && ((sizeof(songc)-1)< MAX_SONG_LENGTH) )
strcpy(song,songc), max=(sizeof(songc))-1, --next_song_c,
printf_small("\nplaying: Frere Jacques - Lazy John - Bruder Jakob\n");
if (next_song_d && ((sizeof(songd)-1)< MAX_SONG_LENGTH) )
strcpy(song,songd), max=(sizeof(songd))-1, --next_song_d,
printf_small("\nplaying: Happy birthday\n");
if (next_song_e && ((sizeof(songe)-1)< MAX_SONG_LENGTH) )
strcpy(song,songe), max=(sizeof(songe))-1, --next_song_e,
printf_small("\nplaying: Take Me Home, Country Roads\n");
if (next_song_f && ((sizeof(songf)-1)< MAX_SONG_LENGTH) )
strcpy(song,songf), max=(sizeof(songf))-1, --next_song_f,
printf_small("\nplaying: Es tanzt ein Bi-ba-butzemann\n");
if (next_song_g && ((sizeof(songg)-1)< MAX_SONG_LENGTH) )
strcpy(song,songg), max=(sizeof(songg))-1, --next_song_g,
printf_small("\nplaying: Ich geh mit meiner Laterne\n");
if (next_song_h && ((sizeof(songh)-1)< MAX_SONG_LENGTH) )
strcpy(song,songh), max=(sizeof(songh))-1, --next_song_h,
printf_small("\nplaying: The little drummer boy\n");
if (next_song_i && ((sizeof(songi)-1)< MAX_SONG_LENGTH) )
strcpy(song,songi), max=(sizeof(songi))-1, --next_song_i,
printf_small("\nplaying: Hey, Pippi Langstrumpf\n");
if (next_song_j && ((sizeof(songj)-1)< MAX_SONG_LENGTH) )
strcpy(song,songj), max=(sizeof(songj))-1, --next_song_j,
printf_small("\nplaying: Stille Nacht, heilige Nacht\n");
if (next_song_k && ((sizeof(songk)-1)< MAX_SONG_LENGTH) )
strcpy(song,songk), max=(sizeof(songk))-1, --next_song_k,
printf_small("\nplaying: Junge komm bald wieder\n");
if (next_song_l && ((sizeof(songl)-1)< MAX_SONG_LENGTH) )
strcpy(song,songl), max=(sizeof(songl))-1, --next_song_l,
printf_small("\nplaying: Lili Marleen\n");
if (next_song_m && ((sizeof(songm)-1)< MAX_SONG_LENGTH) )
strcpy(song,songm), max=(sizeof(songm))-1, --next_song_m,
printf_small("\nplaying: musical scale / chromatic scale / for testing purpose / Tonleiter\n");
printf_fast_f("song-length = %5u Byte[s] \n",max);
pos=0;
if (max>0) // there is something to play
{
Application Note
104
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
// start CAPCOM 6 - Timer T12 – ISR the first time:
SFR_PAGE(_cc2,noSST); // switch to CCU6_PAGE=2 without saving !!!
CCU6_ISSL = CCU6_ISSL | 0x80; // set ST12PM -> Set-Timer-T12Period-Match-Flag
while (pos<=max);
// wait until song end is reached or abort by user is done
}
if ( (SBUF=='z') )
printf_small("Song aborted.\n");
else
printf_fast_f("End of the song reached (pos=%5u of max%5u).\n",pos,max);
}
Application Note
105
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
106
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.C and insert code (set the T12PRE bit):
// enable Timer T12 additional prescaler (1/256-prescaler of T12):
// We must do it ourselves because DAvE can’t do it.
// T12 input clock:
// 24 MHz -> 1/256 (T12PRE=1) -> 1/8 (done by DAvE) -> f= 11,719 kHz (resolution = 85,333 µs)
SFR_PAGE(_cc1, noSST); // switch to CCU6_PAGE=1 without saving !!!
if (((CCU6_TCTR0L>>3)&0x0001)==0)
printf_small("T12 prescaler is disabled\n");
else
printf_small("T12 prescaler is enabled\n");
CCU6_TCTR0L=CCU6_TCTR0L | 0x08; // T12PRE=1
if (((CCU6_TCTR0L>>3)&0x0001)==0)
printf_small("T12 prescaler is disabled\n");
else
printf_small("T12 prescaler is enabled\n");
// Timer T13:
// T13 input clock:
// 24 Mhz -> 1/2 (done by DAvE) -> 12 MHz (resolution = 83,333 ns)
Application Note
107
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
108
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
T12PRE=1:
SFR_PAGE(_cc1, noSST);
// switch to CCU6_PAGE=1
// without saving !!!
Application Note
109
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Mouse position: C/C++ Projects, XC878 [Activ - Debug]: click right mouse button
select New click Header File
Application Note
110
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
New Header File: Header File: insert: read_song_string.h
Click Finish
Application Note
111
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Insert:
extern void read_song_string (void);
Application Note
112
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Mouse position: C/C++ Projects, XC878 [Activ - Debug]: click right mouse button
select New click Source File
Application Note
113
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
New Source File: Source File: insert: read_song_string.c
Click Finish
Application Note
114
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Insert:
#include "main.h"
#include "read_song_string.h"
void SetOctaveNORMAL(void)
{
OctaveLOW = OFF; // clear Global Variable
SFR_PAGE(_cc0, noSST);
// switch to page 0
CC6_vStopTmr(CC6_TIMER_13); // Stop Timer 13: CCU6_TCTR4H |= 0x01
SFR_PAGE(_cc1, noSST);
CCU6_TCTR0H = 0x01;
// switch to page 1
// prescaler = 2: load CCU6 timer 13 control register 0 high
SFR_PAGE(_cc0, noSST);
// switch to page 0
CC6_vStartTmr(CC6_TIMER_13); // Start Timer 13: CCU6_TCTR4H |= 0x02
}
void SetOctaveLOW(void)
{
OctaveLOW = ON; // set Global Variable
SFR_PAGE(_cc0, noSST);
// switch to page 0
CC6_vStopTmr(CC6_TIMER_13); // Stop Timer 13: CCU6_TCTR4H |= 0x01
SFR_PAGE(_cc1, noSST);
CCU6_TCTR0H = 0x02;
// switch to page 1
// prescaler = 4: load CCU6 timer 13 control register 0 high
SFR_PAGE(_cc0, noSST);
CCU6_TCTR4H = 0x02;
// switch to page 0
// Start Timer 13: CCU6_TCTR4H |= 0x02
}
// Note:
// The function read_song_string() is a recursive function and will be called recursively until a note
is found.
// The local variable substr is only used within one function-call to determine the tempo and
// can be destroyed from one function-call to another.
// substr could also be defined as either a static or a global variable.
// Therefore, the keyword reentrant is not needed.
void read_song_string (void)
{
unsigned char substr[4]={0};
current_note_length=old_note_length;
switch (song[pos])
{
// select note:
case 'C': note=0;
Application Note
115
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
switch (song[++pos])
{
case '+': note++; pos++; break;
case '-': octave--;
note=11;
pos++;
default : ;
break;
}
break;
break;
case 'D': note=2;
switch (song[++pos])
{
case '+': note++; pos++; break;
case '-': note--; pos++; break;
default: ;
break;
}
break;
case 'E': note=4;
switch (song[++pos])
{
case '+': note++; pos++; break;
case '-': note--; pos++;
break;
default : ;
break;
}
break;
case 'F': note=5;
switch (song[++pos])
{
case '+': note++; pos++; break;
case '-': note--; pos++;
break;
default : ;
break;
}
break;
case 'G': note=7;
switch (song[++pos])
{
case '+': note++; pos++; break;
case '-': note--; pos++;
break;
default : ;
break;
}
break;
case 'A': note=9;
switch (song[++pos])
{
case '+': note++; pos++; break;
case '-': note--; pos++; break;
default : ;
break;
}
break;
Application Note
116
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
case 'H': note=11;
switch (song[++pos])
{
case '+': octave++;
}
note=0;
pos++;
case '-': note--; pos++;
default : ;
break;
break;
break;
break;
// adjust note length:
case 'L': switch (song[++pos])
{
case '1': if (song[++pos]=='6')
current_note_length=length_of_a_whole_note/16;
else
{
pos--;
current_note_length=length_of_a_whole_note;
}
break;
case '2': current_note_length=length_of_a_whole_note/2; break;
case '4': current_note_length=length_of_a_whole_note/4; break;
case '8': current_note_length=length_of_a_whole_note/8; break;
default : ;
break;
}
old_note_length=current_note_length;
pos++;
read_song_string(); break;
// set rest:
case 'P': switch (song[++pos])
{
case '1': if (song[++pos]=='6')
current_note_length=length_of_a_whole_note/16;
else
{
pos--;
current_note_length=length_of_a_whole_note;
}
break;
case '2':current_note_length=length_of_a_whole_note/2; break;
case '4':current_note_length=length_of_a_whole_note/4; break;
case '8':current_note_length=length_of_a_whole_note/8; break;
default :
; break;
}
note=12;
pos++;
break;
Application Note
117
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
// adjust octave:
case 'O': switch (song[++pos])
{
case '0': octave=1; break;
case '1': octave=2; break;
case '2': octave=4; break;
case '3': octave=8; break;
default : if (song[pos]=='L') octave=1, SetOctaveLOW();
if (song[pos]=='N') octave=1, SetOctaveNORMAL();
break;
}
pos++;
read_song_string(); break;
// tempo:
case 'T': pos++;
substr[3]=0; //string termination
if (song[pos]=='1')
{
substr[0]=song[pos];
substr[1]=song[++pos];
substr[2]=song[++pos];
}
else
{
substr[0]=song[pos];
substr[1]=song[++pos];
substr[2]=' ';
}
tempo=atoi(substr);
pos++;
read_song_string(); break;
default: ; break;
} /* end case */
// extend note length by half:
if (song[pos]=='.')
{
old_note_length=current_note_length;
current_note_length=current_note_length*3.0/2.0;
pos++;
}
if (pos==max) pos++;
} /* end read_song_string */
Application Note
118
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note: Now we want to see line numbers (page 1/2):
Window - Preferences
Application Note
119
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note: Now we want to see line numbers (page 1/2):
Window - Preferences
Preferences: General: Editors: Text Editors: tick Show line numbers
Click OK
Application Note
120
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
121
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
122
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
123
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
124
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
125
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
126
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
In the following code sequences
SFR_PAGE(_cc1, noSST);
CCU6_TCTR0H = 0x01;
// switch to page 1
// prescaler = 2: load CCU6 timer 13 control register 0 high
and
SFR_PAGE(_cc1, noSST);
CCU6_TCTR0H = 0x02;
// switch to page 1
// prescaler = 4: load CCU6 timer 13 control register 0 high
we have to access the T13CLK bit field in the TCTR0H register.
Application Note
127
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
128
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
void read_song_string (void)
{
// code
read_song_string(); // recursive call
// code
}
Note (DAvE_Bench_XC800_Release_Notes.doc, Limitations):
Functions are static by default and are non-reentrant.
Note:
Function read_song_string calls itself until a note is found (recursive function).
The break condition for the recursion is that a note is found.
Note:
Normally, functions in DAvE-Bench cannot be called recursively or in a fashion which causes
reentrancy. The reason for this limitation is that function arguments and local variables are stored in
fixed memory locations. Recursive calls to the function use the same memory locations. And, in this
case, arguments and locals would get corrupted.
Note:
In our case we do not use any function arguments or any local variables which must be saved.
The function read_song_string only sets global variables for note length, rest, octave, tempo, and
extend note length by half.
Application Note
129
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.H and insert Project Includes:
#include <stdlib.h>
#include <string.h>
#include "read_song_string.h"
Application Note
130
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click MAIN.H and insert Global Variables (extern declaration):
// Music:
extern unsigned int T13_values[];
extern unsigned int length_of_a_whole_note;
extern unsigned char xdata song[];
extern volatile unsigned int xdata note;
extern volatile unsigned int xdata octave;
extern volatile unsigned int xdata current_note_length;
extern volatile unsigned int xdata old_note_length;
extern volatile unsigned int xdata tempo;
extern volatile unsigned int pos;
extern unsigned int max;
extern volatile bit OctaveLOW;
Application Note
131
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click SHARED_INT.C and insert Global Variables:
unsigned int ui_help1=0;
unsigned int ui_help2=0;
Application Note
132
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Double click SHARED_INT.C and insert ISR-Code (timer T12 period match):
if ( (char)SBUF == 'z' ) // song aborted by user
pos=max+1;
if (pos<=max)
{
read_song_string(); // read next note
// this function is called recursively until a note is
found
// T12PR: adjust note length / set Timer 12 period value for note length:
// Page 1: T12PRL, T12PRH
SFR_PAGE(_cc1,noSST); // switch to CCU6_PAGE = 1 without saving
ui_help1=current_note_length;
ui_help1=ui_help1/tempo;
ui_help1=ui_help1*120;
//CC6_vSetTmrPeriod(CC6_TIMER_12,(current_note_length/tempo*120));
CC6_vSetTmrPeriod(CC6_TIMER_12,ui_help1);
SFR_PAGE(_cc0,noSST); // switch to CCU6_PAGE = 0 without saving
// Page 0: CC60SRL, CC60SRH:
// Channel_0: not used, only for measurement (100% duty cycle):
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_0,0);
// Page 0: CC61SRL, CC61SRH:
// Channel_1: not used, only for measurement (100% duty cycle):
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_1,0);
// Page 0: CC62SRL, CC62SRH:
// Channel_2: if compare value CCU6_CC62SR == 0 -> 100 % duty cycle for note
length:
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_2,0);
// Page 0: bit: T12STR in TCTR4L
CC6_vEnableShadowTransfer(CC6_TIMER_12);
// T13, adjust note frequency / set Timer 13 period value for note frequency:
// Page 1: T13PRL, T13PRH:
SFR_PAGE(_cc1,noSST); // switch to CCU6_PAGE = 1 without saving
ui_help2=T13_values[note];
ui_help2=ui_help2/octave;
//CC6_vSetTmrPeriod(CC6_TIMER_13,(T13_values[note]/octave));
CC6_vSetTmrPeriod(CC6_TIMER_13,ui_help2);
SFR_PAGE(_cc0,noSST); // switch to CCU6_PAGE = 0 without saving
// Channel_3: duty cycle note-frequency = 50 %
// Page 0 : CC63SRL, CC63SRH:
ui_help2=ui_help2/2;
//CC6_vLoadChannelShadowRegister(CC6_CHANNEL_3,(T13_values[note]/octave/2));
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_3,ui_help2);
// Page 0: bit: T13STR in TCTR4H
CC6_vEnableShadowTransfer(CC6_TIMER_13);
if
else
else
else
else
else
else
else
else
else
if
if
if
if
if
if
if
if
if
(note
(note
(note
(note
(note
(note
(note
(note
(note
(note
Application Note
==
==
==
==
==
==
==
==
==
==
0)
1)
2)
3)
4)
5)
6)
7)
8)
9)
printf_small("note=c ");
printf_small("note=cis");
printf_small("note=d ");
printf_small("note=dis");
printf_small("note=e ");
printf_small("note=f ");
printf_small("note=fis");
printf_small("note=g ");
printf_small("note=gis");
printf_small("note=a ");
133
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
else if (note ==10) printf_small("note=ais");
else if (note ==11) printf_small("note=h ");
else if (note ==12) printf_small("note=---");
else
printf_small("note=???");
if
else
else
else
else
else
if
if
if
if
(octave
(octave
(octave
(octave
(octave
==
==
==
==
==
1 && OctaveLOW==OFF) printf_small("*O0*");
1 && OctaveLOW== ON) printf_small("*OL*");
2) printf_small("*O1*");
4) printf_small("*O2*");
8) printf_small("*O3*");
printf_small("????");
printf_fast_f(", T12-pv=%5u,",current_note_length);
printf_fast_f("T12-p=%1.2f[s], ",current_note_length*85.3333/1000.0/1000.0);
printf_fast_f("T13-pv=%5u,", T13_values[note]/octave);
if (OctaveLOW==OFF)
printf_fast_f("T13f=%7.0f[Hz]\n",1/((T13_values[note]/octave)*83.3333/1000.0/1000.0/1000.0));
else if (OctaveLOW==ON)
printf_fast_f("T13f=%7.0f[Hz]\n",1/((T13_values[note]/octave)*166.6667/1000.0/1000.0/1000.0));
IO_vTogglePin(P3_1); // Show start of next note on Port 3 Pin 1
// Page 0: bit: T12RS in TCTR4L
CC6_vStartTmr(CC6_TIMER_12); // Set Timer 12 Run Set bit T12RS
}
Application Note
134
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
135
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
IO_Port_3.1 will be toggled
when a new note is started.
Application Note
136
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Registers used:
Application Note
137
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Generate your application program:
Project – Rebuild Active Project
or: click
Application Note
138
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
0 Error(s)
☺
Application Note
139
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
**** Build of configuration Debug for project XC878 ****
C:\DAvE-Bench-100\SDCC_UTILS\make all
'Building file: ../CC6.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "CC6.s" "../CC6.C"
'Finished building: ../CC6.C'
' '
'Building file: CC6.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "CC6.s" -O "CC6.rel"
'Finished building: CC6.s'
' '
'Building file: ../IO.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "IO.s" "../IO.C"
'Finished building: ../IO.C'
' '
'Building file: IO.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "IO.s" -O "IO.rel"
'Finished building: IO.s'
' '
'Building file: ../MAIN.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "MAIN.s" "../MAIN.C"
../MAIN.C:375: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:378: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:381: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:384: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:387: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:390: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:393: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:396: warning 94: comparison is always true due to limited range of
Application Note
140
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
data type
../MAIN.C:402: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:408: warning 94: comparison is always true due to limited range of
data type
../MAIN.C:411: warning 94: comparison is always true due to limited range of
data type
'Finished building: ../MAIN.C'
' '
'Building file: MAIN.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "MAIN.s" -O
"MAIN.rel"
'Finished building: MAIN.s'
' '
'Building file: ../MemInitxc878_16FF.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx
"../MemInitxc878_16FF.s" -O "MemInitxc878_16FF.rel"
'Finished building: ../MemInitxc878_16FF.s'
' '
'Building file: ../SHARED_INT.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "SHARED_INT.s" "../SHARED_INT.C"
'Finished building: ../SHARED_INT.C'
' '
'Building file: SHARED_INT.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "SHARED_INT.s" -O
"SHARED_INT.rel"
'Finished building: SHARED_INT.s'
' '
'Building file: ../T01.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "T01.s" "../T01.C"
'Finished building: ../T01.C'
' '
'Building file: T01.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "T01.s" -O "T01.rel"
'Finished building: T01.s'
' '
'Building file: ../UART.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "UART.s" "../UART.C"
'Finished building: ../UART.C'
' '
'Building file: UART.s'
Application Note
141
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "UART.s" -O
"UART.rel"
MOV dir(0x82),dir(0x99) found at 1641 of UART.s
'Finished building: UART.s'
' '
'Building file: ../read_song_string.C'
'Invoking: SDCC Compiler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" -mXC800 -pXC878_16FF --model-large
-I"C:/DAvE-Bench-100\SDCC_XC800\include" -I"C:/DAvE-Bench100\SDCC_XC800\include\xc800" -I"C:/DAvE-Bench100\SDCC_XC800\include\asm\xc800" --opt-code-size --nooverlay --noinduction
--debug -S -o "read_song_string.s" "../read_song_string.C"
'Finished building: ../read_song_string.C'
' '
'Building file: read_song_string.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "read_song_string.s"
-O "read_song_string.rel"
MOV dir(0xf0),dir(0x83) found at 3097 of read_song_string.s
MOV dir(0xf0),dir(0x83) found at 3208 of read_song_string.s
'Finished building: read_song_string.s'
' '
'Building file: ../startupxc878.s'
'Invoking: SDCC Assembler'
"C:/DAvE-Bench-100\SDCC_XC800\bin\as-xc800" -plosgffcx "../startupxc878.s" O "startupxc878.rel"
'Finished building: ../startupxc878.s'
' '
'Building target: XC878.hex'
'Invoking: SDCC Linker'
"C:/DAvE-Bench-100\SDCC_XC800\bin\sdcc" --debug -mXC800 -pXC878_16FF -model-large --iram-size 0x100 -Wl -bBSEG=0x20 --xram-loc 0xF000 --xram-size
0xc00 --code-loc 0x0000 --code-size 0x10000 --data-loc 0x00 --idata-loc 0x80
--stack-loc 0x80 -Wl -bPSEG=0xF000 -o "./XC878.hex" "./CC6.rel" "./IO.rel"
"./MAIN.rel" "./MemInitxc878_16FF.rel" "./SHARED_INT.rel" "./T01.rel"
"./UART.rel" "./read_song_string.rel" "./startupxc878.rel"
'Finished building target: XC878.hex'
' '
0 Error(s)
☺
Application Note
142
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
2.3) Using the debugger (DAvE Bench):
See and hear the result:
We will use
any Terminal Program (e.g. U-SPY) + any Logic Analyser / scope + loudspeakers
+
Application Note
+
143
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Make sure that the XC878 Easy Kit is still connected to the host computer:
USB Connection:
.) used for: UART communication (the UART/RS232/serial interface is available via USB as a
virtual COM port of the second USB channel of the FTDI FT2232 Dual USB to UART/JTAG
interface).
.) used for: On-Chip-Flash-Programming and Debugging (first USB channel of the FTDI FT2232
Dual USB to UART/JTAG interface).
.) the USB connection works also as the power supply.
Application Note
144
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Go back to DAvE Bench and
Start/Launch the debugger:
Click
:
Application Note
145
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Click Yes
Application Note
146
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
147
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Now, start U-SPY: click
Application Note
148
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
149
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Reconfigure U-Spy from:
to:
Application Note
150
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Click
:
Note:
: U-SPY is now ready for serial communication!
Application Note
151
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Go back to DAvE Bench and start the debugger
Click:
Resume
Application Note
152
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Go back to U-SPY and see the result:
Application Note
153
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Connect CC62 (P3.4) and GND (VSSP) to your active loudspeaker(s) - and start/select a song:
Application Note
154
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
See / hear / enjoy the results:
Select/insert/tick % Happy birthday d and click
Application Note
(Start Transmission)
155
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
156
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Use any logic analyser and see the result:
Note:
Song d: Happy birthday:
code unsigned char
songd[]="T120O0L8DDL4EDGL2F+L8DDL4EDAL2GL8DDL4O1DO0HL8GGL4F+L4EO1L8C
CO0L4HGAL2G";
Application Note
157
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
HAPPY BIRTHDAY =
T120O0L8DDL4EDGL2F+L8DDL4EDAL2GL8DDL4O1DO0HL8GGL4F…
Application Note
158
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
HAPPY BIRTHDAY =
T120O0L8DDL4EDGL2F+L8DDL4EDAL2GL8DDL4O1DO0HL8GGL4F…
Toggle:
Start/play
next note
Toggle:
Start/play
next note
Toggle:
Start/play
next note
Toggle:
Start/play
next note
Toggle:
Start/play
next note
Note:
Toggle: Start/play next note:
IO_vTogglePin(P3_1); // Show start of next note on Port 3 Pin 1
CC6_vStartTmr(CC6_TIMER_12); // Set Timer 12 Run Set bit T12RS
Application Note
159
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Now we can measure the frequency of note d (we expect 294 Hz) with the LGA:
294 Hz, note: D’
Application Note
160
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
3.) Appendix: about music (note length and note frequency)
Syntax used in our programming example:
Lx : Change note length
(x = 1,2,4,8,16 -> 1=whole-note, 2=half-note, 4=quarter-note, 8=Eighth-note, 16=16th-note)
Real Music:
note
LENGTH
1/1
Whole Note (Semi-breve)
(4 beats)
1/2
Half-note (Minim)
(2 beats)
1/4
Quarter-note (Crotchet)
(1 beat)
1/8
Eighth-note (Quaver)
(1/2 beat)
1/16
Sixteenth-note/16th-note (Semiquaver)
(1/4 beat)
Application Note
161
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Syntax used in our programming example:
. : Extend preceding note by half of its value
Real Music:
note
LENGTH
½ (2 beats) + (½)/2 (1 beat) = ¾ (3 beats)
Note:
The . extends the length of the note by half of its length.
Application Note
162
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Syntax used in our programming example:
C,D,E,F,G,A,H: play note
Real Music:
Note:
The notes C,D,E,F,G,A,H are named C,D,E,F,G,A,B in other countries.
In this document we stick to the German names.
Application Note
163
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Syntax used in our programming example:
+: The + (Sharp) raises its note (frequency) a semitone: Cis, Dis, Eis, Fis, Gis, Ais, His
Real Music:
Syntax used in our programming example:
-: The – (Flat) lowers its note (frequency) a semitone: Ces, Des, Es, Fes, Ges, As, Hes
Real Music:
Application Note
164
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Syntax used in our programming example:
Px : play rest/pause/interval of silence
(x = 1,2,4,8,16 -> 1=whole-rest, 2=half-rest, 4=quarter-rest, 8=Eighth-rest, 16=16th-rest)
Real Music:
rest
rest
LENGTH
1/1
Whole Rest
(4 beats)
1/2
Half-rest
(2 beats)
1/4
Quarter-rest
(1 beat)
1/8
Eighth-rest
(1/2 beat)
1/16
Sixteenth-rest/16th-rest
(1/4 beat)
Note:
The realisation of our programming example is easier when we deal with rests as notes.
Therefore, playing a rest means playing a note.
The frequency of the note which is a rest was chosen above our hearing threshold level
(e.g. 60.000 Hz).
Application Note
165
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Octave:
Definition:
In music, an octave is the interval between one musical note and another with half or double its
frequency.
Note:
If one note has a frequency of 400 Hz, the note an octave above it is 800 Hz.
Further octaves of a note occur at 2n times the frequency of that note (where n is an integer, such as
2, 4, 8, 16 …).
Syntax used in our programming example:
Ox : change octave (x = 0,1,2,3)
Real Music:
C major scale:
Application Note
166
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
4.) Appendix: CAPCOM6 / CCU6 use to create note length and note frequency
If note a’ is equal to 440 Hz then we get the following frequencies for the musical scale:
*1
C1
D1
E1
F1
G1
A1
H1
C2
*2
*1: frequency/note: source: Schüler Duden, Die Musik
*2: frequency/note: source: http://de.wikipedia.org/wiki/Tonleiter
Application Note
167
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note – frequency (Timer 13), octave = O0, O1, O2 and O3:
O0
O1
O2
O3
In our programming example we are going to use the following period-values for Timer 13:
unsigned int T13_values[] =
{45802,43309,40816,38590,36364,34383,32389,30612,28943,27273,25782,24291,200};
/*
[0]=c',[1]=cis',[2]=d',[3]=dis',[4]=e',[5]=f',[6]=fis',[7]=g',[8]=gis',[9]=a',[10]=ais',[11]=h',
[12]=<Frequency for rest>
*/
So we get the following values shown in the table below
[Note: Timer 13 resolution = 1/(fclk/2) = 1/(24MHz/2) = 83,333 ns]:
T13 period values
T13_values[ 0] = 45802
T13_values[ 1] = 43309
T13_values[ 2] = 40816
T13_values[ 3] = 38590
T13_values[ 4] = 36364
T13_values[ 5] = 34383
T13_values[ 6] = 32389
T13_values[ 7] = 30612
T13_values[ 8] = 28943
T13_values[ 9] = 27273
T13_values[10] = 25782
T13_values[11] = 24291
T13_values[12] =
200
note
c’
cis’
d’
dis’
e’
f’
fis’
g’
gis’
a’
ais’
h’
----
Octave=0
(=’)
scaler for
T13Periodvalue =1
f [Hz]
262
Octave=1
(=’’)
scaler for
T13Periodvalue =2
f [Hz]
523
Octave=2
(=’’’)
scaler for
T13Periodvalue =4
f [Hz]
440
880
1760
494
60000
988
Octave=3
(=’’’’)
scaler for
T13Periodvalue =8
f [Hz]
294
330
349
392
3520
Note:
If one note has a frequency of 400 Hz, the note an octave above it is 800 Hz.
Further octaves of a note occur at 2n times the frequency of that note (where n is an integer, such as
2, 4, 8, 16 …).
e.g. for a’:
f = 1 / ( T13-period-value x T13-resolution ) = 1 / ( 27273 * 83,333 ns ) = 440 Hz
Application Note
168
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note – frequency (Timer 13), octave = OL:
OL
In our programming example we are going to use also the following period-values for Timer 13 for
octave = OL:
unsigned int T13_values[] =
{45802,43309,40816,38590,36364,34383,32389,30612,28943,27273,25782,24291,200};
/*
[0]=c',[1]=cis',[2]=d',[3]=dis',[4]=e',[5]=f',[6]=fis',[7]=g',[8]=gis',[9]=a',[10]=ais',[11]=h',
[12]=<Frequency for rest>
*/
So we get the following values shown in the table below
[Note: Timer 13 resolution = 1/(fclk/4) = 1/(24MHz/4) = 166,6667 ns]:
T13 period values
T13_values[ 0] = 45802
T13_values[ 1] = 43309
T13_values[ 2] = 40816
T13_values[ 3] = 38590
T13_values[ 4] = 36364
T13_values[ 5] = 34383
T13_values[ 6] = 32389
T13_values[ 7] = 30612
T13_values[ 8] = 28943
T13_values[ 9] = 27273
T13_values[10] = 25782
T13_values[11] = 24291
T13_values[12] =
200
Application Note
note
Octave=OL
T13 Prescaler=4
f [Hz]
131
139
147
156
165
175
186
196
208
220
234
247
30000
c
cis
d
dis
e
f
fis
g
gis
a
ais
h
----
169
Octave=ONO0
T13 Prescaler=2
f [Hz]
262
294
330
349
392
440
494
60000
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Therefore we use the following program sequence in our application:
// note-frequency:
CC6_vSetTmrPeriod(CC6_TIMER_13,(T13_values[note]/octave));
// duty-cycle = 50 %:
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_3,(T13_values[note]/octave/2));
CC6_vEnableShadowTransfer(CC6_TIMER_13);
Application Note
170
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
note – length (Timer 12)
The metronome (a piece of equipment that repeats a regular beat, used by musicians to help them
play music at the right speed) allows the exact definition of the tempo.
Application Note
171
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
So we get the following table for speed:
Tempo
Beats per minute
Grave
Largo/Lento
Larghetto moderato
Larghetto
Adagio moderato
Adagio
Adagio cantabile
Andantino moderato
Andantino
Andante moderato
Andante
Allegretto moderato
Allegretto
Moderato 1
Moderato 2
Allegro moderato
Allegro
Vivace 1
Vivace 2
Presto moderato
Presto/Allegro assai
Prestissimo moderato
Prestissimo
40-60
60-66
66-76
76-108
108-120
120-168
168-200
200-208
Note:
Our software supports 72 to 199 Beats per minute:
Tx : Change tempo (x = 72 ... 199 Beats per Minute)
And tempo is used in the following way:
// note-length:
CC6_vSetTmrPeriod(CC6_TIMER_12,(current_note_length/tempo*120));
// 100% duty-cycle:
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_0,0);
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_1,0);
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_2,0);
Application Note
172
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
e.g.
@ 120 means:
120 “beats“ / minute =
2 “beats“ / second '
1 “beat“ = 0,5 second
1/1
note = 4
beats = 4
* 0,5 = 2
[s]
1/2
note = 2
beats = 2
* 0,5 = 1
[s]
1/4
note = 1
beat
* 0,5 = 0,5
[s]
1/8
note = 1/2 beat
= 1
= 1/2 * 0,5 = 0,25
1/16 note = 1/4 beat
[s]
= 1/4 * 0,5 = 0,125 [s]
So we get the following values shown in the table below
(Note: Timer 12 resolution = 85,333 µs):
T12 period values
23438 / 1 = 23438
note
note
1/1
note length
[s]
2
23438 / 2 = 11719
1/2
1
23438 / 4 = 5859
1/4
0,5
23438 / 8 = 2930
1/8
0,25
23438 / 16 = 1465
1/16
0,125
e.g. for
:
note length = T12-period-value / 4 * T12-resolution
note length = 23438 / 4 * 85,333 µs = 0,5 [s]
Application Note
173
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
In our programming example we use the following code sequences:
// Standard - length of a whole note with tempo 120:
unsigned int length_of_a_whole_note = 23438;
// note-length:
case 'L': switch (song[++pos])
{
case '1': if (song[++pos]=='6')
current_note_length=length_of_a_whole_note/16;
else
{
pos--;
current_note_length=length_of_a_whole_note;
}
break;
case '2': current_note_length=length_of_a_whole_note/2;
break;
case '4': current_note_length=length_of_a_whole_note/4;
break;
case '8': current_note_length=length_of_a_whole_note/8;
break;
default : ;
break;
}
old_note_length=current_note_length;
pos++;
read_song_string();
break;
// T12, note-length:
// period value note-length
CC6_vSetTmrPeriod(CC6_TIMER_12,(current_note_length/tempo*120));
// Channel_2:
// if compare value CCU6_CC62SR == 0 -> 100 % duty cycle
// for note length:
CC6_vLoadChannelShadowRegister(CC6_CHANNEL_2,0);
CC6_vEnableShadowTransfer(CC6_TIMER_12);
Application Note
174
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Implementing note length and note frequency on real hardware:
Using XC878 using CAPCOM6 / CCU6: T12 and T13:
T12: note length:
24 MHz -> 1/256 (T12PRE=1) -> 1/8 (done by DAvE) ->
f= 11,719 kHz (resolution = 85,333 µs)
Duty cycle = 100 %
T13: note frequency (Octave = O0, O1, O2 and O3):
24 Mhz -> 1/2 (done by DAvE) ->
12 MHz (resolution = 83,333 ns)
Duty cycle = 50 %
e.g. note = a’ (440 Hz):
CCU6_T13PR=T13_values[note]/octave;
CCU6_T13PR=T13_values[9]/1
CCU6_T13PR=27273/1
CCU6_T13PR=27273
CCU6_CC63SR=CCU6_T13PR/2 ;
CCU6_CC63SR=27273/2
CCU6_CC63SR=13637
Note:
Modulation of CAPCOM6 T12 CC62 output done by T13 (done by hardware functionality)
Application Note
175
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Note:
T13: note frequency (Octave = OL):
24 Mhz -> 1/4 (done by DAvE) ->
12 MHz (resolution = 166,6667 ns)
Duty cycle = 50 %
Application Note
176
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.) Appendix: songs used
5.1.) Song a: Maus am Mars:
// Maus am Mars (song a):
code unsigned char
songa[]="T120O0L4FL8AL4O1C.O0L8FEGL2O1CO0P4P8L4EL8GO1L4C.O0L8EFAL2O1CP4
P8O0L4FL8AO1L4C.O0L8FH-O1L4DFL8FEDDCO0HO1CDCO0H-GL2F.";
Note:
Thanks to Christian Perschl (www.perschl.at).
The songstring above was written down by Christian while humming the melody.
Application Note
177
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.2.) Song b: Yesterday:
// Yesterday (song b):
code unsigned char
songb[]="T120O0L8GL16FL2F.P4L8AHO1C+DEFL4EL8DL2D.P8L8DDCO0H-AGL4HL8AL4A.L4GFL8AL2GL8DL4FL8AL2AAAL4O1DEFL8EDL4E.L8DL4CEFCO0HAL8GL16FL2F.P4L8AHO1C+DEFL4EL8DL2D.P8L8DDCO0H-AGL4HL8AL4A.L4GFL8AL2GL8DL4FL8AL2A";
Note:
Thanks to Christian Perschl (www.perschl.at).
The songstring above was written down by Christian while humming the melody.
Application Note
178
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.3.) Song c: Bruder Jakob:
// Bruder Jakob (song c):
code unsigned char songc[]="T120O0L4FGAFFGAFAH-O1L2CO0L4AH-O1L2CL8CDCO0L8HL4AFO1L8CDCO0L8H-L4AFFCL2FL4FCL2F";
Application Note
179
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.4.) Song d: Happy birthday:
// Happy birthday (song d):
code unsigned char
songd[]="T120O0L8DDL4EDGL2F+L8DDL4EDAL2GL8DDL4O1DO0HL8GGL4F+L4EO1L8C
CO0L4HGAL2G";
Application Note
180
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.5.) Song e: Take Me Home, Country Roads:
// Take Me Home, Country Roads (song e):
code unsigned char
songe[]="T199O0L4DDE.L2D.P2L4EL8DL4EL2G.P2L8AL4A.L4H.L2A.L4EEEDL8EL4GL1GP
1L4DDE.L2D.L4EGGHL1HL4AAAAH.L2A.L4EGGAL2G.L4GAL1HL8HAL4GL1AL4HAL1G
L4HO1L4DL1EL4EEDO0L1HL8HAGAL1HL8HAL4GL1GL4GAL1G";
Application Note
181
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.6.) Song f: Es tanzt ein Bi-ba-butzemann:
// Es tanzt ein Bi-ba-butzemann (song f):
code unsigned char
songf[]="T199O0L8DGGO1DDO0HHGGAADDL4GP8L8DGGO1DDO0HHGGAADDL4GP8L8
HAHO1CO0AHO1CDO0L8HAHO1CO0AHO1CDO0DGGO1DDO0HHGGAADDL4G";
Application Note
182
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.7.) Song g: Ich geh mit meiner Laterne:
// Ich geh mit meiner Laterne (song g):
code unsigned char
songg[]="T120O0L8CL4FL8FAFAO1L4C.O0L4AL8FG.L16GL8GGAGL4F.P4O0L8CL4FL8FA
FAO1L4C.O0L4AL8FG.L16GL8GGAGL4F.P4O0L8AO1L4CO0L8AL4FL8AO1L4CO0L8AL4F
L8FGGGGAGL4FP4.O0L8AO1L4CO0L8AL4FL8AO1L4CO0L8AL4FL8FGGGGAGL4FP4.";
Application Note
183
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.8.) Song h: The little drummer boy:
Application Note
184
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
// The little drummer boy (song h):
code unsigned char
songh[]="T120P2O0L2D.L4EL2F+L4F+L4F+L8GF+L4GL2F+P2L4DDEF+L4F+L4F+L4F+L8G
F+L4GL2F+P2L4EF+L4GAAAHL8AGL4F+L2EP2L4EF+L4GAAAHO1L8CO0L8HL4AL2GL8
HAL4GL2F+L8AGL4F+L2EP1L2D.L4EL4F+F+F+F+L8GF+L4GL2F+P1L8EDL4EL2D";
Application Note
185
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.9.) Song i: Hey, Pippi Langstrumpf:
Application Note
186
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Application Note
187
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
// Hey, Pippi Langstrumpf (song i):
code unsigned char
songi[]="T180OLL4AONO0L4DF+DL2EL8GF+EDL4C+EOLAONO0L4C+L2DF+OLL4AONO
0L4DF+DL2EL8GF+EDL4C+EOLL4AONO0L4C+DP4P2OLL4AONO0L4DF+DL2EL8GF+ED
L4C+EOLAONO0L4C+L2DF+OLL4AONO0L4DF+DL2EL8GF+EDL4C+EOLL4AONO0L4C+
DP4P2O0L2F+L4F+F+L2GL4GL8GF+L4EL8EEL4EL8EDL4C+DEP4L2F+L4F+F+L2GL4GF+
EEDC+DP4L2F+GAH.O1L4DC+O0L4HAGL2AO1L4C+O0L4HAGF+L2G.L4HAGF+EL2F+GL
4AF+GAL2H.O1L4DC+O0L4HAGL2A.O1L4C+O0L4HAGF+L2G.L4HAGF+EL2F+EDP2";
Application Note
188
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.10.) Song j: Stille Nacht, heilige Nacht:
// Stille Nacht, heilige Nacht (song j):
code unsigned char
songj[]="T72O0L8G.L16AL8GL4E.L8G.L16AL8GL4E.O1L4DL8DO0L4H.O1L4CL8CO0L4G.L
4AL8AO1L8C.O0L16HL8AL8G.L16AL8GL4E.L4AL8AO1L8C.O0L16HL8AL8G.L16AL8GL4
E.O1L4DL8DL8F.L16DO0L8HO1L4C.L4E.L8C.O0L16GL8EL8G.L16FL8DL1C.";
Application Note
189
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.11.) Song k: Junge komm bald wieder:
Application Note
190
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
// Junge komm bald wieder (song k):
code unsigned char
songk[]="T120O0L4DDL8C+L8DL4EL4D.OLL8HONO0L4EL4D.OLL8HONO0L2C.L4EEL8D+
L8EL4F+L4E.L8EL4GL4F+L4EL2D.L4GGGEL2CL4GF+L4EL2D.L4F+L4F+.L8EL4EL2DL4E
L4D.L8COLL2H.ONO0L4DDL8C+L8DL4EL4D.OLL8HONO0L4EL4D.OLL8HONO0L2C.L4E
EL8D+L8EL4F+L4E.L8EL4GF+L4AL2GP8L8DDDDDDDDDL4DP8L8DL8D+L8DDDDDL8D
+L8DL4DP8L8DL8EEEEEEL2GP8L8EL1DP8L8DL8EEEL4E.P8L8GGGF+L8GL1A.";
Application Note
191
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.12.) Song l: Lili Marleen:
// Lili Marleen (song l):
code unsigned char
songl[]="T120O0L4EL8E.L16FL4GL4EL8F.L16FL8F.O1L16CO0L2HL8D.L16DL8D.L16EL4FL
8F.L16GL8H.L16AL8G.L16FL4E.L8CL4AL8H.O1L16CO0L4HL4AL4AL4GL4H.L8AL4GL4FL
4A.L8GL4FEL4G.L8EL4G.L8FL4FO1L4DL2CP4O0L4EL4G.L8FL4FOLL4HONO0L2C.";
Application Note
192
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.13.) Song m: musical scale / chromatic scale / for testing purpose / Tonleiter:
// musical scale / chromatic scale / for testing purpose / Tonleiter (song m):
code unsigned char
songi[]="T120O0L4CC+DD+EFF+GG+AA+HO1CC+DD+EFF+GG+AA+HO2CC+DD+EFF+G
G+AA+HO3CC+DD+EFF+GG+AA+HP4O0L8CC+DD+EFF+GG+AA+HO1CC+DD+EFF+GG+
AA+HO2CC+DD+EFF+GG+AA+HO3CC+DD+EFF+GG+AA+HP8O0L16CC+DD+EFF+GG+A
A+HO1CC+DD+EFF+GG+AA+HO2CC+DD+EFF+GG+AA+HO3CC+DD+EFF+GG+AA+HP16
";
Application Note
193
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
5.14.) Another song: Lady Bird:
// Lady Bird:
"T150ONO0L4F+P16F+P16F+.P8L16C+P16L8EP16E.P16L2EL8EP16L4C+P16C+P16C+.P16OLL8AP16
L4HP16G+P16L2EP4ONO0L4F+P16L8F+.P16L2F+P4L4EP16L8E.P16L2EP4L4C+P16L8C+.P16L4C+.O
LAP16L4HP16G+P16EP16L4EP16L8F+.P16L16F+P16L1F+P8L4G+P16G+P16G+P16L8G+.P16F+P16L1
F+";
Note:
Thanks to Maureen Sturgeon.
She wrote down the songstring above.
Application Note
194
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
Summary:
In this step-by-step book you have learned how to use the CAPCOM 6 / CCU6 / PWM Unit.
Have fun and enjoy working with microcontrollers with CCU6 modules!
Note:
There are step-by-step books for 8 bit microcontrollers (e.g. XC866 and XC88x), 16 bit
microcontrollers (e.g. C16x, XC16x, and XE16x) and 32 bit microcontrollers (e.g. TC1796,
TC1766 and TC1130).
All these step-by-step books use the same microcontroller resources and the same example code.
This means: configuration steps, function names and variable names are identical.
This should give you a good opportunity to get in contact with another Infineon microcontroller
family or tool-chain!
There are even more programming examples available using the same style [e.g. ADC-examples,
CAPCOM6-examples (e.g. BLDC-Motor), Simulator examples, C++ examples] based on these
step-by-step books.
Application Note
195
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
6.) Thanks To
Maria, Christian, Hermann and Maureen for their support.
Application Note
196
V2.0, 2010-05
AP08082
XC878 Starter-Kit Playing Music
7.) Feedback (XC878 Playing Music using DAvE Bench):
Your opinion, suggestions and/or criticisms
Contact Details (this section may remain blank should you wish to offer
feedback anonymously):
______________________________________________________
______________________________________________________
______________________________________________________
If you have any suggestions please send this sheet back to:
email: [email protected]
FAX: +43 (0) 4242 3020 5783
Your suggestions:
______________________________________________________
______________________________________________________
______________________________________________________
______________________________________________________
______________________________________________________
______________________________________________________
______________________________________________________
______________________________________________________
Application Note
197
V2.0, 2010-05
http://www.infineon.com
Published by Infineon Technologies AG