Posts

Showing posts from August, 2017

Understanding Interrupt Subroutines

The ISR address function are declared as "weak" type in startup file.  In *.s file format  it is like .word NMI_Handler and Interrupt address is defined in the line .weak NMI_Handler                                             //declared as weak type .thumb_set NMI_Handler,Default_Handler       // NMI_Handler ISR is declared as weak and assigned Default_Handler which is a infinite loop   In *.c  file format it is like void WEAK  NMI_Handler(void); and Interrupt address is defined in the line #pragma weak NMI_Handler = Default_Handler whereas #pragma  is for compiler directives that are machine-specific or operating-system-specific, i.e. it tells the compiler to do something, set some option, take some action, override some default, etc. that may or may not apply to all machines and operating systems.

UART communication using Interrupts and Standard Peripheral Library

Steps: 1)Open CoIDE. New Project 2)Add STM32F10x_MD_STDLIB i.e. standard peripheral library . This will automatically add cmsis_core to the components menu. add the following code in main.c #include "stm32f10x.h" #include "string.h" #include "stm32f10x_usart.h" #include "misc.h" #define RX_BUF_SIZE 80 volatile RX_FLAG_END_LINE = 0; volatile char RX_BUF[RX_BUF_SIZE] = {'\0'}; volatile char RXi; volatile char RXc; void clear_RXBuffer() { for(RXi=0; RXi<RX_BUF_SIZE; RXi++) { RX_BUF[RXi]='\0'; } RXi = 0; } //USART1_IRQHandler ISR is being define in file 'startup_stm32f030.s' //We just need to redefine to overwrite the original void USART1_IRQHandler() { if((USART1->SR & USART_FLAG_RXNE)!= (u16)RESET) { RXc = USART_ReceiveData(USART1); RX_BUF[RXi]=RXc; RXi++; if(RXc != 13 ) { if(RXi > RX_BUF_SIZE-1) { clear_RXBuffer(); } } else { ...

Using Timer

main.c #include "stm32f1xx.h" #include "LCDFunctions.h" int main(void) { InitializePortsForLCD(); LCDDisplaySetup(); RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // Supply clock to TIM1 TIM1->CR1 |= TIM_CR1_CEN;  //Enable Timer TIM1->PSC |= 655; //Prescalar value LCDSendStringsIn2Lines("Counter: ", "Prescalar:"); LCDsendAnInteger(TIM1->PSC, 5);     while(1)     {     LCDSetCursorPosition(9,0);     LCDsendAnInteger(TIM1->CNT,6); //Timer Count     } }

Setting Cursor Position in LCD

LCDFunctions.h #ifndef LCDFunctionsHeader #include <stdio.h> #include <float.h> #define LCDFunctionsHeader #define LCDD0Pin 12 #define LCDD0Port GPIOB #define LCDD1Pin 13 #define LCDD1Port GPIOB #define LCDD2Pin 14 #define LCDD2Port GPIOB #define LCDD3Pin 15 #define LCDD3Port GPIOB #define LCDD4Pin 8 #define LCDD4Port GPIOA #define LCDD5Pin 9 #define LCDD5Port GPIOA #define LCDD6Pin 10 #define LCDD6Port GPIOA #define LCDD7Pin 11 #define LCDD7Port GPIOA #define LCDRegisterSelectPin 7 #define LCDRegisterSelectPort GPIOB #define LCDReadWritePin 8 #define LCDReadWritePort GPIOB #define LCDEnablePin 9 #define LCDEnablePort GPIOB #define LCD_8_bit_dataline 0x38 #define LCD_DisplayON_CursorON 0x0F #define LCD_Increment_Cursor_Position 0x06 #define LCD_Clear_Display 0x01 #define LCD_Next_Line_Command 0xC0 #define delayBeforeEnable 400 #define delayAfterEnable 800 void notExactTimedelay(int delayTim...

Displaying a Float in LCD

