Moderator: tilz0R
DDRD = 0x02;
bool portd4_val = (PIND >> 4);
int x = PIND;
bool pin4_val = (x >> 4);
tilz0R je napisal/-a:Zakaj bi se učil na novo z AVR, ki je soon to be iz proizvodnje?
tilz0R je napisal/-a:Zakaj bi se učil na novo z AVR, ki je soon to be iz proizvodnje?
bool pin4_val = (PIND >> 4);
bool pin4_val = (PIND >> 4)&1;
bool pin4_val = PIND & (1 >> 4);
int main() {
setup();
while(1) {
loop();
}
}
dejko1 je napisal/-a:ali takole (tale se mi zdi najbolj pregledna):
- Koda: Izberi vse
bool pin4_val = PIND & (1 >> 4);
bool pin4_val = PIND & (1 << 4);
PORTD = (1 << PORTD5)
PORTD = (0 << PORTD4)
Lovro7 je napisal/-a:Še nekaj mi ni jasno.
- Koda: Izberi vse
PORTD = (1 << PORTD5)
Ali to zamakne vse bite ali samo nastavi PORT5 na 1?
Več kot testiram manj mi je jasno. Ko uporabim zgornji ukaz nastavi samo to vrednost. Ko pa uporabimpa spremeni vse vrednosti.
- Koda: Izberi vse
PORTD = (0 << PORTD4)
PORTD |= (1<<5);
PORTD &= ~(1<<5)
PORTD ^= (1<<5);
void converte_temp_input(){
ADCSRA |= (1 << ADSC);
}
ISR(ADC_vect){
adc_mask = ADC;
current_temp = ((adc_mask * 40.) / 1024.);
}
wiring.c.o (symbol from plugin): In function `__vector_9':
(.text+0x0): multiple definition of `__vector_9'
.pio\build\ATmega8\src\main.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
void start_lcd_countdown(){
TIFR = (1 << 0);
TCCR0 = (1 << 2) | (1 << 1) |(1 << 0);
sei();
}
ISR(TIMER0_OVF_vect){
if(rot == previus_rot){
PORTD &= ~(1 << 6);
}
}
#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#define MAX_PRE_GAS_TIME 30000 //ms
#define MAX_AFTER_GAS_TIME 45000 //ms
#define MAX_DOT_WELD_TIME 30000 //ms
#define MAX_PULSE_WELD_TIME 30000 //ms
#define TRANSFORMATOR_TO_WIRE_DELAY 100 //ms
#define MOTOR_STARTUP_PULSE_TIME 50 //ms
#define REAL_MAX_PRE_GAS_TIME (MAX_PRE_GAS_TIME / 2)
#define REAL_MAX_AFTER_GAS_TIME (MAX_AFTER_GAS_TIME / 1000)
#define REAL_MAX_DOT_WELD_TIME (MAX_DOT_WELD_TIME / 2)
#define REAL_MAX_PULSE_WELD_TIME (MAX_PULSE_WELD_TIME / 2)
unsigned int pre_gas_time = 0;
uint8_t after_gas_time = 0;
unsigned int dot_weld_time = 0;
unsigned int pulse_weld_time = 0;
unsigned int delay_time = 0;
unsigned int current_delay_time = 0;
uint8_t bit_mask = 0;
uint8_t current_gas_delay = 0;
char motor_started = 0;
void delay_long(unsigned int ms){
delay_time = ms;
TCCR0 = (1 << CS01) | (1 << CS00);
while (current_delay_time < delay_time){
//Do nothing
}
current_delay_time = 0;
TCCR0 = 0x00;
}
void stop_after_gas(){
TCCR1B |= (1 << CS12);
}
void initADC() {
ADMUX = (1 << REFS0);
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}
uint16_t readADC(uint8_t channel) {
ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADC;
}
void startWelding(){
PORTD |= (1 << PORTD1); //release gas
delay_long(pre_gas_time);
PORTD |= (1 << PORTD0); //release current
_delay_ms(TRANSFORMATOR_TO_WIRE_DELAY);
DDRD |= (1 << DDRD3) | (1 << DDRD4); //connect motor and motor pulse to ground
_delay_ms(MOTOR_STARTUP_PULSE_TIME);
DDRD &= ~(1 << DDRD4); //disconnect motor pulse
}
void endWelding(){
DDRD &= ~(1 << DDRD3); //disconnect motor
_delay_ms(TRANSFORMATOR_TO_WIRE_DELAY);
PORTD &= ~(1 << DDRD0); //stop current
stop_after_gas();
}
int main(void) {
//TIMER0
TIMSK |= (1 << TOIE0);
TIFR |= (1 << TOV0);
sei();
//TIMER1
TCCR1B = (1 << WGM12);
OCR1A = 31250;
TIMSK |= (1 << OCIE1A);
TIFR |= (1 << OCF1A);
sei();
DDRD = (1 << DDRD1) | (1 << DDRD0);
PORTD &= ~((1 << PORTD3) | (1 << PORTD4)); //Disable pullup for motor and motor pulse
initADC();
while (1) {
pre_gas_time = (readADC(2) * REAL_MAX_PRE_GAS_TIME) / 1023;
after_gas_time = (readADC(3) * REAL_MAX_AFTER_GAS_TIME) / 1023;
dot_weld_time = (readADC(4) * REAL_MAX_DOT_WELD_TIME) / 1023;
pulse_weld_time = (readADC(5) * REAL_MAX_PULSE_WELD_TIME) / 1023;
//wire release
bit_mask = PIND;
if(!((bit_mask >> 5) & 0x01)){
DDRD |= (1 << DDRD4);
}
else{
DDRD &= ~(1 << DDRD4);
}
//gas release
bit_mask = PIND;
if(!((bit_mask >> 6) & 0x01)){
PORTD |= (1 << PORTD1);
}
else{
PORTD &= ~(1 << PORTD1);
}
//classic welding
if(dot_weld_time < 50 && pulse_weld_time < 50){
bit_mask = PIND;
if(!(bit_mask >> 2) & 0x01){
startWelding();
bit_mask = PIND;
while(!((bit_mask >> 2) & 0x01)){
bit_mask = PIND;
//wait
}
endWelding();
}
}
//dot welding
if(dot_weld_time > 50 && pulse_weld_time < 50){
bit_mask = PIND;
if(!((bit_mask >> 2) & 0x01)){
startWelding();
delay_long(dot_weld_time);
endWelding();
bit_mask = PIND;
while(!((bit_mask >> 2) & 0x01)){
bit_mask = PIND;
//wait
}
}
}
//pulse welding
if(dot_weld_time > 50 && pulse_weld_time > 50){
bit_mask = PIND;
if(!((bit_mask >> 2) & 0x01)){
bit_mask = PIND;
startWelding();
while(!((bit_mask >> 2) & 0x01)){
bit_mask = PIND;
delay_long(dot_weld_time);
//turn motor and current off
DDRD &= ~(1 << DDRD3);
_delay_ms(TRANSFORMATOR_TO_WIRE_DELAY);
PORTD &= ~(1 << PORTD0);
delay_long(pulse_weld_time);
//turn motor and current on
PORTD |= (1 << PORTD0); //release current
_delay_ms(TRANSFORMATOR_TO_WIRE_DELAY);
DDRD |= (1 << DDRD3) | (1 << DDRD4); //connect motor and motor pulse to ground
_delay_ms(MOTOR_STARTUP_PULSE_TIME);
DDRD &= ~(1 << DDRD4); //disconnect motor pulse
}
endWelding();
}
}
}
}
ISR(TIMER0_OVF_vect){
current_delay_time++;
}
ISR(TIMER1_COMPA_vect){
current_gas_delay++;
if(current_gas_delay >= after_gas_time){
TCCR1B &= ~(1 << CS12);
PORTD &= ~(1 << PORTD1);
current_gas_delay = 0;
}
}
Ali obstaja simulator za druge AVR-je?
Kroko je napisal/-a:current_delay_time in current_gas_delay spremenljivki obvezno deklariraj kot "volatile".Ali obstaja simulator za druge AVR-je?
Zakaj pa delaš direktno z registri? Je grdo, neskalabilno, slabo razumljivo...
Zakaj se ti zdi " ADCSRA |= (1 << ADSC);" bole kot "analogRead()"?
Kroko je napisal/-a:Pa tudi sicer:
https://en.wikipedia.org/wiki/Hardware_abstraction
oziroma HAL je bil "izumljen" ravno zato, da ločiš funkcionalnost programa od črevesja.
Kroko je napisal/-a:Poglej, kako je Tilen to lepo naredil v svoji LwBTN knjižnici.
https://docs.majerle.eu/projects/lwbtn/en/latest/
Tako lahko simulira delovanje svoje knjižnice kar na PC-ju, kar je ultimativni debug.
Lovro7 je napisal/-a:Seveda je lažje uporabiti analogRead() ampak raje malo več razmišljam. Škodilo mi ne bo.
Lovro7 je napisal/-a:Brez njega bi bilo programiranje 100x težje. Nima pa na primer Arduino.h in podobne knjižnice vseh funkciji, ki jih ponuja mikrokrmilnik (TIMER1, TIMER2, FAST PWM, merjenje notranje temperature...).
Kroko je napisal/-a:Lovro7 je napisal/-a:Seveda je lažje uporabiti analogRead() ampak raje malo več razmišljam. Škodilo mi ne bo.
Nisem rekel, da moraš uporabiti analogRead() ampak da ne uporabljaj ADCSRA |= (1 << ADSC);Lovro7 je napisal/-a:Brez njega bi bilo programiranje 100x težje. Nima pa na primer Arduino.h in podobne knjižnice vseh funkciji, ki jih ponuja mikrokrmilnik (TIMER1, TIMER2, FAST PWM, merjenje notranje temperature...).
Tudi tega, da uporabljaj Arduino.h nisem nikoli napisal.
Moji odgovori so precel bolj globoki, kot se zdi na prvi pogled. Verjamem pa, jih ni veliko, ki bi jih razumeli.
Vprašaj NacMan-a, kako ga sekiram da mora vsako malenkost narediti tako, kot je prav.
Lahko pripravim online tečaj, na katerem bom tvojo kodo za varilni aparat poštimal, tako, kot je treba. (edino moj code style ja malo specifičen in ni tipično C-jevski saj ga uporabljam tudi v drugih jezikih).
+1valter je napisal/-a:Waw to bi pa bilo nekaj res dobrega
Kroko je napisal/-a:Lovro7 je napisal/-a:Seveda je lažje uporabiti analogRead() ampak raje malo več razmišljam. Škodilo mi ne bo.
Nisem rekel, da moraš uporabiti analogRead() ampak da ne uporabljaj ADCSRA |= (1 << ADSC);Lovro7 je napisal/-a:Brez njega bi bilo programiranje 100x težje. Nima pa na primer Arduino.h in podobne knjižnice vseh funkciji, ki jih ponuja mikrokrmilnik (TIMER1, TIMER2, FAST PWM, merjenje notranje temperature...).
Tudi tega, da uporabljaj Arduino.h nisem nikoli napisal.
Moji odgovori so precel bolj globoki, kot se zdi na prvi pogled. Verjamem pa, jih ni veliko, ki bi jih razumeli.
Vprašaj NacMan-a, kako ga sekiram da mora vsako malenkost narediti tako, kot je prav.
Lahko pripravim online tečaj, na katerem bom tvojo kodo za varilni aparat poštimal, tako, kot je treba. (edino moj code style ja malo specifičen in ni tipično C-jevski saj ga uporabljam tudi v drugih jezikih).
Po forumu brska: 0 registriranih uporabnikov in 1 gost