STM8S001J3 由于 VCAP 的需要因此少了一支 I/O 引脚,跟另外 2 颗 8 引脚的 STM8 比较起来少了 PB7,而这一支引脚的复用功能是 SPI 的 MISO,因此对于 STM8S001J3 来说 SPI 是没有 MISO 引脚的。
9 H9 `8 w5 h, Z2 u4 j" l }9 K- V& [! b) P& C& G2 Y
) L7 S) a4 {" C$ e
; r/ x' U, W2 W: TSPI 的 CPOL 与 CPHA 设定决定了四种时序关系:& K" V9 }) ~# H; K" j
0 u. x j( l/ @/ i* A3 i
CPOL CLOCK POLARITY 时钟极性
, c( J, G- L8 s6 W: L 0 SCK空闲状态保持低电位
3 `* r/ U6 w7 ]) ^1 G 1 SCK空闲状态保持高电位3 s0 w7 z. _. I7 ]# S; s! L2 q5 [" Z
CPHA CLOCK PHASE 时钟相位
X: t/ |$ A5 X4 @6 I 0 SCK时钟的第一个边缘进行数据采集( e$ q6 q& o/ s
1 SCK时钟的第二个边缘进行数据采集
; \2 w, b. o& P. s7 y2 }# u6 e
7 H4 A- t; i( E( ]- Q3 x) Z
& _6 O t/ l- h/ p, [% M
3 |. i" H, \0 e9 B$ J( f6 J' j一般比较常用的似乎是 CPOL = 0 , CPHPA = 0,比如说外接 74HC595 这类的 8 位串行入并行出的移位寄存器就需要做这样的设定,也就是在时钟上升缘时将数据移入寄存器内。% e: n8 e( e0 O) s4 m- m; Y9 ], {
. q$ I" s* Q; _$ `
R3 l. p$ ~/ Z0 o
- x/ i4 h( C" i" h% ?
由于后面我打算连接 MAX7219 显示模块,因此先实现一个 SPI 的测试程序来熟悉一下功能,我使用逻辑分析仪采集数据的输出,程序中让 STM8S001J3 由 SPI 引脚输出 0x01、0x02、0x04、0x08、0x10、0x20、0x40、0x80 数据,NSS 引脚由程序控制输出。测试程序中有一个需要注意的地方,由于 MOSI 这支引脚也在 pin8 与烧录使用的 SWIM 同一支脚,因此程序的一开始需要先加上一个 5 秒的延时代码。
6 |* o( K; z9 ?4 g+ @* ?! [3 B0 }% t8 Z: ~/ d
SPI 初始化:
* o4 i4 W2 e* z# O) v2 f% M- SPI_Init(SPI_FIRSTBIT_MSB, // 高位在前1 W& d$ [/ @+ k) w; i: r
- SPI_BAUDRATEPRESCALER_2, // 传输速率为主时钟 1/2# T: M+ Q( n( T5 B/ K! ~
- SPI_MODE_MASTER, // 主机模式0 R5 E; y; Y2 R9 T* l
- SPI_CLOCKPOLARITY_LOW, // CPOL = 06 _( x/ {. f8 s6 Q2 {
- SPI_CLOCKPHASE_1EDGE, // CPHA = 0% i q: K; T' `
- SPI_DATADIRECTION_2LINES_FULLDUPLEX, // 全双工模式
/ G8 `7 @: y+ C3 @2 O5 x$ k - SPI_NSS_SOFT, // 软件管理 NSS
- e7 |( V; D7 k& m; | - 0x07); // CRC 校验
复制代码
& X4 ^/ i( g: J% y O5 R& V: Q& f3 v7 G5 _9 _3 X
逻辑分析仪数据采集:
. U1 E$ n( L- }" V; i/ r5 O) f$ I4 ^ ]2 y Q! ?/ Q# `8 ?+ v1 I1 g( i
- G3 D6 k l* e% L3 [" l
) P9 N& v# r0 ?! O/ D在先前的实验没有留意 STM8S001J3 上电后的系统时钟缺省设定是多少?直觉上一直认为应该是内部 HSI 的 16MHz,而程序中 SPI 的传输速率设定在主时钟的 1/2,因此 SCK 频率应该是 8MHz,但是在逻辑分析仪采集的 SCK 频率却是 1MHz!: k4 [5 J6 C: n, X
. ?5 V _+ w, L
& X8 ]4 k" D) [1 {' Z! `: ?, }
9 h! a* I" O9 v6 e- d: U查询规格书看到了这样的说明:) f! J$ y$ d9 o+ y- ~# B* A" H
+ p# Q8 y& R, Y f! B4 A8 ]
. ~! V9 t+ R& R) Q& T- t' y; D- c: k0 w
7 F# C: P% V7 w, Z原来芯片复位 (RESET) 之后的可编程分频器设定在 8,因此主时钟频率就是 2MHz,所以我所采集到的 SCK 频率就是 1MHz 没错。为了得到比较快速的传输速率,我在 main 回圈的开头增加了对时钟设定的函数,将时钟设定在最高的 16MHz。9 F2 s6 ~, l( y- l+ G/ p* E
& x) z b0 g2 D
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); % _" _: |5 z7 e4 k9 H
2 M5 ], E# O2 [7 D6 {2 Q' \8 A3 q# S运行结果也得到了预期的 8MHz:' \# b/ k/ j. H: ~4 x: w
# P5 L3 M; v) b6 D8 _6 } M( w* x0 R5 K
( A; g2 M. [' O# [! u& q
3 C% {7 d; g E' t/ u0 Q: V. {; \) ~5 G8 f
一个错误的教训!我一开始是将 CLK_HSIPrescalerConfig() 函数放在延时 5 秒代码之前,然而编程烧录过一次之后的再次编程就失败了!难道这颗芯片变砖了?延时 5 秒的代码是官方提供的,这应该是在主频为 2MHz 的条件下计算的,然而目前在延时 5 秒前我就将主频设定在 16MHz,那是否延时的时间就只剩不到 1 秒呢?原本板子在上电后可以有足够的时间按下 IAR 上的编程动作,现在延时时间减少了,我假如按钮编程的动作快一点的话是否可以就救回这一颗芯片,让芯片可以重新再烧录呢?1 ~# b m$ P' s* G0 }% q( s
! M i @2 m) E& n1 L- J3 i; ]在试了很多次之后我放弃了,还好我在 ST 天猫也买了芯片,只好换上芯片后继续后续的实验。
) L5 G# C# ?2 N: J2 Z2 K% I/ p& b7 F8 }
main 回圈:
c Z/ T3 L1 s( ^
0 x' d' @4 G% B: P: N- void main(void)
/ y+ D& L5 r2 N0 R2 ? - {
. `! O% @! M6 R0 L - uint8_t Dta[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};% ~1 ?, r* ^0 o2 L5 i
- uint8_t idx = 0;& N( o( }9 X/ o
-
' v' s( j# w( l6 Y8 P4 C7 t, m) O: Q - /* -------------STM8S001 startup-------------- */
: `( \9 g+ ], @, y) P - /* delay for SWIM connection: ~5seconds */
3 w- C: f4 \" ~/ M2 z - STARTUP_SWIM_DELAY_5S;
& C+ O, ]0 C( g6 p( j$ m -
9 P( }& J, q, D0 D, C - /* configure unbonded pins */# x( a5 @7 f1 n
- CONFIG_UNUSED_PINS_STM8S001;
' n2 k; Q0 H. h& |/ K# O9 f - ' J6 [9 M8 k3 F# [" A
- GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); // NSS
( K8 r6 W8 q- h - GPIO_WriteHigh(GPIOA, GPIO_PIN_3);
& Q3 P: b7 f6 i5 z' s5 K - /* ------------------------------------------- */
- O. ^1 k6 @9 e8 i9 e - 9 l% Q* E4 _, N1 a3 B' K0 C
- /*High speed internal clock prescaler: 1*/4 O- n) W$ H8 A- F8 e
- CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
( d# u, W9 A2 u/ f! \ - : E9 ]+ S0 l3 o }4 x( w* S3 k8 u6 C
- /* SPI configuration */( w3 \' U1 a$ e& P
- SPI_DeInit();% b- D& Z; v p) V: v, f
# [5 o) G$ Q0 n- /* Initialize SPI in Slave mode */1 R: O7 ?* p f- ]$ I/ C
- SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_LOW,8 C- G2 f6 U# m9 o# Q z
- SPI_CLOCKPHASE_1EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,0x07);
# { K6 j% `' v. {
; K, g6 v" E0 D) u4 q5 ^ J! K- /* Enable the SPI*/
/ ?" o* v o; o* @- v - SPI_Cmd(ENABLE);
/ ]- G" f) b$ U2 U6 Q; J - ) G! x0 i; T( N6 y4 l ~
- while (1)
" O1 Y: O: W9 K, o - {3 V7 p) D4 J+ |. g5 L/ T
- while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);% h/ q- [! R# A& @' J
-
5 j, L% H V$ T% R) M7 ~ - GPIO_WriteLow(GPIOA, GPIO_PIN_3); // NSS = 0
/ M+ H# Z4 A V6 Z/ ` - # I& Z* e7 E4 y
- SPI_SendData(Dta[idx++]);8 A3 j/ [* g1 j, h! q; j! k
- if(idx == 8) idx = 0;+ k2 k5 Y" K/ I# ~4 m0 w8 x/ w
r0 c2 }$ s8 `: L/ F& U5 f9 n- GPIO_WriteHigh(GPIOA, GPIO_PIN_3); // NSS = 1
4 v1 w/ V* Q ~ - }
) |5 s- B8 q5 ^ - }
复制代码
& C8 R, d$ P; } H
" Z- K) Z' E7 A5 n. `/ E源代码:% u9 l+ l6 T* c- d4 C2 f& j' {7 T
B07.rar
(958 KB, 下载次数: 12)
|
感谢关注