STM32 odczyt danych z AC i transwer przec RS232


Odczytując dane z przetwornika AC należy zapisać je najlepiej do tablicy o ilości elementów równej ilości przetworników AC, następnie zamienić je na dane typu string poprzez rzutowanie.

Dane te możemy wtedy wpisać do portu USART który to wyśle je nam na komputer poprzez złącze RS232 lub bluuthu podłączonego do tego portu.

Oto przykład takiego rozwiązania nie piszę całego kodu tylko ważniejsze szczegóły, podczas pisania używam standardowych bibliotek STM32F10x_StdPeriph_Lib_V3.3.0

Tworzenie tablicy

unsigned char buforTx[50]={0}; // tablica do wysyłania poprzez usart

unsigned short int buforADC[8]={0}; // tablica do zapisu danych z przetwornika AC

unsigned char buforRx[17]={0}; // tablia odbioru opcjonalnie

unsigned char bufRxIndex=0;

unsigned char bufTxIndex=0;

bool odebranoDane=FALSE;

unsigned int a = 0;

podprogram odczytu danych z przetworników AC

void ADC_Config(void)

{

//konfigurowanie przetwornika AC

ADC_InitTypeDef ADC_InitStructure;

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //Jeden przetwornik, praca niezalezna

ADC_InitStructure.ADC_ScanConvMode = ENABLE; //Pomiar dwoch kanalow, konieczne skanowanie kanalow

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //Pomiar w trybie ciaglym

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //Brak wyzwalania zewnetrznego

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //Wyrownanie danych do prawej - 12 mlodszych bitow znaczacych

ADC_InitStructure.ADC_NbrOfChannel = 8; //Liczba uzywanych kanalow =2

ADC_Init(ADC1, &ADC_InitStructure); //Incjalizacja przetwornika

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_13Cycles5); //Kanal 14 - GPIOC4 - potencjometr na plytce ZL27ARM

ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_13Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_13Cycles5); //Kanal 16 - wewnetrzny czujnik temp. procesora

ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 5, ADC_SampleTime_13Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_13Cycles5); //Kanal 14 - GPIOC4 - potencjometr na plytce ZL27ARM

ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_13Cycles5);

ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_13Cycles5); //239,5 => 17.1us = czas zalecany w dokumentacji MUC dla miernika temperatury

ADC_TempSensorVrefintCmd(ENABLE); //Wlaczenie czujnika temperatury procesora

ADC_DMACmd(ADC1,ENABLE); //Wlaczenie DMA dla ADC

ADC_Cmd(ADC1, ENABLE); //Wlacz ADC1

ADC_ResetCalibration(ADC1); //Reset rejestrow kalibracyjnych ADC1

while(ADC_GetResetCalibrationStatus(ADC1)); //Odczekanie na wykonanie resetu

ADC_StartCalibration(ADC1); //Kalibracja ADC1

while(ADC_GetCalibrationStatus(ADC1)); //Odczekanie na zakonczenie kalibracji ADC1

}

By zapisać dane do tablicy należy jeszcze skonfigurować kanał DMA

void DMA_Config(void)

{

//konfigurowanie DMA

#define ADC1_DR_Address 0x4001244C; //adres rejestru ADC1->DR

DMA_InitTypeDef DMA_InitStructure;

DMA_DeInit(DMA1_Channel1); //Usun ewentualna poprzednia konfiguracje DMA

DMA_InitStructure.DMA_PeripheralBaseAddr = (unsigned long int)ADC1_DR_Address; //Adres docelowy transferu

DMA_InitStructure.DMA_MemoryBaseAddr = (unsigned long int)&buforADC; //Adres poczatku bloku do przeslania

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //Kierunek transferu

DMA_InitStructure.DMA_BufferSize = 8; //Liczba elementow do przeslania (dlugosc bufora)

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Wylaczenie automatycznego zwiekszania adresu po stronie ADC

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Wlaczenie automatycznego zwiekszania adresu po stronie pamieci (bufora)

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //Rozmiar pojedynczych przesylanych danych po stronie ADC (HalfWord = 16bit)

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //Rozmiar pojedynczych przesylanych danych po stronie pamieci (bufora)

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //Tryb dzialania kontrolera DMA - powtarzanie cykliczne

DMA_InitStructure.DMA_Priority = DMA_Priority_High; //Priorytet DMA - wysoki

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //Wylaczenie obslugi transferu z pamieci do pamieci

DMA_Init(DMA1_Channel1, &DMA_InitStructure); //Zapis konfiguracji

//Wlacz DMA, kanal 1

DMA_Cmd(DMA1_Channel1, ENABLE);

}

Należy skonfigurować układ przerwań dla transferu danych pomiędzy przetwornikami i pamięcią oraz portem wyjściowym USART

void NVIC_Config(void)

