====== 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 =====
/*
Basic ver 3 demo program
7-seg function and demo
Raivo Sell/Erki Leitaru
*/
#define F_CPU 14745600UL
#include
#include
#define SET(x) |= (1<=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();
}
}
===== 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.
//
// Simple up/down counting single 7-segment digit example.
//
// Raivo Sell, Erki Leitaru, Mikk Leini
//
// 2009
//
#define F_CPU 14745600UL
// Include avrlibc
#include
#include
// 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);
}
}
===== 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.
//
// Simple up/down counting single 7-segment digit example.
//
// Raivo Sell, Erki Leitaru, Mikk Leini
//
// 2009
//
// Include avrlibc
#include
#include
// Include common library
#include "pinops.h"
/* PS! For distance Lab use:
#include
*/
// 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);
}
}
===== Liens externes =====
[[http://en.wikipedia.org/wiki/Seven-segment_display|7-segment display in Wikipedia]]