Stuck with basic programming of STM32L-Discovery - stm32l152

I've got a STM32L-Discovery Board, which has got a STM32L152R8 microprocessor. I'm quite stuck trying to make basic things work.
I've looked the examples given by ST (the current consumption touch sensor and the temperature sensor), and I think they aren't user-friendly, with so many libraries, sub-processes and interrupts, that make the code really difficult to understand.
I've tried to turn on the blue LED (GPIO PB6), but I can't manage to do that.
My code compiles correctly but does nothing to the board. This is the code of "main.c".
RCC->AHBRSTR = 0x00000002;
RCC->AHBRSTR = 0x00000000;
RCC->AHBENR = 0x00000002;
GPIOB->MODER = 0x00001000;
GPIOB->OTYPER = 0x00000040;
GPIOB->OSPEEDR = 0x00001000;
GPIOB->PUPDR = 0x00000000;
GPIOB->ODR = 0x00000040;
while(1) {}
Am I missing something? Could I find really basic examples somewhere?
Thanks in advance!

The standard peripheral library that ST supplies on their website is a good starting point. It has examples on programming a GPIO. Note that their code is absolutely horrible, but at least it works and is something to start with.
What compiler/debugger are you using? If you are using IAR, then you can view the GPIO registers while stepping thru the code. Please post the values of the GPIO registers to your question and maybe we can help.

RCC->AHBENR = 0x00000002;
Change to "RCC->AHBENR |= 0x00000002;"
This will ensure you enable GPIOB without disabling everything else. The existing code will disabled important things like the flash memory controller and all the other GPIOs.
GPIOB->MODER = 0x00001000;
// This will set pin 6 as output, and all other pins as input. Was this your intent?
Change to "GPIOB->MODER = (GPIOB->MODER & 0xFFFFDFFF ) | 0x00001000;"
This will set pin 6 as an output without changing the configuration of any other pins.
GPIOB->OTYPER = 0x00000040;
// This will set the output type as open drain, meaning you can only pull the line down.
Change to "GPIOB->OTYPER |= 0x00000040;"
Set output as push-pull instead of open drain. You later code attempts to set this line high which will not work as an open drain output will pull to ground or allow the line to float. A push-pull output will allow you to set the line high or low.

Related

AVR setting output repeatedly toggles the pin

I'm writing a firmware for an ATMega328 and facing some issues. After searching in my logic for hours I could boil the code down to the most basic example and still have the problem.
I'm setting a pin to the value of a variable. Because I don't want to store to copies of a big array I'm setting the pin to the same value over and over again and if the variable changes, the pin gets set to a different state.
int main() {
DDRB |= _BV(PB2);
while (1) {
PINB |= _BV(PB2);
_delay_ms(50);
}
return 0;
}
The problem is that with this code the pin toggles on and off every 50ms.
I could think of restructuring my code so I can detect change of the mentioned variable without the need of a copy.
But in the end I don't understand the problem, because I'm setting a bit of the output port to the same value over and over again.
PINB is input register (output register is PORTB).
And yes, writing 1 to input register PINx toggle bit in corresponding output register PORTx and pin value in modern (almost all for now) AVRs.

how to set fpga attribute?

i am trying to turn a led on and off by fpga but IO properties of reg(s) is set to 'OFF' which is output flip flop!
My question is that how can I set IO register to NO in ISE?
I have tried this :
inst "led_error" IOB = false;
but nothing changed.
thanks in advance.
There is a routing options to push FFs into the pads which you can switch on or off. (In ISE it is a stand alone placement option, I have not found it in Vivado yet.)
BUT!!!!
In a previous question you mentioned that two of your the I/Os (which happen to have the 'OFF' attribute) don't work. The OFF is unlikely to be the source of that problem. All what he routing tool did was take an existing internal FF and move it into the pad to improve I/O timing.
I suggest you start looking elsewhere why your output does not work. e.g. check the clock which goes to the FFs which drive the outputs.
I re-awakened my old ISE program and as expected found it under the map settings (Right click on "Map" and select "Process Properties..."):

gcc-avr ATmega16/32 Programming

