SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Downloaden Sie, um offline zu lesen
Mikrokontroller Laboratórium Jegyzőkönyv
1.Feladat leírása:
A12 feladat:
 LED mátrix Készítsen kiegészítő hardver egységet az STM32 NUCLEO-F446RE kithez, amely egy 8x8-as
LED mátrix kijelzőt valósít meg!
 Az LED mátrix sorkiválasztása történjen időmultiplexelt vezérléssel, az oszlopvezérlés pedig SPI buszon
(sorosan), 8 bites léptetőregiszter segítségével.
 Az áramkör megtervezése, megépítése és üzembe helyezése után készítsen el egy az eszköz
bemutatására szolgáló demonstrációs célú tesztprogram rendszert, amely az egyetemünkhöz,
karunkhoz, szakirányunkhoz vagy ágazatunkhoz kapcsolódó animációkat jelenít meg a kijelzőn.
 Az animációkat PC-n hozza létre, és az egyes animációk letöltése, kezelése, cseréje soros porton
keresztül, egy kliensprogram segítségével történjen.
 A kommunikációhoz virtuális soros portot használjon, melyet a kiten megtalálható USB port
segítségével valósítson meg!
2.Nyáktervezés:
Nyákterv
Led-mátrix és vezérlésének kapcsolási rajza
Vezetékek bekötési rendje a Nucleo Kit-be
Alkatrészlista
A kész eszköz
3. Inicializálás CubeMx segítségével:
1. PIN-ek megfelelő inicializálása
2. Órajel megfelelő beállítása
3. Interruptok engedélyezése
4.A PROGRAM:
1. az általam írt vagy megváltoztatott .c és .h fájlok
main.c
//időmultiplexelt kirajzoláshoz, forciklussal megyünk végig
ezen a tömbön és mindig 1 sort rajzolunk ki
uint16_t LED_array[]=
{
GPIO_PIN_0,
GPIO_PIN_1,
GPIO_PIN_2,
GPIO_PIN_3,
GPIO_PIN_4,
GPIO_PIN_5,
GPIO_PIN_6,
GPIO_PIN_7
};
//iteratív változóim, itt vannak definiálva mert több 3
szintű egymásba ágyazott forcikulusban is ezeket használom
uint16_t i;
uint16_t j;
uint16_t r;
uint16_t w;
uint8_t temp;//az aktuális sor aktuálisan kirajzolt értéke
benne található(rotálás eredménye ide kerül)
uint8_t SPI_In=0b00000000;
uint8_t SPI_Out;
// tesztváltozó
uint16_t LED_ALL=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|
GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
//Latch enable és Output enable
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
// a nucleo zöld ledjét beállítja
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);
//az összes sort GPIO oldalról kikapcsoljuk/negált logika
HAL_GPIO_WritePin(GPIOC,LED_ALL,GPIO_PIN_SET);
//a leddriver shiftreget is inaktiváljuk
SPI_SendReceive(&SPI_In,&SPI_Out,1);
while (1)
{
if(STRING_DISPLAY_ON)
{
for(w=0;w<STRING_LENGTH;w++)
{
init_display(display_aft,mystring[w]);
for(r=0;r<8;r++)
{
shift_aft_to_curr();
for(j=0;j<3;j++)
{
for(i=0;i<8;i++)
{
HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_RESET);
SPI_SendReceive(&display_curr[i],&SPI_Out,1);
HAL_Delay(2);
HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_SET);
}
if(!STRING_DISPLAY_ON)
{goto end;}
}
}
}
}
else
{
for(r=0;r<128;r++)//itt írom ki az uart adatokat
erre külön függvény majd menjen
{
for(j=0;j<HOLD_TIME;j++)//ez a rotálás miatt kell mert minden
r értéket az első forból 3 cilusig kell
kitartani . hal_delay nem jó mert folyamatosan kell pörögni a függvénynek
{
for(i=0;i<8;i++)
{
if(!TIME_IS_ON)
{
switch(CURR_ROW_SIZE)//megnézzük a képernyő üzemmódot és a megfelelő
/ függvényeket meghívva előkésítjük a következő képernyő képet
{
case 8:temp=leddot[i];
break;
case 16:temp=_rotr16(leddot16[i],r);
break;
case 32:temp=_rotr32(leddot32[i],r);
break;
case 64:temp=_rotr64(leddot64[i],r);
break;
}
HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_RESET);//for ciklusba vagyunk minden
i++ ra a következő sor megfelelő ledjei világítanak de a megfelelő időzítéssel
elértem hogy az emberi szemnek folyamatosnak tűnjön a világítás
SPI_SendReceive(&temp,&SPI_Out,1);//a megfelelő sor adatai kimennek
HAL_Delay(2);//kicsit hagyjuk világítani
HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_SET);//majd elsötétítjük
}
A végtelen ciklusomban 3 féle eset alakulhat:
1. szöveg kíírás
2. óra kirajzolás
(1-2 ről bővebben lejjebb)
3. egyéb animáció kirajzolása
 ennek 4 módja
o 8 bit: szeszéles képernyőkép,
ekkor nem rotálom a
képernyőt a többi esetben
viszont igen
o 16bit
o 32bit:Az aut animáció ezen
megy
o 64bit
else
{
temp=led_hour_array[hour][i]|led_minsec_array[second][i]|led_minsec_array[minute][i];
HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_RESET);//forciklusba vagyunk minden i++
ra a következő sor megfelelő ledjei világítanak de a megfelelő időzítéssel elértem hogy
az emberi szemnek folyamatosnak tűnjön a világítás
SPI_SendReceive(&temp,&SPI_Out,1);//a megfelelő sor adatai kimennek
HAL_Delay(2);//kicsit hagyjuk világítani
HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_SET);//majd elsötétítjük
}
if(STRING_DISPLAY_ON)
{goto end;}
}
}
if(second==0)
{
if(minute==0)
{
if(hour==0)
{
hour=12;
}
hour--;
minute=60;
}
minute--;
second=60;
}
second--;
}
}
end:;
/*}*/
}
/* USER CODE END 3 */
}
TIME Animáció a main.c-ben
Itt minden órához, perchez és másodperchez tartozó 8x8 as kép el van tárolva megfelelő 2D-s tömbökben.
Az órához tartozók a led_hour_array[][] ahogy a perc/másodpercnek is vamn külön tömbje és ezek a megfelelő pillanatokban egymásra
vagyolva vannak. A számolás a ciklus végén történik ez akkor is fut ha nem óra üzemmódban vagyunk.
Szövegkiírás a main.c-ben
Alapvetően 2 tömb van jelen(display_curr[] és display_aft[]) és ezeket a kapott string alapján töltögetjük.
 a program indulásakor mind a 2 tömb csupa nulla
 amikor először belépünk a szövegkiíró üzemmódba a legfelső forciklus elején az a display_aft[] tömböt az első karakternek
megfelelően inicializáljuk
 majd fokozatosan átshiftelem a display_aft[] tartalmát a display_bef[]-be , amikor ez kész újratöltöm a display_aft[]-ot a
következő karakter szerint
 amint a szó végére érek aminek a hosszát a STRING_LENGTH változóban tárolom újrakezdem a műveletet
 ha új uart parancs érkezik akkor a műveletet goto utasítás segítségével megszakítom
