on Sunday, January 5, 2014
Hi,
As I'm starting with CADSoft Eagle software, I wanted to make a simple 2 motor driver board.
This board can control 2 DC motors using the L298 circuit from ST.


You can find the complete data-sheet of the circuit here

The schematics:


The circuit:





on Saturday, January 4, 2014
The STM32F4 discovery is a wonderful board but it is really not freindly when testing with all its ugly male connectors that it is impossible to put it in a lab board.

I don't know if anyone did this before, but I made a small adapter in eagle for this board so it can be easily integrated with other test or prototyping project or it can be simply used in a hole PCB board.

Download the part from here:


 
Hi,
Stepper motors are very commun in many applications, they are widely used in printers scanners and many other equipements thanks to their easy control.


I really advice you to understand how bipolar stepper works before testing the following code.
Start from here !

 The following code is for controlling a bipolar stepper motor using STM32F4 discovery board.
I used a l293D for power interface between the stepper and the board like the following image:


And The I used this simple code to control my stepper in one direction with fixed speed using half step control.

void GPIOD_Initialize(){
GPIO_InitTypeDef GPIOD_Stepper;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

GPIOD_Stepper.GPIO_Mode = GPIO_Mode_OUT;
GPIOD_Stepper.GPIO_OType = GPIO_OType_PP;
GPIOD_Stepper.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_7;
GPIOD_Stepper.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIOD_Stepper.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD,&GPIOD_Stepper);
}


int main(void)
{
GPIOD_Initialize();
while(1){
GPIO_Write(GPIOD,GPIO_Pin_1);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_1| GPIO_Pin_3);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_3);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_5|GPIO_Pin_3);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_5);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_5|GPIO_Pin_7);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_7);
Delay(100);
GPIO_Write(GPIOD,GPIO_Pin_7|GPIO_Pin_1);
Delay(100);
}
}



on Thursday, January 2, 2014
Hello,
This time I'll give you a short tutorial about how to use timers with the STM32.
Timers are very useful when it comes to make a precise period of time independantly from your main loop execution.


The stm32F4 has many timers each one with a specific need. I'm just going to use the Timer 2 to make an interruption each 0.25 sec.
I use a C# program to calculate what values to put in the prescaler and the periode to get my required interruption time.
https://www.mediafire.com/?bq21q5qd7frcvba

The code has comments in it but if there is something that is not clear explained in the comments below, I'll be happy to answer.


void TIM2_IRQHandler(void){
static short i = 0;
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_WriteBit(GPIOD,GPIO_Pin_13,i++);
GPIO_ToggleBits(GPIOD, GPIO_Pin_14);
}
}

void INTTIM_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* Time base configuration */

TIM_TimeBaseStructure.TIM_Period = 1000000 - 1; // 1 MHz down to 1 KHz (1 ms)
TIM_TimeBaseStructure.TIM_Prescaler = 43- 1; // 24 MHz Clock down to 1 MHz (adjust per your clock)
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* TIM IT enable */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}

int main(void)
{

STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
STM_EVAL_LEDInit(LED5);
STM_EVAL_LEDInit(LED6);
INTTIM_Config();
while(1);
}

on Wednesday, October 9, 2013
We really need to integrate ourselves in the middle of social life, a person that cannot integrate in his society would be qualified as non normal or with no regular behavior.
The fact is, that integrating in the society is a very relative concept, a person that cannot integrate himself in a specific society could be the most popular in another society, and we take the example of gamers or real geeks that bunch of guys that are so addicted to a video game or hacking computer software, have real problem with integrating within a society where the one who can use MSWord is qualified as a one who masters the computer. But the same Geeky person would be so popular in a society of geeks.

Here we go back to the point that in order to be popular or at least can integrate in a society, a person MUST share with the society its common believes, practices, way of thinking and looking to the world.
To integrate with a society a person must talk like they talk even if there is actually nothing wrong with hes talking and way of reasoning, a person must joke like they do, eat like they do even if it'is not healthy for him to eat the food they eat or the way they eat not eating like them take a -1 from his popularity mark.