First add " Retarget_printf " in the project LCDFunctions.h #ifndef LCDFunctionsHeader #include <stdio.h> #include <float.h> #define LCDFunctionsHeader #define LCDD0Pin 12 #define LCDD0Port GPIOB #define LCDD1Pin 13 #define LCDD1Port GPIOB #define LCDD2Pin 14 #define LCDD2Port GPIOB #define LCDD3Pin 15 #define LCDD3Port GPIOB #define LCDD4Pin 8 #define LCDD4Port GPIOA #define LCDD5Pin 9 #define LCDD5Port GPIOA #define LCDD6Pin 10 #define LCDD6Port GPIOA #define LCDD7Pin 11 #define LCDD7Port GPIOA #define LCDRegisterSelectPin 7 #define LCDRegisterSelectPort GPIOB #define LCDReadWritePin 8 #define LCDReadWritePort GPIOB #define LCDEnablePin 9 #define LCDEnablePort GPIOB #define LCD_8_bit_dataline 0x38 #define LCD_DisplayON_CursorON 0x0F #define LCD_Increment_Cursor_Position 0x06 #define LCD_Clear_Display 0x01 #define LCD_Next_Line_Command 0xC0 #define delayBeforeEnable 400 #define delayAfterEnable 800 void notExactTimedel...

Displaying String and Integers on LCD

First add " Retarget_printf " in the project LCDFunctions.h #ifndef LCDFunctionsHeader #include <stdio.h> #define LCDFunctionsHeader #define LCDD0Pin 12 #define LCDD0Port GPIOB #define LCDD1Pin 13 #define LCDD1Port GPIOB #define LCDD2Pin 14 #define LCDD2Port GPIOB #define LCDD3Pin 15 #define LCDD3Port GPIOB #define LCDD4Pin 8 #define LCDD4Port GPIOA #define LCDD5Pin 9 #define LCDD5Port GPIOA #define LCDD6Pin 10 #define LCDD6Port GPIOA #define LCDD7Pin 11 #define LCDD7Port GPIOA #define LCDRegisterSelectPin 7 #define LCDRegisterSelectPort GPIOB #define LCDReadWritePin 8 #define LCDReadWritePort GPIOB #define LCDEnablePin 9 #define LCDEnablePort GPIOB #define LCD_8_bit_dataline 0x38 #define LCD_DisplayON_CursorON 0x0F #define LCD_Increment_Cursor_Position 0x06 #define LCD_Clear_Display 0x01 #define LCD_Next_Line_Command 0xC0 #define delayBeforeEnable 400 #define delayAfterEnable 800 void notExactTimedelay(int delayTime) { vol...

Displaying Characters to LCD

LCDFunctions.h #ifndef LCDFunctionsHeader #define LCDFunctionsHeader #define LCDD0Pin 12 #define LCDD0Port GPIOB #define LCDD1Pin 13 #define LCDD1Port GPIOB #define LCDD2Pin 14 #define LCDD2Port GPIOB #define LCDD3Pin 15 #define LCDD3Port GPIOB #define LCDD4Pin 8 #define LCDD4Port GPIOA #define LCDD5Pin 9 #define LCDD5Port GPIOA #define LCDD6Pin 10 #define LCDD6Port GPIOA #define LCDD7Pin 11 #define LCDD7Port GPIOA #define LCDRegisterSelectPin 7 #define LCDRegisterSelectPort GPIOB #define LCDReadWritePin 8 #define LCDReadWritePort GPIOB #define LCDEnablePin 9 #define LCDEnablePort GPIOB #define delayBeforeEnable 400 #define delayAfterEnable 800 void notExactTimedelay(int delayTime) { volatile int i; for (i = 0; i < delayTime; ++i) { } } void SetupBitsAndPorts(GPIO_TypeDef *port, int pinNumber) { //Setup Reset and Clock Control Register if(port == GPIOA) { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;  //Enable clock to Port A ...

Writing a header file

#ifndef LCDFunctionsHeader    //If LCD Functions is not defined (#ifndef) then define (#define) it #define LCDFunctionsHeader <Code Here> #endif  If LCD Functions is not defined (#ifndef) then define (#define) it

Some bit level programming

1) Test bit#7 on the byte (byte name is "character") and sending it to port C pin 9      if(character & 0b00000001)      { GPIOB->BSRR |= GPIO_BSRR_BS9;} 2) Assigning 1 to nth bit of a byte named "BSRR"     BSRR |= (1<<n)     Assigning 0 to nth bit of a byte named "BSRR"     BSRR |= ~(1<<n) 3) There is no " bool " data type in C. We  have to use " uint8_t " as substitute

Toggle LED with Push Button (Debouncing)

