This is an old revision of the document!


7-segment numeric display

The Study board is equipped with 7-segment LED display and its driver A6275 (datasheet). The driver is connected to controller ports PORTC and PORTG.

the schematics is shown below. The latch is connected to PORTG2, Serial to PORTC6 and clock to PORTC7.

7seg_schematics.jpg

Example 1

/* 
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();
	}
}

Example 2

this example does not contain global variables and only functions are used. It is more easy to copy the functions into user program. All variables are 8 bit where possible.

//
// 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);
	}
}

Example 3

“pinops.h” library is used to simplify the port and pin usage. See here for more detail description.

LED driver is replaced by the avrlibc driver.

//
// 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);
	}
}
en/examples/digi/7seg.1237962744.txt.gz · Last modified: 2020/07/20 09:00 (external edit)
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