Nahodne zmeny na RB7 porte

NA ATmega8 sa mi pri vykonavani programu nahoodne zostane vystup portu B7 bud v log0 alebo log1. Pricom ostatne porty sa obsuhuju v tom istom podprograme a idu. Nevie niekto cim by to mohlo byt. Int oscilator 8Mhz. prerusenie od ADC A TIMER1_COMPA_vect. DAKUJEM

Bez programu ti k tomu těžko někdo něco řekne. Schéma (alespoň těsné blízkosti mcu, hlavně napájení) by taky nebylo od věci.

upravujem schemu nabijacky NiMH z jednej stranky…je to uvedene v programe…

/oooooooooooooooooooooooooooooooooooooooooooo
oooooooooo ooooooooo
oooooooooo PROGRAM: NiMH Charger ooooooooo
oooooooooo Version: 1.0 ooooooooo
oooooooooo SOLARSKI © 2005/12 ooooooooo
oooooooooo ATtiny26-8PI ooooooooo
oooooooooo Q = 8 MHz intRC ooooooooo
oooooooooo t = 125 ns ooooooooo
oooooooooo ooooooooo
oooooooooooooooooooooooooooooooooooooooooooo
/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
//#include <avr/signal.h>
//#include “komunikacia.h”
#include “serial.h”
#define F_CPU 8000000UL //Definovanie názvu F_CPU ako hodnotu 1000000HZ
#include <util/delay.h> //knižnica pre oneskorenia

static FILE mystdout = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE);

