- •Московский авиационный институт
- •(Государственный технический университет)
- •Кафедра 304
- •Курсовой проект на тему:
- •«Проектирование и аппаратная реализация наземной станции управления и отображения телеметрии беспилотного летательного аппарата»
- •Москвa 2014 Введение
- •Теоретическая часть Микроконтроллер stm32f103vct6
- •Процессоры Cortex
- •Жидкокристаллический дисплей
- •Контроллер сенсорной панели ads7843
- •Блок схема ads7843
- •Практическая часть
- •Заключение
Практическая часть
Программная реализация ядра графической библиотеки
#ifndef __GUICORE_H
#define __GUICORE_H
#include "MCU_DRIVER.h"
#include "USER/GlobalVar.h"
#include "Primitives.h"
#include "Widget.h"
#include "Screen.h"
#include "Other.h"
#include "FONTS/font_1.h"
#define MAX_Y 240
#define MAX_X 320
#define RGB565CONVERT(red, green, blue) (uint16_t)( (( red >> 3 ) << 11 ) | (( green >> 2 ) << 5 ) | ( blue >> 3 ))
#define FILL 1
#define NO_FILL 0
#define READY 1
#define NOT_READY 0
#define WHITE 0xFFFF
#define BLACK 0x0000
#define GREY 0xF7DE
#define BLUE 0x001F
#define BLUE2 0x051F
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define ORANGE RGB565CONVERT(255, 102, 0)
#define HOME_SCREEN 0
#define ALTITUDE_GRAPH_SCREEN 1
#define COMPASS_GRAPH_SCREEN 2
#define TEMPERATURE_GRAPH_SCREEN 3
#define VOLTAGE_GRAPH_SCREEN 4
#define FLY_VIEW_SCREEN 5
#define FLY_SETTINGS_SCREEN 6
#define CONSOLE_SCREEN 7
#define RENDERING_TIME 10
#define SCREEN_RENDERING_PAUSE 500
#endif /*__GUICORE_H */
Программная реализация драйвера тачскрина
#include "ADS7843.h"
#define X_AXE 0x90
#define Y_AXE 0xd0
#define X_MIN 150
#define Y_MIN 110
#define X_MAX 1770
#define Y_MAX 1840
void MCU_TP_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
/* Configure SPI1 pins: SCK, MISO and MOSI ---------------------------------*/
GPIO_InitStructure.GPIO_Pin = TP_GPIO_Pin_SCK | TP_GPIO_Pin_MISO | TP_GPIO_Pin_MOSI;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TP_PORT_SPI, &GPIO_InitStructure);
/* TP_CS */
GPIO_InitStructure.GPIO_Pin = TP_GPIO_Pin_CS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TP_PORT_CS, &GPIO_InitStructure);
TP_Deselect();
}
void MCU_TP_EXTI_Config(void)
{
/* TP_IRQ */
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6);
EXTI_ClearITPendingBit(EXTI_Line6);
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_Line = EXTI_Line6;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void MCU_TP_SPI_Config(void)
{
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* DISABLE SPI1 */
SPI_Cmd(SPI1, DISABLE);
/* SPI1 Config -------------------------------------------------------------*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
}
void TP_WriteCommand(uint8_t cmd)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, cmd);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI1);
}
uint16_t TP_ReadData(void)
{
uint16_t msb, lsb;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1,0x0000);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
msb = SPI_I2S_ReceiveData(SPI1);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1,0x0000);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
lsb = SPI_I2S_ReceiveData(SPI1);
return ((msb<<8 | lsb)>>4);
//return (msb<<8 | lsb);
}
uint16_t TP_ReadAxis(uint32_t axis)
{
uint32_t i, counter = 0;
int16_t result = 0;
TP_Select();
for (i = 0; i < 10; i++)
{
if (GPIO_ReadInputDataBit(TP_PORT_IRQ, TP_GPIO_Pin_IRQ) == 0)
{
TP_WriteCommand(axis);
result += TP_ReadData();
//Delay_ms(1);
counter++;
}
}
TP_Deselect();
result /= counter;
result = (axis == X_AXE) ? (result - X_MIN) : (result - Y_MIN);
result = (result > 0) ? (result) : (0);
return result;
}
void TP_ReadCoordinates(uint32_t *X_Axis, uint32_t *Y_Axis)
{
uint32_t x, y;
x = TP_ReadAxis(X_AXE);
y = TP_ReadAxis(Y_AXE);
if ( (x == 0) || (y == 0) )
{
return;
}
*X_Axis = ( (x * 10) / ( (X_MAX * 10) / 320) );
*Y_Axis = ( (y * 10) / ( (Y_MAX * 10) / 240) );
}
void TP_Calibrate(void)
{
/*
uint32_t i, j;
char mass[40];
typedef struct Matrix
{
int32_t An, A = An/Divider
Bn, B = Bn/Divider
Cn, C = Cn/Divider
Dn, D = Dn/Divider
En, E = En/Divider
Fn, F = Fn/Divider
Divider ;
} MATRIX ;
MATRIX matrix;
POINT DisplaySample[3] =
{
{(MAX_X * 15) / 100, (MAX_Y * 15) / 100},
{(MAX_X * 50) / 100, (MAX_Y * 85) / 100},
{(MAX_X * 85) / 100, (MAX_Y * 15) / 100}
};
POINT ScreenSample[3];
POINT RealCoordinate, CorrectCoordinate;
LCD_DrawRect(0, 0, MAX_X, MAX_Y, FILL, BLACK);
for(i = 0; i < 3; i++)
{
sprintf(mass, "Touch red point to calibrate...");
LCD_DrawText(15, 65, mass, GREEN, BLACK);
LCD_DrawCross(DisplaySample[i].x, DisplaySample[i].y, RED);
while(GPIO_ReadInputDataBit(TP_PORT_IRQ, TP_GPIO_Pin_IRQ) != 0)
{
//
}
ScreenSample[i].x = TP_Read_Axis(X_AXE);
ScreenSample[i].y = TP_Read_Axis(Y_AXE);
LCD_DrawCross(DisplaySample[i].x, DisplaySample[i].y, GREEN);
sprintf(mass, "Point %d read;", i + 1);
LCD_DrawText(15, 81 + i * 16, mass, GREEN, BLACK);
Delay_ms(1000);
while(GPIO_ReadInputDataBit(TP_PORT_IRQ, TP_GPIO_Pin_IRQ) != 1)
{
//
}
}
sprintf(mass, "Calibration OK!");
LCD_DrawText(15, 81 + i * 16, mass, GREEN, BLACK);
matrix.An = ((DisplaySample[0].x - DisplaySample[2].x) * (ScreenSample[1].y - ScreenSample[2].y)) -
((DisplaySample[1].x - DisplaySample[2].x) * (ScreenSample[0].y - ScreenSample[2].y)) ;
matrix.Bn = ((ScreenSample[0].x - ScreenSample[2].x) * (DisplaySample[1].x - DisplaySample[2].x)) -
((DisplaySample[0].x - DisplaySample[2].x) * (ScreenSample[1].x - ScreenSample[2].x)) ;
matrix.Cn = (ScreenSample[2].x * DisplaySample[1].x - ScreenSample[1].x * DisplaySample[2].x) * ScreenSample[0].y +
(ScreenSample[0].x * DisplaySample[2].x - ScreenSample[2].x * DisplaySample[0].x) * ScreenSample[1].y +
(ScreenSample[1].x * DisplaySample[0].x - ScreenSample[0].x * DisplaySample[1].x) * ScreenSample[2].y ;
matrix.Dn = ((DisplaySample[0].y - DisplaySample[2].y) * (ScreenSample[1].y - ScreenSample[2].y)) -
((DisplaySample[1].y - DisplaySample[2].y) * (ScreenSample[0].y - ScreenSample[2].y)) ;
matrix.En = ((ScreenSample[0].x - ScreenSample[2].x) * (DisplaySample[1].y - DisplaySample[2].y)) -
((DisplaySample[0].y - DisplaySample[2].y) * (ScreenSample[1].x - ScreenSample[2].x)) ;
matrix.Fn = (ScreenSample[2].x * DisplaySample[1].y - ScreenSample[1].x * DisplaySample[2].y) * ScreenSample[0].y +
(ScreenSample[0].x * DisplaySample[2].y - ScreenSample[2].x * DisplaySample[0].y) * ScreenSample[1].y +
(ScreenSample[1].x * DisplaySample[0].y - ScreenSample[0].x * DisplaySample[1].y) * ScreenSample[2].y ;
*/
/*NewPoint.x = ( (matrix.An * A ) +
(matrix.Bn * B ) +
matrix.Cn
) / matrix.Divider ;
NewPoint.y = ( (matrix.Dn * A) +
(matrix.En * B ) +
matrix.Fn
) / matrix.Divider ;*/
}
Заголовочный файл драйвера тачскрина
#ifndef _ADS7843_H
#define _ADS7843_H
#include "MCU/MCU_CORE.h"
#define EE_ADR_COEF 0x10
// SPI for TouchPanel (ADS7843)
#define TP_GPIO_Pin_SCK GPIO_Pin_5
#define TP_GPIO_Pin_MISO GPIO_Pin_6
#define TP_GPIO_Pin_MOSI GPIO_Pin_7
#define TP_GPIO_Pin_CS GPIO_Pin_4
#define TP_GPIO_Pin_IRQ GPIO_Pin_6
#define TP_PORT_SPI GPIOA
#define TP_PORT_CS GPIOA
#define TP_PORT_IRQ GPIOB
#define TP_Select() GPIO_ResetBits(TP_PORT_CS, TP_GPIO_Pin_CS)
#define TP_Deselect() GPIO_SetBits(TP_PORT_CS, TP_GPIO_Pin_CS)
//Touch panel(SPI, GPIO and EXTI) settings
void MCU_TP_GPIO_Config(void);
void MCU_TP_EXTI_Config(void);
void MCU_TP_SPI_Config(void);
void TP_WriteCommand(uint8_t cmd);
uint16_t TP_ReadData(void);
uint16_t TP_ReaAxis(uint32_t axis);
void TP_ReadCoordinates(uint32_t *X_Axis, uint32_t *Y_Axis);
void TP_Calibrate(void);
#endif /*__ADS7843_H*/
Программная реализация драйвера контроллера дисплея
#include "HX8347A.h"
void MCU_LCD_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable FSMC, GPIOD, GPIOE and AFIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
/* PD.00(D2), PD.01(D3), PD.04(RD), PD.5(WR), PD.7(CS), PD.8(D13), PD.9(D14), PD.10(D15), PD.11(RS) PD.14(D0) PD.15(D1) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 |
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10), PE.14(D11), PE.15(D12) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 |
GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
void MCU_LCD_FSMC_Config(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 10;//3
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 10;//9
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0;//1
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMTimingInitStructure.FSMC_AddressSetupTime = 3;
FSMC_NORSRAMTimingInitStructure.FSMC_AddressHoldTime = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_DataSetupTime = 3;//9
FSMC_NORSRAMTimingInitStructure.FSMC_BusTurnAroundDuration = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_CLKDivision = 0;//1
FSMC_NORSRAMTimingInitStructure.FSMC_DataLatency = 0;
FSMC_NORSRAMTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTimingInitStructure;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}
void LCD_Init(void)
{
LCD_WriteReg(0x0042,0x0008);
// VENDOR
LCD_WriteReg(0x0046,0x00A4);
LCD_WriteReg(0x0047,0x0053);
LCD_WriteReg(0x0048,0x0000);
LCD_WriteReg(0x0049,0x0044);
LCD_WriteReg(0x004a,0x0004);
LCD_WriteReg(0x004b,0x0067);
LCD_WriteReg(0x004c,0x0033);
LCD_WriteReg(0x004d,0x0077);
LCD_WriteReg(0x004e,0x0012);
LCD_WriteReg(0x004f,0x004C);
LCD_WriteReg(0x0050,0x0046);
LCD_WriteReg(0x0051,0x0044);
//240x320 window setting
LCD_WriteReg(0x0002,0x0000); // Column address start2
LCD_WriteReg(0x0003,0x0000); // Column address start1
LCD_WriteReg(0x0004,0x0000); // Column address end2
LCD_WriteReg(0x0005,0x00ef); // Column address end1
LCD_WriteReg(0x0006,0x0000); // Row address start2
LCD_WriteReg(0x0007,0x0000); // Row address start1
LCD_WriteReg(0x0008,0x0001); // Row address end2
LCD_WriteReg(0x0009,0x003f); // Row address end1
// Display Setting
LCD_WriteReg(0x0001,0x0006); // IDMON=0, INVON=1, NORON=1, PTLON=0
LCD_WriteReg(0x0016,0x0068); // MY=0, MX=0, MV=0, ML=1, BGR=0, TEON=0 0048
LCD_WriteReg(0x0023,0x0095); // N_DC=1001 0101
LCD_WriteReg(0x0024,0x0095); // PI_DC=1001 0101
LCD_WriteReg(0x0025,0x00FF); // I_DC=1111 1111
LCD_WriteReg(0x0027,0x0002); // N_BP=0000 0010
LCD_WriteReg(0x0028,0x0002); // N_FP=0000 0010
LCD_WriteReg(0x0029,0x0002); // PI_BP=0000 0010
LCD_WriteReg(0x002a,0x0002); // PI_FP=0000 0010
LCD_WriteReg(0x002C,0x0002); // I_BP=0000 0010
LCD_WriteReg(0x002d,0x0002); // I_FP=0000 0010
LCD_WriteReg(0x003a,0x0001); // N_RTN=0000, N_NW=001 0001
LCD_WriteReg(0x003b,0x0000); // P_RTN=0000, P_NW=001
LCD_WriteReg(0x003c,0x00f0); // I_RTN=1111, I_NW=000
LCD_WriteReg(0x003d,0x0000); // DIV=00
LCD_WriteReg(0x0035,0x0038); // EQS=38h
LCD_WriteReg(0x0036,0x0078); // EQP=78h
LCD_WriteReg(0x003E,0x0038); // SON=38h
LCD_WriteReg(0x0040,0x000F); // GDON=0Fh
LCD_WriteReg(0x0041,0x00F0); // GDOFF
LCD_WriteReg(0x0038,0x0000);
// Power Supply Setting
LCD_WriteReg(0x0019,0x0049); // CADJ=0100, CUADJ=100, OSD_EN=1 ,60Hz
LCD_WriteReg(0x0093,0x000F); // RADJ=1111, 100%
LCD_WriteReg(0x0020,0x0040); // BT=0100
LCD_WriteReg(0x001D,0x0007); // VC1=111 0007
LCD_WriteReg(0x001E,0x0000); // VC3=000
LCD_WriteReg(0x001F,0x0004); // VRH=0011
LCD_WriteReg(0x0020,0x0020);
LCD_WriteReg(0x001D,0x0003);
//VCOM SETTING
LCD_WriteReg(0x0044,0x004D); // VCM=101 0000 4D
LCD_WriteReg(0x0045,0x000E); // VDV=1 0001 0011
LCD_WriteReg(0x001C,0x0004); // AP=100
LCD_WriteReg(0x001B,0x0018); // GASENB=0, PON=0, DK=1, XDK=0, VLCD_TRI=0, STB=0
LCD_WriteReg(0x001B,0x0010); // GASENB=0, PON=1, DK=0, XDK=0, VLCD_TRI=0, STB=0
LCD_WriteReg(0x0043,0x0080); //set VCOMG=1
// Display ON Setting
LCD_WriteReg(0x0090,0x007F); // SAP=0111 1111
LCD_WriteReg(0x0026,0x0004); //GON=0, DTE=0, D=01
LCD_WriteReg(0x0026,0x0024); //GON=1, DTE=0, D=01
LCD_WriteReg(0x0026,0x002C); //GON=1, DTE=0, D=11
LCD_WriteReg(0x0026,0x003C); //GON=1, DTE=1, D=11
// INTERNAL REGISTER SETTING
LCD_WriteReg(0x0057,0x0002); // TEST_Mode=1: into TEST mode
LCD_WriteReg(0x0095,0x0001); // SET DISPLAY CLOCK AND PUMPING CLOCK TO SYNCHRONIZE
LCD_WriteReg(0x0057,0x0000); // TEST_Mode=0: exit TEST mode
}
void LCD_SetAddress(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend)
{
LCD_WriteReg(0x0002, Xstart>>8);
LCD_WriteReg(0x0003, Xstart);
LCD_WriteReg(0x0004, Xend>>8);
LCD_WriteReg(0x0005, Xend);
LCD_WriteReg(0x0006, Ystart>>8);
LCD_WriteReg(0x0007, Ystart);
LCD_WriteReg(0x0008, Yend>>8);
LCD_WriteReg(0x0009, Yend);
}
void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue)
{
LCD_REG = LCD_Reg; //Write 16-bit Index, then Write Reg
LCD_RAM = LCD_RegValue; //Write 16-bit Reg
}
uint16_t LCD_ReadReg(uint8_t LCD_Reg)
{
LCD_REG = LCD_Reg; //Write 16-bit Index (then Read Reg)
return LCD_RAM; //Read 16-bit Reg
}
void LCD_WriteRAM_Prepare(void)
{
LCD_REG = 0x0022;
}
void LCD_WriteRAM(uint16_t RGB_Code)
{
LCD_RAM = RGB_Code; //Write 16-bit GRAM Reg
}
uint16_t LCD_ReadRAM(void)
{
//Write 16-bit Index (then Read Reg)
LCD_REG = 0x0022; //Select GRAM Reg
return LCD_RAM; //Read 16-bit Reg
}
Заголовочный файл драйвера контроллера дисплея
#ifndef __HX8347A_H
#define __HX8347A_H
#include "MCU/MCU_CORE.h"
#define LCD_REG (*((volatile unsigned short *) 0x60000000)) /* RS = 0 */
#define LCD_RAM (*((volatile unsigned short *) 0x60020000)) /* RS = 1 */
//LCD(GPIO and FSMC) settings
void MCU_LCD_GPIO_Config(void);
void MCU_LCD_FSMC_Config(void);
//LCD main functions
void LCD_Init(void);
void LCD_SetAddress(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend);
void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue);
uint16_t LCD_ReadReg(uint8_t LCD_Reg);
void LCD_WriteRAM_Prepare(void);
void LCD_WriteRAM(uint16_t RGB_Code);
uint16_t LCD_ReadRAM(void);
#endif /*__HX8347A_H */
Программная реализация графических примитивов
#include "Primitives.h"
void LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint16_t Fill, uint16_t Color)
{
uint32_t i, j;
if ( (Xpos >= MAX_X) || (Ypos >= MAX_Y) )
{
return;
}
LCD_SetAddress(Xpos, Ypos, Xpos + Width - 1, Ypos + Height - 1);
LCD_WriteRAM_Prepare();
if (Fill == 1)
{
for(i = 0; i < Width; i++)
{
for(j = 0; j < Height; j++)
{
LCD_WriteRAM(Color);
}
}
}
else
{
LCD_DrawLine(Xpos, Ypos, Xpos + Width - 1, Ypos, Color);
LCD_DrawLine(Xpos + Width - 1, Ypos, Xpos + Width - 1, Ypos + Height - 1, Color);
LCD_DrawLine(Xpos + Width - 1, Ypos + Height - 1, Xpos, Ypos + Height - 1, Color);
LCD_DrawLine(Xpos, Ypos + Height - 1, Xpos, Ypos, Color);
}
}
void LCD_DrawPoint(uint16_t Xpos, uint16_t Ypos, uint16_t Color)
{
if ( (Xpos >= MAX_X) || (Ypos >= MAX_Y) )
{
return;
}
LCD_SetAddress(Xpos, Ypos, Xpos, Ypos);
LCD_WriteRAM_Prepare();
LCD_WriteRAM(Color);
}
void LCD_DrawLine(uint16_t Xpos1, uint16_t Ypos1, uint16_t Xpos2, uint16_t Ypos2, uint16_t Color)
{
uint32_t Xpos, Ypos, Add_X, Add_Y, d_X, d_Y;
int32_t P, i;
/* if (Xpos1 == Xpos2)
{
LCD_DrawRect(Xpos1, Ypos1, 1, Ypos2 - Ypos1, FILL, Color);
//return;
}
if (Ypos1 == Ypos2)
{
LCD_DrawRect(Xpos1, Ypos1, Xpos2 - Xpos1, 10, FILL, Color);
//return;
}*/
(Xpos1 >= Xpos2) ? (d_X = Xpos1 - Xpos2) : (d_X = Xpos2 - Xpos1);
(Ypos1 >= Ypos2) ? (d_Y = Ypos1 - Ypos2) : (d_Y = Ypos2 - Ypos1);
Xpos = Xpos1;
Ypos = Ypos1;
(Xpos1 > Xpos2) ? (Add_X = -1) : (Add_X = 1);
(Ypos1 > Ypos2) ? (Add_Y = -1) : (Add_Y = 1);
if(d_X >= d_Y)
{
P = 2 * d_Y - d_X;
for(i = 0; i <= d_X; ++i)
{
LCD_DrawPoint(Xpos, Ypos, Color);
if(P < 0)
{
P += 2 * d_Y;
Xpos += Add_X;
}
else
{
P += 2 * d_Y - 2 * d_X;
Xpos += Add_X;
Ypos += Add_Y;
}
}
}
else
{
P = 2 * d_X - d_Y;
for(i = 0; i <= d_Y; ++i)
{
LCD_DrawPoint(Xpos, Ypos, Color);
if(P < 0)
{
P += 2 * d_X;
Ypos += Add_Y;
}
else
{
P += 2 * d_X - 2 * d_Y;
Xpos += Add_X;
Ypos += Add_Y;
}
}
}
}
void LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius, uint16_t Fill, uint16_t Color)
{
int32_t a, b, P;
a = 0;
b = Radius;
P = 1 - Radius;
do
{
if(Fill == 1)
{
//Horisontal normal rendering
LCD_DrawRect(Xpos - a, Ypos + b, 2 * a, 1, FILL, Color);
LCD_DrawRect(Xpos - a, Ypos - b, 2 * a, 1, FILL, Color);
LCD_DrawRect(Xpos - b, Ypos + a, 2 * b, 1, FILL, Color);
LCD_DrawRect(Xpos - b, Ypos - a, 2 * b, 1, FILL, Color);
//Vertical normal rendering
LCD_DrawRect(Xpos + b, Ypos - a, 1, 2 * a, FILL, Color);
LCD_DrawRect(Xpos - b, Ypos - a, 1, 2 * a, FILL, Color);
LCD_DrawRect(Xpos + a, Ypos - b, 1, 2 * b, FILL, Color);
LCD_DrawRect(Xpos - a, Ypos - b, 1, 2 * b, FILL, Color);
}
else
{
LCD_DrawPoint(Xpos + a, Ypos + b, Color);
LCD_DrawPoint(Xpos + b, Ypos + a, Color);
LCD_DrawPoint(Xpos - a, Ypos + b, Color);
LCD_DrawPoint(Xpos - b, Ypos + a, Color);
LCD_DrawPoint(Xpos + b, Ypos - a, Color);
LCD_DrawPoint(Xpos + a, Ypos - b, Color);
LCD_DrawPoint(Xpos - a, Ypos - b, Color);
LCD_DrawPoint(Xpos - b, Ypos - a, Color);
}
if(P < 0)
{
P += 3 + 2 * a++;
}
else
{
P += 5 + 2 * (a++ - b--);
}
} while(a <= b);
}
void LCD_DrawChar(uint16_t Xpos, uint16_t Ypos, char Symbol, uint16_t SymbolColor, uint16_t BackgroundColor)
{
uint16_t i, j;
uint8_t buffer[16], tmp_char;
memcpy(buffer, AsciiLib[Symbol - 32] ,16);
for(i = 0; i < 16; i++)
{
tmp_char = buffer[i];
for(j = 0; j < 8; j++)
{
if( ( (tmp_char>>(7 - j) ) & 0x01 )== 0x01 )
{
LCD_DrawPoint(Xpos + j, Ypos + i, SymbolColor);
}
else
{
LCD_DrawPoint(Xpos + j, Ypos + i, BackgroundColor);
}
}
}
}
void LCD_DrawText(uint16_t Xpos, uint16_t Ypos, char *str, uint16_t SymbolColor, uint16_t BackgroundColor)
{
uint8_t TempChar;
do
{
TempChar = *str++;
LCD_DrawChar( Xpos, Ypos, TempChar, SymbolColor, BackgroundColor );
if( Xpos < MAX_X - 8 )
{
Xpos += 8;
}
else
{
if ( Ypos < MAX_Y - 16 )
{
Xpos = 0;
Ypos += 16;
}
else
{
Xpos = 0;
Ypos = 0;
}
}
}
while ( *str != 0 );
}
void LCD_DrawCross(uint16_t Xpos, uint16_t Ypos, uint16_t Color)
{
LCD_DrawLine(Xpos - 15, Ypos, Xpos - 2, Ypos, Color);
LCD_DrawLine(Xpos + 2, Ypos, Xpos + 15, Ypos, Color);
LCD_DrawLine(Xpos, Ypos - 15, Xpos, Ypos - 2, Color);
LCD_DrawLine(Xpos, Ypos + 2, Xpos, Ypos + 15, Color);
LCD_DrawLine(Xpos - 15, Ypos + 15, Xpos - 7, Ypos + 15, WHITE);
LCD_DrawLine(Xpos - 15, Ypos + 7, Xpos - 15, Ypos + 15, WHITE);
LCD_DrawLine(Xpos - 15, Ypos - 15, Xpos - 7, Ypos - 15, WHITE);
LCD_DrawLine(Xpos - 15, Ypos - 7, Xpos - 15, Ypos - 15, WHITE);
LCD_DrawLine(Xpos + 7, Ypos + 15, Xpos + 15, Ypos + 15, WHITE);
LCD_DrawLine(Xpos + 15, Ypos + 7, Xpos + 15, Ypos + 15, WHITE);
LCD_DrawLine(Xpos + 7, Ypos - 15, Xpos + 15, Ypos - 15, WHITE);
LCD_DrawLine(Xpos + 15, Ypos - 15, Xpos + 15, Ypos - 7, WHITE);
}
Заголовочный файл графических примитивов
#ifndef PRIMITIVES_H_
#define PRIMITIVES_H_
#include "GUI_CORE.h"
void LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height, uint16_t Fill, uint16_t Color);
void LCD_DrawPoint(uint16_t Xpos, uint16_t Ypos, uint16_t Color);
void LCD_DrawLine(uint16_t Xpos1, uint16_t Ypos1, uint16_t Xpos2, uint16_t Ypos2, uint16_t Color);
void LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius, uint16_t Fill, uint16_t Color);
void LCD_DrawChar(uint16_t Xpos, uint16_t Ypos, char Symbol, uint16_t SymbolColor, uint16_t BackgroundColor);
void LCD_DrawText(uint16_t Xpos, uint16_t Ypos, char *str, uint16_t SymbolColor, uint16_t BackgroundColor);
void LCD_DrawCross(uint16_t Xpos, uint16_t Ypos, uint16_t Color);
#endif /* PRIMITIVES_H_ */
Ф-Я НАСТРОЙКИ ИНТЕРФЕЙСА РАДИОМОДУЛЯ
oid MCU_USART2_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//USART2_TX -> PA2 , USART2_RX -> PA3
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
//USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
Ф-Я ПРИЕМА СООБЩЕНИЯ С РАДИОМОДУЛЯ
void USART2_IRQHandler (void)
{
#define READING_MESSAGE 0
#define WAITING_MESSAGE 1
volatile static char UART1_RxBuffer[MAX_MESSAGE_LENGTH];
volatile char RxSymbol;
volatile static uint32_t i, Counter, Status = WAITING_MESSAGE;
volatile char RecivedCheckSum, CalculatedCheckSum, CheckSumIndex = MAX_MESSAGE_LENGTH - 1;
if (USART2->SR & USART_SR_RXNE)
{
RxSymbol = USART2->DR;
switch(Status)
{
case WAITING_MESSAGE:
{
if (RxSymbol != '[')
{
//Ждём появления '['
}
else
{
Counter = 0;
Status = READING_MESSAGE;
}
return;
}
case READING_MESSAGE:
{
if (RxSymbol != ']') //Пришёл символ конца сообщения ']' ?
{
UART1_RxBuffer[Counter] = RxSymbol; //Нет. Записали пришедший символ в буфер
Counter++;
if (Counter > MAX_MESSAGE_LENGTH) //Символ конца сообщения потерялся. Выставляем флаг ошибки и ждём новое сообщение
{
X_BEE.CommunicationError++; //+ ошибка
Status = WAITING_MESSAGE;
}
}
else
{
//Конец строки обнаружен. Проверяем, что принятых байтов не меньше длины сообщения,
//контрольную сумму, выставляем флаг.
if (Counter < MAX_MESSAGE_LENGTH) //Символ конца пришёл раньше.
{
X_BEE.CommunicationError++; //+ ошибка
Status = WAITING_MESSAGE;
return;
}
RecivedCheckSum = UART1_RxBuffer[CheckSumIndex]; //Последний байт - контрольная сумма
for (i = 0, CalculatedCheckSum = 0; i < CheckSumIndex; i++)
{
CalculatedCheckSum ^= UART1_RxBuffer[i];
}
if (CalculatedCheckSum == RecivedCheckSum)
{
ReceivedMessage.Altitude = 10 * (UART1_RxBuffer[2] - '0') + (UART1_RxBuffer[3] - '0');
ReceivedMessage.Compass = 100 * (UART1_RxBuffer[8] - '0') + 10 * (UART1_RxBuffer[9] - '0') + (UART1_RxBuffer[10] - '0');
ReceivedMessage.Temperature = 10 * (UART1_RxBuffer[14] - '0') + (UART1_RxBuffer[15] - '0');
ReceivedMessage.Voltage = 100 * (UART1_RxBuffer[20] - '0') + 10 * (UART1_RxBuffer[21] - '0') + (UART1_RxBuffer[22] - '0');
X_BEE_Counter = 0;
X_BEE.CommunicationSuccess++; //+ удача
}
else
{
X_BEE.CommunicationError++; //+ ошибка
}
Status = WAITING_MESSAGE;
}
}
return;
}
}
}