{

//Konfigurowanie kontrolera przerwan NVIC

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef VECT_TAB_RAM

// Jezeli tablica wektorow w RAM, to ustaw jej adres na 0x20000000

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else // VECT_TAB_FLASH

// W przeciwnym wypadku ustaw na 0x08000000

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

//Wlacz przerwanie od ADC

NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

//Przerwanie od USART1

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

Ostatnie ustawienia to port komunikacji USART

void USART_Config(void)

{

//konfigurowanie ukladu USART

USART_InitTypeDef USART_InitStructure;

USART_InitStructure.USART_BaudRate = 19200; //Predkosc transmisji =19200bps

USART_InitStructure.USART_WordLength = USART_WordLength_8b; //Dlugosc slowa = 8 bitow

USART_InitStructure.USART_StopBits = USART_StopBits_1; //1 bit stopu

USART_InitStructure.USART_Parity = USART_Parity_No; //Brak kontroli parzystosci

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //Kontrola przeplywu danych (brak)

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Tryb pracy

USART_Init(USART1, &USART_InitStructure);

USART_Cmd(USART1, ENABLE);

}

Pozostaje nam jeszcze ustawić przerwanie w pliku biblioteki stm32f10x_it.c w linijce około 580 void USART1_IRQHandler(void)

Treść danych

extern unsigned char buforRx[];

extern unsigned char bufRxIndex;

extern unsigned char buforTx[];

extern unsigned char bufTxIndex;

extern bool odebranoDane;

extern unsigned int a;

void USART1_IRQHandler(void)

{

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

{

buforRx[bufRxIndex] = USART_ReceiveData(USART1); //Odczyt danej automatycznie kasuje flage przerwania

if(buforRx[bufRxIndex] == 0x0D) //Wykrycie znaku \CR

{

odebranoDane = TRUE;

while (bufRxIndex<17) { //wyzerowanie znakow do konca bufora (zabezpiecza przed wyswietlaniem "smieci")

buforRx[bufRxIndex]=0;

bufRxIndex++;

}

bufRxIndex = 0;

} else { //Obsluga pozostalych, "zwyklych" znakow

bufRxIndex++;

if (bufRxIndex>16){ //Zabezpieczenie przed przepelnieniem bufora jesli odbierany tekst jest dluzszy niz 16 znakow

bufRxIndex=0;

} } }

if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) {

USART_SendData(USART1, buforTx[bufTxIndex++]); //Wyslij kolejny znak i zwieksz indeks bufora wyjsciowego

if(buforTx[bufTxIndex-1] == 0x0D) //Jesli wysylany zostal ostatni znak (CR)

{

USART_ITConfig(USART1, USART_IT_TXE, DISABLE); //Wylacz przerwanie = koniec transmisji

bufTxIndex = 0;

a++;

} } }

Pozwala to na transmisję danych w przerwaniu co odciąża procesor od pracy

Oto główna część kodu programu zapewniająca prawidłową transmisję danych

int main(void)

{

RCC_Config();

GPIO_Config();

NVIC_Config();

DMA_Config();

ADC_Config();

USART_Config();

ADC_SoftwareStartConvCmd(ADC1, ENABLE); //rozpocznij przetwarzanie AC

while (1) {

for (i=0;i<1000000;i++)

if(a>500){a=0;}

sprintf((char*)buforTx," %04i %04i %04i %04i %04i %04i %04i %04i %04i %1c",a,buforADC[0],buforADC[1],buforADC[2],buforADC[3],buforADC[4],buforADC[5],buforADC[6],buforADC[7],0x01);

// zamiana danych z int na char poprzez rzutowanie co pozwala wyświetlać dane na komputerze bezpośrednio po odebraniu.

buforTx[49]=0X0D; //Dodanie znacznika nowej linii (i konca transmisji)

USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //Wlacz przerwanie = rozpocznij transmisjie

}; }

W razie problemów lub gdy czegoś nie można zrozumieć pomogę w miarę możliwości

Mój adres zbigniew.kolb@gmail.com



Wyszukiwarka

Podobne podstrony:
STM32 przesyłanie danych przez usatr RS232
5 Mathcad Zapis i odczyt danych
05 Normalizacja struktury bazy danych (AC)
odczytywanie danych z diagramu - poziom podstawowy, Odczytywanie danych, diagramy
diagramy procentowe gi, Odczytywanie danych, diagramy
DIAGRAMY Z PAPIEŻEM - SCENARIUSZ, Odczytywanie danych, diagramy
5 Mathcad Zapis i odczyt danych
Odczytywanie danych przedstawionych na wykresach kl VI
Odczytywanie danych przedstawionych na wykresach kl 6
1 Statystyka ODCZYTYWANIE DANYCH STATYSTYCZNYCH odpowiedzi
Jak zapisać i potem odczytać grafikę lub dowolny plik w bazie danych, PHP Skrypty
jak zapisac i potem odczytac grafikę lub dowolny plik w bazie danych, PHP Skrypty
Zestawienie funkcji modułu mysqli odczytujących dane, bazy danych
Wyznaczanie ładunku właściwego, Wyznaczanie ładunku właściwego e do m metodą magnetronową 8, Zestawi
Systemy Baz Danych (cz 1 2)

więcej podobnych podstron