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