Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
fr:examples:digi:7seg [2009/03/25 11:16] sdeniaudfr:examples:digi:7seg [2020/07/20 12:00] (current) – external edit 127.0.0.1
Line 1: Line 1:
 +====== Afficheur numérique 7 segments ======
 +
 +{{:examples:7-seg.jpg|}}
 +
 +La carte d'étude est équipée d'un affichage à LED 7 segments et de son pilote A6275 ({{:examples:datasheets:a6275_led_driver.pdf|datasheet}}).
 +Le pilote est connecté aux ports PORTC et PORTG du contrôleur.
 +
 +Le schéma est présenté ci-dessous. Le //latch// est connecté à PORTG2, le //Serial// à PORTC6 et l'horloge à PORTC7.
 +
 +{{:examples:7seg_schematics.jpg?500}}
 +
 +
 +===== Exemple 1 =====
 +
 +<code c>
 +/* 
 +Basic ver 3 demo program
 +7-seg function and demo
 +Raivo Sell/Erki Leitaru
 +*/
 +#define F_CPU 14745600UL
 +
 +#include <avr/io.h>
 +#include <util/delay.h>
 +
 +#define SET(x) |= (1<<x)  //defineeritakse kõrge bit pordis x
 +#define CLR(x) &=~(1<<x)  //defineeritakse madal bit pordis x
 +#define bit_get(p,m) ((p) & (m)) //returns 1 if bit is set, otherwise returns 0
 +#define BIT(x) (0x01 << (x))
 +
 +void write_display (void);
 +void nop_delay(int count);
 +
 +int i;//for cycle
 +int digit;//digit to display on segment
 +int nr;//segment map representation of the digit
 +int delta;//to create a counting effect
 +int num = 0;
 +char buffer[7];
 +
 +void nop_delay(int count){
 + unsigned int j;
 + for (j=0; j<count;j++) {asm volatile ("nop");}
 +}
 +
 +void write_display (void) {
 + switch (digit) //table read to get segment map representation of the digit
 + {
 + case 0 : nr = 0b00111111;break; //every bit corresponds to one segment
 + case 1 : nr = 0b00000110;break; //"1"
 + case 2 : nr = 0b01011011;break; //"2" and so on
 + case 3 : nr = 0b01001111;break; 
 + case 4 : nr = 0b01100110;break; 
 + case 5 : nr = 0b01101101;break; 
 + case 6 : nr = 0b01111100;break; 
 + case 7 : nr = 0b00000111;break;
 + case 8 : nr = 0b01111111;break; 
 + case 9 : nr = 0b01100111;break;  
 + default: nr = 0b01111001;//E
 + }
 +
 + PORTG CLR (2); //latch low
 + for(i=7; i>=0; i--) //for every bit in the byte
 + {
 + //if bit is set, sets the data out pin
 + if (bit_get(nr, BIT(i))) PORTC SET (6); //serial out
 + else PORTC CLR (6); //serial out
 +
 + PORTC SET (7); //clock high
 + nop_delay(8);//series of one cycle delays to ensure required timing (according to datasheet)
 +
 + PORTC CLR (7); //clock low
 + nop_delay(8);
 + }
 + PORTG SET (2); //latch high
 +
 +}
 +
 +int main(void){
 +
 + //7-seg init
 +    PORTC = 0xFF; // set output high -> turn all LEDs off
 +    DDRC  = 0xF8; // PC0...PC2 -> input; PC3...PC5 -> output for LED; PC7 & PC6 outputs for clock and data
 + DDRG  = 0x04;//PG2 is latch output
 +
 + digit = 8;
 + delta = 1;//increment or decrement
 +
 + while(1) {
 + num++;
 + _delay_ms(1000);
 + digit=digit+delta;//change digit by delta
 + if(digit>8) {delta=-1*delta;};//upper limit
 + if(digit<1) {delta=-1*delta;};//lower limit
 + write_display();
 + }
 +}
 +
 +</code>
 +
 +===== Exemple 2 =====
 +
 +Cet exemple ne contient pas de variables globales, uniquement des fonctions sont utilisées. Il est plus facile de copier les fonctions dans le programme de l'utilisateur. Toutes les variables sont en 8 bits là ou cela est possible.
 +
 +<code c>
 +//
 +// Simple up/down counting single 7-segment digit example.
 +//
 +// Raivo Sell, Erki Leitaru, Mikk Leini
 +//
 +// 2009
 +//
 +#define F_CPU 14745600UL
 +
 +// Include avrlibc
 +#include <avr/io.h>
 +#include <util/delay.h>
 + 
 +// Macros for bit manipulation
 +#define BIT(x) (1 << (x))
 +#define SET(x) |=  BIT(x)
 +#define CLR(x) &= ~BIT(x)
 +#define SETTO(value, bit, to) value = ((to) ? value | BIT(bit) : value & ~BIT(bit)) 
 +#define ISSET(value, bit) ((value) & (BIT(bit)))
 +
 +//
 +// Delay cycle
 +// On each cycle "no-operation" instruction is executed
 +//
 +void nop_delay(unsigned int count)
 +{
 + for (unsigned int i = 0; i < count; i++)
 + {
 + asm volatile ("nop");
 + }
 +}
 +
 +//
 +// 7 segment display initialization
 +//
 +void segment_diplay_init(void)
 +{
 + // Port C pin 7 - clock output, pin 6 data output
 + DDRC |= 0xC0; 
 +
 + // Port G pin 2 - latch output
 + DDRG |= 0x04;
 +}
 +
 +//
 +// Digit writing to 7 segment display
 +//
 +void segment_display_write(unsigned char digit)
 +{
 + unsigned char map;
 +
 + // Decimal to segment map
 + switch (digit)
 + {
 + case 0 : map = 0b00111111; break; // Every bit corresponds to one segment
 + case 1 : map = 0b00000110; break; // "1"
 + case 2 : map = 0b01011011; break; // "2"
 + case 3 : map = 0b01001111; break; // "3" and so on
 + case 4 : map = 0b01100110; break; 
 + case 5 : map = 0b01101101; break; 
 + case 6 : map = 0b01111100; break; 
 + case 7 : map = 0b00000111; break;
 + case 8 : map = 0b01111111; break; 
 + case 9 : map = 0b01100111; break;  
 + default: map = 0b01111001;        // E like Error
 + }
 +
 + // Latch low
 + PORTG CLR(2);
 +
 + // Send every bit in the byte. MSB (most significant bit) first.
 + for (signed char i = 7; i >= 0; i--)
 + {
 + // If bit is set, sets the data out pin, otherwise not
 + SETTO(PORTC, 6, ISSET(map, i));
 +
 + // Clock high for certain period
 + PORTC SET(7); 
 + nop_delay(8);
 +
 + // Clock low for certain period
 + PORTC CLR(7);
 + nop_delay(8);
 + }
 +
 + // Latch high 
 + PORTG SET(2); 
 +}
 +
 +//
 +// Program entrance function
 +//
 +int main(void)
 +
 + unsigned char digit = 0; // Digit to display on segment
 + signed char delta = 1;   // Digit modifying value
 +
 + // 7 segment display initialization
 + segment_diplay_init();  
 + 
 +  // Endless loop
 + while (1)
 + {
 + // Write digit
 + segment_display_write(digit);
 +
 + // Increase digit value by delta (which can be negative also)
 + digit += delta;
 +
 + // Swap counting direction on 0 and 9
 + if (digit == 0) delta = +1;
 + if (digit == 9) delta = -1;
 +
 + // Wait 1000 ms
 + _delay_ms(1000);
 + }
 +}
 +</code>
 +
 +===== Exemple 3 =====
 +
 +La bibliothèque "pinops.h" est utilisée pour simplififier l'usage du port et du pin.  [[en:examples:pinops|Voir ici]] pour une description plus détaillée.
 +
 +Le pilote des LED est remplacé par le pilote avrlibc.
 +
 +<code c>
 +//
 +// Simple up/down counting single 7-segment digit example.
 +//
 +// Raivo Sell, Erki Leitaru, Mikk Leini
 +//
 +// 2009
 +//
 +
 +// Include avrlibc
 +#include <avr/io.h>
 +#include <util/delay.h>
 +
 +// Include common library
 +#include "pinops.h"
 +
 +/* PS! For distance Lab use:
 +#include <util/pinops.h>
 +*/
 + 
 +// Configure pins
 +#define SEGMENT_DISPLAY_LATCH      PORTPIN(G, 2)
 +#define SEGMENT_DISPLAY_DATA_OUT   PORTPIN(C, 6)
 +#define SEGMENT_DISPLAY_CLOCK      PORTPIN(C, 7)
 +
 +//
 +// 7 segment display initialization
 +//
 +void segment_display_init(void)
 +{
 + // Set latch, data out and clock pins as output
 + setup_output_pin(SEGMENT_DISPLAY_LATCH);
 + setup_output_pin(SEGMENT_DISPLAY_DATA_OUT);
 + setup_output_pin(SEGMENT_DISPLAY_CLOCK);
 +}
 +
 +//
 +// Digit writing to 7 segment display
 +//
 +void segment_display_write(unsigned char digit)
 +{
 + unsigned char map;
 +
 + // Decimal to segment map
 + switch (digit)
 + {
 + case 0 : map = 0b00111111; break; // Every bit corresponds to one segment
 + case 1 : map = 0b00000110; break; // "1"
 + case 2 : map = 0b01011011; break; // "2"
 + case 3 : map = 0b01001111; break; // "3" and so on
 + case 4 : map = 0b01100110; break; 
 + case 5 : map = 0b01101101; break; 
 + case 6 : map = 0b01111100; break; 
 + case 7 : map = 0b00000111; break;
 + case 8 : map = 0b01111111; break; 
 + case 9 : map = 0b01100111; break;  
 + default: map = 0b01111001;        // E like Error
 + }
 +
 + // Latch low
 + clear_pin(SEGMENT_DISPLAY_LATCH);
 +
 + // Send every bit in the byte. MSB (most significant bit) first.
 + for (signed char i = 7; i >= 0; i--)
 + {
 + // If bit is set, sets the data out pin, otherwise not
 + set_pin_to(SEGMENT_DISPLAY_DATA_OUT, IS_BIT_SET(map, i));
 +
 + // Clock high for certain period
 + set_pin(SEGMENT_DISPLAY_CLOCK)
 + _delay_us(1);
 +
 + // Clock low for certain period
 + clear_pin(SEGMENT_DISPLAY_CLOCK)
 + _delay_us(1);
 + }
 +
 + // Latch high
 + set_pin(SEGMENT_DISPLAY_LATCH);
 +}
 +
 +//
 +// Program entrance function
 +//
 +int main(void)
 +
 + unsigned char digit = 0; // Digit to display on segment
 + signed char delta = 1;   // Digit modifying value
 +
 + //digit = int (void) { return 2; }; 
 +
 + // 7 segment display initialization
 + segment_display_init();  
 + 
 +  // Endless loop
 + while (1)
 + {
 + // Write digit
 + segment_display_write(digit);
 +
 + // Increase digit value by delta (which can be negative also)
 + digit += delta;
 +
 + // Swap counting direction on 0 and 9
 + if (digit == 0) delta = +1;
 + if (digit == 9) delta = -1;
 +
 + // Wait 1000 ms
 + _delay_ms(1000);
 + }
 +}
 +</code>
 +
 +===== Liens externes =====
 +[[http://en.wikipedia.org/wiki/Seven-segment_display|7-segment display in Wikipedia]]
  
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0