Toggle LED with Push Button (Debouncing) #include "stm32f1xx.h" int main(void) { //Setup Reset and Clock Control Register   RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;  //Enable clock to Port C RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;  //Enable clock to Port B //Setup GPIO Registers of Port C GPIOC->CRH |= GPIO_CRH_MODE13; //Port C13 in Output Mode, 50 MHz GPIOC->CRH &= ~(GPIO_CRH_CNF13); //Port C13 in General Purpose output, Push Pull //Setup GPIO Registers of Port B GPIOB->CRL &= ~(GPIO_CRL_MODE1); //Port B1 in Input Mode GPIOB->CRL |= GPIO_CRL_CNF1_0; //Port B1 in Floating State determined by CNF1[1:0] GPIOB->CRL &= ~(GPIO_CRL_CNF1_1); volatile char ButtonPressed = 0; GPIOC->BSRR |= GPIO_BSRR_BS13; //Turn OFF LED volatile unsigned int ButtonPressedConfidenceLevel = 0;  // Determines time for which button is kept pressed volatile unsigned int ButtonReleasedConfidenceLevel = 0; // Determines time for w...

Toggle LED with Push Button (debouncing introduced)

#include "stm32f1xx.h" int main(void) { //Setup Reset and Clock Control Register   RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;  //Enable clock to Port C RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;  //Enable clock to Port B //Setup GPIO Registers of Port C GPIOC->CRH |= GPIO_CRH_MODE13; //Port C13 in Output Mode, 50 MHz GPIOC->CRH &= ~(GPIO_CRH_CNF13); //Port C13 in General Purpose output, Push Pull //Setup GPIO Registers of Port B GPIOB->CRL &= ~(GPIO_CRL_MODE1); //Port B1 in Input Mode GPIOB->CRL |= GPIO_CRL_CNF1_0; //Port B1 in Floating State determined by CNF1[1:0] GPIOB->CRL &= ~(GPIO_CRL_CNF1_1); volatile char ButtonPressed = 0; GPIOC->BSRR |= GPIO_BSRR_BS13; //Turn OFF LED volatile unsigned int ButtonPressedConfidenceLevel = 0;  // Determines time for which button is kept pressed volatile unsigned int ButtonReleasedConfidenceLevel = 0; // Determines time for which button is kept released volatile unsigne...

volatile keyword

Courtesy: Arduino.cc volatile is a keyword known as a variable  qualifier , it is usually used before the datatype of a variable, to modify the way in which the compiler and subsequent program treats the variable. Declaring a variable volatile is a directive to the compiler. The compiler is software which translates your C/C++ code into the machine code, which are the real instructions for the Atmega chip in the Arduino. Specifically, it directs the compiler to load the variable from RAM and not from a storage register, which is a temporary memory location where program variables are stored and manipulated. Under certain conditions, the value for a variable stored in registers can be inaccurate. A variable should be declared volatile whenever its value can be changed by something beyond the control of the code section in which it appears, such as a concurrently executing thread. In the Arduino, the only place that this is likely to occur is in sections of code associated ...

Switch Input and LED output

Image
Switch connected at Port B1 and output connected at Port C13 #include "stm32f1xx.h" void waitForAmoment(int Moment) {  volatile int i,j;  for (i = 0; i < Moment; ++i)  {   j++;  } } int main(void) { //Setup Reset and Clock Control Register   RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;  //Enable clock to Port C RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;  //Enable clock to Port B //Setup GPIO Registers of Port C GPIOC->CRH |= GPIO_CRH_MODE13; //Port C13 in Output Mode, 50 MHz GPIOC->CRH &= ~(GPIO_CRH_CNF13); //Port C13 in General Purpose output, Push Pull //Setup GPIO Registers of Port B GPIOB->CRL &= ~(GPIO_CRL_MODE1); //Port B1 in Input Mode GPIOB->CRL |= GPIO_CRL_CNF1_0; //Port B1 in Floating State GPIOB->CRL &= ~(GPIO_CRL_CNF1_1);     while(1)     {     if(GPIOB->IDR & GPIO_IDR_IDR1)     {     GPIOC->BSRR |= GP...

Blinking a LED in STM32F103C8T6 (Blue Pill) Board

1) First Include STM32F103xB_CUBELIB and cmsis_core in the project #include "stm32f1xx.h" void waitForAmoment(int Moment) { volatile int i,j; for (i = 0; i < Moment; ++i) { j++; } } int main(void) { //Enable the GPIO Clock by AHB and RCC RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; GPIOC ->CRH |= GPIO_CRH_MODE13; //PC13 in output mode, 50 MHz GPIOC->CRH &= ~(GPIO_CRH_CNF13); //PC13 General Purpose Output, Push Pull Config     while(1)     {     GPIOC->BSRR |= GPIO_BSRR_BS13;     waitForAmoment(1000000);     GPIOC->BRR |= GPIO_BRR_BR13;     waitForAmoment(1000000);     } }