I have just entered into AVR MCU programming using gcc-avr, but when I see sample programs I am not able to make out much from the code:
DDRD |= (1 << PD7);
TCCR2 = (1 << WGM21) | (0 << WGM20);
TCCR2 |= (1 << COM20);
TCCR2 |= (6 << CS20);
I do not see also any declarations variables : DDRD, PD7, TCCR2, WGM21, WGM20, COM20, CS20, but they are directly used. Please let me know how I can know all pre-defined variables and its usage? It becomes very difficult in understanding the code without knowing the same.
Thanks in advance.
That kind of code is very common when programming embedded systems, although you will need to look at the header files and the AVR documentation to learn what those specific identifiers mean. Be aware that it can be very complex if you're new to this, and you will need to understand how to work with raw binary and C-style bit shifts/operators. (There are lots of tutorials online if you need to learn more about that.)
I'll try to explain the basic principle though.
All of the identifiers you saw will be preprocessor constants (i.e. #define ...), rather than variables. DDRD and TCCR2 will specify memory locations. These locations will be mapped onto certain functionality, so that setting or clearing certain bits at those locations will change the behaviour of the device (e.g. enable a clock divider, or set a GPIO pin high or low, etc.).
PD7, WGM21, WGM20, COM20, and CS20 will all be fairly small numbers. They specify how far you need to offset certain bit patterns to achieve certain results. Bit-wise operators (such as | and &) and bit-shift operators (typically <<) are used to create the patterns which are written to the memory locations. The documentation will tell you what patterns to use.
I'll use a simple fictional example to illustrate this. Let's say there is a register which controls the value of some output pins. We'll call the register OUTPUT1. Typically, each bit will correspond to the value of a specific pin. Turning on pin 4 (but leaving the other pins alone) might look like this:
OUTPUT1 |= (1 << PIN4);
This bitwise OR's the existing register with the pattern to turn pin 4 on. Turning that pin off again might look like this:
OUTPUT1 &= ~(1 << PIN4);
This bitwise AND's the existing register with everything except the pattern to turn pin 4 on (which results in clearing the bit). That's an entirely fictional example though, so don't actually try it!
The principle is basically the same for many different systems, so once you've learned it on AVR, you will hopefully be able to adapt to other devices as well.

PIC16F88, portb.bit6, and I2C

I am having an odd problem with my PIC16F88. I have an EEPROM connected thru I2C and it works flawlessly until I write to portb.bit6. From that point on, I start getting garbage from my EEPROM. I tried explicitly disabling Timer 1, which uses portb.6 for oscillator-out but that did not help. I tried cutting the trace from the PIC pin (pin 12) so that there is nothing physically connected to it and that did not help. My C code is simple, either portb.6 = 0 or portb.6 = 1. Either way, reading the EEPROM thru I2C fails forever more. The generated ASM code looks fine. The problem occurs on every board that I have tried it on, so it is not localized to one PCB. I am mystified. Any suggestions?
It turns out that it is necessary to write a zero bit to the SCL and SDA pins every time before writing to any bit in portb. FWIW, I was bit-banging rather than using the SSP peripheral of the PIC16F88 for the I2C communicaitons. Thanks to the people on the Yahoo group, Electronics_101, for figuring out this puzzle.

Is it possible to save some data parmanently in AVR Microcontroller?

Well, the question says it all.
What I would like to do is that, every time I power up the micro-controller, it should take some data from the saved data and use it. It should not use any external flash chip.
If possible, please give some code-snippet so that I can use them in AVR studio 4. for example if I save 8 uint16_t data it should load those data into an array of uint16_t.
You have to burn the data to the program memory of the chip if you don't need to update them programmatically, or if you want read-write support, you should use the built-in EPROM.
Pgmem example:
#include <avr/pgmspace.h>
PROGMEM uint16_t data[] = { 0, 1, 2, 3 };
int main()
{
uint16_t x = pgm_read_word_near(data + 1); // access 2nd element
}
You need to get the datasheet for the part you are using. Microcontrollers like these typically contain at least a flash and sometimes multiple banks of flash to allow for different bootloaders while making it easy to erase one whole flash without affecting another. Likewise some have eeprom. This is all internal, not external. Esp since you say you need to save programatically this should work (remember how easy it is to wear out a flash do dont save unless you need to). Either eeprom or flash will meet the requirement of having that information there when you power up, non-volatile. As well as being able to save it programmatically. Googling will find a number of examples on how to do this, in addition to the datasheet you apparently have not read, as well as the app notes that also contain this information (that you should have read). If you are looking for some sort of one time programmable fuse blowing thing, there may be OTP versions of the avr, and you will have to read the datasheets, programmers references and app notes on how to program that memory, and should tell you if OTP parts can be written programmatically or if they are treated differently.
The reading of the data is in the memory map in the datasheet, write code to read those adresses. Writing is described in the datasheet (programmers reference manual, users guide, whatever atmel calls it) as well and there are many examples on the net.

Resources