Очень прошу помочь, проблемы с Atmega161
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено SergMel 23 мая 2003 г. 06:48

Вроде бы простая программа.
После включения питания по метке 20мс передаёт 4-е байта по каждому каналу, но недолго.
передачи продолжаются, но передаётся только 1 байт.
Т.е. такое ощущение, что перестают вырабатываться прерывания по окончании передачи байта. Т.к. для пеоредачи происходит включение передатчика, а выключение его происходит после передачи пакета.
Текст прилагаю, может что-нибудь подскажете, программирую на AVR впервые.

Компилятор IAR 2.27b

#define ENABLE_BIT_DEFINITIONS
#include
#include

// постоянная таймера на период 20мс - период проверки связи в тесте
#define constDivTimer1 65392
//; светодиод приёма по 1 каналу
#define Pr1 32
//; светодиод приёма по 2 каналу
#define Pr2 16
//; разрешение передачи канала 1
#define CS1 8
//; разрешение передачи канала 0
#define CS2 4
//; прерывание от контроллера 2
#define INTR0 2


volatile unsigned char SVDtimer1; // счётчик приёмов 1
volatile unsigned char SVDtimer2; // счётчик приёмов 2


unsigned char ft1;// флаг срабатывания таймера Т1
unsigned char TBlk1;// флаг срабатывания таймера Т1
unsigned char TBlk2;// флаг срабатывания таймера Т1
unsigned char sosp;// переменная состояния порта С
unsigned char ft0;// флаг вспомогательный

volatile char countUART0; // счётчик передачи
volatile char countUART1; // счётчик передачи
volatile unsigned char* ptrUART0; // указатель на передаваемый байт
volatile unsigned char* ptrUART1; // указатель на передаваемый байт
volatile unsigned char startSPI; // признак начала обмена по SPI
unsigned char ptr1; // счётчик приёма UART1
unsigned char ptr2; // счётчик приёма UART0
unsigned char PRS1, PRS2;

unsigned char i;
// Структуры буфера передачи
struct OutBuffer {
unsigned char Adres;
unsigned char Dlin;// длина посылки
unsigned char Komanda;
unsigned char ksm;
};
struct OutBuffer bufferUART0; // буфер передачи -3 байта второго канала
struct OutBuffer bufferUART1; // буфер передачи -3 байта первого канала

// Структура буфера приёма
struct InBufer {
unsigned char Adres;
unsigned char Dlin;//байт длины передаваемой посылки
unsigned char Status; // байт диагностики
unsigned int mass;// информационные байты -2
unsigned char ksm;
};
union InBuffer {
struct InBufer;
unsigned char buffer[6];
};

union InBuffer bufferUARTI2;// буфер приёма 5 байтов
union InBuffer bufferUARTI1;// буфер приёма -5 байтов

//------------------------------------------------------
// подпрограмма подсчёта контрольной суммы из 4 байтов
unsigned char KsmSum(unsigned char* ptr,unsigned char n) {
unsigned char i;
unsigned char ksm = 0;
for (i = 0; i < n; i++) ksm += *ptr++;
return ksm;
}
//----------------------------------------------------------
// Подпрограмма обработки прерывания переполнения Таймера 1- 20 мс период опроса ИП
#pragma vector = TIMER1_OVF_vect
__interrupt void TIMER1_OVF0_interrapt(void)
{
TCNT1 = constDivTimer1; // зададим константу счёта
ft0 = 1;
if (TBlk1 > 0) {
TBlk1--;// наращиваем счётчик задержки блокировки
if(TBlk1 == 0) { PORTC &= ~Pr1; SVDtimer1 = 20; }
}
if (TBlk2 > 0) {
TBlk2--;// наращиваем счётчик задержки блокировки
if(TBlk2 == 0) { PORTC &= ~Pr2; SVDtimer2 = 20; }
}
}
//-----------------------------------------------------
// прерывание передачи по 1 каналу
#pragma vector = UART1_TX_vect
__interrupt void UART1_TX_interrapt(void)
{
if(countUART1 > 0){
UDR1 = *++ptrUART1;
countUART1--;
}
else {
PORTC |= CS1;// отключить передатчик
UCSR1B |= RXEN1;// разрешить приём
}
}
//--------------------------------------------------------------
// прерывание передачи по 0 каналу
#pragma vector = UART0_TX_vect
__interrupt void UART0_TX_interrapt(void)
{
if(countUART0 > 0){
UDR0 = *++ptrUART0;
countUART0--;
}
else {
PORTC |= CS2; // отключить передатчик
UCSR0B |= RXEN0;// разрешить приём
}
}
//--------------------------------------------------------

