Easyelectronics.ru

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

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



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

Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
 Заголовок сообщения: Не могу передать или принять данные по USART.
СообщениеДобавлено: 03 окт 2019, 15:38 
Заглядывает иногда

Зарегистрирован: 14 июн 2019, 10:29
Сообщения: 57
Хочу реализовать RS485 интерфейс на базе микросхемы MAX487.
Написал программу, которая просто отсылает байт, но проблема в том, что на выходе совершенно не то, что нужно.
Точнее при скорости 9600 данные передаются, а при скорости 115200, на шине какая-то дичь.
Программа:
Код:
/*
* Tester.c
*
* Created: 02.10.2019 6:07:12
* Author : Михаил
*/



#define F_CPU 8000000UL
#define SCL_CLOCK 100000L
#define time 100L

#define BAUDRATE 9600


#include <avr/io.h>
#include <compat/twi.h>
#include <util/delay.h>

//Protutypes of TWI functions
void TWI_init ();
char TWI_start (unsigned char address);
void TWI_start_wait (unsigned char address);
char TWI_rep_start (unsigned char address);
void TWI_stop ();
char TWI_write (unsigned char data);
char TWI_readACK ();
char TWI_readNAK ();

//Prototypes of USART function
void USART_init(uint8_t speed);
void USART_transmit(char data);

//Prototupe of LCD functions
void LCD_send_command (uint8_t data);
void LCD_send_data (uint8_t data);
void LCD_init ();


int main(void){

   TWI_init();
   LCD_init();
   LCD_send_data('H');
   LCD_send_data('e');
   LCD_send_data('l');
   LCD_send_data('l');
   LCD_send_data('o');
   LCD_send_data(' ');
   LCD_send_data('W');
   LCD_send_data('O');
   LCD_send_data('R');
   LCD_send_data('L');
   LCD_send_data('D');
   TWI_stop();

      
   DDRD = 0xFF;
   PORTD = (1 << PIND7);
   
   USART_init(0);
   
   while (1){
      USART_transmit('1');
      _delay_ms(1000);
   }
}


// TWI_atmega8
void TWI_init(){
   TWSR = 0x00;
   TWBR = ((F_CPU / SCL_CLOCK) - 16) / 2;
}

char TWI_start (unsigned char address){
   uint8_t twst;
   
   TWCR |= (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
   while (!(TWCR & (1 << TWINT)));
   
   twst = (TW_STATUS & 0xF8);
   if ((twst != TW_START) && (twst != TW_REP_START))
   return 1;

   TWDR = address;
   TWCR |= (1 << TWINT) | (1 << TWEN);
   while (!(TWCR & (1 << TWINT)));
   
   twst = (TW_STATUS & 0xF8);
   if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK))
   return 1;
   return 0;
}

void TWI_start_wait(unsigned char address){
   uint8_t   twst;
   while (1){
      // send START condition
      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
      // wait until transmission completed
      while(!(TWCR & (1<<TWINT)));
      // check value of TWI Status Register. Mask prescaler bits.
      twst = TW_STATUS & 0xF8;
      if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
      // send device address
      TWDR = address;
      TWCR = (1<<TWINT) | (1<<TWEN);
      // wail until transmission completed
      while(!(TWCR & (1<<TWINT)));
      // check value of TWI Status Register. Mask prescaler bits.
      twst = TW_STATUS & 0xF8;
      if ((twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK)){
         // device busy, send stop condition to terminate write operation
         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
         // wait until stop condition is executed and bus released
         while(TWCR & (1<<TWSTO));
         continue;
      }
      //if( twst != TW_MT_SLA_ACK) return 1;
      break;
   }
}

char TWI_rep_start(unsigned char address){
   return TWI_start(address);
}

char TWI_write (unsigned char data){
   uint8_t twst;
   TWDR = data;
   TWCR |= (1 << TWINT) | (1 << TWEN);
   while (!(TWCR & (1 << TWINT)));
   
   twst = TW_STATUS & 0xF8;
   if (twst != TW_MT_DATA_ACK)
   return 1;
   return 0;
}