The problem is not integrating could be very harmful for some people, the fact that they loose connection with their entourage and surrounding colleagues, the fact that they are not respected or acknowledged for what they do best. For example a person who masters fishing would have no value in a society of hunters. And here we conclude that to integrate in a society, you must actual do something that is relevant and useful for them, otherwise a person with deviated skills cannot easily integrate with a society.

But any person in the world no matter how intelligent, crazy, ugly, beautiful, rich or poor need to have people surrounding him, that can talk with him ask for him and worry about him. It is a natural need and it's very harmful to take it from someone which hes only curse that he was born with a deviated skills.

So any person in this world must be conscious of this fact, and therefore open his mind to different ideas and different believes. respect the other competence even if it is not relevant to him it could be relevant for someone else, it could help other societies.
Any person should not judge other people way of thinking as bizarre or weird, he could actual look more bizarre in another Time and Place Circumstances.

Finally, I would like to invite you to be more opened with weird people, they are actually more interesting than the typical believes.

Mazen


on Friday, September 20, 2013
LCD can be a very useful part in any microcontroller based project. It helps to monitor variables and program status with simple texts or numbers.

For this application I used a JHD 162 A alphanumeric LCD, like the picture above.
It hast 16 pins specified like this
VEE is used for contrast, so attache it to a potentiometer  and choose your best contrast. Or simply plug it to 5V if you need maximum contrast.
D0, D1, D2, D3 are grounded
I managed to find a library for STM32VL, so I needed to bring some changes to it before it works. This library works both for JHD 162A and the hd44780.

lcd_hd44780.h
//******************************************************************************
// THE SOFTWARE INCLUDED IN THIS FILE IS FOR GUIDANCE ONLY.
// AUTHOR SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
// OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
// FROM USE OF THIS SOFTWARE.
//******************************************************************************

//##############################################################################
// lcd_hd44780.h
//##############################################################################

//****************************************************************************//
#include "main.h"


#define LCD_GPIO GPIOD
#define LCD_CLK_LINE RCC_AHB1Periph_GPIOD

#define LCD_D4 GPIO_Pin_1
#define LCD_D5 GPIO_Pin_3
#define LCD_D6 GPIO_Pin_5
#define LCD_D7 GPIO_Pin_7

#define LCD_RS GPIO_Pin_0
#define LCD_RW GPIO_Pin_2
#define LCD_EN GPIO_Pin_4
//******************************************************************************//


#define HD44780_CLEAR 0x01

#define HD44780_HOME 0x02

#define HD44780_ENTRY_MODE 0x04
#define HD44780_EM_SHIFT_CURSOR 0
#define HD44780_EM_SHIFT_DISPLAY 1
#define HD44780_EM_DECREMENT 0
#define HD44780_EM_INCREMENT 2

#define HD44780_DISPLAY_ONOFF 0x08
#define HD44780_DISPLAY_OFF 0
#define HD44780_DISPLAY_ON 4
#define HD44780_CURSOR_OFF 0
#define HD44780_CURSOR_ON 2
#define HD44780_CURSOR_NOBLINK 0
#define HD44780_CURSOR_BLINK 1

#define HD44780_DISPLAY_CURSOR_SHIFT 0x10
#define HD44780_SHIFT_CURSOR 0
#define HD44780_SHIFT_DISPLAY 8
#define HD44780_SHIFT_LEFT 0
#define HD44780_SHIFT_RIGHT 4

#define HD44780_FUNCTION_SET 0x20
#define HD44780_FONT5x7 0
#define HD44780_FONT5x10 4
#define HD44780_ONE_LINE 0
#define HD44780_TWO_LINE 8
#define HD44780_4_BIT 0
#define HD44780_8_BIT 16

#define HD44780_CGRAM_SET 0x40

#define HD44780_DDRAM_SET 0x80

