Easyelectronics.ru

Электроника для всех
Текущее время: 22 янв 2021, 20:49

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
 Заголовок сообщения: soft uart, прием, atmega32. Не работает)
СообщениеДобавлено: 22 авг 2019, 18:23 
Только пришел

Зарегистрирован: 13 дек 2018, 18:24
Сообщения: 8
Добрый день!

Помогите, кому не лень с реализацией программного uart на atmega32.

Написал, потестировал в протеусе, все ок. Собрал в железе - не работает.

С передачей все ок, а вот с приемом какой-то затык - ничего не понимаю.

внешка - max232 - atmega32. Для приема используется int0.

Упростил как мог код - при приеме любого символа (срабатывании int0) должна меняться передача. В протеусе все работает, в живом контроллере нет.

Алгоритм на пальцах следующий: t1 - прерывание, которое используется во время передачи. Если буфер не пустой, то по каждому тику меняет состояние вывода. int0 - прерывание, которое детектирует прием. Внутри int0 разрешается прерывание t2. После первого срабатывания по ниспадающему фронту, через полтика t2 начинается считывание битов, int0 запрещается. После считывания всех бит, int0 разрешается, t2 запрещается.

После старта программ раз в секунду передает данные в uart, при любом приеме (не важно чего, лишь бы int0 сработал) должен меняться символ на другой до следующего приема.

Код:
volatile uint16_t txbyte;
volatile uint8_t rxbyte;
volatile uint8_t txbitcount;
volatile uint8_t rxbitcount;

void soft_uart_init();
void soft_uart_send(uint8_t tb);
int16_t soft_uart_recieve(uint8_t* rb);

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


#define TXPORT PORTD      
#define RXPORT PIND      
#define TXDDR DDRD      
#define RXDDR DDRD      
#define TXD 3         
#define RXD 2         


#define F_CPU 14745600UL
#define T_DIV      0x02   // DIV = 8
#define BAUD_DIV   192//0xС0   // Скорость = 9600 бод ( 14745600 / 8 ) / 9600 = 192 (0xC0)

bool temp = 0;

ISR(INT0_vect)
{
   rxbitcount = 0x09;            
   rxbyte = 0x00;
   
   if(temp == 1)
   {
      temp = 0;
   }
   else
   {
      temp = 1;
   }
   TCNT2 = (BAUD_DIV/2);         
   GICR &= ~(1 << INT0);         
      
   TIFR |= (1 << OCIE1A) | (1 << TOV2);   
   TIMSK |= (1 << TOIE2);         
}

ISR (TIMER2_OVF_vect)
{
      if(RXPORT & (1 << RXD))   
      {
         rxbyte |= 0x80;         
      }
      
      
      if(--rxbitcount == 0)         
      {
         // если приняли весь байт, то отключаем прием
         TIMSK &= ~(1 << TOIE2);   
         TIFR |= (1 << TOV2);      
         
         GIFR |= (1 << INTF0);      
         GICR |= (1 << INT0);      
      }
      else
      {
         rxbyte >>= 0x01;      
      }
}      
   
void soft_uart_init()
{
      temp = 0;
   
      txbyte = 0xFFFF;      
      rxbyte = 0x00;         
      txbitcount = 0x00;      
      rxbitcount = 0x09;      
      
      TXDDR |= (1 << TXD);      
      RXDDR &= ~(1 << RXD);      
      TXPORT |= (1 << TXD);      
      RXPORT |= (1 << RXD);      
   
   
      //timer2
      TCCR2 |= (0 << CS20)|(1 << CS21)|(0 << CS22)|(1 << WGM21)|(0 << WGM20); //presc = 8 //pg127 //ctc mode pg125
      OCR2 = BAUD_DIV;
      TCNT2 = 0;
            
      //int0
      GICR |= (1<<INT0);
      MCUCR |= (1<<ISC01)|(1<<ISC00);
      
      //timer1
      OCR1A = BAUD_DIV;      
      TCNT1 = 0;
      TCCR1A |= (0 << WGM11)|(0 << WGM10);
      TCCR1B |= (0 << CS12)|(1 << CS11)|(0 << CS10)|(0 << WGM13)|(1 << WGM12); //presc = 8 //pg110
      TIMSK |= (1 << OCIE1A);   

   
      sei();            
}

ISR (TIMER1_COMPA_vect)
{
   cli();
      
   TXPORT = (TXPORT & ~(1 << TXD)) | ((txbyte & 0x01) << TXD);
   txbyte = (txbyte >> 0x01) + 0x8000;   
      
   if(txbitcount > 0)         
   {
      txbitcount--;         
   }

   sei();
}

void soft_uart_send(uint8_t tb)
{
   while(txbitcount);      
   txbyte = (tb + 0xFF00) << 0x01;
   txbitcount = 0x0A;      
}

int main(void)
{
   uint8_t b = 0;
   
   soft_uart_init();
   
   b = 32; //0x20
   soft_uart_send(b);
         
   b = 117; //0x75
   soft_uart_send(b);

while (1)
   {   
      if(temp)
      {
         b = 32; //0x20
         soft_uart_send(b);
            
         b = 122; //0x7A
         soft_uart_send(b);
                              
         b = 32; //0x20
         soft_uart_send(b);
            
         _delay_ms(1000);
      }
   
      else
      {
         b = 32; //0x20
         soft_uart_send(b);
         
         b = 117; //0x75
         soft_uart_send(b);
               
         b = 32; //0x20
         soft_uart_send(b);
         
         _delay_ms(1000);
      }
   
   }
   return (0);
}


Всю голову сломал, max232 менял, контроллер менял, int0 на int1 менял.
Результат эмуляции в протеусе:
Show


Сигнал на ножке контроллера на железке:
Show


В общем хелп ми)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: soft uart, прием, atmega32. Не работает)
СообщениеДобавлено: 22 авг 2019, 22:26 
Заглядывает иногда

Зарегистрирован: 22 мар 2012, 21:55
Сообщения: 89
Откуда: г.Пермь
temp не должна быть volatile?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: soft uart, прием, atmega32. Не работает)
СообщениеДобавлено: 23 авг 2019, 10:18 
Только пришел

Зарегистрирован: 13 дек 2018, 18:24
Сообщения: 8
хм, переделал на volatile int temp

стало срабатывать однократно - нажмешь первый раз меняется символ, а дальше сколько не нажимай остается одинаковым. но уже прогресс)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: soft uart, прием, atmega32. Не работает)
СообщениеДобавлено: 24 авг 2019, 18:00 
Старожил

Зарегистрирован: 25 фев 2011, 18:45
Сообщения: 3693
Откуда: Новосибирск
Может фьюзы не так выставлены. Частота ядра снижена в 8 раз?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB