ITGenerations
[avr] 세븐세그먼트 1씩 증가 본문
// source 25
/*
1씩 증감 코드
최대값 99
99넘어가면 0으로 100 으로 되서 초기화 됨
세그먼트 보면서 1과 10의 자리가
다르게 나오면 portd 6,8 바꿔 주면댐
*/
*/
#include <avr/interrupt.h>
#include <util/delay.h>
#include "iseg7.h"
void msec_delay(int n);
int main()
{
unsigned short data=0;
ISeg7Init();
sei();
while(1)
{
msec_delay(100);
data+=1;
ISeg7DispNum(data,10);
}
}
void msec_delay(int n)
{
for(; n>0; n--)
_delay_ms(1);
}
*/
/* 호출 소스
//=================================================
// iseg7.c : 인터럽트를 사용한 4자리
// 7-세그먼트 동적 표시 프로그램
//=================================================
#include <avr/io.h>
#include <avr/interrupt.h>
#include "iseg7.h" // 7-세그먼트 구동 헤더파일
#define N_BUF 5 // 수를 저장할 버퍼의 크기
#define N_SEGMENT 4 // 7-세그먼트의 개수
#define SSEG_CONT PORTD // 7세그먼트 제어 포트
#define DDR_CONT DDRD
#define SSEG_DATA PORTA // 7세그먼트 데이터 포트
#define DDR_DATA DDRA
#define CONT_MASK ((1<<PD7)|(1<<PD6)|(1<<PD5)|(1<<PD4))
//제어 포트로 사용하는 포트 마스크
#define OUTPUT_VALUE (1<<PD4)//제어 포트 중 최하위 비트로 설정
//=======================================================
// 수에 대한 7-세그먼트의 코드
// 마지막 코드 SegTable[16]은 세그먼트를 끄는 데 사용
//=======================================================
static unsigned char SegTable[17] // 7-세그먼트 코드 값
= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x6F, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71,
0x00};
//--------------------------
// 수를 저장할 배열
// cnumber[0] : 1자리수 저장
// cnumber[1] : 10자리수 저장
// . . .
//--------------------------
static unsigned char cnumber[N_BUF]
= {16,16,16,16,16}; // 초기에 모두 끈다.
//====================================================
// 7-세그먼트의 제어/데이터 포트 초기화 및 타이머/카운터 초기화
//====================================================
void ISeg7Init()
{
SSEG_CONT |= CONT_MASK; // 모든 7-세그먼트를 끈다.
DDR_CONT |= CONT_MASK; // 제어포트의 상위니블을
// 출력으로 설정
DDR_DATA = 0xFF; // 테이터포트는 모두 출력으로 설정
// 타이머/카운터 0 비교일치 인터럽트 설정
// 타이머/카운터 0는 CTC 모드로 동작
TCCR0 = (1<<WGM01); // CTC 모드/타이머 정지, OC0 핀 미사용
OCR0 = 78; // 5msec마다 비교일치 인터럽트 발생
TIMSK |= (1<<OCIE0);// 타이머 0 비교일치 인터럽트 허용
TCCR0 |= 0x07; // 분주비 1024로 타이머 시작
}
//====================================================
// 2바이트 부호 없는 정수를 받아 주어진 진법으로 4자리
// 7-세그먼트에 동적으로 표시하는 함수
// (이 함수는 각 세그먼트에 표시할 숫자를 cnumber[]배열에
// 저장만 한다. 실제 표시는 인터럽트 서비스루틴에서 수행한다.)
// 입력 : num - 7-세그먼트에 표시할 수
// radix - 사용 진법
//=====================================================
void ISeg7DispNum(unsigned short num,
unsigned short radix)
{
int j;
//--------------------------------------------------
// cnumber[0] ~ cnumber[N_BUF-1] = 16: 세그먼트를 끈다.
//--------------------------------------------------
TIMSK &= ~(1<<OCIE0); //타이머 0 비교일치 인터럽트 금지
for(j=0; j<N_BUF; j++) cnumber[j] = 16;
j=0; // 1자리를 가리킴
do
{
cnumber[j++] = num % radix; //나머지
num /= radix; // 몫
}while(num);
TIMSK |= (1<<OCIE0); //타이머 0 비교일치 인터럽트 허용
}
//====================================================
// 인터럽트 서비스 루틴
//
// 인터럽트가 걸릴 때마다 index가 가리키는 세그먼트에 데이터를
// 표시하고, index는 계속 회전 이동하게 된다.
//=====================================================
//
ISR(TIMER0_COMP_vect) // 카운터/타이머 0 비교일치 인터럽트
{
static int index = 0;
// 현재 index가 가리키는 자리수를 표시한다.
SSEG_CONT = (SSEG_CONT & ~CONT_MASK) |
(~(OUTPUT_VALUE<<index) & CONT_MASK);
SSEG_DATA = ~SegTable[cnumber[index]];
index++; // 인덱스 이동
if(index == N_SEGMENT) index = 0;
}
*/
/*
// 해더파일 소스
//======================================================================
// iseg7.h : 인터럽트를 사용한 7-세그먼트
// 동적 구동 프로그램의 헤더파일
//======================================================================
#ifndef __ISEG7_H__
#define __ISEG7_H__
void ISeg7Init(void);
void ISeg7DispNum(unsigned short num,
unsigned short radix);
void ISeg7DispStr(unsigned char *str);
#endif
*/
'Univ > AVR atmega128' 카테고리의 다른 글
[avr]키패드 입력, 세븐세그먼트 [실패] (0) | 2017.12.09 |
---|---|
세븐 세그먼트 + 키패드 (0) | 2017.12.09 |
[avr] 세븐세그먼트/트랜지스터 사용 o (0) | 2017.12.09 |
[avr]세븐세그먼트, 트랜지스터 사용 x (0) | 2017.12.09 |
[avr] 타이머 (0) | 2017.12.08 |