WinAVR + Atmega8 = USB устройство

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
SubDia
Держит паяльник хвостом
Сообщения: 995
Зарегистрирован: Сб апр 02, 2011 17:59:22
Откуда: Город-герой Севастополь

Re: WinAVR + Atmega8 = USB устройство

Сообщение SubDia »

Satyr писал(а):А преподы - слушать их надо очень аккуратно. Ведь как правило, знания их очень локальные, при этом и объем практики пренебрежимо мал по сравнению с теорией -))
Этот человек вообще работает в одной серьезной забугорной конторе и занимается разработкой микропроцессорных блоков контроля радиосредствами (для военных). И опыта у него как у нас с Вами, только еще на сто умножить. Так что верить его словам у меня оснований более чем достаточно. :)
К тому же я и сам неоднократно сталкивался с такими ситуациями, когда инициатором связи должен выступать именно компьютер. Ну да ладно, это лирика.
alexey6522, можно сделать что-либо наподобие вот такого:

Код: Выделить всё

u8 msg[]=" Hello world! ";    
u32 msg_buf=0;  
while (msg[msg_buf])        
    {
      while ((UCSRA&(1<<UDRE)) == 0){} 
      UDR=msg[msg_buf]; msg_buf++;  
    } 
Либо воспользоваться стандартной библиотекой ввода-вывода (stdio.h).
pavel_cydenov: Вобще я праAVRославный человек. Но и про ислARM слышал много хорошего )
MrYuran: Самые ортодоксальные — это PICудеи )
Katz: Не, 51-ники. )
Изображение
Реклама
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: WinAVR + Atmega8 = USB устройство

Сообщение alexey6522 »

SubDia
Спасибо! теперь у меня получается передать строку и не одну. Хотел оформить все это в виде отдельной функции и вышла неувязочка, при вызове

функция передачи сообщения

Код: Выделить всё

void USART_vSendByte(unsigned char u8Data[]) {
  unsigned int msg_buf=0;
  while((UCSRA&(1<<UDRE)) == 0); // Wait if a byte is being transmitted
  UDR = u8Data[msg_buf]; msg_buf++; // Transmit data
}
Её вызов

Код: Выделить всё

USART_vSendByte(' Hello world! '); //Отправляем данные в порт
компилятор в этом случае говорит на буржуйском
main.c:71: warning: passing argument 1 of 'USART_vSendByte' makes pointer from integer without a cast
Хотя по сути я делаю тоже самое что и если бы все это оформил в int main(void)
Реклама
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Re: WinAVR + Atmega8 = USB устройство

Сообщение md5sum »

alexey6522 писал(а):Уже руки опускаются с этих COM портом, интересно, а с USB HID так же тяжело работать, мда, наверно моя панель для авиасимулятора будет долго разрабатываться, хочу сделать панель автопилота с ручками задачи высоты авт. скорости и т.д.
и что бы все значения отображались на индикаторе
Во первых определитесь со скоростью МК - от нее будет плясать скорость передачи.
8МГц тактовая / (16*9600) -1 = 51.08 в UBRR заносим 51
8 МГц / (16*57600) -1 = 7.68 - работать не будет т.к. велика ошибка
8 МГц / (8*57600)-1 = 16.36 - работать может и будет, но неустойчиво
8 МГц / (8*38400)-1 = 25.04 - в UBRR заносим 25, в UCSRA установить бит U2X - т.к. искользуем удвоение скорости (в делителе 8 а не 16)
12 Мгц / (8*57600) = 25.04 - в UBRR заносим 25, в UCSRA установить бит U2X - т.к. искользуем удвоение скорости (в делителе 8 а не 16)
Первый и последние два варианта будут работать 100%
Теперь отправка:

Код: Выделить всё

void USART_vSendByte_as_hex(const unsigned char u8Data) { 
/*Отправляем байт в ASCII HEX кодах*/
	uint8_t tmp;
	// Wait if a byte is being transmitted
	while((UCSRA&(1<<UDRE)) == 0);
	// Transmit data
	tmp= (u8Data>>4) & 0x0f; //старший нибл
	if (tmp<10) tmp+=0x30; else tmp+=0x37;
	UDR = tmp;
	while((UCSRA&(1<<UDRE)) == 0);
	// Transmit data
	tmp= u8Data & 0x0f; // младший нибл
	if (tmp<10) tmp+=0x30; else tmp+=0x37;
	UDR = tmp;
	}
Отправка строки строка должна заканчиваться нулем (0x00)

Код: Выделить всё

void USART_vSend_str(const char *data) { 
	char *tmp;
	tmp=data;

	while (*tmp) {
		// Wait if a byte is being transmitted
		while((UCSRA&(1<<UDRE)) == 0);
		// Transmit data
		UDR = *tmp;
		tmp++;
	}
}
Отправлять строку можно как обычно USART_vSend_str("Hello");
Нулевой символ добавит компилятор, а если надо отправить буфер USART_vSend_str(buff);
То Вам надо позаботиться о том, что-бы последним символом был 0
— Не говорите мне что делать и я не скажу куда Вам идти...
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: WinAVR + Atmega8 = USB устройство

Сообщение alexey6522 »

Спасибо парни, здорово помогли! Хочу еще с парой строк разобраться

Код: Выделить всё