gpio.c
void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
/*SHF_LE*//*SHF_OE*/
GPIO_InitStruct.Pin =GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|
GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
/* USER CODE BEGIN 2 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if((!TIME_IS_ON)&&STRING_DISPLAY_ON)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);//tesztelés
CURR_ROW_SIZE=8;
TIME_IS_ON=1;
HOLD_TIME=40;
STRING_DISPLAY_ON=0;
return;
}
if(TIME_IS_ON&&(!STRING_DISPLAY_ON))
{
STRING_DISPLAY_ON=0;
TIME_IS_ON=0;
CURR_ROW_SIZE=32;
HOLD_TIME=3;
return;
}
if((!TIME_IS_ON)&&(!STRING_DISPLAY_ON))
{
STRING_DISPLAY_ON=1;
TIME_IS_ON=0;
return;
}
}
spi.c
const uint32_t spi_timeout = 5000;
/* USER CODE END 0 */
SPI_HandleTypeDef hspi3;
/* SPI3 init function */
void MX_SPI3_Init(void)
{
hspi3.Instance = SPI3;
hspi3.Init.Mode = SPI_MODE_MASTER;
hspi3.Init.Direction = SPI_DIRECTION_2LINES;
hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi3.Init.NSS = SPI_NSS_SOFT;
hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
Itt érdemes megemlíteni hogy a PC13-on
lévő pushbutton külső megszakítás hajt
végre, a PC-ről lehúzott eszközön ennek
segítségévekl tudok az animációk között
váltani.
A gomb megnyomására a soron következő
üzemmód fontos változói beálításra
kerülnek, ezek funkcióját deklarációjuknál
kifejtem.
spi.c ben az spi-hez tartozó az alapvető
funkciók lettek megvalósítva.
küldés,fogadás,inicializálás,stb.
hspi3.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi3) != HAL_OK)
{
Error_Handler();
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(spiHandle->Instance==SPI3)
{
/* USER CODE BEGIN SPI3_MspInit 0 */
/* USER CODE END SPI3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI3_CLK_ENABLE();
/**SPI3 GPIO Configuration
PC10 ------> SPI3_SCK
PC11 ------> SPI3_MISO
PC12 ------> SPI3_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN SPI3_MspInit 1 */
/* USER CODE END SPI3_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI3)
{
/* USER CODE BEGIN SPI3_MspDeInit 0 */
/* USER CODE END SPI3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI3_CLK_DISABLE();
/**SPI3 GPIO Configuration
PC10 ------> SPI3_SCK
PC11 ------> SPI3_MISO
PC12 ------> SPI3_MOSI
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12);
}
/* USER CODE BEGIN SPI3_MspDeInit 1 */
/* USER CODE END SPI3_MspDeInit 1 */
}
/* USER CODE BEGIN 1 */
HAL_StatusTypeDef SPI_Send(uint8_t* pData, uint16_t dataSize)
{
HAL_SPI_Transmit(&hspi3,pData,dataSize,spi_timeout);
return HAL_OK;
}
HAL_StatusTypeDef SPI_Receive(uint8_t* pData, uint16_t dataSize)
{
HAL_SPI_Receive(&hspi3,pData,dataSize,spi_timeout);
return HAL_OK;
}
/** SPI küldés és fogadás egyszerre. */
HAL_StatusTypeDef SPI_SendReceive(uint8_t* pDataIn, uint8_t *pDataOut, uint16_t dataSize)
{
HAL_SPI_TransmitReceive(&hspi3,pDataIn,pDataOut,dataSize,spi_timeout);
return HAL_OK;
}
usart.c
#include "usart.h"
#include "gpio.h"
#include "string.h"
#include "time.h"
#include "font.h"
/* USER CODE BEGIN 0 */
uint8_t lastReceivedUartCommand = 0;
char rxBuffer;
uint16_t CURR_ROW_SIZE=32;//alapértelmezetten 32-nek lett most véletlen beállítva
de üres regisztert rotál tehát lényegtelen, az első beérkezett uart
csomagnál eldől hogy milyen üzemmódban működünk
#define TXBUFFERSIZE 255
char txBuffer[TXBUFFERSIZE];
HAL_StatusTypeDef stat;
uint8_t mystring[50]={'n'-' ','i'-' ','n'-' ','c'-' ','s'-' ',' '-' ','s'-' ','z'-' ','o'-' ','v'-' ','e'-' ','g'-' ',' '-' '};
//ebbe tárolom a kiírandó szót
uint8_t STRING_LENGTH_INIT;//bekérem a sring hosszát
uint8_t STRING_LENGTH=13;//string hossza
uint8_t STRING_LENGTH_TEMP=0;//ennek segítségével nézem hogy elértem már e a kért szó végét
uint8_t STRING_DISPLAY_ON=0;//magának a string kiírásnak az állapotjelzője
uint8_t STRING_IS_ON=0;//stringkiírással kapcsolatos adatok uarton való fogadásának állapota
uint8_t TIME_IS_ON=1; //az óra üzemmódot jelző változó
uint8_t TIME_INIT=0; //ez a változó azt jelzi amikor az óra inicializálás adatai jönnek, amíg ez igaz minden adatot erre hasznosítunk
uint8_t HOLD_TIME=50;//meddig tatson egy képernőképet a kimeneten ,,, time nál ugy 1 mp ig kell
uint8_t time_type=0;
uint8_t digit=1;
uint8_t leddot[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
uint16_t leddot16[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből
{
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
uint32_t leddot32[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből
{
0x00ff00ff,
0x38c738c7,
0x7c8344bb,
0x7c8344bb,
0x7c8344bb,
0x38c738c7,
0x00ff00ff,
0x00ff00ff
};
uint64_t leddot64[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből
{
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000,
0b0000000000000000000000000000000000000000000000000000000000000000
};
uint8_t display_curr[]=
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
uint8_t display_aft[]=
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
uint16_t Row_counter=0;//maximumértéke a vízszintes szélességet befojásolja
alapértelmezetten 8 de ha rotáljuk shiftreget akkor lehet jóval több is
uint16_t Col_counter=0;//függöleges szélesség, maximum ugye 8 lehet ,
persze lehet bonyolítani itt is a dolgot
//az ascii karaktert a megfelelő üzemmódokban a
megfelelő típussá kell konvertálni ezekre ott van szülségem
uint8_t intBuffer8;
uint16_t intBuffer16;
uint32_t intBuffer32;
display_curr[] és display_aft[] inicializálás
működésük előbbikben részletezve volt
uint64_t intBuffer64;
uint8_t second=59;
uint8_t minute=59;
uint8_t hour=11;
//void init_display();
//A uart callback függványből ezek a függvények hívódnak meg a megfelelő időpontban
void UART_PROCESS_8BITDISPLAY();
void UART_PROCESS_16BITDISPLAY();
void UART_PROCESS_32BITDISPLAY();
void UART_PROCESS_64BITDISPLAY();
void UART_ASCII_SHIFT_CONVERT();
void ROW_COL_STEP();
/* USER CODE END 0 */
UART_HandleTypeDef huart2;
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
stat=HAL_UART_Receive_IT(&huart2, (uint8_t*)&rxBuffer, 1);
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* Peripheral interrupt Deinit*/
HAL_NVIC_DisableIRQ(USART2_IRQn);
}
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
/* USER CODE BEGIN 1 */
/** String küldése, nem blokkolva. */
HAL_StatusTypeDef UART_SendString(char *str)
{
//IDE INKÁBB VÁRAKOZÓSI SOR KELL
while ((huart2.gState != HAL_UART_STATE_BUSY_RX) && (huart2.gState != HAL_UART_STATE_READY))
{
}
strncpy(txBuffer, str, TXBUFFERSIZE);
uint32_t length = strlen(txBuffer);
return HAL_UART_Transmit_IT(&huart2, (uint8_t*)txBuffer, length);
return HAL_OK;
óra,perc,másodperc 0-tól 59-ig megy sikerült
fordított sorrendbe bepötyögnöm az összeset
úgyhogy azért számlálok visszafele.
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
{
uint8_t len_temp;
if(STRING_IS_ON)
{
if(STRING_LENGTH_INIT)
{
len_temp=rxBuffer-'0';
STRING_LENGTH=len_temp+10*STRING_LENGTH;
STRING_LENGTH_INIT--;
STRING_LENGTH_TEMP=0;
}
else
{
mystring[STRING_LENGTH_TEMP]=rxBuffer-'!'+1;
STRING_LENGTH_TEMP++;
if(STRING_LENGTH_TEMP==STRING_LENGTH)
{
STRING_IS_ON=0;
STRING_DISPLAY_ON=1;
}
}
}
else
{
if(TIME_INIT)
{
switch(rxBuffer)// üzemmódnak megfelelő uartkezelés hívódik
{
case 'h':
time_type=0;
digit=1;
break;
case 'm':
time_type=1;
digit=1;
break;
case 's':
time_type=2;
digit=1;
break;
default:
switch(time_type)
{
case 0:hour=rxBuffer;
break;
case 1:minute=rxBuffer;
break;
case 2:second=rxBuffer;
TIME_INIT=0;
break;
}
}
}
else
{
switch(rxBuffer)//az egyik legfontosabb rész , itt döntjük
el hogy a bejövőcsomag az üzemmódot akarja állítani vagy pedig a kijelzőt
{ //kijelzőt csak 0 és 1 gyel állítunk ,
kliensprogramra erre figyelek ezért van itt a default , ha üzemmód
csomag érkezik azt nem tároljuk el a leddot[]tömben hanem csak értelmezzük
case'a':CURR_ROW_SIZE=8;//8 bites animáció nincs shift
TIME_IS_ON=0;
HOLD_TIME=3;
STRING_DISPLAY_ON=0;
break;
case'b':CURR_ROW_SIZE=16;//16 bites animáció
TIME_IS_ON=0;
HOLD_TIME=3;
STRING_DISPLAY_ON=0;
break;
case'c':CURR_ROW_SIZE=32//32 bites animáció
TIME_IS_ON=0;
HOLD_TIME=3;
STRING_DISPLAY_ON=0;
break;
case'd':CURR_ROW_SIZE=64;// 64 bites animáció
TIME_IS_ON=0;
HOLD_TIME=3;
STRING_DISPLAY_ON=0;
break;
case't':CURR_ROW_SIZE=8;//idő animáció
TIME_IS_ON=1;
TIME_INIT=1;
ACTUAL_TIME_INIT=1;
HOLD_TIME=40;
STRING_DISPLAY_ON=0;
break;
case's':STRING_IS_ON=1; //szöveg kiírás
STRING_LENGTH_INIT=2;
STRING_LENGTH=0;
TIME_IS_ON=0;
break;
default:
switch(CURR_ROW_SIZE)// üzemmódnak megfelelő uartkezelés hívódik
{
case 8:UART_PROCESS_8BITDISPLAY();
break;
case 16:UART_PROCESS_16BITDISPLAY();
break;
case 32:UART_PROCESS_32BITDISPLAY();
break;
Itt történik a string valamint annak hosszának a
beolvasása. A hossz 2 karakter ennek
lekezelése látható az if igaz ágában.
Amint beolvastunk mindent a string
inicializálás állapotának jelzőbitjét kinullázzuk
majd a string kiírás jelzőbitjét igazzá teszem.
Óra üzemmódban az aktuális idő
beolvasása.Minden időegység 1 karakter
hosszú, kliens oldalon itt charrá konvertálok és
utána használom csak a .Tostring() függvényt
hogy elférjek 1 byte-on.
amikor semmilyen inicializálás
nem zajlik itt dől el hogy melyik
üzemmódba lépünk.
érdemes megemlíteni hogy a
Holdtime alapvetően 3 hogy
megfelelően sebességgel
heledjon a tartalom a kijelzőn,
óra üzemmódban viszont kb.
egy másodpercenként váltson
ezért 40.
case 64:UART_PROCESS_64BITDISPLAY();
break;
}
break;
}
}
}
HAL_UART_Receive_IT(handle, (uint8_t*)&rxBuffer, 1);
}
void UART_PROCESS_8BITDISPLAY()
{
uint8_t i;
if((Row_counter==0)&&(Col_counter==0))//mindig akkor nullázzuk a képernyőt amikor a
következő képernyőkép első bitje megérkezett(értelemszerűen) és azt egyből ki is rajzoljuk
{
for(i=0;i<8;i++)
{
leddot[i]=0;
}
//draw_OK=0;
}
UART_ASCII_SHIFT_CONVERT();//beérkezett asciiból kivonjuk a '0'
karaktert majd a megfelelő típusra konvertáljuk ezelután annyival shifteljük ahanyadik adat a sorban
leddot[Col_counter]=leddot[Col_counter]| intBuffer8;//az eddigi adatokhoz hozzávagyolom
Row_counter++;
ROW_COL_STEP();//a sorok és oszlopok novelésének nullázásának lekezelése
}
void UART_PROCESS_16BITDISPLAY()
{
uint8_t i;
if((Row_counter==0)&&(Col_counter==0))
{
for(i=0;i<8;i++)
{
leddot16[i]=0;
}
//draw_OK=0;
}
UART_ASCII_SHIFT_CONVERT();
leddot16[Col_counter]=leddot16[Col_counter]| intBuffer16;//az eddigi adatokhoz hozzávagyolom
Row_counter++;
ROW_COL_STEP();
}
void UART_PROCESS_32BITDISPLAY()
{
uint8_t i;
if((Row_counter==0)&&(Col_counter==0))
{
for(i=0;i<8;i++)
{
leddot32[i]=0;
}
//draw_OK=0;
}
UART_ASCII_SHIFT_CONVERT();
leddot32[Col_counter]=leddot32[Col_counter]| intBuffer32;//az eddigi adatokhoz hozzávagyolom
Row_counter++;
ROW_COL_STEP();
}
void UART_PROCESS_64BITDISPLAY()
{
uint8_t i;
if((Row_counter==0)&&(Col_counter==0))
{
for(i=0;i<8;i++)
{
leddot64[i]=0;
}
//draw_OK=0;
}
UART_ASCII_SHIFT_CONVERT();
leddot64[Col_counter]=leddot64[Col_counter]| intBuffer64;//az eddigi adatokhoz hozzávagyolom
Row_counter++;
ROW_COL_STEP();
}
void UART_ASCII_SHIFT_CONVERT()
{
rxBuffer = rxBuffer - '0';//1 vagy 0 érkezik és char ból int be konvertálom
switch(CURR_ROW_SIZE)
{
case 8:intBuffer8=rxBuffer;
intBuffer8=intBuffer8<<Row_counter;
break; //annyit shiftelem amelyik sorba tartozik az adat
case 16:intBuffer16=rxBuffer;
intBuffer16=intBuffer16<<Row_counter;
break;
case 32:intBuffer32=rxBuffer;
intBuffer32=intBuffer32<<Row_counter;
egyenként érkeznek be az
animáció bitjei ezeket
mikor beérkeznek a
képernyő egy sorának
méretére konvertálom
majd annyival shiftelem
ahanyadik elemnél tartunk
az adott „col” ban és ezt
végül hozzávagyolom az
eddigi értékhez
break;
case 64:intBuffer64=rxBuffer;
intBuffer64=intBuffer64<<Row_counter;
break;
}
}
void ROW_COL_STEP()
{
//azér van itt nyolc mert mindig kiírás után novelem a sort
azaz ha a 7. row-t kiírtam akkor növelek 8 ra és ilyenkor 0-zódik minden
//a következő kiírés pedig már az új kijelzőkép első pontja lesz
if(Row_counter%CURR_ROW_SIZE==0)//ha elértem a sor végét az
{ //oszlopot növelem a sort nullázom
if(Col_counter==7)//ha bejött minden adat akkor 0-zok mindent
{//utsó bit nem megy ki ezt még javítani kell
Row_counter=0;
Col_counter=0;
//draw_OK=1;
//init_display();
}
else
{
Col_counter++;
Row_counter=0;
}
}
}
void USART3_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart2);
}
void init_display(uint8_t* display,uint8_t letternum)
{
uint8_t i;
uint8_t temp;
for(i=0;i<8;i++)
{
temp=IMAGES[letternum][i];
temp = (temp & 0xF0) >> 4 | (temp & 0x0F) << 4;
temp = (temp & 0xCC) >> 2 | (temp & 0x33) << 2;
temp = (temp & 0xAA) >> 1 | (temp & 0x55) << 1;
display[i]=temp;
}
}
font.h
http://xantorohara.github.io/led-matrix-editor/#
led_time.h
tartalmaza az egyes időpontokhoz tartozó képet
Kliensoldal:
itt döntöm el hogy új sorba
kell e lépni esetleg végeztem
a beolvasással
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace MIKROLAB
{
public partial class Form1 : Form
{
private SerialPort MyPort;
private char actualstatus;
private int CURR_DISPLAY_SIZE;
string LETTER_A ="0001100000111100001111000110011001100110111111111111111111000011";
string LETTER_B= "1111110011000110110000111111111011111110110000111100011011111100";
string LETTER_C ="0011111101111111111000001110000011100000111000000111111100111111";
string LETTER_CC =
"001111110011111101111111011111111110000011100000111000001110000011100000111000001110000011100
00001111111011111110011111100111111";
string LETTER_AAAA =
"000110000001100000011000000110000001100000011000000110000001100000111100001111000011110000111
1000011110000111100001111000011110000111100001111000011110000111100001111000011110000111100001
1110001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100
1100110011001100110011001100110011001101111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111110000111100001111000
0111100001111000011110000111100001111000011";
string LETTER_CCCC=
"000110000001100000011000000110000011110000111100001111000011110000111100001111000011110000111
1000110011001100110011001100110011001100110011001100110011001100110111111111111111111111111111
111111111111111111111111111111111111111000011110000111100001111000011";
string ANIMAT_bme_AUT=
"111010001111000000111000111111101001110110000000011110000111111011101010111000001111100110110
0001001100010000001110110011011000011101000111100111001100110110000000000000000011100011001101
100000000000000001111111111111011000000000000000111000000111100110000";
string SMILE =
"0000000001100110011001100000000011000011110000111111111101111110";
string TWO_SMILE = "0000000000000000
0110011001100110
0110011001100110
0000000000000000
0100001001000010
0100001001000010
0011110000111100
0000000000000000";
public Form1()
{
InitializeComponent();
init();
}
private void init()
{
MyPort = new SerialPort();
MyPort.BaudRate = 115200;
MyPort.PortName = "COM3";
MyPort.Open();
}
private void button1_Click(object sender, EventArgs e)
{
MyPort.Write("c");
for (int i = 0; i < 256; i++)
{
MyPort.Write(ANIMAT_bme_AUT[i].ToString());
}
}
private void button3_Click(object sender, EventArgs e)
{
MyPort.Write("a");
for (int i = 0; i < 64; i++)
{
MyPort.Write(SMILE[i].ToString());
}
}
private void button4_Click(object sender, EventArgs e)
{
MyPort.Write("d");
for (int i = 0; i < 512; i++)
A kiküldendő animációkat stringekben
tárolom
az 1-5 ös gombok segítségével
mennek ki az animációk
mindegyik hasonlóan működik ,
első teendőjük hogy a
hosszoknak megfelelő
üzemmódparancsot kiadják
{
MyPort.Write(LETTER_AAAA[i].ToString());
}
}
private void button5_Click(object sender, EventArgs e)
{
MyPort.Write("b");
for (int i = 0; i < 128; i++)
{
MyPort.Write(TWO_SMILE[i].ToString());
}
}
private void button2_Click(object sender, EventArgs e)
{
MyPort.Write("a");
for (int i = 0; i < 64; i++)
{
MyPort.Write("0");
}
}
private void button6_Click_1(object sender, EventArgs e)
{
int hour = DateTime.Now.Hour;
if (hour > 11)
{
hour = hour - 13;
}
//hour = 12 - hour;
int minute = 60- DateTime.Now.Minute;
int second = 60- DateTime.Now.Second;
MyPort.Write("t");
MyPort.Write("h");
MyPort.Write(((char)hour).ToString());
MyPort.Write("m");
MyPort.Write(((char)minute).ToString());
MyPort.Write("s");
MyPort.Write(((char)second).ToString());
}
private void button7_Click(object sender, EventArgs e)
{
MyPort.Write("s");
if (textBox1.TextLength < 10)
{
MyPort.Write("0");
}
MyPort.Write(textBox1.TextLength.ToString());
MyPort.Write(textBox1.Text);
}
}
}
Óra inicializálás.
24h –s formátumot 12h-ssá
kell varázsolni
A szöveg valamint annak
hosszának elküldése
ezzel a függvénnyel
„kapcsolom ki” a
képernyőt
ha az eszközre ráadjuk az áramot esz
a képernyő fogad
a hátulsó nyomógombbal váltogathatjuk
az üzemmódokat, amikor még nem
dugtuk föl pc-re a default értékeket
láthatjuk
szöveg kiírásnál a „nincs szöveg” string
shiftelődik
A kliensszoftverrel a következő funkciók érhetőek el.
1. Aut-BME animáció 32x8 –as képernyőn
2. Smile animáció 8x8 as képernyőn nincs shift
3. smile animáció 16x8 as képernyőn van shift
4. szöveg kiírása maximum 50 karakterig
5. képernyő lekapcsolása
6. Aktuális idő mutatása
Led matrix-dokumentáció

Weitere ähnliche Inhalte

Empfohlen

Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...DevGAMM Conference
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationErica Santiago
 
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellGood Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellSaba Software
 

Empfohlen (20)

Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
Ride the Storm: Navigating Through Unstable Periods / Katerina Rudko (Belka G...
 
Barbie - Brand Strategy Presentation
Barbie - Brand Strategy PresentationBarbie - Brand Strategy Presentation
Barbie - Brand Strategy Presentation
 
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them wellGood Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
Good Stuff Happens in 1:1 Meetings: Why you need them and how to do them well
 

Led matrix-dokumentáció

  • 1. Mikrokontroller Laboratórium Jegyzőkönyv 1.Feladat leírása: A12 feladat:  LED mátrix Készítsen kiegészítő hardver egységet az STM32 NUCLEO-F446RE kithez, amely egy 8x8-as LED mátrix kijelzőt valósít meg!  Az LED mátrix sorkiválasztása történjen időmultiplexelt vezérléssel, az oszlopvezérlés pedig SPI buszon (sorosan), 8 bites léptetőregiszter segítségével.  Az áramkör megtervezése, megépítése és üzembe helyezése után készítsen el egy az eszköz bemutatására szolgáló demonstrációs célú tesztprogram rendszert, amely az egyetemünkhöz, karunkhoz, szakirányunkhoz vagy ágazatunkhoz kapcsolódó animációkat jelenít meg a kijelzőn.  Az animációkat PC-n hozza létre, és az egyes animációk letöltése, kezelése, cseréje soros porton keresztül, egy kliensprogram segítségével történjen.  A kommunikációhoz virtuális soros portot használjon, melyet a kiten megtalálható USB port segítségével valósítson meg! 2.Nyáktervezés: Nyákterv
  • 2. Led-mátrix és vezérlésének kapcsolási rajza Vezetékek bekötési rendje a Nucleo Kit-be
  • 5. 3. Inicializálás CubeMx segítségével: 1. PIN-ek megfelelő inicializálása 2. Órajel megfelelő beállítása
  • 6. 3. Interruptok engedélyezése 4.A PROGRAM: 1. az általam írt vagy megváltoztatott .c és .h fájlok
  • 7. main.c //időmultiplexelt kirajzoláshoz, forciklussal megyünk végig ezen a tömbön és mindig 1 sort rajzolunk ki uint16_t LED_array[]= { GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_2, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7 }; //iteratív változóim, itt vannak definiálva mert több 3 szintű egymásba ágyazott forcikulusban is ezeket használom uint16_t i; uint16_t j; uint16_t r; uint16_t w; uint8_t temp;//az aktuális sor aktuálisan kirajzolt értéke benne található(rotálás eredménye ide kerül) uint8_t SPI_In=0b00000000; uint8_t SPI_Out; // tesztváltozó uint16_t LED_ALL=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3| GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; //Latch enable és Output enable HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET); // a nucleo zöld ledjét beállítja HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET); //az összes sort GPIO oldalról kikapcsoljuk/negált logika HAL_GPIO_WritePin(GPIOC,LED_ALL,GPIO_PIN_SET); //a leddriver shiftreget is inaktiváljuk SPI_SendReceive(&SPI_In,&SPI_Out,1); while (1) { if(STRING_DISPLAY_ON) { for(w=0;w<STRING_LENGTH;w++) { init_display(display_aft,mystring[w]); for(r=0;r<8;r++) { shift_aft_to_curr(); for(j=0;j<3;j++) { for(i=0;i<8;i++) { HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_RESET); SPI_SendReceive(&display_curr[i],&SPI_Out,1); HAL_Delay(2); HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_SET); } if(!STRING_DISPLAY_ON) {goto end;} } } } } else { for(r=0;r<128;r++)//itt írom ki az uart adatokat erre külön függvény majd menjen { for(j=0;j<HOLD_TIME;j++)//ez a rotálás miatt kell mert minden r értéket az első forból 3 cilusig kell kitartani . hal_delay nem jó mert folyamatosan kell pörögni a függvénynek { for(i=0;i<8;i++) { if(!TIME_IS_ON) { switch(CURR_ROW_SIZE)//megnézzük a képernyő üzemmódot és a megfelelő / függvényeket meghívva előkésítjük a következő képernyő képet { case 8:temp=leddot[i]; break; case 16:temp=_rotr16(leddot16[i],r); break; case 32:temp=_rotr32(leddot32[i],r); break; case 64:temp=_rotr64(leddot64[i],r); break; } HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_RESET);//for ciklusba vagyunk minden i++ ra a következő sor megfelelő ledjei világítanak de a megfelelő időzítéssel elértem hogy az emberi szemnek folyamatosnak tűnjön a világítás SPI_SendReceive(&temp,&SPI_Out,1);//a megfelelő sor adatai kimennek HAL_Delay(2);//kicsit hagyjuk világítani HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_SET);//majd elsötétítjük } A végtelen ciklusomban 3 féle eset alakulhat: 1. szöveg kíírás 2. óra kirajzolás (1-2 ről bővebben lejjebb) 3. egyéb animáció kirajzolása  ennek 4 módja o 8 bit: szeszéles képernyőkép, ekkor nem rotálom a képernyőt a többi esetben viszont igen o 16bit o 32bit:Az aut animáció ezen megy o 64bit
  • 8. else { temp=led_hour_array[hour][i]|led_minsec_array[second][i]|led_minsec_array[minute][i]; HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_RESET);//forciklusba vagyunk minden i++ ra a következő sor megfelelő ledjei világítanak de a megfelelő időzítéssel elértem hogy az emberi szemnek folyamatosnak tűnjön a világítás SPI_SendReceive(&temp,&SPI_Out,1);//a megfelelő sor adatai kimennek HAL_Delay(2);//kicsit hagyjuk világítani HAL_GPIO_WritePin(GPIOC,LED_array[i],GPIO_PIN_SET);//majd elsötétítjük } if(STRING_DISPLAY_ON) {goto end;} } } if(second==0) { if(minute==0) { if(hour==0) { hour=12; } hour--; minute=60; } minute--; second=60; } second--; } } end:; /*}*/ } /* USER CODE END 3 */ } TIME Animáció a main.c-ben Itt minden órához, perchez és másodperchez tartozó 8x8 as kép el van tárolva megfelelő 2D-s tömbökben. Az órához tartozók a led_hour_array[][] ahogy a perc/másodpercnek is vamn külön tömbje és ezek a megfelelő pillanatokban egymásra vagyolva vannak. A számolás a ciklus végén történik ez akkor is fut ha nem óra üzemmódban vagyunk. Szövegkiírás a main.c-ben Alapvetően 2 tömb van jelen(display_curr[] és display_aft[]) és ezeket a kapott string alapján töltögetjük.  a program indulásakor mind a 2 tömb csupa nulla  amikor először belépünk a szövegkiíró üzemmódba a legfelső forciklus elején az a display_aft[] tömböt az első karakternek megfelelően inicializáljuk  majd fokozatosan átshiftelem a display_aft[] tartalmát a display_bef[]-be , amikor ez kész újratöltöm a display_aft[]-ot a következő karakter szerint  amint a szó végére érek aminek a hosszát a STRING_LENGTH változóban tárolom újrakezdem a műveletet  ha új uart parancs érkezik akkor a műveletet goto utasítás segítségével megszakítom
  • 9. gpio.c void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); /*SHF_LE*//*SHF_OE*/ GPIO_InitStruct.Pin =GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4| GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; HAL_GPIO_Init(GPIOC,&GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* EXTI interrupt init*/ HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); } /* USER CODE BEGIN 2 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if((!TIME_IS_ON)&&STRING_DISPLAY_ON) { HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);//tesztelés CURR_ROW_SIZE=8; TIME_IS_ON=1; HOLD_TIME=40; STRING_DISPLAY_ON=0; return; } if(TIME_IS_ON&&(!STRING_DISPLAY_ON)) { STRING_DISPLAY_ON=0; TIME_IS_ON=0; CURR_ROW_SIZE=32; HOLD_TIME=3; return; } if((!TIME_IS_ON)&&(!STRING_DISPLAY_ON)) { STRING_DISPLAY_ON=1; TIME_IS_ON=0; return; } } spi.c const uint32_t spi_timeout = 5000; /* USER CODE END 0 */ SPI_HandleTypeDef hspi3; /* SPI3 init function */ void MX_SPI3_Init(void) { hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_MASTER; hspi3.Init.Direction = SPI_DIRECTION_2LINES; hspi3.Init.DataSize = SPI_DATASIZE_8BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; Itt érdemes megemlíteni hogy a PC13-on lévő pushbutton külső megszakítás hajt végre, a PC-ről lehúzott eszközön ennek segítségévekl tudok az animációk között váltani. A gomb megnyomására a soron következő üzemmód fontos változói beálításra kerülnek, ezek funkcióját deklarációjuknál kifejtem. spi.c ben az spi-hez tartozó az alapvető funkciók lettek megvalósítva. küldés,fogadás,inicializálás,stb.
  • 10. hspi3.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi3) != HAL_OK) { Error_Handler(); } } void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) { GPIO_InitTypeDef GPIO_InitStruct; if(spiHandle->Instance==SPI3) { /* USER CODE BEGIN SPI3_MspInit 0 */ /* USER CODE END SPI3_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_SPI3_CLK_ENABLE(); /**SPI3 GPIO Configuration PC10 ------> SPI3_SCK PC11 ------> SPI3_MISO PC12 ------> SPI3_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* USER CODE BEGIN SPI3_MspInit 1 */ /* USER CODE END SPI3_MspInit 1 */ } } void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) { if(spiHandle->Instance==SPI3) { /* USER CODE BEGIN SPI3_MspDeInit 0 */ /* USER CODE END SPI3_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_SPI3_CLK_DISABLE(); /**SPI3 GPIO Configuration PC10 ------> SPI3_SCK PC11 ------> SPI3_MISO PC12 ------> SPI3_MOSI */ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12); } /* USER CODE BEGIN SPI3_MspDeInit 1 */ /* USER CODE END SPI3_MspDeInit 1 */ } /* USER CODE BEGIN 1 */ HAL_StatusTypeDef SPI_Send(uint8_t* pData, uint16_t dataSize) { HAL_SPI_Transmit(&hspi3,pData,dataSize,spi_timeout); return HAL_OK; } HAL_StatusTypeDef SPI_Receive(uint8_t* pData, uint16_t dataSize) { HAL_SPI_Receive(&hspi3,pData,dataSize,spi_timeout); return HAL_OK; } /** SPI küldés és fogadás egyszerre. */ HAL_StatusTypeDef SPI_SendReceive(uint8_t* pDataIn, uint8_t *pDataOut, uint16_t dataSize) { HAL_SPI_TransmitReceive(&hspi3,pDataIn,pDataOut,dataSize,spi_timeout); return HAL_OK; } usart.c #include "usart.h" #include "gpio.h" #include "string.h" #include "time.h" #include "font.h"
  • 11. /* USER CODE BEGIN 0 */ uint8_t lastReceivedUartCommand = 0; char rxBuffer; uint16_t CURR_ROW_SIZE=32;//alapértelmezetten 32-nek lett most véletlen beállítva de üres regisztert rotál tehát lényegtelen, az első beérkezett uart csomagnál eldől hogy milyen üzemmódban működünk #define TXBUFFERSIZE 255 char txBuffer[TXBUFFERSIZE]; HAL_StatusTypeDef stat; uint8_t mystring[50]={'n'-' ','i'-' ','n'-' ','c'-' ','s'-' ',' '-' ','s'-' ','z'-' ','o'-' ','v'-' ','e'-' ','g'-' ',' '-' '}; //ebbe tárolom a kiírandó szót uint8_t STRING_LENGTH_INIT;//bekérem a sring hosszát uint8_t STRING_LENGTH=13;//string hossza uint8_t STRING_LENGTH_TEMP=0;//ennek segítségével nézem hogy elértem már e a kért szó végét uint8_t STRING_DISPLAY_ON=0;//magának a string kiírásnak az állapotjelzője uint8_t STRING_IS_ON=0;//stringkiírással kapcsolatos adatok uarton való fogadásának állapota uint8_t TIME_IS_ON=1; //az óra üzemmódot jelző változó uint8_t TIME_INIT=0; //ez a változó azt jelzi amikor az óra inicializálás adatai jönnek, amíg ez igaz minden adatot erre hasznosítunk uint8_t HOLD_TIME=50;//meddig tatson egy képernőképet a kimeneten ,,, time nál ugy 1 mp ig kell uint8_t time_type=0; uint8_t digit=1; uint8_t leddot[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }; uint16_t leddot16[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből { 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, 0b0000000000000000, 0b0000000000000000 }; uint32_t leddot32[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből { 0x00ff00ff, 0x38c738c7, 0x7c8344bb, 0x7c8344bb, 0x7c8344bb, 0x38c738c7, 0x00ff00ff, 0x00ff00ff }; uint64_t leddot64[]=//itt tárolom a bejövő adatot externnel hivatkozok rá a mainből { 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000, 0b0000000000000000000000000000000000000000000000000000000000000000 }; uint8_t display_curr[]= { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }; uint8_t display_aft[]= { 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 }; uint16_t Row_counter=0;//maximumértéke a vízszintes szélességet befojásolja alapértelmezetten 8 de ha rotáljuk shiftreget akkor lehet jóval több is uint16_t Col_counter=0;//függöleges szélesség, maximum ugye 8 lehet , persze lehet bonyolítani itt is a dolgot //az ascii karaktert a megfelelő üzemmódokban a megfelelő típussá kell konvertálni ezekre ott van szülségem uint8_t intBuffer8; uint16_t intBuffer16; uint32_t intBuffer32; display_curr[] és display_aft[] inicializálás működésük előbbikben részletezve volt
  • 12. uint64_t intBuffer64; uint8_t second=59; uint8_t minute=59; uint8_t hour=11; //void init_display(); //A uart callback függványből ezek a függvények hívódnak meg a megfelelő időpontban void UART_PROCESS_8BITDISPLAY(); void UART_PROCESS_16BITDISPLAY(); void UART_PROCESS_32BITDISPLAY(); void UART_PROCESS_64BITDISPLAY(); void UART_ASCII_SHIFT_CONVERT(); void ROW_COL_STEP(); /* USER CODE END 0 */ UART_HandleTypeDef huart2; /* USART2 init function */ void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } stat=HAL_UART_Receive_IT(&huart2, (uint8_t*)&rxBuffer, 1); } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct; if(uartHandle->Instance==USART2) { /* USER CODE BEGIN USART2_MspInit 0 */ /* USER CODE END USART2_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_USART2_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART2; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE END USART2_MspInit 1 */ } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART2) { /* USER CODE BEGIN USART2_MspDeInit 0 */ /* USER CODE END USART2_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART2_CLK_DISABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); /* Peripheral interrupt Deinit*/ HAL_NVIC_DisableIRQ(USART2_IRQn); } /* USER CODE BEGIN USART2_MspDeInit 1 */ /* USER CODE END USART2_MspDeInit 1 */ } /* USER CODE BEGIN 1 */ /** String küldése, nem blokkolva. */ HAL_StatusTypeDef UART_SendString(char *str) { //IDE INKÁBB VÁRAKOZÓSI SOR KELL while ((huart2.gState != HAL_UART_STATE_BUSY_RX) && (huart2.gState != HAL_UART_STATE_READY)) { } strncpy(txBuffer, str, TXBUFFERSIZE); uint32_t length = strlen(txBuffer); return HAL_UART_Transmit_IT(&huart2, (uint8_t*)txBuffer, length); return HAL_OK; óra,perc,másodperc 0-tól 59-ig megy sikerült fordított sorrendbe bepötyögnöm az összeset úgyhogy azért számlálok visszafele.
  • 13. } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle) { uint8_t len_temp; if(STRING_IS_ON) { if(STRING_LENGTH_INIT) { len_temp=rxBuffer-'0'; STRING_LENGTH=len_temp+10*STRING_LENGTH; STRING_LENGTH_INIT--; STRING_LENGTH_TEMP=0; } else { mystring[STRING_LENGTH_TEMP]=rxBuffer-'!'+1; STRING_LENGTH_TEMP++; if(STRING_LENGTH_TEMP==STRING_LENGTH) { STRING_IS_ON=0; STRING_DISPLAY_ON=1; } } } else { if(TIME_INIT) { switch(rxBuffer)// üzemmódnak megfelelő uartkezelés hívódik { case 'h': time_type=0; digit=1; break; case 'm': time_type=1; digit=1; break; case 's': time_type=2; digit=1; break; default: switch(time_type) { case 0:hour=rxBuffer; break; case 1:minute=rxBuffer; break; case 2:second=rxBuffer; TIME_INIT=0; break; } } } else { switch(rxBuffer)//az egyik legfontosabb rész , itt döntjük el hogy a bejövőcsomag az üzemmódot akarja állítani vagy pedig a kijelzőt { //kijelzőt csak 0 és 1 gyel állítunk , kliensprogramra erre figyelek ezért van itt a default , ha üzemmód csomag érkezik azt nem tároljuk el a leddot[]tömben hanem csak értelmezzük case'a':CURR_ROW_SIZE=8;//8 bites animáció nincs shift TIME_IS_ON=0; HOLD_TIME=3; STRING_DISPLAY_ON=0; break; case'b':CURR_ROW_SIZE=16;//16 bites animáció TIME_IS_ON=0; HOLD_TIME=3; STRING_DISPLAY_ON=0; break; case'c':CURR_ROW_SIZE=32//32 bites animáció TIME_IS_ON=0; HOLD_TIME=3; STRING_DISPLAY_ON=0; break; case'd':CURR_ROW_SIZE=64;// 64 bites animáció TIME_IS_ON=0; HOLD_TIME=3; STRING_DISPLAY_ON=0; break; case't':CURR_ROW_SIZE=8;//idő animáció TIME_IS_ON=1; TIME_INIT=1; ACTUAL_TIME_INIT=1; HOLD_TIME=40; STRING_DISPLAY_ON=0; break; case's':STRING_IS_ON=1; //szöveg kiírás STRING_LENGTH_INIT=2; STRING_LENGTH=0; TIME_IS_ON=0; break; default: switch(CURR_ROW_SIZE)// üzemmódnak megfelelő uartkezelés hívódik { case 8:UART_PROCESS_8BITDISPLAY(); break; case 16:UART_PROCESS_16BITDISPLAY(); break; case 32:UART_PROCESS_32BITDISPLAY(); break; Itt történik a string valamint annak hosszának a beolvasása. A hossz 2 karakter ennek lekezelése látható az if igaz ágában. Amint beolvastunk mindent a string inicializálás állapotának jelzőbitjét kinullázzuk majd a string kiírás jelzőbitjét igazzá teszem. Óra üzemmódban az aktuális idő beolvasása.Minden időegység 1 karakter hosszú, kliens oldalon itt charrá konvertálok és utána használom csak a .Tostring() függvényt hogy elférjek 1 byte-on. amikor semmilyen inicializálás nem zajlik itt dől el hogy melyik üzemmódba lépünk. érdemes megemlíteni hogy a Holdtime alapvetően 3 hogy megfelelően sebességgel heledjon a tartalom a kijelzőn, óra üzemmódban viszont kb. egy másodpercenként váltson ezért 40.
  • 14. case 64:UART_PROCESS_64BITDISPLAY(); break; } break; } } } HAL_UART_Receive_IT(handle, (uint8_t*)&rxBuffer, 1); } void UART_PROCESS_8BITDISPLAY() { uint8_t i; if((Row_counter==0)&&(Col_counter==0))//mindig akkor nullázzuk a képernyőt amikor a következő képernyőkép első bitje megérkezett(értelemszerűen) és azt egyből ki is rajzoljuk { for(i=0;i<8;i++) { leddot[i]=0; } //draw_OK=0; } UART_ASCII_SHIFT_CONVERT();//beérkezett asciiból kivonjuk a '0' karaktert majd a megfelelő típusra konvertáljuk ezelután annyival shifteljük ahanyadik adat a sorban leddot[Col_counter]=leddot[Col_counter]| intBuffer8;//az eddigi adatokhoz hozzávagyolom Row_counter++; ROW_COL_STEP();//a sorok és oszlopok novelésének nullázásának lekezelése } void UART_PROCESS_16BITDISPLAY() { uint8_t i; if((Row_counter==0)&&(Col_counter==0)) { for(i=0;i<8;i++) { leddot16[i]=0; } //draw_OK=0; } UART_ASCII_SHIFT_CONVERT(); leddot16[Col_counter]=leddot16[Col_counter]| intBuffer16;//az eddigi adatokhoz hozzávagyolom Row_counter++; ROW_COL_STEP(); } void UART_PROCESS_32BITDISPLAY() { uint8_t i; if((Row_counter==0)&&(Col_counter==0)) { for(i=0;i<8;i++) { leddot32[i]=0; } //draw_OK=0; } UART_ASCII_SHIFT_CONVERT(); leddot32[Col_counter]=leddot32[Col_counter]| intBuffer32;//az eddigi adatokhoz hozzávagyolom Row_counter++; ROW_COL_STEP(); } void UART_PROCESS_64BITDISPLAY() { uint8_t i; if((Row_counter==0)&&(Col_counter==0)) { for(i=0;i<8;i++) { leddot64[i]=0; } //draw_OK=0; } UART_ASCII_SHIFT_CONVERT(); leddot64[Col_counter]=leddot64[Col_counter]| intBuffer64;//az eddigi adatokhoz hozzávagyolom Row_counter++; ROW_COL_STEP(); } void UART_ASCII_SHIFT_CONVERT() { rxBuffer = rxBuffer - '0';//1 vagy 0 érkezik és char ból int be konvertálom switch(CURR_ROW_SIZE) { case 8:intBuffer8=rxBuffer; intBuffer8=intBuffer8<<Row_counter; break; //annyit shiftelem amelyik sorba tartozik az adat case 16:intBuffer16=rxBuffer; intBuffer16=intBuffer16<<Row_counter; break; case 32:intBuffer32=rxBuffer; intBuffer32=intBuffer32<<Row_counter; egyenként érkeznek be az animáció bitjei ezeket mikor beérkeznek a képernyő egy sorának méretére konvertálom majd annyival shiftelem ahanyadik elemnél tartunk az adott „col” ban és ezt végül hozzávagyolom az eddigi értékhez
  • 15. break; case 64:intBuffer64=rxBuffer; intBuffer64=intBuffer64<<Row_counter; break; } } void ROW_COL_STEP() { //azér van itt nyolc mert mindig kiírás után novelem a sort azaz ha a 7. row-t kiírtam akkor növelek 8 ra és ilyenkor 0-zódik minden //a következő kiírés pedig már az új kijelzőkép első pontja lesz if(Row_counter%CURR_ROW_SIZE==0)//ha elértem a sor végét az { //oszlopot növelem a sort nullázom if(Col_counter==7)//ha bejött minden adat akkor 0-zok mindent {//utsó bit nem megy ki ezt még javítani kell Row_counter=0; Col_counter=0; //draw_OK=1; //init_display(); } else { Col_counter++; Row_counter=0; } } } void USART3_IRQHandler(void) { HAL_UART_IRQHandler(&huart2); } void init_display(uint8_t* display,uint8_t letternum) { uint8_t i; uint8_t temp; for(i=0;i<8;i++) { temp=IMAGES[letternum][i]; temp = (temp & 0xF0) >> 4 | (temp & 0x0F) << 4; temp = (temp & 0xCC) >> 2 | (temp & 0x33) << 2; temp = (temp & 0xAA) >> 1 | (temp & 0x55) << 1; display[i]=temp; } } font.h http://xantorohara.github.io/led-matrix-editor/# led_time.h tartalmaza az egyes időpontokhoz tartozó képet Kliensoldal: itt döntöm el hogy új sorba kell e lépni esetleg végeztem a beolvasással
  • 16. using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; namespace MIKROLAB { public partial class Form1 : Form { private SerialPort MyPort; private char actualstatus; private int CURR_DISPLAY_SIZE; string LETTER_A ="0001100000111100001111000110011001100110111111111111111111000011"; string LETTER_B= "1111110011000110110000111111111011111110110000111100011011111100"; string LETTER_C ="0011111101111111111000001110000011100000111000000111111100111111"; string LETTER_CC = "001111110011111101111111011111111110000011100000111000001110000011100000111000001110000011100 00001111111011111110011111100111111"; string LETTER_AAAA = "000110000001100000011000000110000001100000011000000110000001100000111100001111000011110000111
  • 17. 1000011110000111100001111000011110000111100001111000011110000111100001111000011110000111100001 1110001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100 1100110011001100110011001100110011001101111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111111111111110000111100001111000 0111100001111000011110000111100001111000011"; string LETTER_CCCC= "000110000001100000011000000110000011110000111100001111000011110000111100001111000011110000111 1000110011001100110011001100110011001100110011001100110011001100110111111111111111111111111111 111111111111111111111111111111111111111000011110000111100001111000011"; string ANIMAT_bme_AUT= "111010001111000000111000111111101001110110000000011110000111111011101010111000001111100110110 0001001100010000001110110011011000011101000111100111001100110110000000000000000011100011001101 100000000000000001111111111111011000000000000000111000000111100110000"; string SMILE = "0000000001100110011001100000000011000011110000111111111101111110"; string TWO_SMILE = "0000000000000000 0110011001100110 0110011001100110 0000000000000000 0100001001000010 0100001001000010 0011110000111100 0000000000000000"; public Form1() { InitializeComponent(); init(); } private void init() { MyPort = new SerialPort(); MyPort.BaudRate = 115200; MyPort.PortName = "COM3"; MyPort.Open(); } private void button1_Click(object sender, EventArgs e) { MyPort.Write("c"); for (int i = 0; i < 256; i++) { MyPort.Write(ANIMAT_bme_AUT[i].ToString()); } } private void button3_Click(object sender, EventArgs e) { MyPort.Write("a"); for (int i = 0; i < 64; i++) { MyPort.Write(SMILE[i].ToString()); } } private void button4_Click(object sender, EventArgs e) { MyPort.Write("d"); for (int i = 0; i < 512; i++) A kiküldendő animációkat stringekben tárolom az 1-5 ös gombok segítségével mennek ki az animációk mindegyik hasonlóan működik , első teendőjük hogy a hosszoknak megfelelő üzemmódparancsot kiadják
  • 18. { MyPort.Write(LETTER_AAAA[i].ToString()); } } private void button5_Click(object sender, EventArgs e) { MyPort.Write("b"); for (int i = 0; i < 128; i++) { MyPort.Write(TWO_SMILE[i].ToString()); } } private void button2_Click(object sender, EventArgs e) { MyPort.Write("a"); for (int i = 0; i < 64; i++) { MyPort.Write("0"); } } private void button6_Click_1(object sender, EventArgs e) { int hour = DateTime.Now.Hour; if (hour > 11) { hour = hour - 13; } //hour = 12 - hour; int minute = 60- DateTime.Now.Minute; int second = 60- DateTime.Now.Second; MyPort.Write("t"); MyPort.Write("h"); MyPort.Write(((char)hour).ToString()); MyPort.Write("m"); MyPort.Write(((char)minute).ToString()); MyPort.Write("s"); MyPort.Write(((char)second).ToString()); } private void button7_Click(object sender, EventArgs e) { MyPort.Write("s"); if (textBox1.TextLength < 10) { MyPort.Write("0"); } MyPort.Write(textBox1.TextLength.ToString()); MyPort.Write(textBox1.Text); } } } Óra inicializálás. 24h –s formátumot 12h-ssá kell varázsolni A szöveg valamint annak hosszának elküldése ezzel a függvénnyel „kapcsolom ki” a képernyőt
  • 19. ha az eszközre ráadjuk az áramot esz a képernyő fogad a hátulsó nyomógombbal váltogathatjuk az üzemmódokat, amikor még nem dugtuk föl pc-re a default értékeket láthatjuk szöveg kiírásnál a „nincs szöveg” string shiftelődik
  • 20. A kliensszoftverrel a következő funkciók érhetőek el. 1. Aut-BME animáció 32x8 –as képernyőn 2. Smile animáció 8x8 as képernyőn nincs shift 3. smile animáció 16x8 as képernyőn van shift
  • 21. 4. szöveg kiírása maximum 50 karakterig 5. képernyő lekapcsolása 6. Aktuális idő mutatása