STM8 UART Haberleşme Reset Sorunu

Başlatan MuratHp, 30 Ağustos 2019, 18:17:26

MuratHp

Herkese merhaba, STM8S103F3Px entegresi ile uart kestirmeli haberleşme yapmaya çalışıyorum. Fakat bir türlü kestirmelerde başarılı olamadım. Main, init, interrupt fonksiyonlarım aşağıdaki gibidir. Mesaj gönderdiğimde anda entegre kendini resetliyor. Nasıl çözebilirim acaba?

main()
{
	init_handler();
	while (1);
}

void init_handler(void){
	GPIO_Init(CONTROL_LED_PORT,(GPIO_Pin_TypeDef)CONTROL_LED_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
	CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
	UART1_DeInit();
	UART1_Init((uint32_t)1200, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO,
              UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);						
	UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
	enableInterrupts();   		
}


INTERRUPT_HANDLER(UART1_TX_IRQHandler, 17)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.*/
		 
}

 INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  /* In order to detect unexpected events during development,
     it is recommended to set a breakpoint on the following instruction.
*/
	char c;
        while (UART1_GetFlagStatus(UART1_FLAG_RXNE) == RESET);
        c = UART1_ReceiveData8();
        UART1_SendData8(c);
        while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);	

}


RaMu

İnternette mevcut kesme uart örneklerini incelemende fayda var.

Kesme içinde yazdığın while ve uart send işlemleri çok yanlış bir mantık.
Bunları kaldırıp kesmede gelen veriyi alıp,
veri alındı anlamında bir bayrak işaretleyip,
mainde bu bayrağa bakarak gereken gönderme işlemini yapabilirsin.

Öncelikle kesmedeki while kısımlarını atıp bir deneyebilirsin.

Kesme, uart tan bir byte data alımı tamamlandı
anlamında geliyor ise dediğim mantık doğru olur.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

Daha önce benzer çalışma yaptım.
https://www.baranekrem.net/iar-ile-stm8s-uart/

Bu arada sen kesme bayrak temizlemeyi unutmuşsun.
Onuda ekle.
Ayrıca @RaMu hocanın dediklerini dikkate al.

MuratHp

Cevaplarınız için çok teşekkür ederim. Her ikisinide dikkate alarak ve örneğin aynısı bir kod yazdım fakat hala başarısızım. Cosmic ve STVD kullanıyorum. Kodlar aşağıdadır. Nerede bir hata var acaba? Ya da derleyiciden kaynaklanan bir hata mı? @baran123 IAR kullanıyorsunuz anladığım kadarıyla.

main.c
#include "stm8s.h"
#include "main.h"

int flag = 0;
char data = 'g';
void init_handler(void){
 /// Clock init
 CLK_DeInit();
 CLK_HSECmd(DISABLE);
 CLK_HSICmd(ENABLE);
 CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
 CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
 CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
 
 GPIO_Init(CONTROL_LED_PORT,(GPIO_Pin_TypeDef)CONTROL_LED_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
 
 
 UART1_DeInit();
 UART1_Init((uint32_t)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
 UART1_ITConfig(UART1_IT_RXNE_OR,ENABLE);
 UART1_Cmd(ENABLE);
 enableInterrupts();
}

main()
{
 init_handler();
 UART1_SendData8('a');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 for(;;){
 if(flag == 1){
 flag = 0;
 UART1_SendData8('b');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 }
 }
}


#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *  where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

main.h
#include "stm8s.h"

#define CONTROL_LED_PORT (GPIOB)
#define CONTROL_LED_PIN (GPIO_PIN_5)
extern int flag;
extern char data;
void init_handler(void);


stm8s_it.c
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  /* In order to detect unexpected events during development,
    it is recommended to set a breakpoint on the following instruction.
*/
 if (UART1_GetITStatus(UART1_IT_RXNE) != RESET)
  { 
 UART1_ClearITPendingBit(UART1_IT_RXNE);
 data = UART1_ReceiveData8();
 flag = 1;
  }
}

baran123

Evet IAR kullanıyorum.
Açıkcası derleyiciden olacağını pek zannetmiyorum ama eğer sizde IAR kurulu ise bir deneyin derim.
Onu haricinde beni şüphelendiren asıl konu RX pini ile Reset'in yanyana olması.
Bu pinlerin kısa devre olmadığına dikkat edin.


Çünkü veri geldiği anda NRST'i 1-0 yapıyor olabilir.

MuratHp

Pinler arasında her hangi bir kısa devre gözükmüyor. Kart olarak resimdeki kartı kullanıyorum. Bir önceki mesajımında yazdığım kod ile resetleme olmuyor fakat flag=1 de olmuyor.


baran123

Alıntı yapılan: MuratHp - 01 Eylül 2019, 12:35:26Pinler arasında her hangi bir kısa devre gözükmüyor. Kart olarak resimdeki kartı kullanıyorum. Bir önceki mesajımında yazdığım kod ile resetleme olmuyor fakat flag=1 de olmuyor.

(Resim gizlendi görmek için tıklayın.)
Burayı anlamadım
Flag olarak yaptında olmuyor ama kesme içnide while kullanınca resetleme oluyor mu ?

MuratHp

Alıntı yapılan: MuratHp - 01 Eylül 2019, 01:05:23Cevaplarınız için çok teşekkür ederim. Her ikisinide dikkate alarak ve örneğin aynısı bir kod yazdım fakat hala başarısızım. Cosmic ve STVD kullanıyorum. Kodlar aşağıdadır. Nerede bir hata var acaba? Ya da derleyiciden kaynaklanan bir hata mı? @baran123 IAR kullanıyorsunuz anladığım kadarıyla.

main.c
#include "stm8s.h"
#include "main.h"

int flag = 0;
char data = 'g';
void init_handler(void){
 /// Clock init
 CLK_DeInit();
 CLK_HSECmd(DISABLE);
 CLK_HSICmd(ENABLE);
 CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE);
 CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
 CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
 
 GPIO_Init(CONTROL_LED_PORT,(GPIO_Pin_TypeDef)CONTROL_LED_PIN, GPIO_MODE_OUT_PP_HIGH_FAST);
 
 
 UART1_DeInit();
 UART1_Init((uint32_t)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
 UART1_ITConfig(UART1_IT_RXNE_OR,ENABLE);
 UART1_Cmd(ENABLE);
 enableInterrupts();
}

main()
{
 init_handler();
 UART1_SendData8('a');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 for(;;){
 if(flag == 1){
 flag = 0;
 UART1_SendData8('b');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 }
 }
}


#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *  where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

main.h
#include "stm8s.h"

#define CONTROL_LED_PORT (GPIOB)
#define CONTROL_LED_PIN (GPIO_PIN_5)
extern int flag;
extern char data;
void init_handler(void);


stm8s_it.c
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  /* In order to detect unexpected events during development,
    it is recommended to set a breakpoint on the following instruction.
*/
 if (UART1_GetITStatus(UART1_IT_RXNE) != RESET)
  { 
 UART1_ClearITPendingBit(UART1_IT_RXNE);
 data = UART1_ReceiveData8();
 flag = 1;
  }
}


