USART - vysílání více bytů PIC18 v C

Opět zdravím,

jsem tu zase s dalším dotazem. Mám problém s vysíláním více bytů za sebou z USARTu. U řady PIC16 jsem používal :

void Uart1SendChr() {
while(!PIR1bits.TX1IF);
TX1REG = (110);
while(!PIR1bits.TX1IF);
TX1REG = (120);
while(!PIR1bits.TX1IF);
TX1REG = (130);
while(!PIR1bits.TX1IF);
TX1REG = (140);
while(!PIR1bits.TX1IF);
TX1REG = (150);
while(!PIR1bits.TX1IF);
TX1REG = (160);
}

a odeslal se mi každý byte. Teď kdy to zkouším u řady PIC18 a vždy se mi odešle jen “160”. No vlasně někdy tam skočí i třeba “120” a “160”. Jen když po while dám třeba DelayMs(500) tak to odečle všechny. Ale to je moc velké zpoždění.
Neměl by někdo funkčí knihovnu s USARTem pro MCC18?
Já jsem našel moc pěknou ale je psaná pro kompilátor HI-tech a nepodařilo se mi ji upravit pro MCC18. Posílám ji v příloze, třeba by měl někdo jiný větší úspěch. Obsahuje dvě složky. Jedna je originál pro HI-Tech a druhá je mnou upravená pro MCC18 - ale nefunkční.
Jinak ještě bych rád požádal o nějaké příkaldy komunikace USART se vstupní i výstupním bufferem.
Dík…
USART tutorial.zip (44.6 KB)

Zkus tento příkaz, uprav si ho dle tvého překladače…

while (!(txsta.TRMT));

I tento bit jsem zkoušel testovat cyklem while.

while(!TXSTA1bits.TRMT);

Výsledek byl stejný.

Casovanie kristalu a uart sedi? Co zvysit rychlost? Na kolko to mas taktovane aky prevodnik

Omlouvám se tohle je moje chyba…
Chyba se netvořila na staně PICky ale na straně programu v počítači, který data zobrazoval.
Stejně jsem ale nedokázal rozchodit příkazy z knihovny, kterou jsem tady přikládal. Mohu posílat jednoduché byty jako char, ale celé textové řetězce mi nejdou. Věděl by někdo co s tím? Ale jen pro MCC18. Ještě trochu tápu v pointerech.

*****************************************************************/
#include “p18f26k22.h”

//#include “htc.h”

void USARTInit();

void USARTWriteByte(char);

void USARTWriteString(char *);

void USARTWriteLine(char *);

void USARTWriteInt(int ,unsigned char);

unsigned char USARTReadByte();

void USARTInit() {
//Baud Rate = 9600 Bits per Second
//*** Note: Valid On 16MHz Crystal ONLY ***
//For other crystal freq calculate new values for SPBRG
SPBRG1=130;
SPBRGH1=6;
//TXSTA REG
TXSTA1bits.TXEN=1;
TXSTA1bits.BRGH=1;
//RCSTA
RCSTA1bits.SPEN=1;
RCSTA1bits.CREN=1; //Enable Receiver (RX)
//BAUDCON
BAUD1CONbits.BRG16=1;
}

void USARTWriteByte(char ch){
//Wait for TXREG Buffer to become available
while(!PIR1bits.TX1IF);
//Write data
TX1REG=ch;
}

void USARTWriteString(char *str){
while((*str)!=‘\0’) {
//Wait for TXREG Buffer to become available
while(!PIR1bits.TX1IF);
//Write data
TX1REG=(*str);
//Next goto char
str++;
}
}

/*
Writes a line of text to USART and goes to new line
The new line is Windows style CR/LF pair.
This will work on Hyper Terminal Only NOT on Linux
*/
void USARTWriteLine(char *ln){
USARTWriteString(ln);
//USARTWriteString(“\r\n”);
USARTWriteByte(10);
USARTWriteByte(13);
}

