Programming The PSoC With 8051 Assembly Instructions
Programming The PSoC With 8051 Assembly Instructions
Introduction
Cypress PSoC (Programmable System on Chip) is a microcontroller with internal peripherals
(timers, PWM generators, DACs, etc.) as well as configurable digital blocks. Its design
environment PSoC Creator is free software that provides you with a space to link your C code
and your configurations of the digital peripherals, GPIO pins, clocking resources, etc. See the
powerpoint Introduction to PSoC Creator for more information on getting started with Creator.
In this document, you will learn how to include 8051 assembly routines in your C code for a
PSoC 3 device (8051 core). This is useful if:
a)
b)
c)
d)
You have assembly code already written that you wish to use
You need to improve the speed of a particular function
You want to manipulate SFRs or memory-mapped I/O devices directly from assembly
You are a 6.115 student studying 8051 assembly, and want to use it in the bulk of your
final project!
First, I created a new 8051 source file: Right click on Source FilesNew Item8051 Keil
Assembly File. Name the file blinky.a51 and click OK.
Here is an assembly function written in Creator. Several A51 assembler statements are needed
and are included with comments indicating the function of each non-familiar line:
$NOMOD51
$INCLUDE (PSoC3_8051.inc)
;
;
;
;
;
;
;
;
;
;
RSEG _COOL
PUBLIC _inc_count
_inc_count:
; Your assembly function here.
mov A, R7
CPL A
mov R0, #40h
loop_back0:
mov R1, #0FFh
loop_back1:
mov R2, #0FFh
loop_back2:
djnz R2, loop_back2
djnz R1, loop_back1
djnz R0, loop_back0
mov R7, A
ret
END
By linking this internal pin to a physical pin on the chip, we can send our PWM signal to the pin
attached to the LED on the kit. We can vary the duty cycle of this blinking as usualby
changing the values of the registers R0-R2 in the above code.
In the main.c source file, you should use your assembly function inc_count. You can pull up the
Pins datasheet for the component APIs. There you will find the Pin_Write(x) function to write a
value directly to an output pin.
#include <device.h>
{
uint8 count = 0;
while(1)
{
count = inc_count(count);
LED_Write(count);
}
}
The last thing we need to do is include a prototype of our function in the device.h header file.
Open this file and add your routine prototype:
#ifndef DEVICE_H
#define DEVICE_H
#include <project.h>
uint8 inc_count(uint8 count);
/* inc_count prototype */
#endif
SEGMENT DATA
RSEG ?DT?MAIN
bob: DS 2
jim: DS 1
; unsigned int bob;
; unsigned char jim;
To access these variables in assembler, you must create an extern declaration that matches the
original declaration. For example:
EXTERN DATA(jim)
If you use in-line assembler, you may simply use C extern variable declarations to generate the
assembler EXTERN declarations.
You may access global variables in assembler using their label names. For example:
MOV A, jim
Note:
Type information is not transmitted to your assembler routines. Assembly code must explicitly
know the type of the global variable and the order in which it is stored.
The EXTERN definitions for a C external variable are generated only if the variable is
referenced by the C code in the module. If an external variable is only referenced by in-line
assembly code, you must declare them in in-line assembly code within that module.
Passing in Registers
C functions may pass parameters in registers and fixed memory locations. A maximum of 3
parameters may be passed in registers. All other parameters are passed using fixed memory
locations. The following tables define which registers are used for passing parameters.
char,
int,
Arg Number 1-byte ptr 2-byte ptr
R7
R6 & R7
(MSB in R6,LSB
in R7)
R4R7
R1R3
(Mem type in R3, MSB in
R2, LSB in R1)
R5
R4 & R5
(MSB in R4,LSB
in R5)
R4R7
R1R3
(Mem type in R3, MSB in
R2, LSB in R1)
R3
R2 & R3
(MSB in R2,LSB
in R3)
R1R3
(Mem type in R3, MSB in
R2, LSB in R1)
The following examples clarify how registers are selected for parameter passing.
Declaration Description
func1 (
int a)
func2 (
int b,
int c,
int *d)
func3 (
long e,
long f)
The first argument, e, is passed in registers R4, R5, R6, and R7. The
second argument, f, cannot be located in registers since those
available for a second parameter with a type of long are already used
by the first argument. This parameter is passed using fixed memory
locations.
func4 (
float g,
char h)
The first argument, g, passed in registers R4, R5, R6, and R7. The
second parameter, h, cannot be passed in registers and is passed in
fixed memory locations.
Register Usage
Assembler functions may change all register contents in the currently selected register bank as
well as the contents of the ACC, B, DPTR, and PSW registers.
When invoking a C function from assembly, assume that these registers are destroyed by the C
function that is called.