void init_ports(void); // definovani vystupu
void init_timer1(void); // nastaveni casovace
void init_adc(void); // nastaveni AD prevodniku
//void delay(unsigned long time); // procedura zpozdeni na instrukcich
unsigned int i = 0; // globalni
// promenne pro AD
unsigned long prumer = 0; // kvuli “poskakovani” hodnoty se pocita prumer -]
unsigned int Uaku[4] = {0,0,0,0}; // vypoctene napeti [mV]
unsigned int ctU = 0; // pocitadlo pro vypocet prumeru
unsigned char adF = 0; // priznak v pokracovani dalsiho prevodu
// pomenne pro nabijeni
unsigned int Umax[4] = {0,0,0,0}; // hodnota maximalniho napeti [mV]
unsigned char chrgF[4] = {0,0,0,0}; // priznak nabijeni
unsigned int ctT = 0; // citac pro preruseni
unsigned int counter[4] = {0,0,0,0}; // citac kdy je merena hodnota rovna nebo mensi nez maximum
unsigned char newA[4] = {0,0,0,0}; // povoleni noveho nabijeni - rozpojeni smycky
unsigned char errF[4] = {0,0,0,0}; // priznak zkratu nebo vady jednotliveho clanku
unsigned char sel = 0; // promenna aktualne zpracovavaneho aku
unsigned int pocett = 0; //
unsigned int testt = 0;
// konstanty a promenne pro HoldOFF
const int hldOffT = 240;//240 // doba do kdy je vyrazen alg ukoncovani 24020010ms = 8min
unsigned int hldOffCT[4] = {0,0,0,0}; // citac
unsigned char hldOffF[4] = {0,0,0,0}; // ukonceni rezimu HoldOff
// systemove konstanty
const int Uref = 2560; // reference pro AD [mV] 2650
// podmiky ukonceni nabijeni
const int topT = 900; // doba vrcholu charakteristiky - 90020010ms = 30min
const char Ufall = 8; // pokles napeti od dosazeneho maxima
// konstanty pro casovani mereni napeti
const int measT = 200; // kazde 200*10ms = 2s se zmeri napeti
// konstanty pro rozliseni vstupu
const int Utop = 1700; // pokud je na vstupu vyssi napeti tak je smycka rozpojena
const int Ubot = 900; // nizsi napeti signalizuje zkrat nebo vadny clanek bolo 700
// konstanty pro piny portu
const char Aku1 = 0b00000100; // PD.2 vystup na vykonovy spinac pro aku1
const char Aku2 = 0b00010000; // PD.4 pro aku2
const char Aku3 = 0b10000000; // PB.7 pro aku3
const char Aku4 = 0b01000000; // PD.6 pro aku4
const char Led1 = 0b00001000; // PD.3 signalizacni LED pro Aku1
const char Led2 = 0b01000000; // PB.6 pro Aku2
const char Led3 = 0b00100000; // PD.5 pro Aku3
const char Led4 = 0b00000001; // PB.0 pro Aku4
//===== >> HLAVNI FUNKCE MAIN << ===============================================
int main(void) {

init_ports(); // nastaveni portu
init(); // init USART

init_adc(); // nastaveni AD prevodniku
init_timer1(); // nastaveni casovace
SREG |= 128; // globalni IRQ
// na zacatku se musi chvilku pockat nez se vsechno zmeri - efekt rozsvecujiciho se sloupce
PORTD |= Led1; _delay_ms(400);//delay(300000);
PORTB |= Led2; _delay_ms(400);//delay(300000);
PORTD |= Led3; _delay_ms(400);//delay(300000);
PORTB |= Led4; _delay_ms(400);//delay(300000);

PORTD &= 255-(Led1+Led3);
PORTB &= 255-(Led2+Led4);
// PORTB &= 255-(Led1+Led2+Led3+Led4);

stdout = &mystdout;           // Odteraz funguje printf();

/* Inicializacia grafickeho prgoramu */

_delay_ms(500); // Kratka 500 ms prestavka aby sa
// vyprazdnil buffer v PC
printf("!RSET\r"); // Reset vymaze okno
printf("!TITL Lahky Priklad\r"); // Nazov okna
printf("!SPAN 1355, 1480\r"); // Rozpatie pre analogove veliciny
printf("!PNTS 2050\r"); // Pocet bodov ktore kreslime
printf("!TMAX 30\r"); // Casova os 30 sekund
printf("!MAXR\r"); // Na konci stoj
printf("!TSMP ON\r"); // Casove znacky ANO
printf("!CLRM\r"); // Vymaz okienko na spravy
printf("!PLOT ON\r"); // Kreslenie ANO
printf("!RSET\r"); // Restart s novymi parametrami
_delay_ms(200); // Kratka 200 ms prestavka aby sa
// vyprazdnil buffer v PC
// Kratka 200 ms prestavka aby sa
// vyprazdnil buffer v PC

// nekonecna smycka
while(1) {
// signalizace nabijeni
if (chrgF[0]) { PORTD |= Led1; } else { PORTD &= 255-Led1; }
if (chrgF[1]) { PORTB |= Led2; } else { PORTB &= 255-Led2; }
if (chrgF[2]) { PORTD |= Led3; } else { PORTD &= 255-Led3; }
if (chrgF[3]) { PORTB |= Led4; } else { PORTB &= 255-Led4; }
// pokud je Uaku < Ubot LED blikaji - signalizace zkratu nebo vadneho clanku
if ( errF[0]|errF[1]|errF[2]|errF[3] ) {
_delay_ms(300);//delay(150000);
if (errF[0]) { PORTD |= Led1; }
if (errF[1]) { PORTB |= Led2; }
if (errF[2]) { PORTD |= Led3; }
if (errF[3]) { PORTB |= Led4; }
_delay_ms(300);//delay(150000);
PORTD &= 255-Led1;
PORTB &= 255-Led2;
PORTD &= 255-Led3;
PORTB &= 255-Led4;
}
// diagnosticky vystup holdoff
// if (!hldOffF[0]){ PORTB |= 8; } else { PORTB &= 255-8; }
// diagnosticky vystup zatizeni hlavni smycky
// PORTB = PINB^16; //PB4

if	(pocett==10000)
	{
/*	printf("Uaku1 %d Uaku2 %d Uaku3 %d Uaku4 %d\n",Uaku[0],Uaku[1],Uaku[2],Uaku[3]);
	sendchar (0x0d);

	printf("Umax1 %d Umax2 %d Umax3 %d Umax4 %d\n",Umax[0],Umax[1],Umax[2],Umax[3]);
	sendchar (0x0d);
	pocett=0;

*/
// printf("%d,%d,%d,%d\r",Uaku[0],Uaku[1],Uaku[2],Uaku[3]);

printf("%d\r",Uaku[1]);

	}
	pocett++;
	
	//	 printf("\n");
//	 sendchar (0x0d);

// printf("%c",znak1a);
/* printf(“Uaku1 %d Uaku2 %d Uaku3 %d Uaku4 %d\n”,Uaku[0],Uaku[1],Uaku[2],Uaku[3]);
sendchar (0x0d);

	printf("Umax1 %d Umax2 %d Umax3 %d Umax4 %d\n",Umax[0],Umax[1],Umax[2],Umax[3]);
	sendchar (0x0d);

*/
// printf(“Uaku1 %d Uaku2 %d Uaku3 %d Uaku4 %d\n”,Uaku[0],Uaku[1],Uaku[2],Uaku[3]);
// sendchar (0x0d);

//	printf("Uaku1 %d Uaku2 %d Uaku3 %d Uaku4 %d\n",Uaku[0],Uaku[1],Uaku[2],Uaku[3]);
//	sendchar (0x0d);

}
return 0;
}
//----- >>preruseni od A/D<< ----------------------------------------------------------
ISR (ADC_vect){
prumer += ADC; // do hodnoty prumer se vzdy pricte namerena hodnota

// vypocet napeti z prumerovane hodnoty
if ( ++ctU >= 100 ) {
Uaku[sel] = ( (prumer / 100) * Uref ) / 1024;
ctU = 0; prumer = 0;
// printf("%d\r",Uaku[2]);

if (Uaku[sel]>Utop) {	 // neni nic pripojeno predchozi aku byl vyndan muze se nabijet novy
  newA[sel] = 1; 								// muze byt vlozen novy clanek pro nabijeni
  chrgF[sel] = 0;								// nenabiji se
  counter[sel] = 0;								// resetuje se citac vrcholu charakteristiky
  hldOffF[sel] = 0;								// nuluje se priznak blokace algoritmu ukonceni nabijeni (holdoff)
  hldOffCT[sel] = 0;}							// resetuje se citac casovace holdoff

if (Uaku[sel]<Ubot) 							// vadny clanek nebo zkrat
{ errF[sel] = 1; }
else { errF[sel] = 0; }

if ((Uaku[sel]<=Utop)&(Uaku[sel]>=Ubot)&(newA[sel])) {
// pokud je spravne napeti a minuly akumulator byl vyndan zacne se nabijet
  chrgF[sel] = 1;								// nastavi flag ktery spusti nabijeni
}
// casovac holdoff
if ( (hldOffF[sel]==0)&(chrgF[sel]) ) {		// pokud se nabiji a neni vyrazen holdoff
  if (++hldOffCT[sel]>=hldOffT) { hldOffF[sel] = 1; }	// po prekroceni dane doby se holdoff vyradi
}
// pokud se nabiji a je vyrazen holdoff provadi se zjisteni nabiteho stavu - alg ukonceni nabijeni
if ( (chrgF[sel])&(hldOffF[sel]) ){
  //pokud je merena hodnoty vyssi nez maximum stanovi se maximum nove a resetuje citac pro vyrazeni casem
  if ( Uaku[sel] > Umax[sel] ) { Umax[sel] = Uaku[sel]; counter[sel] = 0; }
    else {
	  // pokud je pokles vetsi jak Ufall nebo je stagnace po dobu topT tak se nabijeni ukonci
      if ( ((Umax[sel]-Uaku[sel])>Ufall)|(++counter[sel]>=topT) ) {
		chrgF[sel] = 0;
		newA[sel] = 0;
		Umax[sel] = 0;
		counter[sel] = 0;
	  }
    }
}
// prepinani mereni
switch (sel++){
  case 0:
    ADMUX &= 0b11111000;
    ADMUX |= 0b00000011;						// prepnout na dalsi kanal ADC4
    break;
  case 1:
    ADMUX &= 0b11111000;
    ADMUX |= 0b00000010;						// prepnout na dalsi kanal ADC5
    break;
  case 2:
    ADMUX &= 0b11111000;
    ADMUX |= 0b00000001;						// prepnout na dalsi kanal ADC6
    break;
  case 3:
    adF = 0; 									// neprovadet dalsi prevod
    if(chrgF[0]) { PORTD &= 255-Aku1; }		// pokud se nabijelo tak obnovit nabijeni
    if(chrgF[1]) { PORTD &= 255-Aku2; }
    if(chrgF[2]) { PORTB &= 255-Aku3; }
    if(chrgF[3]) { PORTD &= 255-Aku4; }
    break;
}

}
// _delay_us(20);
if (adF) { ADCSRA |= (1<<ADSC); } // spustit A/D - sam sebe
}
//----- >> preruseni od OUTPUT COMPARE 0 <<----------------------------------------------
ISR (TIMER1_COMPA_vect){
// docasne preruseni nabijeni kvuli eliminaci prechodoveho odporu

//	    printf("%d\r",Uaku[2]);

if ( ++ctT == (measT-2) ) {
if (chrgF[0]) { PORTD |= Aku1; }
if (chrgF[1]) { PORTD |= Aku2; }
if (chrgF[2]) { PORTB |= Aku3; }
if (chrgF[3]) { PORTD |= Aku4; }
//testt=1;
}
if (ctT >= measT) {

//if (testt){
adF = 1;									// priznak dalsich prevodu
sel = 0;									// pro Aku1
ADMUX &= 0b11111000;
ADMUX |= 0b00000100;						// ADC3

// _delay_us(20);
ADCSRA |= (1<<ADSC); // spusti prevod A/D
ctT = 0; // nuluje se citac preruseni
// testt=0;
}
// }
// PORTB = PINB^32; // diagnosticky vystup pro mereni rb5
}
//----- >> inicializace A/D prevodniku << ---------------------------------------------
void init_adc(void){
ADMUX |= (1<<REFS1) | (1<<REFS0); // Uref = internal 2,56V
ADMUX |= (0<<MUX3) | (1<<MUX2) | (0<<MUX1) | (0<<MUX0); // ADC4
ADCSRA |= (1<<ADEN) | (1<<ADIE); // A/D zap a preruseni
ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (0<<ADPS0); // A/Dclk = 125kHz (8MHz/64)
}
//----- >> inicializace c/t1 << -------------------------------------------------------
void init_timer1(void){
// TCCR1B |= (1<<CTC1);
TCCR1B |= (0<<WGM13) | (1<<WGM12);

TCCR1B |= (1<<CS12) | (0<<CS11) | (0<<CS10); // CLK/512 //clk/256
OCR1A = 315;//166; // pro 10ms
TIMSK |= (1<<OCIE1A); // output compare match interrupt
}
//----- >> zpozdovaci procedura << ----------------------------------------------------
/*void delay(unsigned long time) {
while( --time ) {}
}
*/
//----- >> inicializace portu << ------------------------------------------------------
void init_ports(void) {
DDRD = 0b01111100; PORTD = 0b01010111; // PA.0 - PA.3 -> vystupy na baze T, PA.4 - PA.7 -> vstupy A/D
DDRB = 0b11111001; PORTB = 0b10000000; // vystupy log.0
DDRC = 0b100001; PORTC = 0;
}

