کد:
/*****************************************************
Project : 4-Bit LED Digital Tube Module
Version :
Date : 8/15/2014
Author : axar
email : ashit.axar@gmail.com
Comments: majul az yek register baraye nemayeshe 4 neviseh
bekar mibarad. cham ke bayad khataye did besazim.
pas LED_PROC() bayad 4 bar faraxani shavad ta 4 neviseh
beja neshan dadeh shavand. [ According to 74HC595 datasheet ]
yek moqavemat 1k ohm be VCC majul peyvast konid.
tip : har anche nemiruyad fana miyabad, berueed,
begostarid jane bahar ra.
Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 16.000000 MHz
*****************************************************/
#include <mega8.h>
// MCU Frequency
#define xtal 16000000UL
#include <delay.h>
#include <stdio.h>
// Display module pin definitions
#define DIO PORTB.1
#define RCLK PORTB.2
#define SCLK PORTB.3
// you may write your own character sources.
const unsigned char LED_SRC[] =
{// 0 1 2 3 4 5 6 7 8 9
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,
// A b C d E F -
0x8C,0xBF,0xC6,0xA1,0x86,0xFF,0xbf,0xff
};
unsigned char LED_BUFF[4];
void LED_SEND(unsigned char digit)
{
unsigned char counter;
for (counter = 8; counter > 0; counter--)
{
if (digit & 0x80) DIO = 1;
else DIO = 0;
delay_us(5);
digit <<= 1;
SCLK = 0;
delay_us(5);
SCLK = 1;
}
}
void LED_PROC(void)
{
static unsigned int shift;
switch(shift)
{
case 0:
// digit 1
LED_SEND(LED_BUFF[0]);
LED_SEND(0x01);
RCLK = 0;
delay_us(5); // (optional: just for sure)
RCLK = 1;
break;
case 1:
// digit 2
LED_SEND(LED_BUFF[1]);
LED_SEND(0x02);
RCLK = 0;
delay_us(5); // (optional: just for sure)
RCLK = 1;
break;
case 2:
// digit 3
LED_SEND(LED_BUFF[2]);
LED_SEND(0x04);
RCLK = 0;
delay_us(5); // (optional: just for sure)
RCLK = 1;
break;
case 3:
// digit 4
LED_SEND(LED_BUFF[3]);
LED_SEND(0x08);
RCLK = 0;
delay_us(5); // (optional: just for sure)
RCLK = 1;
break;
}
if (shift > 3) shift = 0;
else shift++;
}
void LED_DISPLAY(unsigned char * data)
{
LED_BUFF[0] = LED_SRC[*(data + 0)];
LED_BUFF[1] = LED_SRC[*(data + 1)];
LED_BUFF[2] = LED_SRC[*(data + 2)];
LED_BUFF[3] = LED_SRC[*(data + 3)];
}
// you may write your own parser function [optional]
// i have used this instead LED_DISPLAY()
void LED_PARSE(unsigned char * str)
{
unsigned char counter = 0;
const unsigned char LED_MSK[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F -
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'b', 'C', 'd', 'E', 'F', '-', ' '
};
LED_BUFF[0] = LED_SRC[17]; // left most digit
for (counter = 0; counter < 17; counter++)
if (LED_MSK[counter] == *(str + 3))
LED_BUFF[0] = LED_SRC[counter];
LED_BUFF[1] = LED_SRC[17];
for (counter = 0; counter < 17; counter++)
if (LED_MSK[counter] == *(str + 2))
LED_BUFF[1] = LED_SRC[counter];
LED_BUFF[2] = LED_SRC[17];
for (counter = 0; counter < 17; counter++)
if (LED_MSK[counter] == *(str + 1))
LED_BUFF[2] = LED_SRC[counter];
LED_BUFF[3] = LED_SRC[17];
for (counter = 0; counter < 17; counter++) // right most digit
if (LED_MSK[counter] == *(str + 0))
LED_BUFF[3] = LED_SRC[counter];
}
// 1ms Async loop
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0x06;
// 4 cycles/calls needed to complete task
LED_PROC();
}
void main(void)
{
unsigned char display[4];
unsigned int counter = 0;
PORTB = 0x00;
DDRB = 0x0E;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 250.000 kHz
TCCR0=0x03;
TCNT0=0x06;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// Global enable interrupts
#asm("sei")
LED_PARSE("----");
delay_ms(1000);
while (1)
{
sprintf(display, "%4u", counter);
LED_PARSE(display);
counter++;
if (counter >= 10000) counter = 0;
delay_ms(1000);
}
}
در زیر کد هگز برنامه رو برای ATMega8 کامپایل کردم که می تونید پروگرام کنید. این برنامه از 0 تا 9999 می شمارد.