void TWI_stop (){
   TWCR |= (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
   while (TWCR & (1 << TWSTO));
}


char TWI_readACK(){
   TWCR |= (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
   while (!(TWCR & (1 << TWINT)));
   return TWDR;
}

char TWI_readNAK(){
   TWCR |= (1 << TWINT) | (1 << TWEN);
   while (!(TWCR & (1 << TWINT)));
   return TWDR;
}

//LCD functions!
void LCD_send_command(uint8_t data){
   uint8_t firstNibble = 0x00;
   uint8_t secondNibble = 0x00;
   
   firstNibble = (data & 0xF0);
   secondNibble = ((data & 0x0F) << 4);
   
   
   TWI_write((0x08 |firstNibble)); // Set up first nibble.
   _delay_us(time);
   TWI_write((0x0C | firstNibble)); // pin EN set up to high level
   _delay_us(time);
   TWI_write((0x08 | firstNibble)); // pin En set up to low level
   TWI_write((0x08 |secondNibble)); // set up second nibble
   _delay_us(time);
   TWI_write((0x0C | secondNibble)); // pin En set up to high level
   _delay_us(time);
   TWI_write((0x08 | secondNibble)); // pin en set up to lov level
   _delay_us(time);
}

void LCD_send_data(uint8_t data){
   uint8_t firstNibble = 0x00;
   uint8_t secondNibble = 0x00;
   
   firstNibble = (data & 0xF0);
   secondNibble = ((data & 0x0F) << 4);

   
   TWI_write((0x09 |firstNibble)); // Set up first nibble.
   _delay_us(time);
   TWI_write((0x0D | firstNibble)); // pin EN set up to high level
   _delay_us(time);
   TWI_write((0x09 | firstNibble)); // pin En set up to low level
   TWI_write((0x09 |secondNibble)); // set up second nibble
   _delay_us(time);
   TWI_write((0x0D | secondNibble)); // pin En set up to high level
   _delay_us(time);
   TWI_write((0x09 | secondNibble)); // pin en set up to lov level
   _delay_us(time);
   

}

void LCD_init(){
   TWI_start(0x4E);
   TWI_write(0x00);
   _delay_ms(1000);
   
   TWI_write(0x20);
   _delay_us(100);
   TWI_write(0x24);
   _delay_us(100);
   TWI_write(0x20);
   _delay_ms(5);
   LCD_send_command(0x28);
   LCD_send_command(0x08);
   LCD_send_command(0x01);
   _delay_us(100);
   LCD_send_command(0x06);
   LCD_send_command(0x0C);
   _delay_ms(10);
}

//USART
void USART_init(uint8_t speed){
   UBRRL = (F_CPU/BAUDRATE/16-1); // Вычисляем скорость обмена данными
   UBRRH = (F_CPU/BAUDRATE/16-1) >> 8;
   
   UCSRB |= (1 << RXCIE)| // Разрешаем прерывание по завершению приема данных
   (1 << RXEN)|(1 << TXEN); // Включаем приемник и передатчик
   
   UCSRC |= (1 << URSEL)| // Для доступа к регистру UCSRC выставляем бит URSEL
   (1 << UCSZ1)|(1 << UCSZ0);
   
}

void USART_transmit(char data){
   while(!( UCSRA & (1 << UDRE)));
   UDR = data;
}


         
      

Схема:


Вложения:
2019-10-03_14-36-30.png
2019-10-03_14-36-30.png [ 26.05 Кб | Просмотров: 381 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать или принять данные по USART.
СообщениеДобавлено: 03 окт 2019, 16:59 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 117
Откуда: Омск
8МГц не делится нацело до скорости 115200.
Либо используйте другую частоту (ниже), либо выбирайте подходящий кварц.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать или принять данные по USART.
СообщениеДобавлено: 03 окт 2019, 17:36 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3051
https://trolsoft.ru/ru/uart-calc в помощь


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать или принять данные по USART.
СообщениеДобавлено: 03 окт 2019, 17:52 
Заглядывает иногда

Зарегистрирован: 14 июн 2019, 10:29
Сообщения: 57
-Alan- писал(а):
8МГц не делится нацело до скорости 115200.
Либо используйте другую частоту (ниже), либо выбирайте подходящий кварц.

Так просто! Спасибо!!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать или принять данные по USART.
СообщениеДобавлено: 04 окт 2019, 01:07 
Старожил
Аватара пользователя

Зарегистрирован: 18 май 2013, 20:43
Сообщения: 5038
Откуда: Кемеровская область, Киселевск
Вложение:
Screenshot_13.png
Screenshot_13.png [ 23.32 Кб | Просмотров: 317 ]

Вложение:
Screenshot_14.png
Screenshot_14.png [ 41.75 Кб | Просмотров: 317 ]

_________________
RADIOWOLF.RU


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


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


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

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


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

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

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