Buradaki kodu kullandığımda her hangi bir resetleme yapmıyor. Yani aslında sizin yazdığınız kodda. Fakat yinede flag=1 durumuna gerçekleşmiyor. Terminalde her hangi bir şekilde geri dönüş göremiyorum.

for(;;){
 if(flag == 1){
 flag = 0;
 UART1_SendData8('b');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 }

ahuramazda

volatile diye tanımlayın flag değişkenini

MuratHp

Yine bir değişiklik elde edemedim.  :( Çıldırmama az kaldı.

RaMu

Alıntı yapılan: MuratHp - 01 Eylül 2019, 21:07:04...
 Çıldırmama az kaldı.
Doktorun sensin.
Pes etme örnekleri incele,
uğraş çözersin muhakkak.

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

baran123

Öncelikle bağlantılardan emin ol.
TX-RX çapraz bağlantı olmalı.
Sonra haberleşme ayarlarının aynı olduğundan emin ol.
Diğer tarafda 9600 8N1 yaptığından emin ol.

Sonra PC den veri yolluyorsan Realterm gibi anlaşılır bir program ile tekrar kontrol et.
Elinde var ise logic analyzer ile pinleri örnekleyerek gözlemle.

Cosmic mi kullanıyorsun ?

MuratHp

#12
Realterm kullanıyorum. STM8S'den mesaj alabiliyorum. Main kodunun başındaki a karakteri ekrana geliyor. Fakat ben mesaj gönderdiğimde bir değişiklik olmuyor. Ayarlar aşağıdaki gibi fakat hala başarısız sonuçlanıyor.

 Cosmic kullanıyorum. IAR'ın kickstart lisansını almaya çalıştım fakat başarılı olamadım. Hata veriyor lisans.

Dönüştürücü olarak da linkteki kartı kullanıyorum.
https://tr.aliexpress.com/item/32650148276.html



main()
{
 init_handler();
 UART1_SendData8('a');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 for(;;){
 if(flag == 1){
 flag = 0;
 UART1_SendData8('b');
 while (UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);
 
 }
 }
}

devrecii

Bir de direkt  for döngüsü içinde uart almayı dene interruptusz, değişkeni belirli sürede gönder değişm var mı görürsün en azından donanımsal bir hata olmadığını görmüş olursun. İntterupt fonksiyonu interupt vectör dizinine bağlanmış mı bu da sorun.

MuratHp

Son güncelleme ve mutlu, huzurlu bir güncelleme  :D IAR ile yazınca sistem düzgün çalıştı. Tahminim stvd kullanırken interrupt vektörü düzgün bağlanmadı. Yardım eden, yorum yapan herkese teşekkür ederim  :)