Hello I was hoping someone could help me debug my short code. I am developing on the demo9s08qg8. I would like to use my 9s08 on a breadboard but so far I am unsuccessful. I think my problem is mainly setting up a proper clock. I would like to use the FFL Engaged Internal (FEI) clock mode. From every document available I understand this allows no additional components to be required for generating a clock, such as a crystal and its capacitors (please correct me if I am wrong). After I try to set up the clock all I want to do is use parallel ports and timer. Here is my attempt. I assume to make my origin $E000 because that is where flash begins even though code warrior prompts me that it will reprogram FLASH every debug. Thanks for the help.
; Include derivative-specific definitions
INCLUDE 'derivative.inc'
XDEF _Startup, main
main:
_Startup:
ORG $E000 ;FLASH BEGINS
MOV #$3F,ICSC1 ;SET CORE CLOCK 16.38KHZ
MOV #$00,ICSC2
LDX #$F6
STX PTAPE ;ENABLE PULL UP RESISTORS
MOV #$FF,PTBDD ;DATA DIRECTION B
MOV #$09,PTADD ;DATA DIRECTION A
LOOP MOV #$09,PTAD ;PA0 & PA3 ON, PA1 & PA2 OFF
JSR TIMER ;TIME DELAY
MOV #$00,PTAD ;PORTA OFF
BRA LOOP
SWI
TIMER MOV #$06,MTIMCLK ;PRESCALE
MOV #$9A,MTIMMOD ;DECIMAL 154
MOV #$60,MTIMSC ;TSCR1
TT BRCLR 7,MTIMSC,TT ;WAIT FOR OVERFLOW FLAG
BSET 7,MTIMSC
RTS
One last small thing I would like to ask is I had this strange alert in codewarrior and it may have something to do with my problem. I have attached the alert. I just click yes and it seems to work fine.
解決済! 解決策の投稿を見る。
Hello Wolfgang,
Now your task is clearer.
My original code worked but is not suited for your task: in fact, due to the high rate clock (BusClok was set to 1MHz) it produces a very small (11us) logic low pulse on PTA0 which repeats at 200Hz rate. You cannot appreciate it on a LED: it will appear you as it is always on! Nevertheless you could see it on an oscilloscope.
There were at least two conceptual errors on my code which did not impede it to work:
These errors were fixed in a rev 03 of the code but there is no visible effect on the result (old code worked well anyway)
Based on your task I edited a rev_04 version in which I used 31,25kHz Internal reference clock instead of 16MHz DCO to produce a 16525Hz BusClock, much better than the original 1MHz in the previous version to generate a visible 1Hz output on PTA0. Now the clock generator functions in FBI instead of FEI mode and the timer produces a perfect square wave output 50% duty you can easily see on your LED, at 1Hz pace. Watchdod was disabled because difficult to serve with this very low clock.
The code was cleared of surplus lines and comments and ordered in a clearer way. A new CW6.3 project was generated you can use to directly burn your 9S08QG8. In the "History section" is still present ver_02 and ver_03 for reference purpose if you want ot study them and their difference. Main code is this now this:
; 9S08QG8 ASM FRAMEWORK EXAMPLE BASED ON CW 6.3
; EDITED BY SALVATORE COSENTINO, 2013-04-12
; File 9S08QG8 main 04.asm
;*****************************************************
; This stationery serves as the framework for a user
; application, as suggested by CODEWARRIOR 6.3
; In this example a LED connected to PTA0 is turned
; ON/OFF at 1Hz rate
;*****************************************************
; Include derivative-specific definitions
INCLUDE 'derivative.inc'
; export symbols to be refer. in the linker .prm file
XDEF _Startup, main
XREF __SEG_END_SSTACK
; symbol defined by the linker for the end of the stack
; variable/data section
MY_ZEROPAGE: SECTION SHORT
; no variables defined
; Code section
MyCode: SECTION
_Startup:
main: LDHX #__SEG_END_SSTACK ; init stack pointer
TXS
CLI ; enable interrupts
; Disable COP, enable BKGD mode, Stop mode and Reset
LDA #%01110011
; |||||||+-- SRTPE=1 (Reset enabled)
; ||||||+--- BKGDPE=1 (Backgnd enabled)
; |||+++---- reserved
; ||+------- STOPE=1 (Stop mode enabled)
; |+-------- COPT=1 (Long time-out)
; +--------- COPE=0 (COP disabled)
STA SOPT1
; BusClock initialization
; Preset IREFCLK as 31.25kHz clk source, FBI mode
; BDIV= 1, ICSout= 31.25kHz, BusClock= 15625Hz
MOV #%01000100,ICSC1
; |||||||+-- IREFSTEN=0 (default)
; ||||||+--- IRCLKEN=0 (default)
; |||||+---- IREFS=1 (Int.ref.ck select)
; ||+++----- RDIV=1 (RDIV_CLK=IREFCLK)
; ++-------- CLKS=01 (FBI mode selected)
MOV #%11000000,ICSC2
; ++-------- BDIV=0, rest by default
; I/O initialization
LDX #%11110110
STX PTAPE ; ENABLE PULL UP RES. ON A
; no pull-up on PA0 & PA3
MOV #$FF,PTBDD ; DDReg B (all out)
MOV #$09,PTADD ; DDReg A (PA0 & PA3 as out)
; Timer initialization
; Timer clock= IREFCLK, Prescaler= 64
; i.e. Tclk= 31250/64= 488.2Hz
; Modulo counter by 244, Fo= roughly 2Hz (500ms cycle)
MOV #%00000110,MTIMCLK ; prescaler= 64
MOV #244-1,MTIMMOD ; 244 modulo counter
; Start timer as free running counter, no interrupt
MOV #%00000000,MTIMSC ; TOIE=0, TRST=0
; Main loop
LOOP JSR TIMER ;TIME DELAY
; Inverts logical level on PA0 to turn on/off a LED
LDA PTAD
EOR #%00000001
STA PTAD
; Watchdog serving (Watchdog is expressly disabled)
; feed_watchdog ; call Wdog macro
BRA LOOP
;*****************************************************
; ROUTINES
;*****************************************************
TIMER BRCLR 7,MTIMSC,TIMER ;WAIT FOR TOF
BCLR 7,MTIMSC ;CLEAR TOF
RTS
Let me know if now this works for you!
By by,
Salvatore
Dear Wolfgang,
There are a lot of inconsistencies or errors in your code, or at least I have not fully understood what you want to do. It seems to me you want to produce some repetitive pulses on two lines of PORT A at an undefined (?) frequency. Here following I will list what I noticed.
Here attached is a complete edited project based on your code on a CW6.3 framework which was tested with CW6 Full Chip Simulator. BusClock was derived by FFE and scaled to 1MHz, the timer is preset as you suggested (prescaler=64, Modulo counter= 155) and the output is a short pulse with 200Hz repetition rate (it should be 100Hz but there is some error in my preset or in the simulation). I did not really test in a breadboard so there may be some other error but simulation is ok. IREFCLK must be trimmed to 31.25kHz as by default during CPU programming: please note there is no explicit instruction in my code to copy factory preset or programmer's found ICSTRIM/FTRIM in the ICSSC register.
Here is the asm portion:
; 9S08QG8 ASM FRAMEWORK EXAMPLE
; CREATED BY CODEWARRIOR 6.3
; EDITED BY SALVATORE COSENTINO, 2013-04-08
; File 9S08QG8 main 02.asm
;*****************************************************
; This stationery serves as the framework for a user
; application.
; For a more comprehensive program that demonstrates
; the more advanced functionality of this processor,
; please see the demonstration applications, located
; in the examples subdirectory of the
; "Freescale CodeWarrior for HC08" program directory.
;*****************************************************
; Include derivative-specific definitions
INCLUDE 'derivative.inc'
; export symbols
XDEF _Startup, main
; we export both '_Startup' and 'main' as symbols.
; Either can be referenced in the linker .prm file
; or from C/C++ later on
XREF __SEG_END_SSTACK
; symbol defined by the linker for the end of the stack
; variable/data section
MY_ZEROPAGE: SECTION SHORT
; Insert here your data definition
; Code section
MyCode: SECTION
main:
_Startup:
LDHX #__SEG_END_SSTACK ; init stack pointer
TXS
CLI ; enable interrupts
; Wolfgang's code:
; MOV #$3F,ICSC1 ;SET CORE CLOCK 16.38KHZ
; #%00111111
; |||||||+ IREFSTEN=1 (?)
; ||||||+- IRCLKEN=1 (?)
; |||||+-- IREFS=1 (Int.ref.ck select)
; ||+++--- RDIV=128 (invalid for IREFS)
; ++------ CLKS=00 (FLL out selected)
; MOV #$00,ICSC2 ; BDIV=0, rest by default
; set ICSout to 2MHz, BusClock = 1MHz
; Int.REF.clk.Selected (31.25-39kHz, 31.25kHz default)
; DCOout= 512*IREF= 512*31.25kHz= 16.00MHz (default)
; BDIV= 8, ICSout= DCOout/BDIV= 2MHz, BusClock= 1MHz
MOV #%00000100,ICSC1
; |||||||+-- IREFSTEN=0 (default)
; ||||||+--- IRCLKEN=0 (default)
; |||||+---- IREFS=1 (Int.ref.ck select)
; ||+++----- RDIV=1 (RDIV_CLK=IREFCLK)
; ++-------- CLKS=00 (FLL out selected)
MOV #%11000000,ICSC2
; ++-------- BDIV=0, rest by default
LDX #%11110110 ; $F6
STX PTAPE ;ENABLE PULL UP RES. ON A
;no pull-up on PA0 & PA3
MOV #$FF,PTBDD ;DDReg B (all out)
MOV #$09,PTADD ;DDReg A (PA0 & PA3 as out)
LOOP MOV #$09,PTAD ;PA0 & PA3 = 1
JSR TIMER ;TIME DELAY
; This line makes only a pulse on A, few clk cycle
; long (11 clk with watchdog serve, i.e. ~11us)
MOV #$00,PTAD ;PA0 & PA3 = 0
; Watchdog serving (Watchdog is preset!)
feed_watchdog ; call Wdog macro
BRA LOOP
;*****************************************************
; ROUTINES
;*****************************************************
; Timer clock= BusClock, Prescaler= 64
; i.e. Tclk= 15625Hz, Modulo counter by 155
; Fo= roughly 100Hz
TIMER MOV #%00000110,MTIMCLK ; =$06 (presc.=64)
MOV #$9A,MTIMMOD ; =154dec
; TOIE set, TRST set (counter reset i.e. disabled)
; CANNOT FUNCTION BECAUSE INTERRUPT IS NOT SERVED
; NOR THE COUNTER IS STARTED!
; MOV #%01100000,MTIMSC ; =$60;TSCR1
; START COUNTER FREE-RUNNING, NO INTERRUPT
MOV #%00000000,MTIMSC ; TOIE=0, TRST=0
TT BRCLR 7,MTIMSC,TT ;WAIT FOR TOF
BSET 7,MTIMSC ;CLEAR TOF
RTS
Sorry by the horrendous format due to the forum editor. The enclosed zipped project file comprised a .rtf copy correctly formatted in addition to the .asm in the source files directory.
Good luck
Salvatore
Thank you very much for the guidance Mr. Cosentino. Unfortunately I am still unable to get a response from my micro-controller when I use your code, or revisions to it. Code Warrior appears to program the target flash correctly. All I want to do is light an LED with the minimal connections in the schematic of my attachment, and then go from there. I made all unused parallel ports high because that is what the datasheet recommends. In reference to your code above, is there a minimum Bus Clock, and how could I program it? I'm not sure if the instructions in your last sentence are mandatory. I don't require that much precision so I hope I can leave well enough alone. I will keep trying. Thanks again.
- Wolfgang
Hello Wolfgang,
Now your task is clearer.
My original code worked but is not suited for your task: in fact, due to the high rate clock (BusClok was set to 1MHz) it produces a very small (11us) logic low pulse on PTA0 which repeats at 200Hz rate. You cannot appreciate it on a LED: it will appear you as it is always on! Nevertheless you could see it on an oscilloscope.
There were at least two conceptual errors on my code which did not impede it to work:
These errors were fixed in a rev 03 of the code but there is no visible effect on the result (old code worked well anyway)
Based on your task I edited a rev_04 version in which I used 31,25kHz Internal reference clock instead of 16MHz DCO to produce a 16525Hz BusClock, much better than the original 1MHz in the previous version to generate a visible 1Hz output on PTA0. Now the clock generator functions in FBI instead of FEI mode and the timer produces a perfect square wave output 50% duty you can easily see on your LED, at 1Hz pace. Watchdod was disabled because difficult to serve with this very low clock.
The code was cleared of surplus lines and comments and ordered in a clearer way. A new CW6.3 project was generated you can use to directly burn your 9S08QG8. In the "History section" is still present ver_02 and ver_03 for reference purpose if you want ot study them and their difference. Main code is this now this:
; 9S08QG8 ASM FRAMEWORK EXAMPLE BASED ON CW 6.3
; EDITED BY SALVATORE COSENTINO, 2013-04-12
; File 9S08QG8 main 04.asm
;*****************************************************
; This stationery serves as the framework for a user
; application, as suggested by CODEWARRIOR 6.3
; In this example a LED connected to PTA0 is turned
; ON/OFF at 1Hz rate
;*****************************************************
; Include derivative-specific definitions
INCLUDE 'derivative.inc'
; export symbols to be refer. in the linker .prm file
XDEF _Startup, main
XREF __SEG_END_SSTACK
; symbol defined by the linker for the end of the stack
; variable/data section
MY_ZEROPAGE: SECTION SHORT
; no variables defined
; Code section
MyCode: SECTION
_Startup:
main: LDHX #__SEG_END_SSTACK ; init stack pointer
TXS
CLI ; enable interrupts
; Disable COP, enable BKGD mode, Stop mode and Reset
LDA #%01110011
; |||||||+-- SRTPE=1 (Reset enabled)
; ||||||+--- BKGDPE=1 (Backgnd enabled)
; |||+++---- reserved
; ||+------- STOPE=1 (Stop mode enabled)
; |+-------- COPT=1 (Long time-out)
; +--------- COPE=0 (COP disabled)
STA SOPT1
; BusClock initialization
; Preset IREFCLK as 31.25kHz clk source, FBI mode
; BDIV= 1, ICSout= 31.25kHz, BusClock= 15625Hz
MOV #%01000100,ICSC1
; |||||||+-- IREFSTEN=0 (default)
; ||||||+--- IRCLKEN=0 (default)
; |||||+---- IREFS=1 (Int.ref.ck select)
; ||+++----- RDIV=1 (RDIV_CLK=IREFCLK)
; ++-------- CLKS=01 (FBI mode selected)
MOV #%11000000,ICSC2
; ++-------- BDIV=0, rest by default
; I/O initialization
LDX #%11110110
STX PTAPE ; ENABLE PULL UP RES. ON A
; no pull-up on PA0 & PA3
MOV #$FF,PTBDD ; DDReg B (all out)
MOV #$09,PTADD ; DDReg A (PA0 & PA3 as out)
; Timer initialization
; Timer clock= IREFCLK, Prescaler= 64
; i.e. Tclk= 31250/64= 488.2Hz
; Modulo counter by 244, Fo= roughly 2Hz (500ms cycle)
MOV #%00000110,MTIMCLK ; prescaler= 64
MOV #244-1,MTIMMOD ; 244 modulo counter
; Start timer as free running counter, no interrupt
MOV #%00000000,MTIMSC ; TOIE=0, TRST=0
; Main loop
LOOP JSR TIMER ;TIME DELAY
; Inverts logical level on PA0 to turn on/off a LED
LDA PTAD
EOR #%00000001
STA PTAD
; Watchdog serving (Watchdog is expressly disabled)
; feed_watchdog ; call Wdog macro
BRA LOOP
;*****************************************************
; ROUTINES
;*****************************************************
TIMER BRCLR 7,MTIMSC,TIMER ;WAIT FOR TOF
BCLR 7,MTIMSC ;CLEAR TOF
RTS
Let me know if now this works for you!
By by,
Salvatore
This code works great except the period viewed from the LED is 16 seconds (8 seconds on, and 8 seconds off). The LED is the only visual aid at my disposal because I do not have an an oscilloscope. When I made the pre-scale 2, while leaving the rest of the code original, the frequency on the LED became 2Hz. For some reason, the exclusive OR instruction did not produce a blinking LED, but a different combination of instructions did. May I ask where you learned to program on this MCU? I would like to get my hands on the material, such as a book. I am usually a big fan of the datasheets, but it seems that there are additional underlying mechanisms that go unmentioned. Thank you for your time.
Sincerely,
- Wolfgang
Hi Wolfgang,
Sorry for the possible mistakes: I did not tested the code on a real hardware but only on Codewarrior's chip emulator and I was sure the code worked (I saw PTA0 to change state in sequence) but I cannot test any frequency, only bus cycles. Setting clock and timer frequencies is always prone to small (or big!) errors and it is the first thing I would test on the real hardware. I am sure you can refine the code, add and test new instructions.
Answering to your question is twofold, the first answer is simple the second more complex:
My engagement with 8-bit microprocessors and uCU is from long ago and started in the late 1976 when I bought the first “low cost” demoboard with an 8-bit processor on it commercially available: it was the Kim1 with a 6502 processor, 1kB ram, 2kB rom. It was a grandfather of actual Freescale 8-bit processors with the same Von Neuman architecture, still very different from Intel like processors (Harvard) or PICs (RISC).
For many years I worked on small tasks on this processor family which also equipped one of the first widespread computer, the Commodore 64. In the late 90ties I began working with the Motorola HC705 processor family which was the most similar to the old 6502 which has became obsolete in the mean time. Now they are some 15 years I work with them on ever more complex projects which are controllers for medium complexity electronic equipment (FM Radio Broadcast transmitters or likewise) or boards.
Passing from 6502 to 68HC705B16 assembler was quite a simple job once understood the different registry organization, addressing and the new peripherals. Perhaps more difficult it was to pass from the Motorola 8-bit assembler of that time to the CodeWarrior 3.1 firstly available to me when I passed to a 68HC08QB4, 8 or 10 years ago: the project framework and the assembler instructions were rather different. The same happened with newer versions of CW up to 6.3 which are expressly aided to C language more than assembler: only recently I did the effort to understand how a project started in 6.3 style is arranged and, even now, most of the files present other than .asm, .prm and derivative are still a black hole. Nevertheless most of the job is to write the asm file and this I can do quite well. I am not still ready to pass to CW10.1 but I will be forced to in the near future: my 9S08PT tower system calls me to this task since nearly 1 year just now!
For this reason and my long experience which improved with the years even if I am not really a software designer, it may be difficult to recommend you how to begin working with uCUs. I started with manuals which accompanied the KIM 1 at the time, then with those related to 68HC705 processors and only lately with the newer 9S08. Strange enough once there were “General Manuals“ which introduced to the programming art with a specific uCU family in addition to the specific data sheet Manuals. Now the latter are extremely big, 2-300 pages for the smaller 8-bit mCU, are countless and become more and more complex but the “General Manuals“ have became unavailable, at least directly from Freescale.
The only one I now of and I bought by itselfs is Fabio Pereira's HCS08 Unleashed: it cost some 20-25$ some years ago and is full of examples and small programs under CodeWarrior 6.0 IDE: it is very fine but unfortunately is essentially aided for C language (not my case). I do not know anything similar aided to modern assembler for the same processors!
One very fine assembler manual is “Understanding Small Microcontrollers” by James M. Sibigtroth: it was enclosed in old 68HC705B16 demo board kits and other kits of the same family. Some reduced/adapted version were edited for other specific microcontrollers of the family like 68HC705J1A or -705C. You may find the original one either new or used, starting from slightly more than 5$ on Amazon. I strongly recommend it: it takes you by hand in the development of a thermostat controller for a boiler or a domestic heating system. While it is written for the HC705 family which uses a older reduced instruction set of the newer HC08 and 9S08, it is pretty compatible and adaptable to the newer series and the examples are extraordinary well done. The so called “Paced loop” explained there has become a standard in my own programs. A reduced version without most examples and without the thermostat controller is freely available from Freescale under the name “M68HC05TB rev.2 - Understanding small microcontrollers.pdf” and you may download it here:
http://cache.freescale.com/files/microcontrollers/doc/ref_manual/M68HC05TB.pdf?fsrch=1&sr=1
Other than this, unfortunately nearly 20 years old now and nor really aided to the 9S08 family, I suggest you read as much as possible program examples like those you may find in many Freescale Application Notes or written by experienced people.
Good work,
Salvatore
I should add that I am not sure what clock is being used internally for FEI, or it's speed. And that is important. I used all the different pre-scalers to comply with the 31-39kHz range, but to no avail.