Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: программирование атмега16
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
zeonix
хочу с ком порта передать на на мк 8, код 56. И если он его примет то PORTB=0x01;

Но возникли вопросы по функции приема данных USART_Receive.
Брал с книги конечно , но неправильная она вроде

Код
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.1b Evaluation
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 18.05.2011
Author  : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type               : ATmega16A
Program type            : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega16a.h>

// Declare your global variables here

unsigned int USART_Receive(void)
{
unsigned char status,resh,resl;
while (!(UCSRA &(1<<RXC))){
status=UCSRA;
resh=UCSRB;
resl=UDR;
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;
resh=(resh>>1)&0x01;
return((resh<<8)|resl);    
}
}

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x01;
DDRB=0xFF;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

if (USART_Receive()==56)  
         PORTB=0x01;
         else  
          PORTB=0x04;


while (1)
      {
      // Place your code here

      }
}


yashok
Немешало бы для начала настроить сам USART.

В функции приема, если нужно 9 бит, я бы написал так

Код
return(((int)resh<<8)|resl);
zeonix
Код
unsigned int USART_Receive(void)
{
unsigned char status,resh,resl;
while (!(UCSRA &(1<<RXC))){
status=UCSRA;
resh=UCSRB;
resl=UDR;
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;
resh=(resh>>1)&0x01;
return(((int)resh<<8)|resl);
}
}


так то есть?
Код
if (USART_Receive()==56)  
         PORTB=0x01;
         else  
          PORTB=USART_Receive();


чет вот тестирую он мне 11111 на порту выводит во всех случаях

то есть я полагаю
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
срабатывает
Палыч
Цитата(zeonix @ May 18 2011, 13:44) *
чет вот тестирую он мне 11111 на порту выводит во всех случаях ...то есть я полагаю if (status & (1<<FE)|(1<<DOR)|(1<<UPE)) срабатывает
Судя по:
Код
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x01;
DDRB=0xFF;
Ваша программа даже не запускается
yashok
USART не настроен.

На какой частоте работает проц и на какой скорости передает ваш com???
zeonix
объясните пожалуйста. Просто я реально новичок в этом. толь собрал свою 1 схему
yashok
Глядя на код хочется взглянуть еще и на схему.
zeonix
схему пока показать не могу, нет возможности пока что.
настройка усарта
Код
UCSRA=0x00;
UCSRB=0x10;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;

так? 4800 бод сделал вроде
yashok
Если у вас проц на частоте 1 МГц работает, то все верно.
Палыч
1. Следует разобраться: почему у Вас при старте программы на порту все единицы? В начале работы Ваша программа заносит в порт В значение 0х01, поэтому до приёма некоего символа - на порту должна быть единица только в младшем разряде порта, в остальных - 0.

2. Ваш МК тактируется от внутреннего генератора или от кварца? Если - первое, то для USART - это не есть хорошо.

P.S. Оператор if хорошо бы переместить внутрь бесконечного цикла:
Код
while (1)
{
   if (USART_Receive()==56)  
         PORTB=0x01;
         else  
          PORTB=USART_Receive();
}
zeonix
то есть кварц поставить?

Я кстати в авр студии 4.8 отлаживал. Дык из-за того что там UCSRA= 0 регистр, то цикл вечный получается на приеме данных. так и должно быть?
zeonix
чето с
Код
unsigned char status,resh,resl;

unsigned int USART_Receive(void)
{
while (!(UCSRA &(1<<RXC))){
status=UCSRA;
resh=UCSRB;
resl=UDR;
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;
resh=(resh>>1)&0x01;
return((resh<<8)|resl); }
//return resl;  
}

не правильная видимо.

переделал так:
Код
/*****************************************************
This program was produced by the
CodeWizardAVR V2.05.1b Evaluation
Automatic Program Generator
© Copyright 1998-2011 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 18.05.2011
Author  : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type               : ATmega16A
Program type            : Application
AVR Core Clock frequency: 1,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/
#define RXCIE 7  
#define RXEN  4
#define TXEN  3
#define URSEL 7
#define UCSZ1 2
#define UCSZ0 1

#include <mega16a.h>
#include <delay.h>

//однобайтный буфер
volatile unsigned char usartRxBuf = 0;



//инициализация usart`a
void USART_Init(void)
{
  UBRRH = 0;
  UBRRL = 51; //скорость обмена 9600 бод
  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN); //разр. прерыв при приеме, разр приема, разр передачи.
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //размер слова 8 разрядов
}

#define UDRE 5
//отправка символа по usart`у
void USART_SendChar(unsigned char sym)
{
  while(!(UCSRA & (1<<UDRE)));
  UDR = sym;
}

//чтение буфера
unsigned char USART_GetChar(void)
{
  unsigned char tmp;
  unsigned char saveState = SREG;
  #asm("cli");
  tmp = usartRxBuf;
  usartRxBuf = 0;
  SREG = saveState;
  return tmp;  
}

//прием символа по usart`у в буфер
interrupt [USART_RXC] void usart_rxc_my(void)
{
  usartRxBuf = UDR;
}



// Declare your global variables here
/*
unsigned char status,resh,resl;

unsigned int USART_Receive(void)
{
while (!(UCSRA &(1<<RXC))){
status=UCSRA;
resh=UCSRB;
resl=UDR;
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;
resh=(resh>>1)&0x01;
return((resh<<8)|resl); }
//return resl;  
}
   */  
  
   unsigned char sym;
  
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x01;
DDRB=0xFF;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// USART disabled

