Closed EmSerg74 closed 1 year ago
I don't know what you want me to do.
Try adding cli();
before your loop, and replace delayMicroseconds
, which is interrupt based, with _delay_us
.
This foto is for the first post:
If you use this code:
// PRG_2 (MCUDUDE MicroCore 2.2.0 (ATINY13); int9.6MHz; Micros enable)
// PB4=1; PB3=644kHz; (0=1.44us; 1=104ns)
// PB4=0; PB0=540kHz; (0=1.52us; 1=320ns)
int main(void){
uint8_t course;
uint8_t course_old;
PORTB = B00010000;
DDRB = B00001111;
while(1){
course = (uint8_t) bitRead(PINB, 4); // ?=if not (uint8_t) then 32bit!
if(course != course_old){
delayMicroseconds(30);
course_old = course;
}
if(course>0){
PORTB = B00010001;
PORTB = B00010000;
PORTB = B00010010;
PORTB = B00010000;
} else {
PORTB = B00010100;
PORTB = B00010000;
PORTB = B00011000;
PORTB = B00010000;
}
}
}
then the result will be like this: &
If you delete delay:
// PRG_2 (MCUDUDE MicroCore 2.2.0 (ATINY13); int9.6MHz; Micros disable)
// PB4=1; PB3=1207kHz; (0=720ns; 1=104ns)
// PB4=0; PB0= 880kHz; (0=816ns; 1=312ns)
int main(void){
uint8_t course;
uint8_t course_old;
PORTB = B00010000;
DDRB = B00001111;
while(1){
course = (uint8_t) bitRead(PINB, 4); // ?=if not (uint8_t) then 32bit!
if(course != course_old){
// delayMicroseconds(30); //
course_old = course;
}
if(course>0){
PORTB = B00010001;
PORTB = B00010000;
PORTB = B00010010;
PORTB = B00010000;
} else {
PORTB = B00010100;
PORTB = B00010000;
PORTB = B00011000;
PORTB = B00010000;
}
}
}
then we will get this result:
I understand that the ARDUINO IDE code is much larger and contains a lot of garbage, so it is very slow. Why use conversion if it works chaotically? People think that their code works correctly, but they are mistaken and spend time on it, and then they get disappointed. Why give hope in this way that they will be able to learn programming? (as a result, they realize that they have been deceived and begin to study atmel studio.)
I think it is clear what we are talking about, in the last code, when the output PB4 = 0 or 1 on the pin, the signal on PB0-PB3 should have the same frequency and waveform - almost a meander due to the setting frequency of 9.6MHz. But this is not happening. Maybe I should use the WinAVR program instead of the cli()?
I understand that the ARDUINO IDE code is much larger and contains a lot of garbage, so it is very slow. Why use conversion if it works chaotically? People think that their code works correctly, but they are mistaken and spend time on it, and then they get disappointed.
That's why 3rd party cores exist. MicroCore is pretty much as efficient as C code can get for AVR. I also tend not to discuss with people that are not interested in a solution, and instead just want to be rude.
if you don't use void setup()
and void loop()
in your code, but instead use int main()
, the compiler won't include any Arduino code, and you're working bare metal. What you decide to add to your program is your choice. You won't get significantly better performance by using WinAVR or Atmel Studio.
The only "Arduino code" in this program is bitRead, which is just this macro: #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
. If your code is slow, you're to blame.
delayMicroseconds is a timer-based function, and there are good reasons to sometimes use this instead of _delay_us.
int main(void){
uint8_t course;
uint8_t course_old;
PORTB = B00010000;
DDRB = B00001111;
while(1){
course = (uint8_t) bitRead(PINB, 4); // ?=if not (uint8_t) then 32bit!
if(course != course_old){
// delayMicroseconds(30); //
course_old = course;
}
if(course>0){
PORTB = B00010001;
PORTB = B00010000;
PORTB = B00010010;
PORTB = B00010000;
} else {
PORTB = B00010100;
PORTB = B00010000;
PORTB = B00011000;
PORTB = B00010000;
}
}
}
If you really want code that can toggle a pin really fast, try this instead:
int main()
{
DDRB |= 1 << PB2;
while(1)
{
PINB = 1 <<PB2;
}
}
I know about such a fast code, but it doesn't fit me by definition. I need to generate a signal with a frequency of 100kHz on two pins. When switching the input signal level, the signal generation should be on the other two pins. When switching the input signal, there should be a delay and on all pins the signal = 0. The maximum frequency on the Arduino IDE is 79kHz and 82kHz, depending on the input signal. It is the difference in the generated frequencies that creates the problem. With frequent switching, the difference of 3kHz is an audible sound range. This is the main problem, and the second problem is the inability to reach a frequency of 100 kHz using an internal quartz at 9.6 MHz.
When I tried to use the code faster (the command POTRB = 1; is executed in one clock cycle, and bitWrite(PORTB,0,1); or PORTB |= _BV(pin); are executed in two clock cycles,) I was never able to compensate for the frequency difference. How to make the signal generation be the same and equal to 100kHz?
If you need a stable 100kHz signal, this can be achieved using the internal timer. Note that the internal 9.6 MHz RC oscillator is usually a bit off, so you'll have two tweak the OCR0A/OCR0B values to get as close to 100kHz as possible. However, when using the timer, you'll stuck with pin PB0 and PB1.
void setup() {
// Disable all interrupts
TIMSK0 |= (0<< OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);
// Define outputs
DDRB = (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// Enable CTC
TCCR0A |= (1<<WGM01) | (0<<WGM00);
TCCR0B |= (0<<WGM02);
// 9.6MHz / 100kHz (should be 43 if the internal oscillator were accurate)
OCR0A = 44;
OCR0B = 44;
// Toggle on Compare Match
TCCR0A |= (0<<COM0A1) | (1<<COM0A0) | (0<<COM0B1) | (1<<COM0B0);
// No prescaler
TCCR0B |= (0<<CS02) | (0<<CS02) | (1<<CS00);
// Make it start
GTCCR |= (1<<PSR10);
// Force one invert
TCCR0B |= (1<<FOC0B);
}
void loop() {
}
I think this issue can probably be closed.
Hi, on the oscilloscope, it generates a square wave with a duty cycle of 50%, but this cannot be in the code! my code:
Here such garbage is compiled. For a long time I could not understand why my code did not work until I saw this: