lcd.c
. s$ d9 `, W( G1 b/ |3 b- j1 c( _) ?! a2 i+ t+ ~6 ]
- void lcd_init()
4 x' Z( x* Y" T q0 L% l2 h - {7 X6 a5 E% ~* Y! m
- GPIO_InitTypeDef GPIO_InitStructure;
# C' d* v3 y5 g( P, ~; g+ o - SPI_InitTypeDef SPI_InitStructure;, d4 t( Q9 X! ]
3 L1 _9 d% \3 w0 c8 _, C |+ j- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE );//PORTA时钟使能
- n: y. t. ~7 a5 w% Q' m - RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );//SPI1时钟使能
" W8 n/ C, f; B# R) { - 1 k6 C4 d* ^' r' Q
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
- P y1 |- l% v - 0 w- B* P( A3 h$ d
- 7 r! _; E( t* c; l5 v; V3 B
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_15;
. k" ^1 z6 F0 ^" h/ h* l- J. q - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
* y2 e3 E u$ w' }# e. n9 J - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 6 n. u- B4 C+ m" w: ]7 @* p" E' ?
- GPIO_Init(GPIOA, &GPIO_InitStructure);/ v4 j. q+ U- u+ C2 S( F; v
- GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_8|GPIO_Pin_15);
3 O# `/ |( x- F5 m, u
* m, h# l- H9 l- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;2 U" H; K( I/ ]' }0 ?5 Z: ~
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
v5 B6 v Y, e) R) p - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 5 C: h) D" M- o; l( B/ S
- GPIO_Init(GPIOB, &GPIO_InitStructure);
/ h6 v4 {4 f- n. K' m1 d - GPIO_SetBits(GPIOB,GPIO_Pin_3); 8 y7 J* g6 n- ^$ [! {' b2 s
-
# d& E6 k+ C* U! L# K8 y* u! q/ v, z - 8 \1 Y0 A Z8 A# f# V1 V
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7;8 l- g, U' a9 G; \! r) n! X% w5 W
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 0 A' j2 ? H' I( f/ F
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;7 w& J. [7 h. A
- GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
$ R2 r2 m( u1 W1 \, Y( d9 `; O/ ]3 D6 r8 z
! u* O+ a2 `) p5 `( o4 m! `- GPIO_SetBits(GPIOA,GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7); //PB13/14/15上拉* [; b% S0 D9 x: I2 o, r/ D4 X
6 D- G: `4 B, \" P5 @# H( s- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工9 T% _/ x+ n2 p) x' g
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
3 ~! q, C9 h+ M8 a4 A6 q1 O2 P" y9 O - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构! {/ F$ _0 ?& b, `2 o8 t
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平
1 ^" v9 W* T6 e) q1 t8 Y6 z - SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
. T5 G& r. B) Z+ t3 u1 M - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制% d) l1 `! R3 i; z* K. R) K* _
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256
: w) `3 T& m% V! B& J - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始. o5 A y; ]% N R3 Y6 E
- SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式7 D+ G% `* {4 G
- SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器1 a1 b! Z: w4 o
- / U, n Y! K, ^/ l' l4 G
- SPI_Cmd(SPI1, ENABLE); //使能SPI外设
6 P5 }" S4 B/ A! ^ X# d& w - : K3 {$ ]/ b- z" w
- // lcd_read_write_byte(0xff);//启动传输 2 Q9 o$ c( z* E7 t/ M
-
* K" N2 G2 J7 i; g0 z2 H -
q0 g a8 a: f* D' H# l$ E - lcd_rst=1;
9 y7 X7 m, @ D% E6 D; ^4 T - delay_ms(120);# o: L! Z% {& X5 T) w, p
- lcd_rst=0;
* P+ g ^7 T& @1 o# g$ Z$ i! D - delay_ms(120);$ Z& E# V7 _2 S( L) o
- lcd_rst=1;
& ?) V: V% G' C5 _- o+ d - delay_ms(120);8 U' y9 O# J: v+ h
- /* Sleep Out */
R% M3 S) ]+ U* y! o } - lcd_write_cmd(0x11);" c: ^ U* H2 R2 P7 y
- /* wait for power stability */! [# O5 R5 U% b: K: u: O7 }, b/ B
- delay_ms(120);4 L$ d0 z7 r- B
- ; E8 B* D1 G. K7 P4 i
- lcd_write_cmd(0x36);
; h; F7 e; ~7 y6 l8 e - lcd_write_data(0x00);3 J4 x: g% a9 l5 d2 t% _4 _/ g
- lcd_write_cmd(0x3a);
: n1 R. M& C9 d7 ^. D1 A u - lcd_write_data(0x05);
* j P9 r! P8 R: l% ^) g/ O - //--------------------------------ST7789V Frame rate setting----------------------------------//! r' T2 K8 A( k6 R
- lcd_write_cmd(0xb2);
5 F& i7 x9 `% v/ |( L - lcd_write_data(0x0c);
, e% C! q( w+ @6 t9 V - lcd_write_data(0x0c);& N- ]# J- a7 E/ U# N
- lcd_write_data(0x00);, U% M% [7 [) x" i9 O3 ^" u8 R
- lcd_write_data(0x33);
! @4 T c% Q1 d8 k- m) I - lcd_write_data(0x33);
/ Y& [" q V- e; w: W d - lcd_write_cmd(0xb7);( l! L; F- m" ]
- lcd_write_data(0x35);
0 z% L. M7 o: e- o0 _" o% V - //---------------------------------ST7789V Power setting--------------------------------------//
1 U6 K% a; R- K I2 B: {' w - lcd_write_cmd(0xbb);
0 S4 t! a; ~8 s - lcd_write_data(0x1c);
W- ^* k' O( ]# S - lcd_write_cmd(0xc0);9 t3 S# b+ @1 V7 L7 r) J
- lcd_write_data(0x2c);: X# S) R8 J8 [% E. s# [* [
- lcd_write_cmd(0xc2);
7 U* C" t$ |4 {" [ A. b' k - lcd_write_data(0x01);
, L7 l, {& }/ F( F* s - lcd_write_cmd(0xc3);# o6 F9 Y$ k1 x b) e5 L; d
- lcd_write_data(0x0b);+ S) w; D9 y% Y: F' F6 n4 ^6 K' h
- lcd_write_cmd(0xc4);; t( d0 G4 Z. u9 d
- lcd_write_data(0x20);4 e( N9 V) e& G3 Q; Q! H; |/ V
- lcd_write_cmd(0xc6);' X! c- ]4 T2 x5 ^( N
- lcd_write_data(0x0f);2 s4 B9 \+ ]5 \! Q" b3 m
- lcd_write_cmd(0xd0);
0 s( [1 ]/ C/ p2 `$ g, R - lcd_write_data(0xa4);
+ ]+ N) u3 O6 ^4 L5 e - lcd_write_data(0xa1);& M$ k! @9 r8 f E! `6 M+ r% U" e
- //--------------------------------ST7789V gamma setting---------------------------------------//8 ? H- Y+ C: j2 b& U m5 l
- lcd_write_cmd(0xe0);: u) z: T. h R8 V
- lcd_write_data(0xd0);
' q, I# ]+ V6 s! T: h5 @ e0 p1 ~ - lcd_write_data(0x00);, ^7 A& Z; R }8 @6 W
- lcd_write_data(0x03); Q& o" w. ?- `5 f% k. F
- lcd_write_data(0x09);3 Q; B/ a6 A" w7 j. P
- lcd_write_data(0x13);+ i1 ]/ w3 Y6 X W
- lcd_write_data(0x1c);5 P3 w- |: y+ Y; l' N* ?* C) y
- lcd_write_data(0x3a);
* Q& ^5 ~/ F' @ - lcd_write_data(0x55);6 [4 j( K }2 y# Y
- lcd_write_data(0x48);
; M. a* N# S7 e6 e$ b - lcd_write_data(0x18);
$ a+ u% @6 X/ ?. \ - lcd_write_data(0x12);2 F# l: t" U- c S$ s" Q+ v0 w% T/ e
- lcd_write_data(0x0e);; }5 P# x1 Q) v- j* w$ v
- lcd_write_data(0x19);
+ w' ^% |/ z0 i0 K- r/ a - lcd_write_data(0x1e);
) S2 N' A' L# x: {) k4 f1 G - lcd_write_cmd(0xe1);
* l5 O! U1 m3 j8 l {* I( P - lcd_write_data(0xd0);
! k& S$ ~" J5 h7 w) p7 \2 H/ {% O - lcd_write_data(0x00);; O* B( t5 b' M+ T8 e, j/ d: L
- lcd_write_data(0x03);$ N7 p- x+ k5 e. x
- lcd_write_data(0x09);+ H; ?6 I' {7 |& c4 C
- lcd_write_data(0x05);
& A' I3 ?# E; l - lcd_write_data(0x25);
+ A+ s$ P0 W9 M4 ?6 O - lcd_write_data(0x3a);( C4 ]) E. F) J5 r
- lcd_write_data(0x55);
V, j+ a- z1 o9 X! Y% N - lcd_write_data(0x50);
$ {( q1 f) b0 s7 c' \ - lcd_write_data(0x3d);
( }! G; \7 D# h" m1 J, B/ z. Y - lcd_write_data(0x1c);- h: M4 e3 T( L+ X- m* B
- lcd_write_data(0x1d);
( v* Y, F- t# m* M! @- e/ g - lcd_write_data(0x1d);
& A" D( \: i( o4 E7 O6 n' @ - lcd_write_data(0x1e);5 T! a# P; `( k: q5 y/ ?, c
- lcd_write_cmd(0x29);0 q/ D9 Q+ O9 O1 N; \; U
- , m! T& P4 k0 B
- lcd_address_set(0, 0, LCD_Width - 1, LCD_Height - 1);9 P' {$ {0 `4 E+ t
- lcd_set_speed(SPI_BaudRatePrescaler_2);
& P! U X0 J$ G }: k' Q% s$ B - open_lcd(); + c9 \2 a, O1 w
- @8 y1 r( B( e
7 h: y( L, C! y V, L-
- ~* `5 N* T% \% W2 r. E: P, [ - }
3 L2 L* L [% `2 g
( s& k% ]3 f; {: |9 \- //SPI 速度设置函数* \5 c4 p/ }: f- e( `3 K
- //SpeedSet:
4 Y" y' p3 B; f5 @, w- W6 X - //SPI_BaudRatePrescaler_2 2分频 & p" k. d3 ^9 z' B5 E
- //SPI_BaudRatePrescaler_8 8分频
) S& R9 t; j0 N- x) c7 i - //SPI_BaudRatePrescaler_16 16分频
: X1 P+ n5 P8 ~& o( [/ `" ]6 j/ D - //SPI_BaudRatePrescaler_256 256分频 # i. ]6 Z9 x7 l% W
- $ n! b3 W$ V- U+ x! R$ N8 t7 B
- void lcd_set_speed(u8 SPI_BaudRatePrescaler)
' H" P$ Q. P+ J - {) B% M8 b" |1 Y, q7 X! n- A
- assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));3 y3 Z$ [# q# p! a3 \. I
- SPI1->CR1&=0XFFC7;
6 ?- ^7 X/ u8 ~, ]+ r: P g# a - SPI1->CR1|=SPI_BaudRatePrescaler; //设置SPI1速度 # T7 P3 K# F" G
- SPI_Cmd(SPI1,ENABLE);
7 p9 G5 ?6 i8 p, L
: P p& z/ |$ w0 o$ ]- }
5 ^* U: ?+ i* \$ C3 X6 _# z# R3 C - //SPIx 读写一个字节
8 N# T; m. N4 e+ ?3 I - //TxData:要写入的字节
! [# h0 b: l" u1 M: e$ h6 \ - //返回值:读取到的字节7 S" \/ i- q. r* y' R
- u8 lcd_read_write_byte(u8 TxData)
: Z, a! j, y" d( F) I% Q; } - { 7 \! u7 ^5 @% Z/ O2 T# L) l# Z
- u8 retry=0; % Y- Z( _4 B1 c9 ^0 I. o
- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
) C; }$ z% _2 l& X - {
" T( w. G% w( x; \ - retry++;5 n1 m: v0 Z* F# b2 O- D f+ Y
- if(retry>200)return 0;+ z. n S R( O. _0 G5 a$ |! A' ]
- }
' A) O4 e t C' y - SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据/ f8 z; p) `. C, a
- retry=0;' t. D) V& P* o9 H
2 {4 C- f' i1 N8 r3 w& C- while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位, }5 N: [, ?7 [( W( v5 n
- {
2 p: J c- `" l* ^, U* E - retry++;
+ i6 M9 I0 [9 U. ` - if(retry>200)return 0;% |, ]* Z. w# E; n: a
- }
% ^" E1 L% r$ G$ J; Y( u C1 g - return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
1 [3 e4 x! C' n. _$ b" ?$ t; H/ J - }9 O& I# Q/ d/ \! \1 v- V' k
- / F0 @( G$ A/ \' ` G+ N0 w
- /**; ?% I6 F J" |6 O1 G8 b K8 {/ E5 U
- * @brief 写命令到LCD
/ w$ i* M8 q b: S - *2 O' p" B! k, P9 y+ Y0 T6 l+ @
- * @param cmd 需要发送的命令
9 u& b( ?$ o' @3 @* ? - *+ D( M" y9 E1 T9 p
- * @return void
4 P- v2 P' N4 J, @1 Q - */# F4 y4 E) p- i, n* x+ Q( Q8 A$ i$ }
- void lcd_write_cmd(u8 cmd)/ H5 a- @3 c2 A# L w6 J# o2 Q7 w
- {
: ?' v# l% d, |! b/ o - lcd_dc=0;
4 @3 |! B! v }3 _/ ~, I0 X) w - lcd_cs=0;
s. o- Z6 Y2 V" @5 J: b1 O5 s7 B$ y
3 B9 ~4 P8 _8 m' N- lcd_read_write_byte(cmd);# h! U: A# T d! J2 R H" r5 g2 e
- lcd_cs=1;
, h3 ?: n/ |1 n- A1 @& a - }
) h6 o9 |4 R3 s2 e* \; d - /**
. w& |% J+ k. J0 _3 x( n, F - * @brief 写数据到LCD
! E4 ~4 h% t. X# s; j - *
1 [8 L; C9 J. g# R1 L3 k+ ?: S - * @param cmd 需要发送的数据2 n8 U j% J: O+ S+ t% t: H$ z
- *
! J& ]* I3 h) D - * @return void
4 ?( O+ w* X* l! i# } - */
( m7 M( C0 m! P - void lcd_write_data(u8 data)
( K6 V* Q9 S% H- { - {
6 |9 u8 ]1 L" b( @ - lcd_dc=1;
. `; w9 [; q8 z4 j2 L5 F4 I - lcd_cs=0;; y# i4 R6 `8 ^) b; y" a+ R( ?* x
- lcd_read_write_byte(data);
6 [: A( l' Z0 r Y- Q8 M - lcd_cs=1;
6 w* V% j: m( m; z - }
9 Q+ [( F1 s+ p: S - /**# C& w3 T8 o3 g4 i/ f
- * @brief 写半个字的数据到LCD
$ A4 q# h) ]" A6 ]$ [+ O$ [ - *; O ]& }, a! S9 C
- * @param cmd 需要发送的数据" s/ p6 S- L7 q- s
- *7 t1 Q7 h O, r
- * @return void, ^. E; T) {1 l( b, C
- */
* x3 h8 [- |' g - void lcd_write_halfword(const u16 da) W7 q$ d4 a7 s4 e
- {
/ V9 y# }% v% x$ D' H - u8 data[2] = {0},i=0;2 A8 ^6 s g2 m9 C( u) ]
; H. S i) A: z; |1 o1 \% N- data[0] = da >> 8;- j% ~* m9 v5 O5 ~4 H* p7 K7 {
- data[1] = da;
: u) |% _- L, _* n' |
% u" S# {# N) |; `4 j. V/ v- lcd_dc=1;7 Z; a& f# O6 c2 _
- lcd_cs=0;8 H) |/ y8 p7 j- E
- for(i=0;i<2;i++)+ j" Z. y, h. b; D
- {4 M; h# z9 F6 M% v7 M; e6 t
- lcd_read_write_byte(data<i>);
0 i9 S0 z. b2 a! B - }/ H5 T9 e6 O: e/ p' i) d/ X; v: i) |; g
- lcd_cs=1;$ l4 p6 @1 Q( H" W" k: o
-
! E/ X4 z; N7 I2 X4 L% U" i$ C$ L - }! ]' C$ f; e" ^6 G
0 v4 D% W1 q6 o7 A5 d {- /**0 N7 K* i; g& g
- * 设置数据写入LCD缓存区域
- _ O5 j" |& d4 j/ h - *8 y! w6 j7 g- Q
- * @param x1,y1 起点坐标
' Y+ p/ j X3 i$ I( r5 s - * @param x2,y2 终点坐标6 R2 r, A& n( a3 ]3 j
- *
& T/ J$ }( i0 S; d$ C3 Q$ q* Z7 c9 D' Z$ p - * @return void* K- N. N$ B3 L) A: [
- */3 h+ Y# T$ ]" K0 P9 a3 v+ J3 E
- void lcd_address_set(u16 x1, u16 y1, u16 x2, u16 y2)$ }/ S( L ?8 n7 @7 U, K# g
- {) d1 z: ~; c2 H* y0 z( R! Y: V
- lcd_write_cmd(0x2a);5 F! h/ s D6 i5 `3 F5 `* Y
- lcd_write_data(x1 >> 8);' W: k# J9 ?3 y& z" C
- lcd_write_data(x1);4 f7 c) c( J4 E
- lcd_write_data(x2 >> 8);% A5 A' E% ^0 O
- lcd_write_data(x2);' P0 Y/ ]1 E- G5 f% [
6 u9 o) j! y/ I- lcd_write_cmd(0x2b);% k: Q) U: R+ Z# \: ^8 H4 k# K
- lcd_write_data(y1 >> 8);( r% G9 n; d% t5 D' R
- lcd_write_data(y1);4 K* b1 ]+ ` e1 U
- lcd_write_data(y2 >> 8);. V7 X& r' A4 y J
- lcd_write_data(y2);. {$ r" Y: K: L, v$ I: g
- " l2 j X& L/ N6 M% w1 G
- lcd_write_cmd(0x2C);
; b9 g# V, }1 O' N/ p, Q - }
; g# M$ I& A) V/ B" q9 E - 5 ]& p+ V) o3 M9 }2 f. }* e( Z2 K
- /**' s0 D* x6 N' Q
- * 以一种颜色清空LCD屏
% e/ _" f* K3 Q# X5 b' e! ]% { - *% P }, }6 p5 h( w, S
- * @param color 清屏颜色( O& p) d4 }: B. Q
- *. x7 L z H' V4 S
- * @return void
! C, U/ r2 x" ]9 H/ a Z1 t - */
# ?, h: Q. V5 j- A9 N+ E - void lcd_clear(u16 color)
' C, C) U- |( R8 |: S - {
' Q( i- a; {0 k/ u6 w7 @ - unsigned int i;. v: m4 _/ D, _
- u8 data[2] = {0};. O- q! @) n9 J# W, l$ ]% K
- 5 [5 ]! b. m3 N+ _' a( m
- data[0] = color >> 8;
) I+ U8 \& L; P - data[1] = color;1 U" Z$ O: w' c" o
) B3 w1 D5 V$ i$ P$ q6 T- lcd_address_set(0, 0, LCD_Width - 1, LCD_Height - 1);
' F& W5 Q6 ~3 C1 R* l) c) T, x; X2 ^ -
) L: i/ f4 M4 F$ T' O - lcd_dc=1;) g+ o# T; `' i/ L7 t5 [. G; ?
- lcd_cs=0;
) W6 _' u* i& Y - for(i = 0; i < (LCD_Width*LCD_Height); i++)
, x+ P/ w3 G0 k6 J* {- F! E - {
; d! |' x- ]6 C! P3 g4 s( c. n# z5 F7 a - lcd_read_write_byte(data[0]);! r- r% P3 ~6 A: Q2 i/ Q/ q+ d
- lcd_read_write_byte(data[1]);* v! M1 _2 }! R7 d
- }" g4 N2 ^8 v: w
- lcd_cs=0;/ Z* B4 D' @& c& D0 f3 P
- }( D$ S) ~. l( M, P2 ?) D' P
- : j; t1 B0 r: b! J' h
- /**
1 Y* `$ u2 [, C- c% \6 Y - * 画点函数
% g" a- b* P5 Z/ X! I - *7 f V G, L" P `4 v
- * @param x,y 画点坐标& o7 l5 g1 c8 E0 L2 t, h" e W' C1 x
- *
] J2 e# a. ] o - * @return void
8 H5 Z# k* h2 o* a) T6 u; Q" k9 E) } - */7 s2 ^2 ^& f: w" G+ B
- void lcd_draw_point(u16 x, u16 y,u16 pointColor)5 ~* C6 ^0 ?; B9 h5 D/ F
- {( f% M1 \" l B+ M3 l
- lcd_address_set(x, y, x, y);
& [' Q7 r0 J" g' O5 b - lcd_write_halfword(pointColor);$ c# w Y& j/ R" f" i* T X( g
- }
% ~" b8 f; f$ d2 l" D6 g
- c; j+ Z# Q0 W1 n- /**: G$ q2 g" |( F' f2 E& h' b% L# d
- * @brief 画一个圆
$ \; H2 {. h6 w2 ~: r2 N- P4 v- |! f - *! F1 F$ a' i0 Y
- * @param x0,y0 圆心坐标
: M, f6 O' E& n# p0 ^" n* a - * @param r 圆半径
2 |; X' v8 H; ?: |) N! l( c - *! ]$ Q% j: z, u( n- u" @8 e
- * @return void
) D4 E4 o% b4 o - */: a; s7 b9 |% K2 }, X
- void lcd_draw_circle(u16 x0, u16 y0, u8 r,u16 pointColor)
' S7 ?, Z5 @$ f- i! c! b6 c - {/ `5 p" N* A; o9 @( B
- int a, b;; r% Q8 e' m; v" f: t# t
- int di;& |$ {2 s& Y) ^! b3 f6 Z& V6 Y
- a = 0;/ F, Q0 V, a9 K' r
- b = r;
% B Z' u9 ^3 h; c# q9 A - di = 3 - (r << 1);
7 ^ n" ]0 s$ Q4 \# u5 I2 g, L - ( {" o6 x" F+ L7 ?7 O( V+ a
- while(a <= b)0 `. w9 `6 g5 ~ }0 T
- {+ C8 p$ k$ ?$ A8 v9 M) o
- lcd_draw_point(x0 - b, y0 - a,pointColor);
* _$ t. M- f' F+ |/ w - lcd_draw_point(x0 + b, y0 - a,pointColor);" _& H! h# x) _+ k! O
- lcd_draw_point(x0 - a, y0 + b,pointColor);
* N# o" [/ k- j5 D& I% H8 _( K1 o - lcd_draw_point(x0 - b, y0 - a,pointColor);! l/ {1 _! h5 e" v. ]( E I6 }- R
- lcd_draw_point(x0 - a, y0 - b,pointColor);; o2 B5 I8 t- l2 x7 X7 o1 }
- lcd_draw_point(x0 + b, y0 + a,pointColor);8 S9 f' I: ^; @7 P( X1 s- Z
- lcd_draw_point(x0 + a, y0 - b,pointColor);
' L' ?0 c/ W0 b# t8 ]+ P$ q2 n - lcd_draw_point(x0 + a, y0 + b,pointColor);5 d' D, s8 W2 e" x( x2 h- a5 j
- lcd_draw_point(x0 - b, y0 + a,pointColor);8 M9 u3 p) h' U& a/ G/ I
- a++;0 F5 J+ M9 U5 I
' @3 k* m- @6 Y' P+ m E- if(di < 0)di += 4 * a + 6;
6 Y1 C' [" ^2 p: T/ d; f6 D' ~ - else6 _1 P( ~. i" `2 f
- {
+ j. s; j! D$ }1 T/ e w+ h4 i - di += 10 + 4 * (a - b);8 U# a( f `* l. X
- b--;+ B7 s3 \. O! u# Q9 s
- }
7 Q% x+ T- ]; [' B# q9 m - ! {8 M0 Q, V# J+ Z, V! r& ?
- lcd_draw_point(x0 + a, y0 + b,pointColor);
- N* ^3 `. E8 Y! L. s - }
( \- ~$ i- t% O0 K4 a2 K W - }% g0 i# A9 G% w1 A
' x* ^/ \. }! o4 b6 P" W: N1 Y: p( \- /**
; t4 }% F: l$ j' y; J9 T - * @brief 显示一个ASCII码字符
: N2 z7 K( z' | - *4 o9 r: G4 T! [
- * @param x,y 显示起始坐标 O. m) M; ] ?1 G5 e7 {7 Y$ {
- * @param chr 需要显示的字符( Q$ J) W1 a5 v" k5 P6 s2 X
- * @param size 字体大小(支持16/24/32号字体)
7 T: w+ `3 I! S; t+ b. g - *
* z6 v/ p' i% l2 }3 I/ Y, A - * @return void
9 c0 m6 y$ F& S3 q4 K: R - */
2 }# T& R" ~2 o! Q8 o7 Q - void lcd_show_char(u16 x, u16 y, char chr, u8 size,u16 pointColor,u16 backColor)8 e$ `# _$ X0 R n
- {
2 p/ S) ?# U$ W" _" T - u8 temp, t1, t;2 K- X$ Z4 I. p; Q: Z9 F
- u8 csize; //得到字体一个字符对应点阵集所占的字节数
/ E9 T, `: R+ a' X" B L. k; F2 o - u16 colortemp;
, C/ V+ F: S& A$ a: S - u8 sta;6 p& j- v# i* u/ J5 l0 l0 _ }
( m9 Z/ p! l% a" J) }- chr = chr - ' '; //得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)
9 Z2 P) T$ F- O5 S2 M0 |# c: v* l
~# h: n8 e# Y/ N, E7 I6 D( M- if((x > (LCD_Width - size / 2)) || (y > (LCD_Height - size))) return;0 Q9 B1 Q$ T& f7 q$ Z/ K8 p
2 k8 |7 Q% o& |/ T( j0 K5 x) N2 Q& T- lcd_address_set(x, y, x + size / 2 - 1, y + size - 1);//(x,y,x+8-1,y+16-1)
/ a. F' K' i" H5 U8 u
2 U: Y* o/ F. u. X) I1 i- if((size == 16) || (size == 32) ) //16和32号字体+ w# S+ X( B4 `1 i
- {' l8 L& ]& l8 Q2 M! n- w
- csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
5 c, m) g9 \9 n( F - , J1 W8 B1 G* A& } ^3 @
- for(t = 0; t < csize; t++)
" d1 f3 I, s( p& U) D# Y - {
. m- A8 [7 e+ e! e+ a1 [- v, ] - if(size == 16)temp = asc2_1608[chr][t]; //调用1608字体
1 X5 H0 d; ~4 O8 ^! t( y - else if(size == 32)temp = asc2_3216[chr][t]; //调用3216字体
2 Y. \: F5 g5 Y7 V - else return; //没有的字库& F, u: |9 K$ `! ~
- ( o. @) h: b: n! A1 Q
- for(t1 = 0; t1 < 8; t1++)
; J/ `2 O' V8 l9 Q# w - {
4 }3 g# w" B; {& g7 O/ w5 D6 m - if(temp & 0x80) colortemp = pointColor;
3 E" Q9 Z9 f; a- r5 R; q8 C- b - else colortemp = backColor;
$ q5 p9 a! P9 K% K- q. h
0 h2 U$ H9 W& B2 J+ n- N. c+ \9 u/ _3 S- lcd_write_halfword(colortemp);
2 R, A! H9 w3 a: w2 x, n G - temp <<= 1;
2 M% w: D _( @2 ? - }
2 l! n* c0 h& n- o# Q8 m - }
1 ^6 l1 M( m: n7 _/ c% R0 _6 B [ - }& X) s$ ?: H) a7 a, H$ i& ^6 d
- / R- V) U$ ^8 f( P! W' \
- else if (size == 12) //12号字体 i, E* D, ^5 }: G/ V8 l' v- P
- {- `! c' V/ n1 u, o. O6 r2 A
- csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
, ~1 \. M# p6 R# ^$ M) Q6 P# A
; t8 ~6 \4 n2 @0 u( E. [- for(t = 0; t < csize; t++)6 I1 |8 G5 F( D# r/ @# }# @
- {
4 O: _& O6 `( [5 q- r* o' D - temp = asc2_1206[chr][t];
" U- D2 R& p' g( s/ h
i- _4 } S" d& F$ n- for(t1 = 0; t1 < 6; t1++)* I. h' S2 L* f7 p$ R5 p I
- {, X% k( n8 l+ V; a% P9 H
- if(temp & 0x80) colortemp = pointColor;
# E6 W% K H+ N4 Q3 a( Y2 b0 D" W - else colortemp = backColor;
! ?' Z% O; j6 f, B y
% ?5 W- T# h7 L# w* y- lcd_write_halfword(colortemp);/ q' g; }# r7 ^8 y" u) N0 W' V
- temp <<= 1;2 l- e4 ~/ W1 |# i. \ u
- }) A, p6 z4 ~$ o8 ?9 z9 r) S
- } N0 R" n! N) i- C3 Z2 F7 W
- }$ ^1 W0 V Y+ U% I
-
* s. g3 y: _: j - else if(size == 24) //24号字体9 d* L9 b8 c' g' U3 x
- {
8 F/ Z8 }$ F+ s7 y7 w* U3 `! T - csize = (size * 16) / 8;/ t6 J6 J6 C7 p5 I0 T p8 S
9 w" X4 a( O( m+ I- for(t = 0; t < csize; t++)
0 ]/ y* L5 [+ Z* c; _ - {
3 \' r0 h0 x7 m3 _; D$ I1 {+ d - temp = asc2_2412[chr][t];
; i5 b& S' p( Y8 p; Z! m - 2 o9 Z2 B8 u* u+ y r
- if(t % 2 == 0)sta = 8;
) N& M/ {* @7 W/ ~: k. f - else sta = 4;
) j! |) J3 b% y" f# f
0 ]2 T: n. `# F# p: x& D- for(t1 = 0; t1 < sta; t1++)
( r) z3 w# I1 [& s - {: l' L5 }3 w s2 |, U
- if(temp & 0x80) colortemp = pointColor;
( d1 _7 p- F% q0 l, I6 D5 Y - else colortemp = backColor;
( Z1 B; V$ D3 i - " o+ }) c9 J* L/ H( g
- lcd_write_halfword(colortemp);: m4 M( }% v0 x8 n8 W0 n
- temp <<= 1;
t, ]) l) o' m5 C" _, F - }
2 |. r$ \8 L# m" A; ^ - }& O2 R5 k0 N( L# p
- }/ T' O; D* o( {! f5 F( V7 \5 a
- }' `/ m# ^6 e: k8 N5 T9 ?# ]' {% z
- 0 c" e9 w9 b: r4 i/ n8 @
- 8 v1 @+ H0 ~ ^ e6 q) t
- /**( Z: Q# z' H0 K5 n# `5 c
- * @brief 显示字符串* c0 L6 ^" F' g1 k0 i) y; U) @
- *; ~5 e; M( O6 T. I& }
- * @param x,y 起点坐标
! z: @ E! |" z9 [% m# @- d% C - * @param width 字符显示区域宽度
* L, p1 m. i+ G) q- U4 V1 V - * @param height 字符显示区域高度: w7 i1 F: O: p9 |$ Q( I
- * @param size 字体大小
( E. A X$ W. }4 _/ R/ y - * @param p 字符串起始地址
u% Q* r+ X+ A4 r# I& B - *
8 Y" {% \1 r: F+ F8 ]" @ - * @return void
! u# f% b/ H4 K) x3 c' c; P - */
7 z. e2 C2 Z+ m2 K9 N" c - void lcd_show_string(u16 x, u16 y, u16 width, u16 height, u8 size, char *p,u16 pointColor,u16 backColor)( ~/ x( b J( d0 Y. z
- {
# `7 J$ F% x- J - u8 x0 = x;
1 H; w& X/ p3 @* ^0 e - width += x;
$ q3 `$ v) u6 F& C - height += y;3 e# ~$ u" h) x% c8 b% O
/ G; a" ~6 Y, v1 y( C- while((*p <= '~') && (*p >= ' ')) //判断是不是非法字符!9 M; U5 P2 @' E$ M6 D
- {
: e9 T! |5 Q7 ^. T d - if(x >= width)$ y2 B) F3 b7 W; I1 D: U- \
- {
( a# w' Q! T+ c - x = x0;- j) j$ W7 V3 b, C. |
- y += size;
( p) [ J" _8 L( Z* i$ e4 K - }% A$ N+ @4 E% [
- # s6 F* A$ V" ~. y# e
- if(y >= height)break; //退出
/ w7 e' W t; l4 t2 p
d4 ?' M3 z, L7 R$ L$ O$ I- lcd_show_char(x, y, *p, size,pointColor,backColor);
9 I! Z$ k0 H( V- `2 W- O - x += size / 2;! N$ }2 P( G* R B4 c
- p++;. G, u5 O' `$ v, _. o
- }7 r+ P! R7 W' K. x% I* E
- }
& l( ~) k8 T& [8 m% L, l; ]
( k3 E# S5 f7 f- /**
% }3 {! ~# w) p8 f$ D! U! h0 m2 m; H - * @brief 显示图片
3 C2 w8 L0 M2 Z. U9 H* c: h - *
/ X4 m: V5 p( A- b - * @remark Image2Lcd取模方式: C语言数据/水平扫描/16位真彩色(RGB565)/高位在前 其他的不要选
" L5 y/ e/ M+ h - *7 U1 X, f; q' B/ R6 l( R2 o
- * @param x,y 起点坐标
% Y4 W2 F5 `, B( i& F9 ? - * @param width 图片宽度* v4 {! ~) Q. B. ]9 y1 Z" s; ^. v
- * @param height 图片高度: [3 s" X8 B( x$ {" l" F ]
- * @param p 图片缓存数据起始地址( W: ?! s0 G5 o: o( e
- * n: F, r- M" |( Z% v% D: l, r
- * @return void
: D% W1 r8 L: C - */+ o6 O) t0 K5 F$ v2 } W+ A) m% W
- void lcd_show_image(u16 x, u16 y, u16 width, u16 height, const u8 *p)$ l( c9 I! F) T8 O
- {
( }9 Q. k, Y' S, g3 e# s8 |+ p - u16 i;
9 \# F2 [0 J9 i9 f) P - if(x + width > LCD_Width || y + height > LCD_Height)3 \ T, j7 ]2 K$ Z7 G" Y
- {
7 {; {0 N1 I/ {2 s: ~8 `) m - return;
8 z# [' O6 L6 f - }1 t2 x7 h# a# a% d4 a! P
, }* \0 U, p4 I/ a- lcd_address_set(x, y, x + width - 1, y + height - 1);
! N+ ]7 C3 k. x p1 [2 Y( h
& I/ Y) H, L( |6 ~& [" |: n- lcd_dc=1;
" J) y N1 b) S - 4 H) \: n/ q& }4 ^6 x1 b. A, _
- for(i=0;i<width * height * 2;i++)& w+ q; w& X' W4 W) d7 M
- {
* K) L$ v) O* D% B1 M% _ - lcd_read_write_byte(p<i>);
/ ?; ?& s( C) d" m) f: T - }$ U" g% d6 \" \$ i
- }5 C" s* ?6 Y4 l% Y% g' O
- </i></i>
复制代码 , B3 `9 }: q _& W# a+ i
lcd.h9 o4 @& w# Q0 x, t
! J2 a2 y9 H" X, n h1 U3 v; o' K/ ~6 C
- #define lcd_cs PAout(4) ' Z4 W' `+ I( q
- #define lcd_dc PAout(8) ) I# w/ x4 ?( [. H& E0 ~
- #define lcd_rst PAout(15) - g! I) S% j! k. A
- #define lcd_background PBout(3)
' P" m+ i- s1 C9 h5 [3 y+ C) Y
+ A# T# \3 F% H" j/ W( L- . O2 G: x" M. ]" V: h& Z3 u! \7 s/ H
- #define open_lcd() lcd_background=1- y# L7 o5 z" p
- #define close_lcd() lcd_background=0' n& m6 L$ @' d8 B
: r% E! H3 `" {4 Z7 J
3 r4 F/ x8 g, l& F$ V5 u$ I- //LCD的宽和高定义
7 u" u! ~" r9 x& Z9 h - #define LCD_Width 240
5 m% D* h/ `+ u& k+ h - #define LCD_Height 320
5 V* h- O0 ^ R: w - ) h$ E" V7 m6 D v; w
- //画笔颜色
$ I8 Q9 S' Z: o) t W0 e - #define WHITE 0xFFFF
8 ?1 j4 e0 u) r( T1 V1 ? - #define BLACK 0x0000
6 D9 d; I* M! s7 t - #define BLUE 0x001F
! l' [% h9 o& K: T - #define BRED 0XF81F+ k3 @4 [) p. ?, @
- #define GRED 0XFFE09 Q1 G+ F& ^% U
- #define GBLUE 0X07FF! ?+ o$ \! ], P" _. ]
- #define RED 0xF800* o; ]: R* V# j+ H: a }! b6 n
- #define MAGENTA 0xF81F, c* _* L$ H4 l' y6 T6 x( x) E
- #define GREEN 0x07E00 ]4 I! s, d# F* p% s
- #define CYAN 0x7FFF
7 H5 B: I' f" E) I/ P7 C# _ [ - #define YELLOW 0xFFE02 C( p; K h M
- #define BROWN 0XBC40 //棕色
- ^8 E' G7 i! @7 W0 } - #define BRRED 0XFC07 //棕红色
% {( _9 T: @; K- T* ~8 R - #define GRAY 0X8430 //灰色2 W) O1 ? \' J% r! T, y- t
- //GUI颜色
$ K6 Y& ?& |0 M - 3 T. x s0 U. i" `' F' C8 G* ]- B
- #define DARKBLUE 0X01CF //深蓝色
3 d8 C* J" \- ]$ K - #define LIGHTBLUE 0X7D7C //浅蓝色
/ V3 v2 ~! T) R. ]' G3 g - #define GRAYBLUE 0X5458 //灰蓝色
: b( Y7 P' d. c- b, u- a% _ - //以上三色为PANEL的颜色 4 a! \! U. X p1 l( b& K
- 2 R9 y }! L9 E! o
- #define LIGHTGREEN 0X841F //浅绿色) i+ V4 h2 d% }) ~4 n
- //#define LIGHTGRAY 0XEF5B //浅灰色(PANNEL)
, [& u- v2 t5 @( E - #define LGRAY 0XC618 //浅灰色(PANNEL),窗体背景色
- j: _* v* C+ D
3 h( Z! G9 E9 {6 f$ x- #define LGRAYBLUE 0XA651 //浅灰蓝色(中间层颜色)
/ }( b' r1 J0 z, E! n: S- G - #define LBBLUE 0X2B12 //浅棕蓝色(选择条目的反色)2 ?" g" k [: { e2 N1 H: M7 d( I8 B
. g$ Z0 f0 [% H* [1 I6 A1 e- , S- k4 o5 M$ [! A
- K# B4 A& I" b
- void lcd_init(void);
1 R# N- Y C+ X' p2 q* Q - void lcd_set_speed(u8 SPI_BaudRatePrescaler);* Z0 A, {9 ]8 `7 U
- u8 lcd_read_write_byte(u8 TxData);
+ k `7 Q6 A% u0 z7 W - void lcd_clear(u16 color);
: U+ T5 F7 |4 N8 N" } - u16 lcd_read_id(void);
+ Z" C, v; ~, M/ f# |; q - void lcd_draw_point(u16 x, u16 y,u16 pointColor);
) @# I* f. ?8 ^: m - void lcd_show_image(u16 x, u16 y, u16 width, u16 height, const u8 *p);
- |& f5 R2 a. e9 \0 C - void lcd_show_string(u16 x, u16 y, u16 width, u16 height, u8 size, char *p,u16 pointColor,u16 backColor);9 l+ Y. q8 f$ s0 g; W; ~# Z" c
- void lcd_show_char(u16 x, u16 y, char chr, u8 size,u16 pointColor,u16 backColor);! C6 ?& ]' {9 K* @; b
- void lcd_draw_circle(u16 x0, u16 y0, u8 r,u16 pointColor);6 D/ [' }; S' e7 x: E/ b" G- k
- void lcd_address_set(u16 x1, u16 y1, u16 x2, u16 y2);1 N2 t+ h# X1 U' A" \/ A
- void lcd_write_data(u8 data);9 r/ t. f) s$ r. Z$ `: J) r
- void lcd_write_cmd(u8 cmd);
6 A. x. c% k% q) J4 |' O. F1 l - ( i# h. w+ B. h
8 [4 h+ E g5 c
复制代码
e% a6 ]& M4 d* { |