void main(void) {
DDRA = 0;// порт А в режим ввода
DDRD = 0; // конфигурируем все выводы Порта D на ввод
PORTA =0xff;// подключить резисторы входного порта A
PORTD =0xff;// подключить резисторы входного порта D
DDRC = 0xff; // конфигурируем все выводы Порта C на вывод
PORTC = 0x0c;// все выходы в состояние 0 -2 единицы будут давать 0 на входе управления передачей ADM- запрет передачи

// Программируем UART
UBRRHI = 0;// старшие биты скорости передачи =0

// UCSR0B = 0xd8; // разрешение приёма и передачи 0 канала, прерывание приёма
UCSR0B = TXCIE0+TXEN0;//+RXEN0+RXCIE0; // разрешение приёма и передачи 0 канала, прерывание приёма
UBRR0 = 23; // скорость 19200
UCSR0A |= RXC0; // сбросить флаг приёма
UCSR0A |= TXC0; // сбросить флаг передачи

UCSR1B = TXCIE1+TXEN1;//+RXEN1+RXCIE1; // разрешение приёма и передачи 1 канала, прерывание приёма
UBRR1 = 23; // скорость 19200
UCSR1A |= RXC1; // сбросить флаг приёма
UCSR1A |= TXC1; // сбросить флаг передачи

SVDtimer1 = 20; SVDtimer2 = 20; // задать счётчики приёма

// программирование Таймера 1 - на тактовую частоту 138,8 мкс - период 20 мс
TCCR1B |= 5; // коэффициент деления частоты генератора 4-на 256-34.7мкс период прерываний, 3- на 64 - 8,675мкс
TIMSK |= 0x80;// разрешить прерывания переполнения Таймера 1
TCNT1 = constDivTimer1; // зададим константу счёта

DDRB = 0x48;// 3 младших разряда порта - на ввод MISO на вывод, остальные - на вывод
PORTB = 0xff; // подключить резисторы входного порта

__enable_interrupt(); // разрешить прерывания


bufferUART0.Adres = 0;//
bufferUART1.Adres = 0;//

while (1) { // основной цикл программы

if(ft0) { // метка 20 мс, начнём опрос нижних
ft0 = 0;
UCSR0B &= ~RXEN0;// запретить приём
bufferUART0.Dlin = 3;
bufferUART0.Komanda = 0;// код команды - опрос
bufferUART0.Adres++;
if (bufferUART0.Adres == 32) bufferUART0.Adres = 0;
ptrUART0 = &bufferUART0.Adres;
bufferUART0.ksm = KsmSum(&bufferUART0.Adres,bufferUART0.Dlin);
countUART0 = bufferUART0.Dlin;// передать пакет
PORTC &=~ CS2; // включить передатчик 0 канала
__delay_cycles(280);
ptr2 = 0; // указатель приёма в начало
UDR0 = *ptrUART0;

UCSR1B &= ~RXEN1;// запретить приём
bufferUART1.Komanda = 0;// код команды запроса информации
bufferUART1.Dlin = 3;
bufferUART1.Adres++;
if (bufferUART1.Adres == 32) bufferUART1.Adres = 0;
ptrUART1 = &bufferUART1.Adres;
bufferUART1.ksm = KsmSum(&bufferUART1.Adres,bufferUART1.Dlin);
countUART1 = bufferUART1.Dlin;// передать пакет
PORTC &=~ CS1; // включить передатчик 0 канала
__delay_cycles(280);
ptr1 = 0; // указатель приёма в начало
UDR1 = *ptrUART1;
}

if (PRS2 != 0) {
PRS2 = 0;
if (SVDtimer2 != 0) {
SVDtimer2--;
if (SVDtimer2 == 0) { TBlk2 = 40; PORTC |= Pr2; } // включим с/д наличия связи
}
}
if (PRS1 != 0) {
PRS1 = 0;
if (SVDtimer1 != 0) {
SVDtimer1--;
if (SVDtimer1 == 0) { TBlk1 = 40; PORTC |= Pr1; } // включим с/д наличия связи
}
}
}
}

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru