Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => ARM => Konuyu başlatan: sımışka - 13 Temmuz 2020, 14:58:22

Başlık: Uart ve I2C Birlikte Çalışma Problemi
Gönderen: sımışka - 13 Temmuz 2020, 14:58:22
Merhaba,

Öncelikle kullandığım mikrodenetleyici stm32f103 ve Hal kütüphanesi.

Elimde şu an kod yok daha sonra ekleyeceğim ama sözlü anlatmak gerekirse,
Uart receive interrupt ile bir dizi data alıyorum 1er byte şeklinde toplamda 7 byte veri okuyorum host uygulamadan, aldığım dataları callback funksiyonu içerisinde bir kaç flag setliyorum veya birkaç değişkenin değerini , okuduğum değer ile setliyorum ve ardında 35 byte kadar hosta veri aktarıyorum. Bu 35 byte içerisinde bir kaç input ve output durumu ve dış kesme ile 2 farklı kanalın o anlık değerleri.Günlerce banamısın demeden çalışıyor. Buraya kadar sorun yok.
 
Ardından i2c ile haberleşen adc entegresini aktif ettim, bir kaç hal i2c fonksiyonu kullanıp datayı okuyorum ardından sprintf ile float olarak bir diziye yazıyorum. Bu dizinin 2 bytenıda hosta gönderdiğim 35 byte içerisinde ilgili yerlerine ekliyorum. RX ledim devamlı yanıp sönüyor donanımsal olarak data gelmeye devam ediyor aslında ama bir süre sonra TX ledim artık tamamen sönüyor, data kaçırmaya başlıyorum ve hiç data alamamaya başlıyorum. Stm Studio da gelen buffer ı anlık izliyorum, hiç bir değişim olmamaya başlıyor ve buffer içerisi sıfırlanıyor. Dolayısı ile veri basamıyorum artık. Dinamik bellek alımı vb. işlem yapmıyorum herşey statik.

Kod olmadan fikir yürütecek olursak, neden olabilir acaba ?
 

Başlık: Ynt: Uart ve I2C Birlikte Çalışma Problemi
Gönderen: sımışka - 13 Temmuz 2020, 15:18:39
i2c ile şu şekilde data okuyorum geri dönüşlerini kontrol ediyorum.

HAL_I2C_IsDeviceReady(pI2CHandle,(MCP3424add<<1),1,10)
HAL_I2C_Mem_Read(pI2CHandle,(MCP3424add<<1),configSet,1,ADCdatarec,5,10);
//HAL_I2C_Master_Receive(pI2CHandle,(MCP3424add<<1),ADCdatarec,5,10);

ADCval=(ADCdatarec[2]<<0)|(ADCdatarec[1]<<8)|(ADCdatarec[0]<<16
ADCval = (0x20000&ADCval ? (int)(0x1FFFF&ADCval)-0x20000 : ADCval);
Bu fonksiyonlar polling mode da çalışıyor. Her fonksiyonun timeout değeri 10ms olarak ayarladım, uarttan bana her sorgu 100ms de bir geliyor. 3 fonksiyonda timeout süresinin bitmesine kadar bloklu bir şekilde kalsa bile kurtarıyor olmasını beklerim. Sorunu yanlış yerde mi arıyorum acaba ?
Başlık: Ynt: Uart ve I2C Birlikte Çalışma Problemi
Gönderen: sımışka - 15 Temmuz 2020, 16:45:20
Denediğim kodumu paylaşıyorum. Normalde i2c ile işlemler yaptığım mcp3424 fonksiyonunu kapattığımda hiç bir sorun yaşamıyorum. Uzun süre boyunca veri alıp gönderiyor. Fakat i2c ile işlem yaptığım fonksiyonu açtığımda bir süre sonra örneğin 15 dk sonra uartrxcallback fonksiyonuna girmiyor. Girip girmediğini  counterFlag değişkeni ile stm studio dan anlık izleyerek anlıyorum. Reset butonu ile resetlediğimde tekrar çalışmaya başlıyor. Yardımcı olabilir misiniz ? sprintf fonksiyonundan şüpheleniyorum.


void setConfiguration(CHANNELS channel,RESOLUTION resolution,MEASURE_MODE mode,PGA pga)
{

configSet |= (channel & 0x3) << 5;
configSet |= (mode & 0x1) << 4;
configSet |= (resolution & 0x3) << 2;
configSet |= pga & 0x3;
HAL_I2C_Mem_Read(&hi2c1,(MCP3424add<<1),configSet,1,ADCdatarec,5,10);
}

void MCP3424(){

  if(HAL_I2C_IsDeviceReady(&hi2c1,(MCP3424add<<1),1,10)==HAL_OK){
//   if(HAL_I2C_Mem_Read(&hi2c1,(MCP3424add<<1),configSet,1,ADCdatarec,5,10)==HAL_OK)
//   {
//   HAL_I2C_Master_Receive(&hi2c1,(MCP3424add<<1),ADCdatarec,5,10);
//     HAL_Delay(5);
//   }
  HAL_I2C_Master_Receive(&hi2c1,(MCP3424add<<1),ADCdatarec,5,10);
    HAL_Delay(5);
  }
  ADCval=(ADCdatarec[2])|(ADCdatarec[1]<<8)|(ADCdatarec[0]<<16);
  ADCval = (0x20000&ADCval ? (uint32_t)(0x1FFFF&ADCval)-0x20000 : ADCval);

  //volt=(float)((ADCval/131071.0)*(2.048)*(180/33.0));
  //volt=(float)((((ADCval/131071.0)*((2.048*180.0)/33.0))/249.0)*1000.0);
  volt=(float)((((2048.0)/(131071.0/ADCval))*((4.0)/204.0)));
  sprintf(msgOut,"%.2f\n\r", volt);

  if((msgOut[1])!=46) // çift haneli akım
  {
  a=((msgOut[4]-'0')+((msgOut[3]-'0')*10));
  b=(msgOut[1]-'0')+((msgOut[0]-'0')*10);
  if(b==0 && a<50)
  {
    msg[20]=0;
    msg[21]=0;
  }
  else
  {
  msg[20]=(a & 0x000000ff);
  msg[21]=(b & 0x000000ff);
  }
  }
  else
  {
  a=(msgOut[3]-'0')+((msgOut[2]-'0')*10);
  b=msgOut[0]-'0';

  if(b==0 && a<50)
  {
    msg[20]=0;
    msg[21]=0;
  }
  else
  {
  msg[20]=(a & 0x000000ff);
  msg[21]=(b & 0x000000ff);
  }
  }
}

uint32_t counterFlag=0;
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
counterFlag++;
if(rxIndex==0)
{
for(int i=0;i<UART0_RXBufferSize;i++)
rxBuffer[i]=0;
}
if (rxData!=0x23)
rxBuffer[rxIndex++]=rxData;
else
{
rxIndex=0;
if(rxBuffer[0]==0x7E && rxBuffer[1]==0x01 && rxBuffer[2]==0x01 && rxBuffer[3]==0xAA && rxBuffer[4]==0x02)
{
HAL_UART_Transmit(&huart1, (uint8_t*)msg, sizeof(msg),100);
}
else
{
if(rxBuffer[0]==0x7E && rxBuffer[1]==0x02 && rxBuffer[3]==MESSAGE_OPENCLOSE && (rxBuffer[2]!=0x05 && rxBuffer[2]!=0x06))
{
if(rxBuffer[2]==0x01)
{
if(rxBuffer[5]==0x00)
hsc0_OpenStatus=0;
else
hsc0_OpenStatus=1;
}
if(rxBuffer[2]==0x02)
{
if(rxBuffer[5]==0x00)
hsc1_OpenStatus=0;
else
hsc1_OpenStatus=1;
}
if(rxBuffer[2]==0x03)
{
if(rxBuffer[5]==0x00)
hsc2_OpenStatus=0;
else
hsc2_OpenStatus=1;
}
if(rxBuffer[2]==0x04)
{
if(rxBuffer[5]==0x00)
hsc3_OpenStatus=0;
else
hsc3_OpenStatus=1;
}
}
else if(rxBuffer[0]==0x7E && rxBuffer[1]==0x02 && rxBuffer[3]==MESSAGE_VALUESET && (rxBuffer[2]!=0x05 && rxBuffer[2]!=0x06))
{
if(rxBuffer[2]==0x01)
HSC0_TOTAL = rxBuffer[5]<<24 | rxBuffer[6]<<16 | rxBuffer[7]<<8 | rxBuffer[8];
if(rxBuffer[2]==0x02)
HSC1_TOTAL = rxBuffer[5]<<24 | rxBuffer[6]<<16 | rxBuffer[7]<<8 | rxBuffer[8];
if(rxBuffer[2]==0x03)
HSC2_TOTAL = rxBuffer[5]<<24 | rxBuffer[6]<<16 | rxBuffer[7]<<8 | rxBuffer[8];
if(rxBuffer[2]==0x04)
HSC3_TOTAL = rxBuffer[5]<<24 | rxBuffer[6]<<16 | rxBuffer[7]<<8 | rxBuffer[8];
}
else if(rxBuffer[0]==0x7E && rxBuffer[1]==0x02 && rxBuffer[2]==0x05) // digital cıkıs
{
digitalOutputFlag=1;
if(rxBuffer[3]==0xFF)
{
if(rxBuffer[5]==0x01)
{
msg[18]=0xff;
}
else if (rxBuffer[5]==0x00)
{
msg[18]=0x00;
}
   }
else
{
  msg[18]=rxBuffer[3];
}

}
else if(rxBuffer[0]==0x7E && rxBuffer[1]==0x02 && rxBuffer[2]==0x06)
{
relayFlag=1;
if(rxBuffer[3]==0x03)
{
if(rxBuffer[5]==0x01)
{
retValR1=1;
retValR2=1;
msg[19]=0x03;
}
else
{
retValR1=0;
retValR2=0;
msg[19]=0x00;
}
}
else
{
msg[19]=rxBuffer[3];
if(rxBuffer[3]==0x01)
{
retValR1=1;
retValR2=0;
}
else if(rxBuffer[3] == 0x02)
{
retValR2=1;
retValR1=0;
}
  }
}
else{
for(int i=0;i<UART0_RXBufferSize;i++)
rxBuffer[i]=0;
}
  }
}

HAL_UART_Receive_IT(&huart1, &rxData, 1);//one car
}


main içerisinde ;

 
  HAL_UART_Receive_IT(&huart1, &rxData,1);
  setConfiguration(3,RESOLUTION_18_BITS,CONTINUOUS_MODE,PGA_X1);

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  readInputStatus();
  dataFilling();
  if(relayFlag)
  {
  relayFlag=0;
  if(retValR1)
  HAL_GPIO_WritePin(GPIOA, RELAY1_Pin, GPIO_PIN_RESET);
  else
  HAL_GPIO_WritePin(GPIOA, RELAY1_Pin, GPIO_PIN_SET);
  if(retValR2)
  HAL_GPIO_WritePin(GPIOA, RELAY2_Pin, GPIO_PIN_RESET);
  else
  HAL_GPIO_WritePin(GPIOA, RELAY2_Pin, GPIO_PIN_SET);
  }

  //HAL_I2C_Master_Transmit(&hi2c1,mcp4725_address,buffer,3,100);
  if(digitalOutputFlag)
  {
  digitalOutputFlag=0;
  HAL_I2C_Master_Transmit(&hi2c1,digitalOutputsAddr,&digitalOutputs,1,1000);
  }
  if(c>5000)
  {
  c=0;
  MCP3424();
  }
  c++;
  }


Başlık: Ynt: Uart ve I2C Birlikte Çalışma Problemi
Gönderen: sımışka - 15 Temmuz 2020, 20:05:32
Çözüm:

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{

__HAL_UART_CLEAR_PEFLAG(&huart1);
__HAL_UART_CLEAR_OREFLAG(&huart1);
__HAL_UART_CLEAR_NEFLAG(&huart1);
__HAL_UART_CLEAR_FEFLAG(&huart1);
__HAL_UART_DISABLE_IT(&huart1, UART_IT_ERR);

HAL_UART_Receive_IT(&huart1, &rxData, 1);

}