Возникла потребность собрать генератор испульсов на Atmega8.
Все работает но дело в том что слишком большие погрешости получаются.
Допустим:
Частота 6Khz
6*1000 = 6000
1/6000 = 0.000166667
0.000166667 * 1000 = 0.166667
0.166667/2 = 0.0833335
0.0833335 * 1000 = 83.3335
Полупериод = 83
Но атмега с этим не согласна и получается частота 7397Hz
Частота 3,102
1/3102 = 0.000322373
0.000322373 * 1000 = 0.322373
0.322373/2 = 0.1611865
0.1611865 * 1000 = 161.1865
Полупериод = 161
Но получается частота 3847Hz
Использую самописную функцию для милисекундных задержек, так как стандартные из <util/delay.h> весят очень много, занимают аж 10Kb.
Кварц 10Mhz
Код: Выделить всё
#define TIKS_1MS (10000000/64/1000)
#define TIKS_1US (TIKS_1MS/500)
void sleep_us(unsigned long int us)
{
while(us--){
TCNT0 = 0;
while(TCNT0 < TIKS_1US);
}
}
TCCR0 = (1<<CS02);
sleep_us(83);---------------------
PS: Пересобрал с опциями avr-gcc -mmcu=atmega8 -g -Os -Werror -lm -mcall-prologues -o firmware.o firmware.c и все ок, получился файлик 1,3Кб.
Теперь другой вопрос, так к нему приделать USART? чтобы можно было управлять частотой с компа.
Пример:
Код: Выделить всё
void uart_init(void)
{
UBRRH = 0;
//UBRRL = 52;
//UBRRL = (10000000/(16*9600)) – 1;
UBRRL = 65;
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE);
}
unsigned char USART_Receive(void)
{
while (!(UCSRA & (1<<RXC)));
return UDR;
}
void USART_Transmit(unsigned char data)
{
while (!(UCSRA & (1<<UDRE)));
UDR = data;
}
int main(void){
DDRD = 0xff; // все выводы порта D сконфигурировать как выходы
uart_init();
while(1)
{
USART_Transmit(USART_Receive());
}
}


