별건 아니지만, 예전 프로그램을 조합+개조하여 만들어 본 녀석인데..
흐음.. 엔터를 두번이나 눌러야 하다니 이걸 어떻게 개선을 해야 하려나..
- 서보모터를 시리얼 포트를 통해 값을 입력받아 제어한다.
- 엔터만 눌러대거나, 이상한 각도를 입력하면 서보가 길길댄다.
#include "avr/io.h"
#include "avr/interrupt.h"
volatile unsigned int sv1_high, sv1_low, sv1_flag, sv1_range, sec;
volatile unsigned char Bout;
volatile unsigned char inputval;
volatile unsigned char lastinput;
ISR(USART0_RX_vect)
{
if(UDR0 == 0x0A || UDR0 == 0x0D)
{
if(lastinput != UDR0)
{
sv1_range = inputval;
inputval = 0;
PORTF = 0x01;
}
}
else
{
inputval = inputval * 10 + UDR0 - '0';
PORTF = PORTF << 1;
}
lastinput= UDR0;
}
ISR(TIMER0_OVF_vect)
{
if(sv1_flag == 0)
{
if(sv1_low == 1250)
{
if(sec > 49) sec = 0;
else sec++;
sv1_flag = 1;
sv1_low = 0;
Bout = 0xFF;
}
else
{
sv1_low++;
}
}
else
{
sv1_high++;
if(sv1_high > sv1_range)
{
sv1_flag = 0;
sv1_high = 0;
Bout = 0x00;
}
TCNT0 = 0;
}
}
void init_uart0()
{
UBRR0H = 0;
UBRR0L = 8; // 115k with U2X = 0
UCSR0A = 0x00; // U2X = 0;
UCSR0B = 0xD8;
UCSR0C = 0x06; //Asyncronous - no parity - 1bits(stop) - 8bits(data)
}
int main(void)
{
SREG = 0x80;
DDRF = 0xFF;
DDRC = 0xFF;
TIMSK = 1 << TOIE0;
TCNT0 = 0x00;
TCCR0 = 0x01;
PORTF = 0x01;
// sv1_range = 32; // 0 degree
sv1_range = 76; // 90 degree
// sv1_range = 112; // 180 degree
init_uart0();
sei();
for(;;)
{
// 1msec = 62.5
sec = 0;
while(sec < 49)
{
PORTC = Bout;
}
}
}