How to define a timer in avr-gcc - c

I am learning to use avr-gcc, but I have no idea, how to solve the following task:
The 8 bits from Port B should alternately set from 0 to 1 with an interval of 500 mili seconds.
I appreciate your help.

You can use #include <util/delay.h> , and if you write : _delay_loop_2(1000); you will have a delay of 1 ms;
You could use this function:
void delay()
{
for(int i=0;i<500;i++)
_delay_loop_2(1000);
}

Have a look at this example. This a very basic code for timer0:
#include<avr/io.h>
#include<avr/interrupt.h>
#define F_CPU 1000000UL
unsigned int t=0;
main()
{
DDRD=0xFF;
TCCR0=(1<<CS00);
TCNT0=0;
TIMSK=(1<<TOIE0);
sei();
while(1);
}
ISR(TIMER0_OVF_vect)
{
t++;
if(t==40000)
{
PORTD=~PORTD;
t=0;
}
}

As #Alex said you can #include <util/delay.h>, but instant of using the provided code (by #Alex) you can simple use _delay_ms(500);
This will provide you a delay of 500ms.
The choice is yours, just keep in mind that in both cases the frequency of your clock must be defined properly to your compiler:
Example for 16MHz:#define F_CPU 16000000UL

Related

Pic 18f4550 capture mode

