|
|
View previous topic :: View next topic |
Author |
Message |
TOPFUEL Guest
|
Including ASM code in a C program |
Posted: Thu Sep 01, 2005 9:40 am |
|
|
I am new to using C with Assembly code.
I have a keypad scanning routine and a LCD updating routine that are written in Assembly. I want to use them in a new C project. I have used the #ASM and #ENDASM directives and have been able to include very simple blocks of assembly code. However when I use my entire function I get tons of errors.
How do you handle assembly calls and gotos. Also how do I handle lookup tables that are in assembly?
My code is below, It compiled before I added the ASM code.
Any help or tutorials would be greatly appriciated.
Chris
#include <16F873A.h>
//Clock II
//This is a multi purpose clock project that will display time. It can also be used as a Pit clock and a multi purpose timer.
//Rev 1.0
#fuses XT,NOWDT,NOPROTECT,NOLVP,
int Thousanths;
int Hundredths;
int Tenths;
int Seconds;
int Minutes,TEN_SEC,temp;
int Tenth_Hours;
int Hours;
int Timer0_Overflow(void);
void Scan_Keypad(int);
void Update_LCD(int);
int keycode,count;
Main()
{
//Setup ports and periphials.
SETUP_TIMER_0 (RTCC_DIV_16|RTCC_INTERNAL);
//enable interrupt from timer 0
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
here:
// keypad scanning routine
// Update LCD
goto here;
return(0);
}
Update_LCD()
{
#asm
movf Hundredths,w // get hundredths value
call DecodeValue // decode the value
call ten_set // is ten set?
btfsc TEN_SEC
iorlw 0x80 // set other digit of the number ten
call Send8 // serially output the seg values
movf Tenths,w // get 2nd significant digit
call DecodeValue // decode it
btfsc TEN_SEC // is ten set?
iorlw 0x80 // set other digit of the number ten
call Send8 // serially output it
movlw 0x0 // get 3rd significant digit
call DecodeValue // decode it
iorlw 0x80 // set dp on
call Send8
movlw 0x0 // get Most significant value
call DecodeValue // decode it
call Send8 // serially send it
bcf LOAD // toggle the LOAD line
bsf LOAD // to enable the latches
nop
nop
bcf LOAD // toggle the LOAD line
return
#endasm
}
#asm
org 0x6
DecodeValue:
addwf PCL,F
retlw B'00111111' //decode for 0
retlw B'00000110' //decode for 1
retlw B'01011011' //decode for 2
retlw B'01001111' //decode for 3
retlw B'01100110' //decode for 4
retlw B'01101101' //decode for 5
retlw B'01111101' //decode for 6
retlw B'00000111' //decode for 7
retlw B'01111111' //decode for 8
retlw B'01101111' //decode for 9
retlw B'01110111' //decode for a
retlw B'01111100' //decode for b
retlw B'00111001' //decode for c
retlw B'01011110' //decode for d
retlw B'01111001' //decode for e
retlw B'01110001' //decode for f
ten_set:
movwf temp // save w
movf sec,w // get value of sec
addlw 0xF6 // is sec greater than 9
btfss STATUS, C
goto clear_ten
bsf TEN_SEC // if sec > 9 then set TEN_SEC flag
movf temp, w
return
clear_ten:
bcf TEN_SEC // if sec <= 9 then clear TEN_SEC flag
movf temp, w
return
#endasm
//Interrupt Timer0 function:
#INT_TIMER0 //This occurs every 0.001 seconds
Timer0_Overflow()
{
Thousanths++;
if(Thousanths == 10)
Thousanths = 0;
else
return(0);
Hundredths++;
if(Hundredths == 10)
Hundredths = 0;
else
return(0);
Tenths++;
if(Tenths == 10)
Tenths = 0;
else
return(0);
Seconds++;
if(Seconds == 60)
Seconds = 0;
else
return(0);
Minutes++;
if(Minutes == 60)
Minutes = 0;
else
return(0);
Hours++;
if(Hours == 13)
Hours = 1;
else
return(0);
} |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Thu Sep 01, 2005 10:17 am |
|
|
The whole point of using a c compiler is that you don't have to use assembly. Including asm routines for a keypad and lcd inside c simply because you're too lazy to search for pre-written routines is like hitching up a team of horses to pull a new Ferrari around because you want to get your money's worth out of the horses.
Use the search feature. There are literally tons of examples posted here regarding lcds and keypads. The compiler also ships with examples of how to talk to lcds, keypads, you name it. Look around. |
|
|
Ttelmah Guest
|
|
Posted: Thu Sep 01, 2005 10:26 am |
|
|
There are a lot of potential problems here. It really would be easier just to do it in C!...
The first problem, is that your return table is assuming it is in the same bank as the 'DecodeValue' call, and not therefore controlling the bank registers. This is not necessarily true. You are then locating this code at address 6, which is bang in the middle of the global interrupt handler. As a general comment, interrupt handlers _cannot_ 'return' values. Just use the 'return statement without a value, not 'return(0)'. Though the compiler should fix this, it is asking for problems.
As an example, the C equivalent for the 'DecodeValue' call, and the first few lines is just:
Code: |
const int8 DecodeValue[] = {
0b00111111, //decode for 0
0b00000110, //decode for 1
0b01011011, //decode for 2
0b01001111, //decode for 3
0b01100110, //decode for 4
0b01101101, //decode for 5
0b01111101, //decode for 6
0b00000111, //decode for 7
0b01111111, //decode for 8
01101111, //decode for 9
01110111, //decode for a
01111100, //decode for b
00111001, //decode for c
01011110, //decode for d
01111001, //decode for e
01110001 //decode for f
};
void Update_LCD(void) {
temp t;
t=DecodeValue[Hundredths];
if (t>=10)
t|=0x80;
Send8(t);
//You don't show the code for 'Send8', so stopping here.
}
|
Seriously, this is a C, not an assembler. Treat the assembler, as something that should only be used for a few very minor occasions, where there is a fault in the C, or a specific instruction tha cannot be accessed by the C. In the past there was more need of this than is now the case. Using the assembler requires you to understand the C first, and especially where it is going to place code.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|