STM8S001J3 由于 VCAP 的需要因此少了一支 I/O 引脚,跟另外 2 颗 8 引脚的 STM8 比较起来少了 PB7,而这一支引脚的复用功能是 SPI 的 MISO,因此对于 STM8S001J3 来说 SPI 是没有 MISO 引脚的。
- H$ o. J9 v. W% t G5 f7 w
8 U# u: t3 [1 s) T8 D# \
) X+ P. y/ C) B# o- v+ X: n
3 F; S0 N6 @' a- J9 m, N6 J g; w
SPI 的 CPOL 与 CPHA 设定决定了四种时序关系:* G6 ^: ^: r6 ?# p! R7 P
1 ^4 e: s5 |: r) g9 G* BCPOL CLOCK POLARITY 时钟极性4 j4 ]) u8 S# B% Q1 z; F3 v9 p j- @& g
0 SCK空闲状态保持低电位
: W1 O& k" D6 S5 a' d. |2 [9 @ 1 SCK空闲状态保持高电位0 F- q3 E; f% V
CPHA CLOCK PHASE 时钟相位) ]! B+ q/ k6 c- f2 A1 K
0 SCK时钟的第一个边缘进行数据采集
, ?2 f8 s8 t4 q# u3 } 1 SCK时钟的第二个边缘进行数据采集
, v# w6 x5 S& g) @: q0 E. f* k5 V
, [' b3 }1 @' _% n3 v- S$ R; Z+ x
0 S, |1 e. ^( R1 I/ ?
7 A9 B; P9 _3 {0 Y/ R+ B4 |* H- n
一般比较常用的似乎是 CPOL = 0 , CPHPA = 0,比如说外接 74HC595 这类的 8 位串行入并行出的移位寄存器就需要做这样的设定,也就是在时钟上升缘时将数据移入寄存器内。
3 }& j6 V. n o! v) @) h& y0 t" K' w6 d4 B" n! l+ t t
4 }% l, \. ?; d" e+ J$ a
' D- u3 O8 p. k由于后面我打算连接 MAX7219 显示模块,因此先实现一个 SPI 的测试程序来熟悉一下功能,我使用逻辑分析仪采集数据的输出,程序中让 STM8S001J3 由 SPI 引脚输出 0x01、0x02、0x04、0x08、0x10、0x20、0x40、0x80 数据,NSS 引脚由程序控制输出。测试程序中有一个需要注意的地方,由于 MOSI 这支引脚也在 pin8 与烧录使用的 SWIM 同一支脚,因此程序的一开始需要先加上一个 5 秒的延时代码。
, N- Z3 O7 H& W% R. R- [6 d2 c9 v% `. _6 Y9 }4 k; g; m
SPI 初始化:
. I/ f! V6 }& h* y' E* o- SPI_Init(SPI_FIRSTBIT_MSB, // 高位在前( G |, a# I, ?7 }6 |1 Y g
- SPI_BAUDRATEPRESCALER_2, // 传输速率为主时钟 1/2. \2 ~: A# D) l' P7 k2 K
- SPI_MODE_MASTER, // 主机模式
/ d; }3 D6 z. L+ t% k& U - SPI_CLOCKPOLARITY_LOW, // CPOL = 0/ |# a- D9 ~) \# S6 U
- SPI_CLOCKPHASE_1EDGE, // CPHA = 0
. d. R" l0 B( g7 `% @# g: ?5 _7 f - SPI_DATADIRECTION_2LINES_FULLDUPLEX, // 全双工模式
+ |& Z/ m5 ]0 c8 q% }0 b - SPI_NSS_SOFT, // 软件管理 NSS
, x7 C5 ]) q2 R! G- w, o( M - 0x07); // CRC 校验
复制代码 * h) Y8 g8 W8 T, X+ I
' N6 M* X& j# V$ b. e, |# L
逻辑分析仪数据采集:
) K6 }) h; M9 |* q c" O1 O/ z7 \
1 o, j3 p2 n$ I+ `$ o- w- @- v
& z( _, t/ J$ A# t0 |
4 x, {& W! D9 N5 k( f! W在先前的实验没有留意 STM8S001J3 上电后的系统时钟缺省设定是多少?直觉上一直认为应该是内部 HSI 的 16MHz,而程序中 SPI 的传输速率设定在主时钟的 1/2,因此 SCK 频率应该是 8MHz,但是在逻辑分析仪采集的 SCK 频率却是 1MHz!( c/ }# C% j; B
# M& w9 a, a% z: c
, _2 F' Z: M5 Y+ C- B# [
$ X& D/ b9 M; c. t查询规格书看到了这样的说明:3 V- x u+ j, @7 [3 o. b! F
2 G' X0 ?) o/ C# A* N
N: L9 u4 B$ c0 G
. P+ @ D v& N
原来芯片复位 (RESET) 之后的可编程分频器设定在 8,因此主时钟频率就是 2MHz,所以我所采集到的 SCK 频率就是 1MHz 没错。为了得到比较快速的传输速率,我在 main 回圈的开头增加了对时钟设定的函数,将时钟设定在最高的 16MHz。1 S6 n3 K" o S1 o. R* ^
. Q( t2 s* [6 D7 {
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); 4 k) B4 h! }/ F4 W
( K$ v4 d- H9 h% a; k2 } Y4 Z5 E
运行结果也得到了预期的 8MHz:/ g; d7 _" N, a! i, J" f
$ w8 {. I6 x x, ?3 e- [$ Z b+ W
' x4 [( ^+ o, k7 _5 u% n: E
' K% A8 y9 d0 \! R" U
' {& B4 \! |+ J: ~( ^
一个错误的教训!我一开始是将 CLK_HSIPrescalerConfig() 函数放在延时 5 秒代码之前,然而编程烧录过一次之后的再次编程就失败了!难道这颗芯片变砖了?延时 5 秒的代码是官方提供的,这应该是在主频为 2MHz 的条件下计算的,然而目前在延时 5 秒前我就将主频设定在 16MHz,那是否延时的时间就只剩不到 1 秒呢?原本板子在上电后可以有足够的时间按下 IAR 上的编程动作,现在延时时间减少了,我假如按钮编程的动作快一点的话是否可以就救回这一颗芯片,让芯片可以重新再烧录呢?
. u; `/ N" y4 J$ a7 I4 w
0 N* E7 s I9 g. z在试了很多次之后我放弃了,还好我在 ST 天猫也买了芯片,只好换上芯片后继续后续的实验。! Q1 d8 M/ v8 M1 I& }, H
/ a% [; g- i/ n! X1 bmain 回圈:
7 ^4 U* D+ X. K" p: d% O5 ?) D$ z' U. v9 O8 `7 N1 X0 c5 t: @
- void main(void)
/ T3 ]& e; g" Y2 m% p2 b5 E - {
. }3 R6 p6 ^+ D( c - uint8_t Dta[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
: U( }! g t, d4 u2 k - uint8_t idx = 0;; j3 } f5 L$ f8 P' G8 Z5 Q+ j
-
5 K& Q) u5 e' f, D - /* -------------STM8S001 startup-------------- */
1 Z) ~/ H- X+ R7 L/ A9 L - /* delay for SWIM connection: ~5seconds */
9 z. O8 J6 V/ ^8 Y - STARTUP_SWIM_DELAY_5S;3 x8 H- }2 |6 `" X" S
- 8 @2 F' t; z, e* Q, K" O5 y7 x$ F
- /* configure unbonded pins */+ Q3 ~) s! p6 z6 B/ v- e
- CONFIG_UNUSED_PINS_STM8S001;
. [; A9 T8 h% Q* z- u0 z& p -
! P+ n7 e) A. U0 F - GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); // NSS9 Y0 @# q, }" U+ U) ~
- GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
0 {' M$ m3 N" G! R/ ^3 N - /* ------------------------------------------- */7 n+ h; h( W4 @+ p' K. F
1 U% O. _) c, K# w& j T0 x& u+ [- /*High speed internal clock prescaler: 1*/
/ N; Z, d5 r& J( i% A3 C - CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);' F. U6 t& `( n* F: M; {
- / x# Q& g2 F8 U6 A" l: V& p( K! S8 C
- /* SPI configuration */
" ?" ]% I# I7 U# U0 c% B6 Q - SPI_DeInit();! f1 n p( z w
$ c6 Y7 V0 K! {9 v" s1 ]- /* Initialize SPI in Slave mode */
$ {# a4 e5 c2 K: X5 ]- e6 { j - SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_LOW,( d( O- }- X s
- SPI_CLOCKPHASE_1EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,0x07);! M' M" ?% A$ P1 `+ f
: d e4 s6 C' P+ r- /* Enable the SPI*/
! ^* p2 S# U3 l5 O - SPI_Cmd(ENABLE);. p; L' n' S# i$ a1 I# N S) l
* ]8 c2 x( L% ~* n# ~! l7 ~' y- while (1)
( V( z0 r( V! \$ v; s - {6 A4 u* Q& B2 j* F4 o: e8 b
- while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);
7 a3 b3 l- X% U$ u -
& q( h/ n" ^4 U, T4 e - GPIO_WriteLow(GPIOA, GPIO_PIN_3); // NSS = 09 `0 I: P, m! F( e/ @. L
- ( p" m/ Q9 U0 H B( a. h
- SPI_SendData(Dta[idx++]);7 b, t( F2 }$ Y& v) u
- if(idx == 8) idx = 0;
6 a% m, M8 d2 H1 l. K- V" a - - h. ^, L- c8 O. Q8 p- Y1 }
- GPIO_WriteHigh(GPIOA, GPIO_PIN_3); // NSS = 12 B3 L9 \* ]. i' Z
- } q' ~ g. T9 [$ s
- }
复制代码 ' p3 R: l0 z$ |% T
! `1 V5 V: [: Z2 l8 j1 k% n- ~源代码:
9 R; J; f, h6 a3 ?! `
B07.rar
(958 KB, 下载次数: 11)
|
感谢关注