Forum: PC-Programmierung C Prog zum lesen der seriellen


von bubu (Gast)


Lesenswert?

hallo!
ich versuche gerade ein kleines C programm zu schreiben das mir ein paar 
bytes von der seriellen schnittstelle einliest! das einlesen 
funktioniert auch eigentlich nur mein problem ist hauptsächlich das es 
in c keinen byte datentyp gibt und ich somit chars verwenden muss.
ich habe mein programm so eingestellt das es alle 100ms einen wert 
schickt der immer erhöht wird also von 0 bis 255 und dann wieder von 
vorne anfängt, um alle zahlen zu testen. wenn ich die daten nun 
wegschicke empfange ich diese Werte!

1 2 253 253 252 5 6 7 8 9 0 246 11 12 0 243 14 15 16 239 238 237 20 235 
234 233 24 25 230 27 228 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 
113 114 115 116 117 118 119 120 121 122 123 124 125 126 129 128 0 130 
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 
221 222 223 224 225 226 227 0 229 0 231 232 0 0 236 237 238 239 240 241 
242 243 0 244 245 246 0 247 248 249 250 251 0 0 0 254 1 2 253 253 252 5 
6 7 8 9 0 246 11 12 0 243 14 15 16 239 238 237 20 235 234 233 24 25 230 
27 228 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 
75 76 77 78 79 80 81

man sieht sofort das ein großteil der werte stimmen, jedoch gerade bei 
sonderzeichen in der ASCII tabelle wie LF NL oder DEL liest er einen 
falschen zahlenwert ein! in meinem fall 0 oder irgendeinen zu hohen 
Wert!
jetzt wäre es halt interessant wie man so einen fehler wegbekommen 
könnte da ich ja im idealfall gerne Messwerte im bereich von einem byte 
übertragen würd!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Etwas dünne Infos zu eingestellten Parametern und zur verwendeten 
Hardware, Programmcode sowieso.

Mein Tipp: Die Übertragungsrate ist beim Sender und/oder Empfänger 
abweichend vom Sollwert. Die Abweichung ist so gering, dass noch kein 
Hardwarefehler ausgelöst wird und so hoch, dass bereits einige Bits 
unsauber empfangen werden und die Bytes daraus verstümmelt werden.

von bubu (Gast)


Lesenswert?

also die baudrate müsste eigentlich auf beiden seiten richtig 
eingestellt sein! ebenfalls Stop/Parity bit! hier noch mein c code!
1
int configserial(int fd, int baud)
2
{
3
  struct termios options;
4
  /* Get the current options for the port...*/
5
  tcgetattr(fd, &options);
6
  /* Set the baud rates to 19200...*/
7
  cfsetispeed(&options, translatebaud(baud));
8
  cfsetospeed(&options, translatebaud(baud));
9
  /* Enable the receiver and set local mode...*/
10
  options.c_cflag |= (CLOCAL | CREAD);
11
12
  options.c_cflag &= ~PARENB;
13
  options.c_cflag &= ~CSTOPB;
14
  options.c_cflag &= ~CSIZE;
15
  options.c_cflag |= CS8;
16
17
  /* Set the new options for the port...*/
18
  tcsetattr(fd, TCSANOW, &options);
19
  return 1;  
20
}
21
22
23
int writeport(int fd, char *chars) {
24
  int n;
25
  
26
  int len = strlen(chars);
27
  chars[len] = 0x0d; /* stick a <CR> after the command*/
28
  chars[len+1] = 0x00; /* terminate the string properly*/
29
  n = write(fd, chars, strlen(chars));
30
  if (n < 0) {
31
    fputs("write failed!\n", stderr);
32
    return 0;
33
  }
34
  return 1;
35
}
36
37
38
int main(int args, char *argv[])
39
{
40
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
41
  if (fd == -1) {
42
    BailOut("SERIAL: open_port: Unable to open Serial device!");
43
  } else {
44
    fcntl(fd, F_SETFL, 0);
45
  }
46
  
47
  fprintf(stderr,"baud=%d", getbaud(fd));
48
  configserial(fd,BAUDRATE);
49
  fprintf(stderr,"baud=%d", getbaud(fd));
50
51
        fcntl(fd, F_SETFL, O_SYNC  );
52
53
  /* endless read serial */
54
  while(TRUE) {
55
    if(readport(fd,rMessage)==1)
56
    {
57
      fprintf(stderr,"%d ", rMessage[0]);
58
59
      /* write into filesystem */
60
      data.received1 = rMessage[0];
61
      data.received2 = rMessage[1];
62
    }
63
  }
64
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was für Hardware setzt Du denn da ein? Kommunizieren da zwei PCs 
miteinander oder ein µC mit einem PC? In letzerem Falle: Womit erzeugst 
Du da die Baudrate? Was erzeugt den Takt des µC?

von bubu (Gast)


Lesenswert?

es kommuniziert der PC mit einem Atmega128 der hat ein 14.7Mhz Quarz 
drauf!

UART config:
1
#  define CPU_CLK           14745600  
2
#  define BAUDRATE_MAGIC(x)    ((CPU_CLK >> 4) / x - 1)
3
4
#  define MY_UART1_CONTROL_A                 UCSR1A
5
#  define MY_UART1_CONTROL_B                 UCSR1B
6
#  define MY_UART1_CONTROL_C                 UCSR1C
7
8
#  define MY_UART1_BAUDRATE_H                UBRR1H
9
#  define MY_UART1_BAUDRATE_L                UBRR1L
10
11
void init_uart1(uint8_t mode, uint32_t baud, void (*receivefunction)(uint8_t data))
12
{
13
  if(receivefunction != NULL)
14
    receivefunctionpointer1 = receivefunction;
15
16
  MY_UART1_CONTROL_A = 0x00; //set control register A to 0x00
17
  MY_UART1_CONTROL_B = 0x18; //Enable receiver und transmitter
18
  
19
  MY_UART1_CONTROL_C |= ((1<<UCSZ11) | (1<<UCSZ10)); //8 bit, no parity, 1 stopbit
20
21
22
  //set baut rate
23
  MY_UART1_BAUDRATE_H = (BAUDRATE_MAGIC(baud) >> 8);
24
  MY_UART1_BAUDRATE_L = (BAUDRATE_MAGIC(baud) & 0xFF);
25
26
  //enable RX Interrupt
27
  MY_UART1_CONTROL_B |= (1<<RXCIE0);
28
}
29
30
uint8_t send_byte1(uint8_t byte)
31
{
32
  // Wait for empty transmit buffer 
33
  while ( !(UCSR1A & (1<<UDRE1)) )
34
  ;                       
35
  // Start transmission 
36
  MY_UART1_DATA_REGISTER = byte; 
37
  
38
  return 0;
39
}

nachdem man das init aufgerufen hat kann man dann mit 
send_byte1('<zeichen>') das byte wegschicken!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sieht AVR-seitig OK aus.

Probiere mal die PC-Seite in den RAW Modus zu bringen
Beitrag "serielle Schnittstelle sendet nicht mehr"

von bubu (Gast)


Lesenswert?

jo RAW wars! mein held :) dankeschön!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.