amd, la Jul 12 2009, 08:45 PM, a spus:
@hash84 ce program folosesti pt programare? ( daca este c++ te mai pot ajuta cu idei)
bafta
dap. e c.
dar nu e vorba de asta. programul merge ok pe simulator dupa cum am spus, reiau maine cablajul. poate am gresit ceva.
asta e codul pana acum
/*
* main.c
*
* Created on: 12.07.2009
* Author: hash
*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <stdlib.h>
#include <math.h>
#include <util/delay.h>
#define Wait() while(!(SPSR & (1<<SPIF)))
unsigned char line;
uint16_t volatile adc_value;
unsigned char tens[5];
char t2;
const unsigned char head[11] = {'H','A','S','H','8','4','@','O','S','D'};
// ' ' A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
unsigned char ltrs[189] = { 0, 24,124, 60,120,126,126, 60, 66,124,126, 66, 64,130,130, 60,124, 60,124, 60,124, 66, 66,130,130,130,254,
0, 36, 66, 66, 68, 64, 64, 66, 66, 16, 8, 68, 64,198,194, 66, 66, 66, 66, 66, 16, 66, 66,130, 68, 68, 4,
0, 66, 66, 64, 66, 64, 64, 64, 66, 16, 8, 72, 64,170,162, 66, 66, 66, 66, 64, 16, 66, 66,146, 40, 40, 8,
0, 66,124, 64, 66,124,124, 78,126, 16, 8,112, 64,146,146, 66,124, 66,124, 60, 16, 66, 36,146, 16, 16, 16,
0,126, 66, 64, 66, 64, 64, 66, 66, 16, 8, 72, 64,130,138, 66, 64, 76, 72, 2, 16, 66, 36,146, 40, 16, 32,
0, 66, 66, 66, 68, 64, 64, 66, 66, 16, 72, 68,126,130,134, 66, 64, 70, 68, 66, 16, 66, 36,108, 68, 16, 64,
0, 66,124, 60,120,126, 64, 60, 66,124, 48, 66,126,130,130, 60, 64, 50, 66, 60, 16, 60, 24,108,130, 16,254};
// - . / 0 1 2 3 4 5 6 7 8 9 :
unsigned char nums[98] = { 0, 0, 48,124, 16,124,124, 28,254,124,254,124,124, 0,
0, 0, 68,130, 48,130,130, 36,128,128, 2,130,130, 16,
0, 0, 68,130, 16, 2, 2, 68,128,128, 4,130,130, 0,
124, 0, 48,130, 16, 12, 28,132,124,252, 8,124,126, 0,
0, 0, 0,130, 16, 48, 2,254, 2,130, 16,130, 4, 0,
0, 24, 0,130, 16, 64,130, 4,130,130, 16,130, 8, 16,
0, 24, 0,124, 56,254,124, 4,124,124, 16,124, 48, 0};
void draw_line();
void adc_init(void);
void adc_start_conversion(uint8_t channel);
void read_tens();
ISR(ADC_vect) //intrerupere la terminarea conversiei
{
adc_value = ADCL;
adc_value += (ADCH<<8);
}
ISR(SIG_COMPARATOR)
/*******************************************************************************
*
* ABSTRACT: Triggered on an NTSC sync pulse. This routine determines if it
* is an H or V sync and acts according - eithe resets line counter,
* or increments line counter and calls draw_line().
*
* INPUT: None
* OUTPUT: None
* RETURN: None
*/
{
TCNT0=0; // reset timer
TCNT2=108; // reset 80us interrupt
while(TCNT0<74); // wait 5us to see if H or V sync
if(!((ACSR>>ACO)&1)) { // its an H sync
TCNT0=0; // reset timer
line++;
draw_line();
}
else { // tis a V sync
line=0;
}
} // End SIGNAL(SIG_COMPARATOR)
/******************************************************************************/
ISR(SIG_OVERFLOW2)
/*******************************************************************************
* ABSTRACT: This interrupt will occur if sync is lost - no sync pulses for 80us.
* it is very important that we keep reading the serial port even if
* sync is lost, otherwise intermittent sync can cause corruption of
* the serial datastream because you can get a few chars, miss a few
* (no sync), and get some more... and things get messed up. If we read
* serial port either here or on a line, then we're in good shape.
* INPUT: None
* OUTPUT: None
* RETURN: None
*/
{
TCNT2=108; // reset 80us interrupt
line=0;
read_tens();
}
int main()
{
// PORT B - Video Out
//PB0 used for background dimming
PORTB = 0x00; // Initial state is everything off
DDRB = 0x3E; // Data direction register for port B
// PORT D - Not really used
// Bit/Pin 2 (out) connected the control line on a servo
PORTD = 0x00; // Initial state is everything off
DDRD = 0x00; // Data direction register for port D
//enable the SPI port
SPDR = 0; //CLEAR THE SPI DATA REGISTER!!! OR WILL HOSE THE VIDEO RANDOMLY IF NOT CLEARED!
SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA);
SPSR = 1;
TCCR0 = 0x01; //enable timer w/ no prescaling
TCCR2 = 0x02; //enable timer with /8 prescale
TCNT2 = 108; //overflow will happen after 80us
TIMSK = 1<<TOIE2;
// Initialize the Analog Comparator
SFIOR = 0; // Select AIN1 as neg. input
ACSR = (1<<ACIE)|(1<<ACIS0)|(1<<ACIS1);
line=0; //reset the line counter
adc_init();
// Enable interrupts
sei();
adc_start_conversion(0);
// Initialization complete - system ready. Run program loop indefinitely.
//DDRD=0xff;
while (1)
{
//sleep_mode ();
//read_tens();
}
return(1);
}
void adc_init(void) //initializare modul ADC
{
ADMUX|=(0<<REFS1)|(1<<REFS0); //selectare referinta AREF
ADCSRA |= (1<<ADEN)|(1<<ADIE); //ADC eneble, activare intrerupere
MCUCR|=(1<<SM0)|(0<<SM2)|(0<<SM1); //sleep mode adc noise reduction
}
void adc_start_conversion(uint8_t channel) //conversie adc pe pinul channel
{
ADMUX=(ADMUX&0xF0)|channel; //mux4-0 = canalul care il vrem convertit
ADCSRA |= (1<<ADSC)|(1<<ADIE); //start conversie, activare intrerupere
}
void read_tens()
{
uint8_t t;
uint8_t i;
adc_start_conversion(0);
for(i=0;i<4;i++)
tens[i]='0';
i=0;
while(adc_value!=0)
{
t=adc_value % 10;
if(t==0)
t2='0';
else if(t==1)
t2='1';
else if(t==2)
t2='2';
else if(t==3)
t2='3';
else if(t==4)
t2='4';
else if(t==5)
t2='5';
else if(t==6)
t2='6';
else if(t==7)
t2='7';
else if(t==8)
t2='8';
else if(t==9)
t2='9';
tens[i]=t2;
adc_value=adc_value/10;
i++;
}
}
void draw_line()
/*******************************************************************************
* ABSTRACT: Either outputs stuff to the screen for the current line or
* if there is nothing to be output for the line, does some
* processing.
*
* INPUT: None
* OUTPUT: None
* RETURN: None
*/
{
unsigned char *ltr_p;
unsigned char *num_p;
//unsigned char i, j;
short ltemp;
short ntemp;
//char str[10];
tens[0]=t2;
if ((line > 40) && (line < 48))
{
SPSR=1;
ltemp = (line - 41) * 27 - 64;
ntemp = (line - 41) * 14 - 45;
ltr_p = ltrs+ltemp; //by calculating this pointer you only have to
num_p = nums+ntemp; //add ltemp/ntemp once per line, instead of for
//every char. This tightens up printing a bit
//saves about 3 assembly instructions per char
SPDR = ltr_p['@']; Wait(); //goofy hack to make SPSR=0 work, write an empty char at SPSR=1 first
SPSR=0;
while(TCNT0<113); //wait ~7.5us from H-sync
DDRB|=1; //sink thru PB0
SPDR = ltr_p[head[0]]; Wait();
SPDR = ltr_p[head[1]]; Wait();
SPDR = ltr_p[head[2]]; Wait();
SPDR = ltr_p[head[3]]; Wait();
SPDR = num_p[head[4]]; Wait();
SPDR = num_p[head[5]]; Wait();
SPDR = ltr_p[head[6]]; Wait();
SPDR = ltr_p[head[7]]; Wait();
SPDR = ltr_p[head[8]]; Wait();
SPDR = ltr_p[head[9]]; Wait();
SPSR=0;
TCNT0=0;
while(TCNT0<3); // wait a little bit before turning off dimmer so that the
// length of black box on the right matches the one on the left
DDRB&=0xFE; //PB0 Hi-Z again, and load a blank so spacing is right
}
else if ((line > 210) && (line < 218)) //Battery1 voltage
{
ltemp = (line - 211) * 27 - 64;
ntemp = (line - 211) * 14 - 45;
ltr_p = ltrs+ltemp;
num_p = nums+ntemp;
SPSR = 1;
while(TCNT0<60); //wait ~4us from H-sync
DDRB|=1; //sink thru PB0
SPDR = ltr_p['V']; Wait();
SPDR = num_p['1']; Wait();
SPDR = num_p[':']; Wait();
SPDR = num_p[tens[3]]; Wait();
SPDR = num_p[tens[2]]; Wait();
SPDR = num_p[tens[1]]; Wait();
SPDR = num_p[tens[0]]; Wait();
SPSR=0;
DDRB&=0xFE; //PB0 Hi-Z again, no extra blanking here because it barely fits onscreen
}
}