I have this simply blinky.c
code for AVR
microcontrollers. It compiles and run no problem. But Intellisense in my vscode is going kinda crazy
#define F_CPU 16000000UL
#define LED_PIN 0
#include <avr/io.h>
#include <util/delay.h>
void main()
{
DDRB |= (1 << LED_PIN);
while(1)
{
PORTB ^= (1 << LED_PIN);
_delay_ms(500);
}
}
First I edited the json
to add the needed paths:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/avr/include",
"/usr/avr/include/avr"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "gcc-x86",
"compilerArgs": [
"-Wall "
]
}
],
"version": 4
}
And it sees the functions etc, all but DDRB
and PORTB
:
But when I go to "Go to definition" it even lets me see it. So how come it gives me this IntelliSense error?
To be clear Im on Linux right now (Manjaro). I have installed all the needed libs for avr
s thru pamac
and they work.
Okay, I found a solution. It is caused by the internals of the avr/io.h
files. It includes a certain file with definitions based on #define
of a given microcontroller in the source code. So when I do not specify the controller it won't #include
it in io.h
therefor it is not visible to IntelliSense, but compilation can see it because I specify it. So in order to make io.h
include definitions we need. We have to tell it which controller we will be using. Like that:
#define __AVR_ATmega328P__
So that now my code looks like this:
#define F_CPU 16000000UL
#define LED_PIN 0
#define __AVR_ATmega328P__
#include <avr/io.h>
#include <util/delay.h>
void main()
{
DDRB |= (1 << LED_PIN);
while(1)
{
PORTB ^= (1 << LED_PIN);
_delay_ms(500);
}
}
You can clearly see it when you look up the io.h
file:
#if defined (__AVR_AT94K__)
# include <avr/ioat94k.h>
#elif defined (__AVR_AT43USB320__)
# include <avr/io43u32x.h>
#elif defined (__AVR_AT43USB355__)
# include <avr/io43u35x.h>
#elif defined (__AVR_AT76C711__)
# include <avr/io76c711.h>
#elif defined (__AVR_AT86RF401__)
# include <avr/io86r401.h>
#elif defined (__AVR_AT90PWM1__)
# include <avr/io90pwm1.h>
...
It's basically 500 lines of checking for which controller we are using. If you go to this file and with ctrl+f
or something like that you can easily find how your controller is defined there and include it. This solves the problem because the DDRB
and PORTB
are now defined thanks to resolved pre-processor statements.