void USARTWriteInt(int val,unsigned char field_length){
char str[5]={0,0,0,0,0};
int i=4,j=0;
if(val<0) {
USARTWriteByte(‘-’); //Write ‘-’ sign for negative numbers.
val=(val*(-1)); //Make it positive.
}

//Convert Number To String and pump over Tx Channel.
while(val)	{
	str*=val%10;
	val=val/10;
	i--;
}
if(field_length>5) 
	while(str[j]==0) j++;
else
	j=5-field_length;

for(i=j;i<5;i++) USARTWriteByte('0'+str*);

}

unsigned char USARTReadByte(){
while(!PIR1bits.RCIF); //Wait for a byte
return RC1REG;
}**
usart.h (2.27 KB)

HI-TECH neznám, ale většina IDE, s kterými jsem se setkal používá pro komunikaci přes UART funkce printf a scanf - mezi nima i MCC18.

Ale i bez toho to máš jakési moc komplikované.

Je dobré pro UART mít nějaký buffer a pak by neměl být problém.[code]
#define BUFFER_SIZE 10 // třeba 10

char tx_buffer[BUFFER_SIZE]; //

// teď naplníš buffer svými daty - nezapomeň na konec řetězce dát nulový znak 0x00, nebo ‘\0’ do textu

USARTWriteString(tx_buffer); //odeslání řetězce

//nebo
USARTWriteString(“ahoj\0”); //odeslání řetězce

[/code]

Problém ale je jak u printf , tak u USARTWriteString, že to jsou funkce stavěné na posílání ASCII znaků. Spočívá v tom, že hledají ten nulový znak a přenos ukončí jeho nalezením. A tady můžou nastat dva případy - buď se přenos ukončí dříve, než jsi chtěl - to v případě, že posíláš data v hex. tvaru a ta 0x00 se ti tam může objevit kdekoliv. A nebo ti to tam nasype i byty, které nechceš , protože jsi konec svého řetězce nezakončil nulovým znakem a funkce jede do té doby než ho někde najde :slight_smile:

pro ten případ je potřeba trochu upravit funkci USARTWriteString

void USARTWriteHexData(char *str){ char i; i=sizeof (str); while(i) { //Wait for TXREG Buffer to become available while(!PIR1bits.TX1IF); //Write data TX1REG=str*; //Next goto char i--; }no a pak stačí zadat [code]

char HexData] ={0x0C,0xF2,0x00,0xFF}; //příklad definice řetězce

USARTWriteHexData(HexData);//odeslání řetězce[/code]*

Děkuju za rady. Nakonec jsem si vybral pro posílání celých řetězců funci printf. Pěkně formátuje daný řetězec a nevidím v tom zatím žádnou obtíž. Jediný co musím, je předefinovat funkci putc a includovat soubor stdio.h. Funkce printf se dá použít i pro zobrazení na displej a to se bude taky časem hodit. V pondělí sem hodím přesný zápis funkcí, abych si to nenechal jen pro sebe :slight_smile: Těď PICky nechám spát a půjdu se bavit, už jsem ze čtení návodů a bastlení celej ztuhlej, tak to musím jít rozhejbat :slight_smile:

Ještě jednou díky…

Pokud si vzpomínám tak nevýhoda byla velikost. Na škole jsme měli nějakou education verzi s omezením velikosti hexu a když se použil printf tak už nezbejvalo moc místa na samotnej program.

U 64k flashky typu 18f26k22 se nedostatku místa opravdu, ale opravdu (jak říkává V.K. :smiley: ) bát nemusíš.

len aby sa s toho nestal WINdovsacky pristup… funcie furt tie iste len vykon procesora a ram treba obrovsku. Ono totiž tak sa uP neprogramuju.

A jak se teda programují? A proč Microchip coby výrobce mikrokontolerů má ve vesvém C compileru tu “nenažranou” knihovnu stdio ? Já myslím, že proto, aby lidi mohli využívat výhod jednoduchosti C jazyka včetně jeho standartních knihoven.