Tak v programu není nic vidět. S DDR registrem se hejbe jen v inicializaci, portem (pb7) tam, kde je to logické a alternativní funkce pinu je tady mimo mísu :frowning: Jiný mcu jsi nezkoušel?

Ale že jsou to občas v tom programu perly, jen co je pravda :slight_smile:

procesor neskusal … mohol by som to dat na iny pin…ale predpokladam ze pes bude niekde inde :smiley: prilozim schemu.

uploading.sk/obrazek/g9sbgp3/prvz0002.png

:arrow_right: administrator: příspěvek byl upraven

:arrow_right: administrator: přiloženy externí soubory

Iny procesor nic neriesil akurat to nerobil :smiley: TAk odstranil som toto:

if (!hldOffF[0]){ PORTB |= 8; } else { PORTB &= 255-8; }

PORTB = PINB^16; //PB4

a toto

    PORTB = PINB^32;	

Mohli tieto veci ovplyvnovat stav vystupu portu…ze sa tam ostavala log 0 pripadne 1

To jsou ty perly :slight_smile:
Místo aby napsal “PORTB ^= 1<<4;”, kde je jasně vidět, o co jde, tak tam píše všelijaký nesmylný numera. A tohle to už je vážně úlet: “PORTB &= 255-8;” “const char Led3 = 0b00100000; // PD.5 pro Aku3”
Oblivňovat PB7 to ovšem nemohlo.
16 <=> 1<<PB4
32 <=> 1<<PB5

