The most immediate problem I can see is the following line of code:
#include " 16F877A.h "
You should remove the spaces because it's trying to open a file that contains spaces which is why you're getting multiple errors related to that file. While in general extra whitespace doesn't matter a lot in C / C++ code for any literals enclosed in quotes it certainly does.
Another area where you shouldn't insert extra spaces is also between operators such as ==
so the space between those two characters should be removed from line 10 as well so it should look like this:
if(x == 1) output_high(PIN_D0); // Change output
I figured out how to assemble without error messages.
The error messages you see are caused by the fact that avr-as
does not invoke the C-preprocessor and therefore the #include
lines are read as regular comments.
Create a file ledON.S
and notice the CAPITAL S
in the filename. The capital S
indicates that the C-preprocessor must be invoked first. Create the file with the following content:
#include <avr/io.h>
init: sbi _SFR_IO_ADDR(DDRB),0x05 ; Configure port B pin 5 as output
ret
.global main
main:
call init
loop:
sbi _SFR_IO_ADDR(PORTB),0x05 ; Toggle output pin HIGH
cbi _SFR_IO_ADDR(PORTB),0x05 ; Toggle output pin LOW
rjmp loop
The main
part is required in the source code, this is where usually the main program is located. If you remove it, no real code is executed ever and thus the compiler will complain about that. Code in a routine called init
should be explicitly called from main
. Although the pin toggles, in practice this will be too fast to see with the bare eye. If you check with an oscilloscope you'll see a square wave (I estimate at 25% duty cycle).
Then assemble the source code with:
avr-gcc -mmcu=atmega168a ledON.S -o ledON.o
Again avr-gcc
is required to invoke the C-preprocessor.
To check the result of the assembled program run the following command:
avr-objdump -C -d ./ledON.o
And the resulting disassembly listing looks like this:
./ledON.o: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 34 00 jmp 0x68 ; 0x68 <__ctors_end>
4: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
8: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
10: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
14: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
18: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
1c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
20: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
24: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
28: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
2c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
30: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
34: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
38: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
3c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
40: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
44: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
48: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
4c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
50: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
54: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
58: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
5c: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
60: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
64: 0c 94 3e 00 jmp 0x7c ; 0x7c <__bad_interrupt>
00000068 <__ctors_end>:
68: 11 24 eor r1, r1
6a: 1f be out 0x3f, r1 ; 63
6c: cf ef ldi r28, 0xFF ; 255
6e: d4 e0 ldi r29, 0x04 ; 4
70: de bf out 0x3e, r29 ; 62
72: cd bf out 0x3d, r28 ; 61
74: 0e 94 42 00 call 0x84 ; 0x84 <main>
78: 0c 94 47 00 jmp 0x8e ; 0x8e <_exit>
0000007c <__bad_interrupt>:
7c: 0c 94 00 00 jmp 0 ; 0x0 <__vectors>
00000080 <init>:
80: 25 9a sbi 0x04, 5 ; 4
82: 08 95 ret
00000084 <main>:
84: 0e 94 40 00 call 0x80 ; 0x80 <init>
00000088 <loop>:
88: 2d 9a sbi 0x05, 5 ; 5
8a: 2d 98 cbi 0x05, 5 ; 5
8c: fd cf rjmp .-6 ; 0x88 <loop>
0000008e <_exit>:
8e: f8 94 cli
00000090 <__stop_program>:
90: ff cf rjmp .-2 ; 0x90 <__stop_program>
INTERMEZZO
You'll notice the assembler will automatically initialize the stack pointer
and status register in __ctors_end
.
Also it will automatically add a rjmp
at the end of the code.
Default behaviour of a program assembled by gcc-avr when it ends is:
- turn off interrupts (
_exit
, cli
)
- infinite empty loop that does nothing (
__stop_program
, rjmp .-2
)
Best Answer
In order to port to MSP430, you'll need to modify the makefile to point to the CCS compiler. You'll need to provide the right command line options. You'll also need to hook in your hardware through whatever HAL layers the library provides.
As the project already assumes GCC, you might find porting easier using msp430-gcc.
It sounds as though you are trying to compile lwBT for your PC using MingW and failing. Does your C compiler actually work? Try compiling a "hello world" program.
Look at the Makefile, what commands is it actually running? Remove any '@' characters before lines that execute commands, so you can see what's going on under the hood.