Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

Настройка UART в ATTiny2313.

Чт июн 14, 2012 20:57:14

Начал осваивать UART. Но на самом элементарном застопорился. Вот код:
Код:
#include <intrinsics.h>
#include<ioavr.h>
#include <iotiny2313.h>
#define F_CPU 8000000 //Частота в Гц
#define baudrate 9600 //Скорость
main()
{
unsigned char data='P'; //То, что хочу кинуть
UBRRH=(unsigned char)((F_CPU/(16*baudrate)-1)>>8);//Скорость 9600
UBRRL=(unsigned char)(F_CPU/(16*baudrate)-1);
UCSRA=0;
UCSRB=(1<<TXEN)|(1<<RXEN)|(0<<RXCIE)|(0<<TXCIE)|(0<<UDRIE);//Прерывания офф
UCSRC=(1<<UCSZ0)|(1<<UCSZ1)|(1<<UMSEL);
while(1) //Бесконечный цикл
{
if(UDRE==1)//Если буфер пуст
{
UDR=data; //Кидаем байт
__delay_cycles(F_CPU/2); //Ждем полсекунды
}
}
}

Подключаю в Протеусе терминалку(RXD и TXD терминалки на TXD и RXD контроллера). В терминалке ничего. Однако, если тупо в бесконечном цикле слать байт, то в терминалке просто ставится пробел. В чем проблема?Разбирался-разбирался, что-то не догнал пока :( :( Это может быть из-за того,что бита URSEL в Тини2313 нет вообще? Я думал, что вместо него UMSEL.

Re: Настройка UART в ATTiny2313.

Пт июн 15, 2012 01:17:21

Переделывал чужую терминалку с at90c2313 на ATTiny2313.
Вот рабочий инит rs232 от нее.
Код:
inline void
rs232_init() {
  UBRRL = UC_CLOCK /16 /BAUDRATE -1;          /* set baudrate *//*изменено*/
/*  UCR |= _BV(TXEN) | _BV(RXEN) | _BV(RXCIE); *//* activate sending and receiving */
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  /*изменено*/
}
Вложения
rs232.h
заголовок
(406 байт) Скачиваний: 780
rs232.c
модуль
(900 байт) Скачиваний: 761

Re: Настройка UART в ATTiny2313.

Пт июн 15, 2012 08:47:51

Спасибо вам огромное!!Инит действительно рабочий. Только вот ещё закавыка-как проверять, что байт ушел? Если я пишу так:
Код:
#include <intrinsics.h>
#include<ioavr.h>
#include <iotiny2313.h>
#define F_CPU 8000000
#define BAUDRATE 9600
main()
{
unsigned char data='P';
UBRRL = F_CPU /16 /BAUDRATE -1;          /* set baudrate *//*изменено*/
/*  UCR |= _BV(TXEN) | _BV(RXEN) | _BV(RXCIE); *//* activate sending and receiving */
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  /*изменено*/
while(1)
{
UDR=data;
__delay_cycles(F_CPU/2);
}
}

То каждые полсекунды в терминалке пишется буква "P". А если так:
Код:
#include <intrinsics.h>
#include<ioavr.h>
#include <iotiny2313.h>
#define F_CPU 8000000
#define BAUDRATE 9600
main()
{
unsigned char data='P';
UBRRL = F_CPU /16 /BAUDRATE -1;          /* set baudrate *//*изменено*/
/*  UCR |= _BV(TXEN) | _BV(RXEN) | _BV(RXCIE); *//* activate sending and receiving */
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  /*изменено*/
while(1)
{
if(UDRE==1)
{
UDR=data;
__delay_cycles(F_CPU/2);
}
}
}

То в терминалке вообще пусто :( :( :(
Как все же узнать, что байт ушел(потом это проверять буду прерыванием, но сначала нужно так разобраться)?

Re: Настройка UART в ATTiny2313.

Вс июн 17, 2012 07:54:10

while(1) //Бесконечный цикл
{
while ( !( UCSRA & (1<<UDRE)) ) ;
UDR = data;
__delay_cycles(F_CPU/2); //Ждем полсекунды
}

Re: Настройка UART в ATTiny2313.

Пн июн 18, 2012 08:49:16

UDRE показывает только что пуст регистр UDR, и байт ушел на передачу, а то что байт передан и UDR при этом пуст показывает TXC.

Re: Настройка UART в ATTiny2313.

Вт июн 19, 2012 20:53:36

Хм, тогда может кто-нибудь объяснит, зачем 2 прерывания? Просто смысл не очень понятен, точнее: зачем 2? Ведь можно было просто сообщать, что байт ушел, либо что регистр пуст и можно слать дальше. Но сразу 2...Зачем?

Re: Настройка UART в ATTiny2313.

Вт июн 19, 2012 21:07:44

Во многих своих поделках я при передаче массива следующий байт закидывал в UDR по UDRE, а только послав последний байт, дожидался TXC - сигнал ПЕРЕДАЧА ОКОНЧЕНА. До окончания передачи у меня фоновой задачи не было, поэтому UDRE и TXC ловил не по прерываниям, а по опросу флагов. Как вариант...

Re: Настройка UART в ATTiny2313.

Ср июн 20, 2012 08:45:21

Да да именно так. А зачем сделано 2 на передачу? Ну например если используется дуплексная связь, то нам все равно, передался ли последний байт или нет, мы просто выдаем в UDR данные как только он освободится, а если используется например RS-485, там еще и направлением передачи нужно управлять - а это только по TXC можно сделать иначе байт потеряется.

Re: Настройка UART в ATTiny2313.

Ср июн 20, 2012 16:40:25

А с этого момента поподробнее, пожалуйста. К примеру, хотя бы описания передачи/приема байта в том же RS-485.

Re: Настройка UART в ATTiny2313.

Чт июн 21, 2012 08:32:26

А там все делается точно так же как и с обычным UARTом, только перед передачей нужно на ногу которая соединена с линиями $RE/DE MAX487 подать единицу, а после окончания передачи подать ноль. Пока передаем строку пользуемся флагом UDRE для того чтобы передать данные в UDR, после того как последний байт ушел в UDR, смотрим флаг TXC. Можно например по его прерыванию проверять передались ли все байты и если передались - переводить MAX478 на прием.
Пример передачи:
Код:
UART_WRITE: ;передача строки из флеша по RS485
   CBR   REG0,(1<<SEND_REQUEST) ;сброс флага необходимости передачи
   SBI   PORTD,TX_EN ;переключение MAX487 на передачу
   LDI   ZH,High(CMD0*2) ;указатель на начало строки   
   LDI   ZL,Low(CMD0*2) ;во флеше
   LDI   R17,5 ;длина строки
TX_LOOP:LPM   R16,Z+ ;загружаем байт
   OUT   UDR,R16 ;отправляем в UDR
   SBIS   UCSRA,UDRE ;ждем пока UDR освободится
   RJMP   PC-1
   DEC   R17 ;длина=длина-1
   BRNE   TX_LOOP ;длина>0 передаем следующий
   CLR   R16 ;сброс R16
   SBRS   R16,0 ;ждем пока R16=0
   RJMP   PC-1 ;а он будет=0 пока не сработает прерывание TXC
   CBI   PORTD,TX_EN ;MAX487 - на прием
   RET ;выход
TXC_VECT: ;прерывание TXC
   LDI   R16,0xFF ;меняем R16
   RETI ;выход

Re: Настройка UART в ATTiny2313.

Чт июн 21, 2012 15:43:06

Спасибо вам огромное! Вроде, начинаю разбираться...
Тема закрыта