Zasa to prepisovat nebudem ked to beha… faktom je ze vyhodenim ty troch inkriminovanych riadkov to ide normalne… az na nejake veci ze to nechce korektne prekladat ked je otimalizacia na maxime. Sice to nechapem ale vsetko co som pisal ja tak optimalizovat na max ide. Len poniektory tu maju kdejake problemy ze to nejde… toto je zdarny priklad…
Na druhej strane dakujem autorovi za uvolnenie zdrojaku…

Když přihodíš errory, tak je třeba vyřešíme…
Nebo to jde přeložit ale jen to nefunguje? Typická chyba je chybějící “volatile” u globálních proměnných používaných v přerušení.

No tym by to mohlo byt. ASi tak… zablikaju ledky ao pri starte a potom uz nič … myslim ze nejdu prrerusenia. Ale ked tam dolozim nejake veci pri skusani boli fajn tak to prelozi a ide ale ked to okresem tak nejde…uvidime chcel by som este par zmien…tak to mozno mozno upravim.

Na toto mi nevies odpovedat preco pise ?

+0000020B: 9731 SBIW R30,0x01 Subtract immediate from word
+0000020C: F7F1 BRNE PC-0x01 Branch if not equal
---- C:\at\nabijacka1\default/c:/programs/atmel/winavr-20100110/lib/gcc/…/…/avr/include/util/delay.h
124: File not found
+0000020D: 9701 SBIW R24,0x01 Subtract immediate from word
120: File not found
+0000020E: F7D9 BRNE PC-0x04 Branch if not equal
---- nabijacka1.c ----------------------------------------------------

Tak to nevím, možná by pomohl celý projekt.