I would like to measure a pulse using the pic 18f4550 in capture mode, this pulse is generated by the pic microcontroller itself, for this I use a function which plays the role of the XOR logic gate (you find the function that I've used below). with RC0 and RC2 the inputs and RC6 the signal output. the pulse leaving RC6 enters ccp2 to be measured.
The problem I found is that the ccp2 cannot detect the impulse generated by the microcontroller. I don't know if there are any conditions to connect the pins of the microcontroller or something.
If anyone has an answer or a hint to fix this, I will be grateful!
and if you have any questions feel free to ask .thanks !!
UPDATE: I changed some instructions in the code, now the RC6 output provides a signal. but my LCD does not display anything. the RC6 output is present below.
UPDATE 2: the while(1) in the xor() function blocking the rest of my program, so the program never get out of xor() and my LCD wont display anything. when I don't use the while loop in xor () my RC6 produce anything, the same for the LCD.
I don't know where the problem is, I did everything in my power to find the bug . but the system still not working!!!
I will leave the program as it is, so new readers can understand what I am talking about.
#include <stdio.h>
#include <stdlib.h>
#include "osc_config.h"
#include "LCD_8bit_file.h"
#include <string.h>
unsigned long comtage,capt0,x;
char pulse[20];
char cosinus[20];
float period,dephTempo,deph,phi;
void init (){
IRCF0 =1; /* set internal clock to 8MHz */
IRCF1 =1;
IRCF2 =1;
PIE2bits.CCP2IE=1;
PIR2bits.CCP2IF=0;
CCPR2 =0; /*CCPR1 is capture count Register which is cleared initially*/
T3CONbits.RD16=1;
T3CKPS0=0;
T3CKPS1=0;
TMR3CS=0;
TMR3IF=0;
T3CCP2=0; /*Timer3 is the capture clock source for CCP2*/
}
void xor()
{
while(1)
{
if (PORTCbits.RC0==PORTCbits.RC2)
{
PORTCbits.RC6=0;
}
else if (PORTCbits.RC0!=PORTCbits.RC2)
{
PORTCbits.RC6=1;
}
}
}
void main()
{
TRISCbits.TRISC0=1;
TRISCbits.TRISC2=1;
TRISCbits.TRISC6=0;
xor();
LCD_Init();
while(1)
{
CCP2CON = 0b00000101;
PIR2bits.CCP2IF = 0;
TMR3ON = 0;
TMR3 = 0;
while (!PIR2bits.CCP2IF);
TMR3ON = 1;
CCP2CON = 0b00000100;
PIR2bits.CCP2IF = 0;
while (!PIR2bits.CCP2IF);
comtage = CCPR2;
dephTempo = (((float)comtage /30.518)/65536 );
sprintf(pulse,"%.3f ",dephTempo);
LCD_String_xy(0,0,"the pulse width is : ");
LCD_String_xy(2,9,pulse);
}
}

PIN in Arduino = 0 does not trigger the motors

I am trying to use if statement to control the motors using C on the Arduino Uno board. However, when I set so that when the PIN, which is the sensor equals 0, the motors will run, it does not work at all. I also tried setting the PIN to not equal 0 and 1, both working fine. Can you guys give it a check? Thank you very much.
int MotorL=11;
int DirectionR=12;
int MotorR=10;
int DirectionL=13;
int SensorM=0;
#include <avr/io.h>
#include <util/delay.h>
void setup() {
pinMode(DirectionL,OUTPUT);
pinMode(DirectionR,OUTPUT);
pinMode(SensorM,INPUT);
digitalWrite(DirectionL,HIGH);
digitalWrite(DirectionR,HIGH);
analogWrite(MotorL,0);
analogWrite(MotorR,0);
}
void loop() {
if(PIND &_BV(PD6)==0){ //General movement: forward
analogWrite(MotorL,84);
analogWrite(MotorR,97);
}else{
analogWrite(MotorL,0);
analogWrite(MotorR,0);
}
}
== has higher precedence than &. You need to put the first two terms in parenthesis.
What you mean is:
if((PIND &_BV(PD6))==0)
But what the compiler sees is:
if(PIND & (_BV(PD6)==0))

MPLAB infinite loop

I have 2 questions.
The first: I have a problem in the behavior of this code; when I run it in Proteus the program make flasher "repeat the code in the main function"
what should I do?
This is the code:
#include <p18f452.h>
#include <delays.h>
#include <io.h>
void main ()
{
TRISC=0x00;
PORTC=0xff;
Delay1KTCYx(900);
PORTC=0x00;
Delay1KTCYx(900);
while(1)
{
}
}
The second question: what is the proper delay function I can use? and how can I measure the delay time?
Is the watchdog disabled in simulation ? If it is enabled it will cause the repetition of the program.
Try adding this line after the includes.
#pragma config WDT = OFF
You only have code to generate one flash. Move the flash and delays into the loop:
for(;;)
{
PORTC = 0xff;
Delay1KTCYx(900);
PORTC = 0x00;
Delay1KTCYx(900);
}
Measuring roughly can be made manually by timing N flashes with a stopwatch. It's of course easier to use a measurement intrument (an oscilloscope is nice for this) if you have it.
Also, since your duty cycle is 50%, you can simplify the code:
PORTC = 0;
for (;;)
{
PORTC = ~PORTC;
Delay1KTCYx(900);
}
This uses bitwise not (~) to invert the bits of PORTC, which will make them toggle from one to zero and vice versa. Setting the entire port to 0 before the loop makes sure all pins are at a known state.

window Watchdog Timer STM32F4

Edited
DONE NOW .. I'll reconstruct the code, but now it's done and tested
I need to implement a timer that checks for conditions every x sec .. the problem I face that the program doesn't reset when it enters infinite loop ( away for check like if the system has been halted) ...
these links helped me .. manual from page 74 http://www2.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf ..
and this link http://www.programmershare.com/3518407/
thanks in advance
I currently have this code :
#include "stm32f4xx.h"
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_wwdg.h>
void setup_Periph(void);
void Delay(unsigned long ms);
void Delay(unsigned long ms)
{ unsigned long i,j;
for(i=0;i<ms;i++)
for(j=0;j<1450;j++);
}
void setup_Periph(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
//port initialization
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_Init(GPIOD,&GPIO_InitStructure);
}
void ResetWatchdog(void)
{ WWDG_SetCounter(80);}
void WWDG_IRQHandler(void)
{
if (WWDG_GetFlagStatus())
{
WWDG_SetCounter(0x7f);
WWDG_ClearFlag();
}
}
void FeedDog(float round)
{
while(round)
{ Delay (65);
WWDG_SetCounter(127);
round--;}
}
int main(void)
{
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
//System Clock auf Watchdog
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
WWDG_SetPrescaler(WWDG_Prescaler_8);
//WWDG clock counter = (PCLK1(30MHz)/4096)/1 = 7324 Hz (~137 us)
WWDG_SetCounter(80); //Werte 0x40 und 0x7F
WWDG_SetWindowValue(80); //0x80
//Reset < 120 > 64
WWDG_Enable(127); //WWDG timeout = ~137 us * (127-64) = 8.6ms
WWDG_ClearFlag();
WWDG_EnableIT();
setup_Periph();
//make sure the clk is stable
RCC_HSEConfig(RCC_HSE_ON);
while(!RCC_WaitForHSEStartUp());
GPIO_SetBits(GPIOD, GPIO_Pin_1);
Delay(10000); //10 ms
GPIO_ResetBits(GPIOD, GPIO_Pin_1);
Delay(10000); //100 ms
while (1)
{
GPIO_SetBits(GPIOD, GPIO_Pin_0);
Delay(10000); //10 ms
GPIO_ResetBits(GPIOD, GPIO_Pin_0);
Delay(10000); //100 ms
void ResetWatchdog(void);
WWDG_SetCounter(80);
FeedDog(8);
for(;;) {}
}
}
There are several things very obviously wrong here. Most troubling among them are:
Your Delayms() function does not implement any kind of delay. It appears to configure one of the LEDs to flash.
You are never calling InitWatchdog(). (Instead, you are declaring its prototype within main() for some reason.)
I don't want this to sound too harsh, but: do you know C? This code reads as though it's been put together by copying and pasting pieces from examples without understanding them. If you do not know C, attempting to develop software for an embedded system is not an effective way to learn it, especially without guidance.

Microcontroller PIC16F877A c coding, to control an occupancy sensor and a photodiode at the same time

i am currently doing a prototype which combine 2 sensors, the PIR motion sensor by cytron.
and a photodiode (tiny, with 3 legs, with the model unknown)
The prototype works in a way that, when there is no light, and there is motion, the led will turn on.
Else, it will turn off.
I have wrote codes to test the both sensors separately, it works quite fine.
I face problem of the output of led when i combine the 2 codes.
It is as shown in below:
// include
//==========================================================================
# include <pic.h>
# include <htc.h>
// configuration
//==========================================================================
__CONFIG (0x3F32);
// define
//==========================================================================
#define sensor RB3
#define led RA5
#define led2 RB7
#define light RB5
#define _XTAL_FREQ 4000000
#define delay ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
// main function
//==========================================================================
void main(void)
{
// unsigned long delay_time=5000;
TRISA = 0b00000000;
TRISB = 0b01111111; //Configure Port B as Input
ADCON1 =0B00000110;
led=0;
led2=0;
int i;
while(1) //Infinity Loop
{
if(!light)
{
if(sensor)
{
for(i=5;i>0;i--)
{
led2=0;
led=1;
__delay_ms(10000);
}
}
else if(!sensor)
{
if (i>0)
{ for(i=5;i>0;i--)
{
led2=0;
led=1;
__delay_ms(10000);
}
}
else if(i<=0)
{
led=0;
led2=1;
}
}
}
else if(light)
{
led=0;
led2=1;
}
}
}
I appreciate your help in advance.
Please help.
Thank you.
You declare the variable i but then don't initialize it to a value (I don't think the C compiler initializes it to 0 either, I am not sure). If that was not the case, then imagine the following scenario:, that in the the very first beginning of execution:
it was (!light) and (!sensor), it starts comparing i>0 or i<=0 but what is i initially??
you only assume that the if (sensor) body has executed at least once to give i an initial value. I don't know the details of your program requirements or flow, but I see this as an unsafe and a hidden bug.
While I'm no expert at the PIC micro's I wonder whether the method you are using to access the RAx and RBx is the appropriate one i.e. "led = 0", rather than "led &= ~(1 << led)" or something in like that.
You also seem to not initialize the "int i" variable which I assume would lead to issues with the if statements.
Best regards.
How about something like:
while (1)
{
led_on = 0;
if (!light && !sensor)
{
if (led_on == 0)
{
/* Turn on LED... */
led_on = 1;
}
}
else if (led_on == 1)
{
/* Turn off LED... */
led_on = 0;
}
}
when I was working on pic24 family using assembly language if I needed to assign 2 ports consecutively it turned out that the second assignment would not work(unless you are using tristate buffers...I don't know the exact reason but that was the case...).Anyway...what I'm trying to say is that try to give a few mseconds delay after each led value assignments like:
for(i=5;i>0;i--)
{
led2=0;
_delay_ms(50);
led=1;
__delay_ms(10000);
}

Resources