Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > From ATmega16 to com-Port


Автор: vitaliska 9.9.2007, 14:29
Всем привет!

Необходимо считывать данные с com-порта, на который микроколнтроллер ATmega16 сыпет информацию (одно число/символ).
Скорость 19200, асинхронный режим, 8 инф, один стоповый, без четности.
Вот прошивка МК (WinAVR):
Код


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

#define FOSC 4000000
#define BAUD 19200
#define MYUBRR 12

void USART_Init (unsigned int);
void USART_Transmit(unsigned int);

unsigned int param1;

void main(void)
{
    USART_Init(MYUBRR);
    param1 = 156;
while(1)
{
    USART_Transmit(param1);
    //_delay_ms(100);
    //_delay_ms(100); 
    //_delay_ms(100);
    
}
}


void USART_Init (unsigned int ubrr)
{
    UBRRH = (unsigned char)(ubrr>>8);
    UBRRL = (unsigned char)ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<URSEL)|(3<<UCSZ0);
}


void USART_Transmit(unsigned int data)
{
    while ( !( UCSRA & (1<<UDRE)));
    UDR = data; 
}
//------------------------------------------------------------------------------------------



В HyperTerminal верно отображаются бегущие символы, программа BaseTerm на основе ComBase тоже правильно пишет.

Пытаюсь самостоятельно с помощью API в консольном приложении прочитать порт (XP Home, VS .NET 2003, VC++7.1 ):

Код


#include <windows.h>
#include <stdio.h>

#define    SizeBuffer 1024

//Структуры для настройки COM порта
   DCB           dcb;
   COMMTIMEOUTS  ct;
   COMSTAT       ComState;
   HANDLE        port;
   DWORD         bc,temp;
   OVERLAPPED    Overlap;


   char *buf_in;
   char x;
   int i=0;

 void main (void)
{
    port = CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
       
  //Настройка COM порта
    GetCommState(port, &dcb);

    dcb.DCBlength          = sizeof(DCB);
    dcb.BaudRate           = CBR_19200;
    dcb.fBinary            = 1;
    dcb.fParity               = 1;
    dcb.ByteSize           = 8;
    dcb.Parity             = NOPARITY;
    dcb.StopBits           = ONESTOPBIT;   
        
    SetCommState(port, &dcb);
  //Настройка размера буфера
    SetupComm(port, SizeBuffer, SizeBuffer);

  //Настройка тайм-аутов
    GetCommTimeouts(port, &ct);
    ct.ReadIntervalTimeout         = 10;
    ct.ReadTotalTimeoutMultiplier  = 1;
    ct.ReadTotalTimeoutConstant    = 100;
    ct.WriteTotalTimeoutMultiplier = 0;
    ct.WriteTotalTimeoutConstant   = 0;
    SetCommTimeouts(port, &ct);       
  
  //Очистка линии   
    PurgeComm(port,PURGE_TXCLEAR|PURGE_RXCLEAR);
  //-----------Теперь COM порт открыт-----------
  

  //Чтение из порта 
  while(1)
  {
      ClearCommError(port, &temp, &ComState); 
      //Sleep(100);
      ReadFile(port,buf_in,1,&bc,&Overlap);
      printf("%x",buf_in);
      
  }
   
  //Закрытие COM порта
   CloseHandle(port);
}



В консоли пишет одни нули, то есть видимо неправильно настроен прием. В чем ошибки и что надо добавить. Заранее спасибо.
P.S. Хочу, чтобы в запасе был простой и компактный вариант проекта чтения порта без сторонних библиотек и компонентов. 
 

Автор: vitaliska 9.9.2007, 17:09
Получилось настроить прием после упрощения проекта в соответствии с примером max1000.
Нужно было определить буфер приема как unsigned char, а в функции ReadFile добавить к имени &.  

Работающий вариант:

Код

#include <windows.h>
#include <stdio.h>

//Структуры для настройки COM порта
   DCB           dcb;
   HANDLE        port;
   DWORD         numbytes;
   OVERLAPPED    Overlap;
//----------------------------------
   unsigned char data;
      
 void main (void)
{
  //Настройка COM порта (Асинхронный режим, 19200, 8 бит, 1 стопбит, бита четности нет)
    port = CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
    GetCommState(port, &dcb);
    dcb.BaudRate           = CBR_19200;
    dcb.ByteSize           = 8;
    dcb.Parity             = NOPARITY;
    dcb.StopBits           = ONESTOPBIT;   
    SetCommState(port, &dcb);
  //----------- COM порт настроен-------------
    
  while(1)
  {
      ReadFile(port,&data,1,&numbytes,&Overlap);
      printf("%x \n",data);
  }
   
  //Закрытие COM порта
   CloseHandle(port);
}

  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)