//##############################################################
void lcd_init(void);
void lcd_cls(void);
void lcd_str(unsigned char * text);
void lcd_strxy(unsigned char * text, unsigned char x, unsigned char y);
void lcd_locate(unsigned char x, unsigned char y);
void lcd_int(int n);
void lcd_intxy(int n, unsigned char x, unsigned char y);

//###############################################################

void lcd_writedata(unsigned char dataToWrite);
void lcd_writecommand(unsigned char commandToWrite);
void lcd_writebinary(unsigned int var, unsigned char bitCount);
void lcd_addchar (unsigned char chrNum, unsigned char n, const unsigned char *p);


lcd_hd44780.c
#include "lcd_hd44780.h"
#include "stm32f4xx_gpio.h"
#include
#include
#include
#include "stm32f4_discovery.h"

GPIO_InitTypeDef GPIO_InitStructure;

//-----------------------------------------------------------------------------
void lcd_writenibble(unsigned char nibbleToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
GPIO_WriteBit(LCD_GPIO, LCD_D4,(BitAction) (nibbleToWrite & 0x01));
GPIO_WriteBit(LCD_GPIO, LCD_D5,(BitAction)(nibbleToWrite & 0x02));
GPIO_WriteBit(LCD_GPIO, LCD_D6,(BitAction)(nibbleToWrite & 0x04));
GPIO_WriteBit(LCD_GPIO, LCD_D7,(BitAction)(nibbleToWrite & 0x08));
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
}


//-----------------------------------------------------------------------------
unsigned char LCD_ReadNibble(void)
{
unsigned char tmp = 0;
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_SET);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D4) << 0);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D5) << 1);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D6) << 2);
tmp |= (GPIO_ReadInputDataBit(LCD_GPIO, LCD_D7) << 3);
GPIO_WriteBit(LCD_GPIO, LCD_EN, Bit_RESET);
return tmp;
}


//-----------------------------------------------------------------------------
unsigned char LCD_ReadStatus(void)
{
unsigned char status = 0;

GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(LCD_GPIO, &GPIO_InitStructure);

GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_SET);
GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_RESET);

status |= (LCD_ReadNibble() << 4);
status |= LCD_ReadNibble();

GPIO_InitStructure.GPIO_Pin = LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(LCD_GPIO, &GPIO_InitStructure);

return status;
}


//-----------------------------------------------------------------------------
void lcd_writedata(unsigned char dataToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW, Bit_RESET);
GPIO_WriteBit(LCD_GPIO, LCD_RS, Bit_SET);

lcd_writenibble(dataToWrite >> 4);
lcd_writenibble(dataToWrite & 0x0F);

while(LCD_ReadStatus() & 0x80);
}


//-----------------------------------------------------------------------------
void lcd_writecommand(unsigned char commandToWrite)
{
GPIO_WriteBit(LCD_GPIO, LCD_RW | LCD_RS, Bit_RESET);
lcd_writenibble(commandToWrite >> 4);
lcd_writenibble(commandToWrite & 0x0F);

while(LCD_ReadStatus() & 0x80);
}


//-----------------------------------------------------------------------------
void lcd_str(unsigned char * text)
{
while(*text)
lcd_writedata(*text++);
}


//-----------------------------------------------------------------------------
void lcd_locate(unsigned char x, unsigned char y)
{
lcd_writecommand(HD44780_DDRAM_SET | (x + (0x40 * y)));
}


//-----------------------------------------------------------------------------
void lcd_strxy(unsigned char * text, unsigned char x, unsigned char y)
{
lcd_locate(x,y);
while(*text)
lcd_writedata(*text++);
}


//-----------------------------------------------------------------------------
void lcd_writebinary(unsigned int var, unsigned char bitCount)
{
signed char i;

for(i = (bitCount - 1); i >= 0; i--)
{
lcd_writedata((var & (1 << i))?'1':'0');
}
}


//-----------------------------------------------------------------------------
void LCD_ShiftLeft(void)
{
lcd_writecommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_LEFT | HD44780_SHIFT_DISPLAY);
}


