I have written a program for my At-mega 32 in order to increase and decrease numbers from 0 to 9 and reverse (9 to 0) with the two tactile switch witch you can see in the picture.
But the problem is that while all of the numbers are demonstrated by pressing those switches, only numbers 4 and 7 don't appear properly !?.
My seven segments instead of number 4 demonstrates what you can see in the first picture and for number 7 is shows what you can see in the second picture.
I would appreciate it if someone could have a look at my codes and schematic which I have shared here and help me to find the issue.
Thank you so much,
#include <avr/io.h>
#include <util/delay.h>
#include "global.h"
#include <avr/interrupt.h>
uint8_t Codes[] = {0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6};
uint8_t count=0;
//temp=0
void display(uint8_t digit);
void config(void);
ISR(INT0_vect)
{
if(count<9)
{
count++;
display(count);
}
}
ISR(INT1_vect)
{
if(count>0)
{
count--;
display(count);
}
}
int main(void)
{
config();
while(1)
{
}
}
void config(void)
{
DDRA=0xFF;
PORTA=0;
cbi(DDRD,2);
cbi(DDRD,3);
sbi(PORTD,2);
sbi(PORTD,3);
GICR=(1<<INT1) | (1<<INT0);
MCUCR=0; //low level sensitivity
GIFR=(1 << INTF1) | (INTF0);
sei();
}
void display(uint8_t digit)
{
PORTA=Codes[digit];}
Your code looks correct, I even checked the patterns of Codes[].
Each bit of the patterns is assigned to one specific segment of the display:
Port bit
Segment
PA7
a
PA6
b
PA5
c
PA4
d
PA3
e
PA2
f
PA1
g
Your wiring is wrong, unfortunately the schematic does not show the pin names of the display. It seems as if it's upside down.
Related
I am trying to get readings from 3 rotary encoders (KY-040) and send values via UART.
I am using Arduino-Mega 2560 board but due to requirements reason I am programming it in C.
But when I try to get the reading from encoder I get random numbers.
And it only works with every even number of rotation and program gets stuck at odd rotation. (it seems little odd)
Can anybody please suggest what is wrong with my code.
P.S. I am new working with micro controller.
#define F_CPU 16000000 //Clock Speed
#define UART_BAUD 9600
#include <stdio.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "uart.h"
#include <stdlib.h>
volatile unsigned int encPosZ=0;
void sendEncValue(unsigned int value){
char string[5];
itoa(value, string, 10);
uart_puts(string);
}
// main
int main(void)
{
//disable all interrupts
cli();
uart_init(UART_BAUD_SELECT(UART_BAUD,F_CPU));
DDRE &=~ (1 << PE4);
DDRE &=~ (1 << PE5);
/* set pull-up enabled */
PORTE |= (1 << PE4)|(1 << PE5);
EIMSK |= (1 << INT4)|(1 << INT5);
/* INT4 - falling edge, INT5 - rising edge */
EICRB|= (1<<ISC41)|(1<<ISC51)|(1<<ISC50);
// Enable the Global Interrupt Enable flag
sei();
uart_puts("Started... ");
while(1)
{
_delay_ms(5);
}
return 0;
}
//INT4 interrupt
ISR(INT4_vect)
{
if(!bit_is_clear(PINE, PE5)){
encPosZ++;
}else{
encPosZ--;
}
sendEncValue(encPosZ);
}
//INT5 interrupt
ISR(INT5_vect)
{
if(bit_is_clear(PINE, PE4)){
encPosZ++;
}else{
encPosZ--;
}
sendEncValue(encPosZ);
}
MCUCR is not used for the purpose you are using it. In fact, most of its bits are read-only.
Perhaps you meant to use EICRA and EICRB. These are the registers to set rising and falling edges.
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.
#define F_CPU 16000000UL // AVRJazz28PIN Board Used 16MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_CS PB2
void SPI_Write(uint8_t addr, uint8_t dataout)
{
// Enable CS Pin
SPI_PORT &= ~(1<<SPI_CS);
// Start Address transmission (MOSI)
SPDR = addr;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Start Data transmission (MOSI)
SPDR = dataout;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
// Disable CS Pin
SPI_PORT |= (1<<SPI_CS);
}
char digit[10] = {0,0,0,0,0,0,0,0,0,0};
digit[0] = 0x7E
digit[1] = 0x30
digit[2] = 0x6D
digit[3] = 0x79
digit[4] = 0x33
digit[5] = 0x5B
digit[6] = 0x5F
digit[7] = 0x70
digit[8] = 0x7F
digit[9] = 0x7B
void main()
{
char ch;
char digits_disp[10] = {0,0,0,0,0,0,0,0,0,0};
ch = digits_disp[3];
}
this is a very basic code. I am designing a clock using the MAX 7219 display driver. Before i go into the detail of it, I wanted to get a basic code working where I will initialise the SPI and then declare the value of each character using the datasheet of MAX7219 and then just write a short array to display random numbers. But this code is not working propoerly and keeps saying:
../exp3.c:45: error: conflicting types for 'digits_disp'
../exp3.c:44: error: previous definition of 'digits_disp' was here
Can you please help me on what I am doing wrong and could you tell me how I can initialize my array so that I can display the character '3' on my simulation? In other words, what line of code will i need to add in order to display the characters in my array?
Thank you.
I can't really make sense of your code, but this part of the code is syntactically invalid:
char digit[10] = {0,0,0,0,0,0,0,0,0,0};
digit[0] = 0x7E
digit[1] = 0x30
digit[2] = 0x6D
digit[3] = 0x79
digit[4] = 0x33
digit[5] = 0x5B
digit[6] = 0x5F
digit[7] = 0x70
digit[8] = 0x7F
digit[9] = 0x7B
You probably want to do this instead:
char digit[10] = { 0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B };
From the comment in the 1st line I gather you are using one of the Atmel chips. If so, here is the article that should help you:
http://www.adnbr.co.uk/articles/max7219-and-7-segment-displays
You can use their code as the starting point:
https://gist.github.com/adnbr/2352797
Here is also Arduino version in case anyone else is interested:
https://gist.github.com/nrdobie/8193350
I'm trying to shift my hex output to the left by one, so that I can display digits above 9 on a 7 segment lcd.
Programming on C, the software I'm using is NIOS II, so that I can reprogram straight onto a DE0 Board.
The aim of this project is to increment the value of the of the LCD by one each time 'button1' is pressed. I have done this successfully however of course after 9 it would need to shift to the left and restart from 1, replacing the position it came from with a 0. I've done a fair bit of research but haven't had any luck so any help is appreciated. Thanks.
Code is below:
#include "sys/alt_stdio.h" //for the alt_putstr function below. Outputs to Eclipse console
#include "altera_avalon_pio_regs.h" //for the I/O functions in the while loop below
#include "sys/alt_timestamp.h" //see Nios II Software Developer’s Handbook, Timestamp Driver
#include "system.h"
#define setHeaderOuts HEADEROUTPUTS_BASE+0x10 //HEADEROUTPUTS_BASE is defined in system.h of the _bsp file. It refers to the base address in the Qsys design
//the hex offset (in this case 0x10, which is 16 in decimal) gives the number of bytes of offset
//each register is 32 bits, or 4 bytes
//so to shift to register 4, which is the outset register, we need 4 * (4 bytes) = 16 bytes
#define clearHeaderOuts HEADEROUTPUTS_BASE+0x14 //to shift to register 5 (the 'outclear' register) we need to shift by 5 * (4 bytes) = 20 bytes, (=0x14 bytes)
// offset of 5 corresponds to the 'outclear' register of the PIO.
int main(void)
{
alt_putstr("This is the ELEE1062 version of the NIOS processor");
int buttons = 0; //the buttons on the DE0
//int switches = 0; //the switches on the DE0
int count = 0; //general purpose counter
int hexd = 0;
while(1)
{
buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons
while((buttons & 0x01) == 1) // i.e. while pushbutton 1 is not pressed
{
buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons
}
count=count+1;
IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,count); //display the value of count in binary, using the green LEDs
while((buttons & 0x01) == 0) //i.e. while pushbutton 1 is pressed
{
buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons
}
if (count==0)
{
hexd=0x000000c0;
}
else if (count==1)
{
hexd=0xf9;
}
else if ( count==2)
{
hexd=0xa4;
}
else if ( count==3)
{
hexd=0xb0;
}
else if ( count==4)
{
hexd=0x99;
}
else if ( count==5)
{
hexd=0x92;
}
else if ( count==6)
{
hexd=0x82;
}
else if ( count==7)
{
hexd=0xd8;
}
else if ( count==8)
{
hexd=0x80;
}
else if ( count==9)
{
hexd=0x90;
}
else if ( count>9)
{
hexd= hexd & ~(1<<count);
}
//count=alt_timestamp_start(); //start the timer. Timer increments each clock cycle. Clock for ELEE1062_NIOS is 50MHz
//buttons=IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTONS1_2_BASE); //read the value of the pushbuttons
//switches=IORD_ALTERA_AVALON_PIO_DATA(DE0SWITCHES_BASE); //read the value of the switches
IOWR_ALTERA_AVALON_PIO_DATA(SSEG_BASE,hexd); //DE0 7 segment displays all off --notice that a logic '1' turns the segment off
IOWR_ALTERA_AVALON_PIO_DATA(SSEG_BASE,hexd); //DE0 7 segment displays all on
IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,0x000); //all off --for the green LEDs, a logic '0' turns the LED off
IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,0xfff); //all on
IOWR_ALTERA_AVALON_PIO_DATA(clearHeaderOuts,0x01); //turn off the first pin of the output port
IOWR_ALTERA_AVALON_PIO_DATA(setHeaderOuts,0x01); //turn on the first pin of the output port
//IOWR_ALTERA_AVALON_PIO_DATA(SSEG_BASE,switches); //light up the 7 segment display segments corresponding to how the DE0 switches are set
IOWR_ALTERA_AVALON_PIO_DATA(DE0_LEDS_BASE,buttons); //light up the green LEDs corresponding to which DE0 buttons are pushed
//count=alt_timestamp(); //record the value of the timer, and store in the 'count' variable
}
}
Merely shifting won't work. 9 -> 10 (you can call this shifting) but what about 19 -> 20? Since it is clearly a homework or other form of learning, I will not write code for you. You ultimate goal is to represent numbers on 7 segment led display. Think from that. So as an input you have binary number (count) and output should be led pin signals. Your task is to convert one into another. Led is operating essentially with decimal radix, so you first need to convert binary to series of decimal digits and then convert them to pin signals (this code you have already). To use all four digits you need to convert your number into format 0x11223344 where number denotes led position. 0xF9A4B099 is 1234 (if I am not mistaken).
The following function will return a u32 value composed of four bytes with LED values for the digit display. Note that I don't know what order your display wants the digit in, so you might need to byteswap the return value or something. Also, this function will provide leading zeros for the LED display - you might need to modify things so those show as blanks on the display.
typedef unsigned int u32;
static char led_digits[] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90 };
u32 four_digits( int x)
{
unsigned char c[4];
int i;
for (i = 0; i < 4; ++i)
{
int digit = x % 10;
x = x / 10;
c[i] = led_digits[digit];
}
return (u32)(c[3] << 24) | (u32)(c[2] << 16) | (u32)(c[1] << 8) | (u32)c[0];
}
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);
}