Аналоговые часы на STM32F4 (элипсом)

В продолжении предыдущего своего топика и для более рационального использования полезной площади LCD.






Отличия в функции отрисовки только в наличии 2-х радиусов.
Обычные часы.


void DrawAnalogClock (uint16_t CentrLCDX, uint16_t CentrLCDY, uint16_t ClockRadius,  RTC_TimeTypeDef RTC_TimeStr)
{
	double angle = 0.0;
	double Nx = 0.0;
	double Ny = 0.0;

	//LCD_DrawCircle((uint16_t) CentrLCDX, (uint16_t) CentrLCDY, 1);
	
	for (angle = 0; angle < 12; angle = angle + 1)
		{

			modf ((CentrLCDX + ClockRadius * cos(PiHourNumber*angle - PiHalf)), &Nx);
			modf ((CentrLCDY + ClockRadius * sin(PiHourNumber*angle - PiHalf)), &Ny);
			LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 3);

		}

	for (angle = 0; angle < 60; angle = angle + 1)
		{

			modf ((CentrLCDX + (ClockRadius - 23) * cos(PiMinuteNumber*angle - PiHalf)), &Nx);
			modf ((CentrLCDY + (ClockRadius - 23) * sin(PiMinuteNumber*angle - PiHalf)), &Ny);
			LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 1);

		}
		
	for (angle = 0; angle < 60; angle = angle + 1)
		{

			modf ((CentrLCDX + (ClockRadius - 45) * cos(PiSecondNumber*angle - PiHalf)), &Nx);
			modf ((CentrLCDY + (ClockRadius - 45) * sin(PiSecondNumber*angle - PiHalf)), &Ny);
			LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 0);

		}

		LCD_SetTextColor(LCD_COLOR_BLACK);
		modf ((CentrLCDX + (ClockRadius - 45) * cos(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadius - 45) * sin(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 5);			
		LCD_SetTextColor(LCD_COLOR_GREY);
		modf ((CentrLCDX + (ClockRadius - 45) * cos(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadius - 45) * sin(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Ny);
		LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 0);
		LCD_SetTextColor(LCD_COLOR_CYAN);
		modf ((CentrLCDX + (ClockRadius - 45) * cos(PiSecondNumber*RTC_TimeStr.RTC_Seconds - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadius - 45) * sin(PiSecondNumber*RTC_TimeStr.RTC_Seconds - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 3);
		
		LCD_SetTextColor(LCD_COLOR_BLACK);
		modf ((CentrLCDX + (ClockRadius - 23) * cos(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadius - 23) * sin(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 7);
		LCD_SetTextColor(LCD_COLOR_CYAN);
		modf ((CentrLCDX + (ClockRadius - 23) * cos(PiMinuteNumber*RTC_TimeStr.RTC_Minutes - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadius - 23) * sin(PiMinuteNumber*RTC_TimeStr.RTC_Minutes - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 5);
		LCD_SetTextColor(LCD_COLOR_GREY);
		modf ((CentrLCDX + (ClockRadius - 23) * cos(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadius - 23) * sin(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Ny);
		LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 1);
		
		LCD_SetTextColor(LCD_COLOR_BLACK);
		modf ((CentrLCDX + ClockRadius * cos(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + ClockRadius * sin(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2-1) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 9);
		LCD_SetTextColor(LCD_COLOR_CYAN);
		modf ((CentrLCDX + ClockRadius * cos(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2) - PiHalf)), &Nx);
		modf ((CentrLCDY + ClockRadius * sin(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 7);
		LCD_SetTextColor(LCD_COLOR_GREY);
		modf ((CentrLCDX + ClockRadius * cos(PiHourNumber*RTC_TimeStr.RTC_Hours - PiHalf)), &Nx);
		modf ((CentrLCDY + ClockRadius * sin(PiHourNumber*RTC_TimeStr.RTC_Hours - PiHalf)), &Ny);
		LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 3);
}



И отрисовка элипсоидных часов.


void DrawElipsAnalogClock (uint16_t CentrLCDX, uint16_t CentrLCDY, uint16_t ClockRadiusBig, uint16_t ClockRadiusSmall, RTC_TimeTypeDef RTC_TimeStr)
{
	double angle = 0.0;
	double Nx = 0.0;
	double Ny = 0.0;

	//LCD_DrawCircle((uint16_t) CentrLCDX, (uint16_t) CentrLCDY, 1);
	
	for (angle = 0; angle < 12; angle = angle + 1)
		{
		
			modf ((CentrLCDX + ClockRadiusBig * cos(PiHourNumber*angle)), &Nx);
			modf ((CentrLCDY + ClockRadiusSmall * sin(PiHourNumber*angle)), &Ny);
			LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 3);

		}
		
	for (angle = 0; angle < 60; angle = angle + 1)
		{

			modf ((CentrLCDX + (ClockRadiusBig-30) * cos(PiMinuteNumber*angle)), &Nx);
			modf ((CentrLCDY + (ClockRadiusSmall-30) * sin(PiMinuteNumber*angle)), &Ny);
			LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 1);

		}
		
	for (angle = 0; angle < 60; angle = angle + 1)
		{

			modf ((CentrLCDX + (ClockRadiusBig-60) * cos(PiSecondNumber*angle)), &Nx);
			modf ((CentrLCDY + (ClockRadiusSmall-60) * sin(PiSecondNumber*angle)), &Ny);
			LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 0);

		}
		
		LCD_SetTextColor(LCD_COLOR_BLACK);
		modf ((CentrLCDX + (ClockRadiusBig-60) * cos(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadiusSmall-60) * sin(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 5);	
		LCD_SetTextColor(LCD_COLOR_GREY);
		modf ((CentrLCDX + (ClockRadiusBig-60) * cos(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadiusSmall-60) * sin(PiSecondNumber*(RTC_TimeStr.RTC_Seconds-1) - PiHalf)), &Ny);
		LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 0);
		LCD_SetTextColor(LCD_COLOR_CYAN);
		modf ((CentrLCDX + (ClockRadiusBig-60) * cos(PiSecondNumber*RTC_TimeStr.RTC_Seconds - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadiusSmall-60) * sin(PiSecondNumber*RTC_TimeStr.RTC_Seconds - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 3);
		
		LCD_SetTextColor(LCD_COLOR_BLACK);
		modf ((CentrLCDX + (ClockRadiusBig-30) * cos(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadiusSmall-30) * sin(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 7);
		LCD_SetTextColor(LCD_COLOR_CYAN);
		modf ((CentrLCDX + (ClockRadiusBig-30) * cos(PiMinuteNumber*RTC_TimeStr.RTC_Minutes - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadiusSmall-30) * sin(PiMinuteNumber*RTC_TimeStr.RTC_Minutes - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 5);
		LCD_SetTextColor(LCD_COLOR_GREY);
		modf ((CentrLCDX + (ClockRadiusBig-30) * cos(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + (ClockRadiusSmall-30) * sin(PiMinuteNumber*(RTC_TimeStr.RTC_Minutes-1) - PiHalf)), &Ny);
		LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 1);
		
		LCD_SetTextColor(LCD_COLOR_BLACK);
		modf ((CentrLCDX + ClockRadiusBig * cos(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2-1) - PiHalf)), &Nx);
		modf ((CentrLCDY + ClockRadiusSmall * sin(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2-1) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 9);
		LCD_SetTextColor(LCD_COLOR_CYAN);
		modf ((CentrLCDX + ClockRadiusBig * cos(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2) - PiHalf)), &Nx);
		modf ((CentrLCDY + ClockRadiusSmall * sin(PiHourArrow*(RTC_TimeStr.RTC_Hours*30+RTC_TimeStr.RTC_Minutes/2) - PiHalf)), &Ny);
		LCD_DrawFullCircle((uint16_t) Nx, (uint16_t) Ny, 7);
		LCD_SetTextColor(LCD_COLOR_GREY);
		modf ((CentrLCDX + ClockRadiusBig * cos(PiHourNumber*RTC_TimeStr.RTC_Hours - PiHalf)), &Nx);
		modf ((CentrLCDY + ClockRadiusSmall * sin(PiHourNumber*RTC_TimeStr.RTC_Hours - PiHalf)), &Ny);
		LCD_DrawCircle((uint16_t) Nx, (uint16_t) Ny, 3);
	
}


Перед использованием, нужно определить константы.


#define Pi			3.14159265	//Pi
#define PiHalf			1.570796325	//Pi/2	
#define PiHourNumber		0.523598775	//Pi/6
#define PiMinuteNumber		0.104719755	//Pi/30
#define PiSecondNumber		0.104719755	//Pi/30
#define PiHourArrow		0.0174532925	//Pi/180


Прикрепленный код можно использовать на STM32F429I-DISCO без переделки, только поменять драйвера lcd и sdram на родные, из STM32F429I-Discovery_FW. Кнопкой USER часы будут менять свой вид.
  • -1
  • 22 сентября 2014, 21:40
  • lexanet
  • 1
Файлы в топике: Open4X9I-C.zip

Комментарии (9)

RSS свернуть / развернуть
Тупо такой дисплей использовать под часы. Да и у такого дисплея цветопередача вообще говнянская, и угол обзора никакой. Лучше уж на семисегментниках сделать. STM32F4 + огромный дисплей = из пушки по воробьям.
-1
Да и у такого дисплея цветопередача вообще говнянская, и угол обзора никакой
Для часов очень актуально, да.
Опять же, с тем, что это оверкилл — спорить не буду.
0
  • avatar
  • Vga
  • 23 сентября 2014, 14:21
Для часов — как раз актуально. Я себе часы на OLED собрал, очень удобно, видно отовсюду. А с таким дисплеем только гемор получится
+1
Картинку на TN видно с практически любого угла. У нее искажается цветопередача, но для часов это не игрет никакой роли. Тебя же интересует сколько времени, а не какого цвета стрелка.
0
  • avatar
  • Vga
  • 23 сентября 2014, 14:35
знаю я как там с углами обзора, нихрена там не видно. На STM32F429i-discovery дисплей такого же китайского качества, а чёрного цвета там вообще нет- там серый :)
+1
Сколько видел китайцев — различить картинку можно под любым углом. Конечно, цветопередача при этом может даже инвертироваться — но для часов это роли не играет.
0
  • avatar
  • Vga
  • 23 сентября 2014, 14:53
Часы на таком дисплее и таком камне могут использоваться в качестве заставки в «дежурном режиме». Висят на стеночке, показывают время. Нажали капу, табу или чтото случилось, переключились на отображение другой информации. Счас едет ко мне LCD 7 дюймов, будет так работать. Да и интересно было сделать. Формулу элипса искал в инете минут 20.
+2
ну если только так
0
Формулу элипса искал в инете минут 20.
Надо было икать формулу эллипса.
+2
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.