//-----------------------------------------------------------------------------
void LCD_ShiftRight(void)
{
lcd_writecommand(HD44780_DISPLAY_CURSOR_SHIFT | HD44780_SHIFT_RIGHT | HD44780_SHIFT_DISPLAY);
}


//-----------------------------------------------------------------------------
void lcd_init(void)
{
volatile unsigned char i = 0;
volatile unsigned int delayCnt = 0;
RCC_AHB1PeriphClockCmd(LCD_CLK_LINE, ENABLE);
GPIO_InitStructure.GPIO_Pin = LCD_D4|LCD_D5|LCD_D6|LCD_D7|LCD_RS|LCD_RW|LCD_EN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_Init(LCD_GPIO, &GPIO_InitStructure);

GPIO_ResetBits(LCD_GPIO, LCD_RS | LCD_EN | LCD_RW);

for(delayCnt = 0; delayCnt < 300000; delayCnt++);

for(i = 0; i < 3; i++) {
lcd_writenibble(0x03);
for(delayCnt = 0; delayCnt < 30000; delayCnt++);
}

lcd_writenibble(0x02);

for(delayCnt = 0; delayCnt < 6000; delayCnt++);

lcd_writecommand(HD44780_FUNCTION_SET |
HD44780_FONT5x7 |
HD44780_TWO_LINE |
HD44780_4_BIT);

lcd_writecommand(HD44780_DISPLAY_ONOFF |
HD44780_DISPLAY_OFF);

lcd_writecommand(HD44780_CLEAR);

lcd_writecommand(HD44780_ENTRY_MODE |
HD44780_EM_SHIFT_CURSOR |
HD44780_EM_INCREMENT);

lcd_writecommand(HD44780_DISPLAY_ONOFF |
HD44780_DISPLAY_ON |
HD44780_CURSOR_OFF |
HD44780_CURSOR_NOBLINK);

}


//-----------------------------------------------------------------------------
void lcd_addchar (unsigned char chrNum, unsigned char n, const unsigned char *p)
{
lcd_writecommand(HD44780_CGRAM_SET | chrNum * 8);
n *= 8;
do
lcd_writedata(*p++);
while (--n);
}


//-----------------------------------------------------------------------------
void lcd_cls(void){
lcd_writecommand(HD44780_CLEAR);
}



unsigned char* intToStr(int n){
int i = 0;
int j = 0;
char *tmp = (char*)malloc(sizeof(char));
unsigned char *ret = (unsigned char*)malloc(12);
if(n<0 data-blogger-escaped-i="" data-blogger-escaped-j="" data-blogger-escaped-n="" data-blogger-escaped-ret="-" data-blogger-escaped-while="">9){
*tmp = n%10+48;
n-=n%10;
n/=10;
tmp++;
i++;
}
*tmp = n+48;
i++;
while(i--){
ret[j++] = *tmp--;
}
return ret;
}
void lcd_int(int a){
unsigned short ch,
first; //you need this to display 0 if there was any char

//Get first char
ch = a/10000;
if(ch){
lcd_writedata(48+ch);
first = 1;
}

//Get second char
ch = (a/1000)%10;
if(ch || first){
lcd_writedata(48+ch);
first = 1;
}

//Get third char
ch = (a/100)%10;
if(ch || first){
lcd_writedata(48+ch);
first = 1;
}

//Get fourth char
ch = (a/10)%10;
if(ch || first){
lcd_writedata(48+ch);
//first = 1; //q
}

//Get fifth char
ch = a%10;
//if(ch || first) //you dont need to check las one if ch is 0 then just display it, unless you dont want to then uncomment this line ("//q" line too)
lcd_writedata(48+ch);
// lcd_str(intToStr(n));
}

void lcd_intxy(int n, unsigned char x, unsigned char y){
lcd_locate(x,y);
lcd_int(n);
}



main.c
lcd_init();

while (1)
{

lcd_locate(1,0);
lcd_str("Mazen");
lcd_locate(7,0);
lcd_str("A.");
lcd_locate(0,1);
lcd_str("-3125");

}

Update:
Number display function is fixed