Here is a "simplified blinky" example from MikroC meant to toggle the user LED at a rate that is visible to the naked eye:
void main()
{
GPIO_Clk_Enable(&GPIOA_BASE);
GPIO_Digital_Output(&GPIOA_BASE, _GPIO_PINMASK_5);
GPIOA_ODR |= (1<<_GPIO_PIN_5);
while(1)
{
GPIOA_ODR ^= (1<<_GPIO_PIN_5);
Delay_ms(300);
}
}
The expected result of this code is that the port A5 pin (LED) will toggle at a 300ms rate. The microcontroller part is an STM32L476RG on a NUCLEO board.
The actual result is still -- nothing at all. No blinking.
I have tested the board by loading the hex file from an identical board onto it, restoring the "factory" blinking demo that responds to presses of the user button. It works. So the device is fine and the programming process is working.
I have stepped through the code in the debugger and watched GPIOA_ODR register toggle just as intended.
My Scheme, created by using the "Default" button, running the core at 4 MHZ from from the MSI internal oscillator, is as follows:
<?xml version="1.0"?>
<MCU_DEVICE_FLAGS>
<DEVICE>
<DEVICE_NAME>STM32L476RG</DEVICE_NAME>
<SETTINGS>
<COUNT>32</COUNT>
<SETTING0>
<NAME>MSI clock enable</NAME>
<DESCRIPTION>MSI oscillator ON</DESCRIPTION>
</SETTING0>
<SETTING1>
<NAME>MSI clock PLL enable</NAME>
<DESCRIPTION>MSI PLL OFF</DESCRIPTION>
</SETTING1>
<SETTING2>
<NAME>MSI clock range selection</NAME>
<DESCRIPTION>MSI Range is provided in RCC_CSR register</DESCRIPTION>
</SETTING2>
<SETTING3>
<NAME>MSI clock ranges in RCC_CR register</NAME>
<DESCRIPTION>range 6 around 4MHz</DESCRIPTION>
</SETTING3>
<SETTING4>
<NAME>HSI clock enable</NAME>
<DESCRIPTION>HSI16 oscillator OFF</DESCRIPTION>
</SETTING4>
<SETTING5>
<NAME>HSI16 always enable for peripheral kernels</NAME>
<DESCRIPTION>No effect on HSI16 oscillator</DESCRIPTION>
</SETTING5>
<SETTING6>
<NAME>HSI16 automatic start from Stop</NAME>
<DESCRIPTION>HSI16 oscillator is not enabled by hardware when exiting Stop mode with MSI as wakeup clock</DESCRIPTION>
</SETTING6>
<SETTING7>
<NAME>HSE clock enable</NAME>
<DESCRIPTION>HSE oscillator OFF</DESCRIPTION>
</SETTING7>
<SETTING8>
<NAME>HSE crystal oscillator bypass</NAME>
<DESCRIPTION>HSE crystal oscillator not bypassed</DESCRIPTION>
</SETTING8>
<SETTING9>
<NAME>Clock security system enable</NAME>
<DESCRIPTION>Clock security system OFF</DESCRIPTION>
</SETTING9>
<SETTING10>
<NAME>Main PLL enable</NAME>
<DESCRIPTION>PLL OFF</DESCRIPTION>
</SETTING10>
<SETTING11>
<NAME>SAI1 PLL enable</NAME>
<DESCRIPTION>PLLSAI1 OFF</DESCRIPTION>
</SETTING11>
<SETTING12>
<NAME>SAI2 PLL enable</NAME>
<DESCRIPTION>PLLSAI2 OFF</DESCRIPTION>
</SETTING12>
<SETTING13>
<NAME>System clock switch</NAME>
<DESCRIPTION>MSI selected as system clock</DESCRIPTION>
</SETTING13>
<SETTING14>
<NAME>Set and cleared by software to control the division factor of the AHB clock</NAME>
<DESCRIPTION>SYSCLK not divided</DESCRIPTION>
</SETTING14>
<SETTING15>
<NAME>APB low-speed prescaler (APB1)</NAME>
<DESCRIPTION>HCLK not divided </DESCRIPTION>
</SETTING15>
<SETTING16>
<NAME>APB high-speed prescaler (APB2)</NAME>
<DESCRIPTION>HCLK not divided </DESCRIPTION>
</SETTING16>
<SETTING17>
<NAME>Wakeup from Stop and CSS backup clock selection</NAME>
<DESCRIPTION>MSI oscillator selected as wakeup from stop clock and CSS backup clock</DESCRIPTION>
</SETTING17>
<SETTING18>
<NAME>Microcontroller clock output</NAME>
<DESCRIPTION>MCO output disabled, no clock on MCO</DESCRIPTION>
</SETTING18>
<SETTING19>
<NAME>Microcontroller clock output prescaler</NAME>
<DESCRIPTION>MCO is divided by 1</DESCRIPTION>
</SETTING19>
<SETTING20>
<NAME>Main PLL, PLLSAI1 and PLLSAI2 entry clock source</NAME>
<DESCRIPTION>No clock sent to PLL, PLLSAI1 and PLLSAI2</DESCRIPTION>
</SETTING20>
<SETTING21>
<NAME>Division factor for the main PLL and audio PLL (PLLSAI1 and PLLSAI2) input clock</NAME>
<DESCRIPTION>PLLM = 1</DESCRIPTION>
</SETTING21>
<SETTING22>
<NAME>Main PLL multiplication factor for VCO</NAME>
<DESCRIPTION>16</DESCRIPTION>
</SETTING22>
<SETTING23>
<NAME>Main PLL PLLSAI3CLK output enable</NAME>
<DESCRIPTION>PLLSAI3CLK output disable</DESCRIPTION>
</SETTING23>
<SETTING24>
<NAME>Main PLL division factor for PLLSAI3CLK (SAI1 and SAI2 clock)</NAME>
<DESCRIPTION>PLLP = 7</DESCRIPTION>
</SETTING24>
<SETTING25>
<NAME>Main PLL PLL48M1CLK output enable</NAME>
<DESCRIPTION>PLL48M1CLK output disable</DESCRIPTION>
</SETTING25>
<SETTING26>
<NAME>Main PLL division factor for PLL48M1CLK (48 MHz clock)</NAME>
<DESCRIPTION>PLLQ = 2</DESCRIPTION>
</SETTING26>
<SETTING27>
<NAME>Main PLL PLLCLK output enable</NAME>
<DESCRIPTION>PLLCLK output disable</DESCRIPTION>
</SETTING27>
<SETTING28>
<NAME>Main PLL division factor for PLLCLK (system clock)</NAME>
<DESCRIPTION>PLLR = 2</DESCRIPTION>
</SETTING28>
<SETTING29>
<NAME>LSI oscillator enable</NAME>
<DESCRIPTION>LSI oscillator OFF</DESCRIPTION>
</SETTING29>
<SETTING30>
<NAME>MSI range after Standby mode (RCC_CSR)</NAME>
<DESCRIPTION>Range 6 around 4 MHz (reset value)</DESCRIPTION>
</SETTING30>
<SETTING31>
<NAME>Core Voltage</NAME>
<DESCRIPTION>VCORE = 1.2 V</DESCRIPTION>
</SETTING31>
</SETTINGS>
</DEVICE>
</MCU_DEVICE_FLAGS>
Question: What is wrong with this default scheme or this simple code that prevents this from working?
N.B. I have chosen the MikroC tag even though this is an STM32 part. The definition for the MikroC tag is incorrectly specific to PIC devices.
When I contacted the vendor about this problem, they gave me a scheme file to load. I attempted to load it but it wouldn't even load. It had some spelling errors. After correcting them based on the default scheme above, the example still didn't work. They had chosen many non-default settings. My rationale is that if I'm using the default (MSI) clock and default scheme, I should at least be able to get the part to run at 4MHz and have a successful starting point for further improvements.
Finally, the configuration register values from the project configurator are as follows:
RCC_CR : $40021000 : 0x00000061
RCC_CFGR : $40021008 : 0x00000000
RCC_PLLCFGR : $4002100C : 0x00001000
RCC_CSR : $40021094 : 0x00000600
PWR_CR1 : $40007000 : 0x00000200
GPIO_Digital_Output() configures the pin as a output but it may not enable the clock to the GPIO peripheral. Try adding a call to GPIO_Clk_Enable(&GPIOC_BASE).
Related
I am new to MP programming and I am working on a project with codevision program, which requires to:
Connect potentiometer at A0.
Generate a PWM signal with an equivalent average DC voltage to the measured value of the voltage of the potentiometer.
The measured voltage from the DAC is displayed on line 1 of lcd (16*2).
Choose a suitable RC circuit to get a pure DC voltage.
Connect the generated PWM signal to the ICP1 and calculate its duty cycle and display it on line 2 off the screen.
So the screen should be like:
Pot1 = 0.000 V
Duty Cycle = ..%
I made the first line but I don't know how to implement timer1 into this requirement.
Also timer 1 has ICRH and ICRL and I am confused which of them should be used.
My knowledge of Micro-controllers is fairly limited at this point, but here goes.
I have an Led Driver PT6959 which I'm trying to interface with. Data is read serially by the Driver IC on the input CLK rising edge once the STB input line goes low.
My question is, how do I know what the input CLK frequency should be?
Does it matter? Or should it be the same as the Led Driver OSC Pin frequency?
I've read the datasheet but can't find any reference to specifying an input CLK frequency.
If your microcontroller has a SPI port, connect as follows:
DIN <-- SPI-MOSI
CLK <-- SPI-CLK
STB <-- CS (often just a GPIO rather than a dedicated SPI chipselect)
The SPI peripheral will then do most of the work for you. Most SPI peripherals allow different combinations of polarity and phase known as modes:
Mode CPOL CPHA
0 0 0
1 0 1
2 1 0
3 1 1
The PT6959 operates in mode 3.
The clock rate is probably not be critical. If you are bit-banging it rather than using SPI, it need not even be periodic or fixed - it is the state of DIN on rising and falling edges that is critical - not the frequency. The device will have some maximum rate - the data sheet specifies this in terms of minimum mark/space widths of >=400ns, assuming a 50% mark:space, that would correspond to 1.25MHz, but there is little benefit in operating at the maximum speed.
I have found it finally here the bigger datasheet fourteen (14) pages, not three.
So the time constraints for this signal as below,
PW CLK (Clock Pulse Width) ≥ 400ns
t setup (Data Setup Time) ≥ 100ns
t CLK-STB (Clock - Strobe Time) ≥ 1μs
t TZH (Rise Time) ≤ 1μs
t TZL < 1μs
V1.7
PW STB (Strobe Pulse Width) ≥ 1μs
t hold (Data Hold Time) ≥ 100ns
t THZ (Fall Time) ≤ 10μ
fosc=Oscillation Frequency
t TLZ < 10μs
As you can see the minimum clock pulse can be as 400ns which means the maximum clock frequency can found as 1/(2x400x10-9) = 1250000Hz (1.25Mhz)
Other calculations you can do the same way. But, yes, it is everything needed better covered at time-diagrams, which are given in the document above. I place them here just in case the link can die one day.
I have a very simple code that print out something to the terminal then goes directly to sleep.
For some reason the device is consuming more current during sleep mode. It is drawing 0.24 mA but I know it should be less than that. Without sleep it is consuming 4.32 mA. I've ran the most basic software I can and must be missing something.
Please what are some of the factors that effect power consumption? I really need to lower power consumption but I don't know what's causing it be that high. Here is the Datasheet for your own convenience.
/*
File: main.c
Date: 2011-SEP-4
Target: PIC18F87J11
IDE: MPLAB 8.76
Compiler: C18 3.40
*/
#include <p18cxxx.h>
#include <usart.h>
#pragma config FOSC = HSPLL, WDTEN = OFF, WDTPS = 4096, XINST = OFF
#define FOSC (4000000UL)
#define FCYC (FOSC/4UL)
#define BAUD 9600UL
#define SPBRG_INIT (FOSC/(16UL*BAUD) - 1)
void main(void)
{
/* set FOSC clock to 4MHZ */
OSCCON = 0x70;
/* turn off 4x PLL */
OSCTUNE = 0x00;
/* make all ADC inputs digital I/O */
ANCON0 = 0xFF;
ANCON1 = 0xFF;
/* test the simulator UART interface */
Open1USART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, SPBRG_INIT);
putrs1USART("PIC MICROCONTROLLERS\r\n");
Close1USART();
/* sleep forever */
Sleep();
}
Thanks in advance!
Update 1: I noticed adding the following code decreased it to 0.04 mA
TRISE = 0;
PORTE = 0x0C;
And If I was to change PORTE to the following, it increased to 0.16 mA.
PORTE = 0x00;
But I don't really understand what all of that means ... or how the power consumption went down. I have to be missing something in the code but I don't know what it is.
Update 2: This code gives me unstable current consumption. Sometimes 2.7 mA other times 0.01 mA. I suspect the problem with WDTCONbits.REGSLP = 1;
Download Code
Current consumption nicely went down from 0.24 mA to 0.04 mA when OP change settings on port outputs.
This is expected in typical designs, the outputs control various circuitry. Example: An output, by driving high, may turn on an LED(1), taking an additional 0.20 mA. In another design, an output, by driving low, may turn on an LED. In a 3rd design, not driving may turn on an LED.
OP needs to consult the schematic or designer to determine what settings result in low power. Further, certain combinations may/may not be allowed during low power mode.
Lastly, the sequence of lowering power, disabling, etc. on the various design elements may be important. The sequence to to shut things down is usually reversed in bringing them back on-line.
#Chris Stratton has good ideas in the posted comment.
(1) A low powered LED.
I am working on UART with pic32mx5xx. All I need is to send a message from pic to terminal (Putty), but it is not working as I would get invalid characters appearing. The baud rate is set to 19200, how do I calculate the clock frequency?
Is it true that the clock frequency of the UART is 16 times the baud rate. If I do the math the clock frequency should be 307200, but this is doesn't seem right.
Can someone help me understand how baud rate and clock frequency relate to each other ? Also how to calculate both?
Thanks!
The baud rate generator has a free-running 16-bit timer. To get the desired baud rate, you must configure its period register UxBRG and prescaler BRGH.
When BRGH is set to 0 (default), the timer is incremented every 16th cycle of peripheral bus clock.
When BRGH is 1, the timer increments every 4th cycle.
It is usually better to set BRGH to 1 to get a smaller baud rate error, as long as the UxBRG value doesn't grow too large to fit into the 16-bit register (on slower baud rates).
The value in the period register UxBRG determines the duration of one pulse on the data line in baud rate generator's timer increments.
See the formulas in section 21.3 - UART Baud Rate Generator in the reference manual to learn how to calculate a proper value for UxBRG.
To compute the period of the 16-bit baud rate generator timer to achieve the desired baud rate:
When BRGH = 0:
UxBRG = FPB / (16 * BAUDRATE) - 1
When BRGH = 1:
UxBRG = FPB / (4 * BAUDRATE) - 1
Where FPB is the peripheral bus clock frequency.
For example, if FPB = 20 MHz and BRGH = 1 and the desired baud rate 19200, you would calculate:
UxBRG = 20000000 / (4 * 19200) - 1
= 259
If you are using some of the latest development libraries and code examples from Microchip you may find that there are already UART methods in the libraries that will set up the PIC for your needs. If you dig deep into the new compiler directory structures you will find help files in the microsoft format (no fear, if you are on a Unix type computer there are Unix utilities that read these types of files.). There you can drill down into the help to find the documentation of various ready made methods you can call from your program to configure the PIC's hardware. Buyer Beware, the code is not that mature. For instance I was working on a PIC project that needed to sample two analog signals. The PIC hardware A/D converter was very complex. But it was clear the ready made code only covered about 10% of that PIC's abilities.
-good luck
I'm trying to transmit serial over the pic18f45k22 eusart peripheral. The messages get sent exactly as expected when the clock is running at 16Mhz, but if I set the PLL to on (so that the the oscillator runs at 64Mhz), I get a framing error.
I have changed the SPBRG registers to account for the new clock frequencey, and tried changing the baudrate generator to both 16 and 8 bit modes, but with no joy.
Current code:
OSCCONbits.IRCF = 0b111; //change Fosc to 16Mhz
OSCTUNEbits.PLLEN = 1; //enable PLL to multiply Fosc by 4
/*Set baud rates and related registers*/
/*For BRG16 = 1 and BRGH = 1, Baud rate = Fosc/(4([SPBRG:SPBRGH]+1)) */
SPBRGH1 = 0; //Set Baud rate control regs to 34 to give baudrate of 115.2k
SPBRG1 = 138;
BAUDCON1bits.BRG16 = 1; //16 bit mode (baudrate generator)
TXSTAbits.BRGH = 1; //Set high speed baud rate
Thanks in advance,
Huggzorx
I'm not familiar with that specific chip but in general, this is what I look at when my UART isn't behaving.
1) Can your clock be divided down to the baud rate with little enough error. Assuming that your baud rate formula in the comments is correct, I think you're okay there:
Baud rate = 16 MHz / (4*(34 + 1)) = 114286 (0.8% error)
Baud rate = 64 MHz / (4*(138 + 1)) = 115107 (0.08% error)
2) Make sure your chip is producing the baud rate you think it should be producing. Some PLLs are really picky about how you turn them on. It's also easy to mis-configure a peripheral. I find that an oscilloscope is your best bet to diagnose this type of problem. If you have access to one, scope the PIC's transmit pin and check that your bit width is 8.68us (1/115200).
If it's 4 times that size (34.72us), then your PLL didn't lock. If it's just a bit off, then the formula might be wrong.
It's not much but hopefully it gets you going in the right direction.