DS=((indikator[i / 10] << 8 ) | indikator[i % 10];
if (i==99) // Если i > 99 то обнуляем
     i=0;
else i++;
 или вот тоже самое но записано по другому
DS=(indikator[i] << 8 ) | indikator[j];
  if (j==9)
  {
   j = 0;         
   if (i==9) // Если i > 9 то обнуляем
     i=0;
   else i++;
   }
   else j++;
 
меня интересует всего две строки
DS=((indikator[i / 10] << 8 ) | indikator[i % 10];
DS=(indikator << 8 ) | indikator[j];
кто может объяснить что означает << 8б почему именно 8 и почему стоит знак | (или)
Объясню вкратце, это счетчик и он считает от 0 до 99 в схеме два сдвиговых регистра
, я думал что хорошо знаю C++ и Delphi оказывается это не так.
Вложения
схема2.JPG
(85.1 КБ) 347 скачиваний
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Re: WinAVR + Atmega8 = USB устройство

Сообщение md5sum »

alexey6522 писал(а):почему именно 8
Может потому, что в байте 8 бит? :))
alexey6522 писал(а):я думал что хорошо знаю C++ и Delphi оказывается это не так.
:))
— Не говорите мне что делать и я не скажу куда Вам идти...
Реклама
Аватара пользователя
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029
Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:

Re: WinAVR + Atmega8 = USB устройство

Сообщение IfoR »

alexey6522 писал(а):я думал что хорошо знаю C++ и Delphi оказывается это не так.
Хорошо знать C++? Деточка, это невозможно. 8)
К тому же это не C++, а C и вот его уже хорошо знать не помещало бы.
<< - это оператор побитового сдвига влево на n бит. В данном случае на 8 бит, ака байт.
| - это оператор побитовое ИЛИ. Он принимает оператор ИЛИ в каждому соответствующему биту в паре чисел.
Т.е. этот код помещает код цифры десятков в старший байт числа, а код единиц в младший.
Изображение
/dev/urandom - гигабайты информации.

OS: openSUSE 13.2 (x86_64)
Реклама
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: WinAVR + Atmega8 = USB устройство

Сообщение alexey6522 »

Я чувствую себя новичком в С, мне правда стыдно.
Вот код счетчика, частично переделанный из 2-х разрядного в 4-х разрядный, в схеме 4 сдвиговых регистра, т.е. 32 канала и 32 бита, на участке кода
for (i=0;i<32;i++) {
if ((data&0x80000000)==0x00){
надеюсь сделал правильно, а как мне изменить следующий немаловажный участок отвечающий за сдвиг в случае если младший байт числа равен 9
DS=((indikator[i / 10] << 8 ) | indikator[i % 10]; эта часть кода предназначена для 2-х разрядного числа, как мне увеличить до 4-разрядного?
т.е. мне надо добавить еще сдвиг на 16 бит (2 байта) и получим что-то типа
DS=((indikator[i / 10] << 8 ) | (indikator[i / 10] << 8 ) | (indikator[i / 10] << 8 ) | indikator[i % 10]

Код: Выделить всё

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

// составляем из сегментов цифры
#define   N0   (0x3F)      //0
#define   N1   (0x06)      //1
#define   N2   (0x5B)      //2
#define   N3   (0x4F)      //3
#define   N4   (0x66)      //4
#define   N5   (0x6D)      //5
#define   N6   (0x7D)      //6
#define   N7   (0x07)      //7
#define   N8   (0x7F)       //8
#define   N9   (0x6F)      //9

unsigned char indikator[10]={N0, N1, N2, N3, N4, N5, N6, N7, N8, N9};
unsigned char y=0; //переменная y   

void export_data (unsigned int data)
{
  unsigned char i; //переменная i
  for (i=0;i<32;i++) {
    if ((data&0x80000000)==0x00){
      PORTD&=~_BV(PD5); //Выставляем биты данных на PD5 (DATA канал)    
     }
    else {
     PORTD|=_BV(PD5);
     }
    PORTD|=_BV(PD6); //Импульс на SH_CP (запись)
    PORTD&=~_BV(PD6);
    data<<=1;
  } 

   PORTD|=_BV(PD7); //Импульс на ST_CP (защелка - вывод на индикатор записанных данных)
    PORTD&=~_BV(PD7);
}

int main(void)
{
  unsigned int DS=0;   //переменная DS
  unsigned int i=0;    //переменная i
  PORTD=0x00; //Первоначально устанавливаем на всех выходах 0
  DDRD=0xff; //установить PD0-PD2 как выходы

  while (1)  //Бесконечный цикл
   {   
      DS=((indikator[i / 10] << 8) | indikator[i % 10]); //Закодированное число в 16hex системе исчисления
      export_data(DS);   //Отправляем данные на сдвиговый регистр
      if (i==9999)  // Если i > 9999 то обнуляем
        i=0;
      else i++;
      _delay_ms(500);  //пауза 300 мс.
   }
}
alexey6522
Встал на лапы
Сообщения: 149
Зарегистрирован: Чт июл 28, 2011 18:12:28

Re: WinAVR + Atmega8 = USB устройство

Сообщение alexey6522 »

Наверно вопрос некорректно задал, в общем хочу собрать секундомер, что бы считал от 0 до 99999, как видите 5 разрядов, но знаю только как реализовать от 0 до 99 проблема в выдаче данных на индикатор
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»