STM32 Buffered Usart

Başlatan ErsinErce, 27 Ağustos 2013, 21:45:57

ErsinErce

Şu an için tek tek karakter alırken sıkıntı çıkarıyor min 2 karakter istiyor, üzerinde uğraşılması gerekiyor

aşağıdaki kodlar ile gönderim ve alım için 2 buffer mevcut göndermek istediğim veriyi bu buffera atıp interruptlar ile kendi kendine halletmesini bekliyorum
Benzer yapı DMA ile de yapılabilir ama DMA'nın başka işi olunca kolaylık sağlıyor tabi bu arada normalde başka işlerle uğraşıyorum

gets paket olarak verileri aldığından buffer ı maks uzunluğa göre ayarlamanız gerekiyor

veri alınırken paketin bittiği IDLE biti ile anlaşılıyor bu bit de son alınan frame den sonra ayarlanan hıza göre 1 frame bekliyor bu süre içinde data gelmezse flag kaldırılıyor

ekstra;
bir veri akışı sırasında sizi ilgilendirmeyen veriler geliyorsa usart uyku moduna alınıp gereksiz interruptdan kurtarılabiliniyor.
IDLE biti sayesinde hat boşalınca tekrar usart uyandırılabiliyor veya ilk gelen data x olursa uyan durumu da mevcut ama karşılaştıracağı datayı nereye yazıyoruz ona uğraşamadım

bir başlangıç olması açısından örnek kodlar;


char gets_usart(char *s ,char n){
	if(n==3){
		if(Usart3_RC){
			USART3->CR1&=~USART_CR1_RXNEIE;
			memcpy(s ,Usart3_RBuffer ,Usart3_Raddr );
			Usart3_Raddr=0;
			Usart3_RC=0;
			USART3->CR1|=USART_CR1_RXNEIE;
			return 1;
		}
		else{
			return 0;
		}		
	}


char puts_usart(char *s ,char n){
	if(n==3){
		if(Usart3_TC){
			Usart3_Tlen=strlen(s);
			memcpy(Usart3_TBuffer ,s ,Usart3_Tlen );
			Usart3_Taddr=0;
			Usart3_TC=0;
			USART3->DR = Usart3_TBuffer[Usart3_Taddr];
			Usart3_Taddr++;
			USART3->CR1|=USART_CR1_TXEIE;
			return 1;
		}
		else{
			return 0;
		}		
	}


void USART3_IRQHandler(){
	volatile unsigned short Usart3_SR;
	Usart3_SR = USART3->SR;
	if((Usart3_SR&USART_SR_RXNE)&&(USART3->CR1&USART_CR1_RXNEIE)){
		Usart3_RBuffer[Usart3_Raddr] = USART1->DR;
		Usart3_Raddr++;
		USART3->CR1|=USART_CR1_IDLEIE;
	}
	if((Usart3_SR&USART_SR_IDLE)&&(USART3->CR1&USART_CR1_IDLEIE)){
		USART3->CR1&=~USART_CR1_IDLEIE;
		Usart3_RC=1;
	}
	if((Usart3_SR&USART_SR_TXE)&&(USART3->CR1&USART_CR1_TXEIE)){
		USART3->DR = Usart3_TBuffer[Usart3_Taddr];
		Usart3_Taddr++;
		if(Usart3_Taddr == Usart3_Tlen){
			USART3->CR1&=~USART_CR1_TXEIE;
			USART3->CR1|=USART_CR1_TCIE;
		}
	}
	if((Usart3_SR&USART_SR_TC)&&(USART3->CR1&USART_CR1_TCIE)){
		USART3->CR1&=~USART_CR1_TCIE;
		Usart3_TC=1;
	}
}

Klein

STM32'deki IDLE mekanizması nasıl çalışıyor?
Boşta kalınca IDLE moda geçiyor ama  bu Timeout süresini ne belirliyor? kaç bit uzunluğunda?
Idle moddan çıkmak için yeni bir veri mi gelmesi gerekiyor?
özel bir uyandırma deseni mi gerekiyor?
vs..
vs..

Biraz kolaycılık oluyor ama , datasheetlere gömülmeyi hiç gözüm yemiyor.

ErsinErce

#2
hat 1 frame boyunca boşta yani sürekli 0 geliyorsa IDLE 'ı çakıyor hocam :)
frame boyu sizin ayarladığınız parametrelerde belli zaten 8n1 115200 gibi
IDLE(r-o) Tekrar RXNE(veri geliyor biti) aktif olmadan aktifleşmiyor başka esprisi yok
aradaki boşlukları tespit ediyor sadece datasheet'te 2 satırdan fazlasına yer verilmemiş zaten  :)


uyandırma kısmı ektsra, kafa karıştırdı sanırım 485 gibi ortamlarda kolaylık sağlar diye belirttim
bir veri dizisi gelirken o veri dizisini işlemeyecekseniz almanıza gerek olmadığından receiver ı uyutabiliyorsunuz
hat boşa düşünce IDLE ile tekrar receiver aktif olabiliyor, yada belli bir başlangıç datası bekleyerek usartcr2 de 4 bitlik adresle karşılaştırma yapıyormuş
sf:773


Klein

Kaç frame boynca veri gelmezse Idle olacağı seçilebiliyor mu?



ErsinErce