UCSRA=0x00;
UCSRB=0x10;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

   /*   if (USART_Receive()==56)  
         PORTB=0x02;
         else  
         PORTB=USART_Receive();
       */
      
      

  
  USART_Init();
//  LCD_Init();
  #asm("sei");
//  LCD_SendStringFlash("uart:");
  
  while(1){
    sym = USART_GetChar(); //читаем буфер
    if (sym){             //если что-то приняли, то
//      LCD_Goto(6,0);
//      LCD_WriteData(sym); //отображаем на lcd принятый символ
      USART_SendChar('O'); //отвечаем компу "Ok "
      USART_SendChar('k');  
      USART_SendChar(' ');  
    }
  }  
    
/*
while (1)
      {    
      // Place your code here  
       PORTB=0x01;
       delay_ms(1000);  
       PORTB=0x00;
       delay_ms(1000);  
      
  
      }  */

}

как http://www.chipenable.ru/index.php/program...usart-uart.html

все равно такой же эффект
yashok
Какой эффект?
Вы в прерывания попадаете??
zeonix
можете пояснить что происходит когда на МК на TxD (RxD ) подаешь сигнал?

То есть, вот есть переходник usb-com. Дальше с TxD и RxD ком порта идут на соответствующие порты ds232а(14 и 7(для 16 портового)). Затем с 11 и 10 заводим уже на атмегу.

Потом с ком порта передаем че нить(не важно че)
Сделать если PORTB= принятый байт , то чето да должно менятся же.

Дык вот... как сам процесс происходит?
Ну то есть прокомментируйте этот код:
Код
unsigned char status,resh,resl;

unsigned int USART_Receive(void)
{
while (!(UCSRA &(1<<RXC))){
status=UCSRA;
resh=UCSRB;
resl=UDR;
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;
resh=(resh>>1)&0x01;
return((resh<<8)|resl); }
}


Если записать в вечный цикл PORTB= USART_Receive();
то все будут 11111 на порте Б. Так как он вылетит
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;

ну то есть касяк где то видимо. Если на ds232a замкнуть тупо TxD и RxD , то обратно значение вернется. Значит на порты МК норм передаваться должно + Мк работает, то есть проводил опыт без ком порта, светодиод подрубал - моргал.

То есть либо в функции этой че то не так.

Есть где почитать что происходит с Мк когда ему передают таким образом данные? то есть что с регистрами должно происходить7
Палыч
Цитата(zeonix @ May 19 2011, 18:50) *
Если записать в вечный цикл PORTB= USART_Receive();
то все будут 11111 на порте Б. Так как он вылетит
if (status & (1<<FE)|(1<<DOR)|(1<<UPE))
return -1;
Само-сабой разумеется, т.к. условие всегда не ноль (см. приоритеты операций). Нужно записать: if (status & ( (1<<FE)|(1<<DOR)|(1<<UPE) ) )
XVR
Цитата
Ну то есть прокомментируйте этот код:
В коде 2 ошибки. Работать не будет
Палыч
Цитата(XVR @ May 20 2011, 09:45) *
В коде 2 ошибки.
Ага, точно: там ещё одна ошибка - неверно организовано ожидание приёма байта (можно сравнить с примером из DS).
zeonix
какие? Ну я и говорю. С книги списал.
Палыч
Цитата(zeonix @ May 23 2011, 14:57) *
какие? Ну я и говорю. С книги списал.
Лучше - заглядывать в DS.

1. Ожидание готовности (приёма байта). В DS:
Код
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
Т.е. выполняется цикл до тех пор пока не будет принят байт, при этом ничего более не делается. У вас же, напротив, в цикле выполняются действия, как будто байт принят.

2. Не обратили внимание на приоритет операций при проверке переменной status (см. пост #15)
zeonix
Цитата
Лучше - заглядывать в DS.

че за сегмент данных?
alvy
DS = DataSheet
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.