STM8S001J3 由于 VCAP 的需要因此少了一支 I/O 引脚,跟另外 2 颗 8 引脚的 STM8 比较起来少了 PB7,而这一支引脚的复用功能是 SPI 的 MISO,因此对于 STM8S001J3 来说 SPI 是没有 MISO 引脚的。0 [3 y5 z3 w2 Q, L4 j/ g; u
! E- Q% s0 ` b2 t4 d+ n3 B: f w
+ V! H; A) o. s
0 S5 G b. z2 z, tSPI 的 CPOL 与 CPHA 设定决定了四种时序关系:
% b( i! l, L- |4 b# D% {
2 ~: w; z! f9 W/ tCPOL CLOCK POLARITY 时钟极性
) V9 q; C7 o3 B1 i T 0 SCK空闲状态保持低电位
, ?$ O% u1 x. M) ` 1 SCK空闲状态保持高电位
! U$ B' \9 `, \( E' b bCPHA CLOCK PHASE 时钟相位
6 y& w5 B) f* p( j; c8 v. N0 c, P 0 SCK时钟的第一个边缘进行数据采集7 G7 l8 T8 s6 y7 M! e
1 SCK时钟的第二个边缘进行数据采集
7 g& {" c1 ]2 L' f3 c0 d
" i7 C5 i8 Q+ u7 ~6 h
9 n, A2 X; S8 H( C e
0 N6 z7 j& t! O ^, t" h# ^一般比较常用的似乎是 CPOL = 0 , CPHPA = 0,比如说外接 74HC595 这类的 8 位串行入并行出的移位寄存器就需要做这样的设定,也就是在时钟上升缘时将数据移入寄存器内。9 _2 ~: ^5 f$ R/ \6 |! e
. t8 Z2 k1 T ~6 K9 Y8 a% \6 [( |
. p" Z& X9 u+ p2 @
2 u* g. Y. k. {
由于后面我打算连接 MAX7219 显示模块,因此先实现一个 SPI 的测试程序来熟悉一下功能,我使用逻辑分析仪采集数据的输出,程序中让 STM8S001J3 由 SPI 引脚输出 0x01、0x02、0x04、0x08、0x10、0x20、0x40、0x80 数据,NSS 引脚由程序控制输出。测试程序中有一个需要注意的地方,由于 MOSI 这支引脚也在 pin8 与烧录使用的 SWIM 同一支脚,因此程序的一开始需要先加上一个 5 秒的延时代码。' J$ j, J- Q' Z/ ` D( _. S5 {
% A/ u* |; r: Z* |SPI 初始化:
$ L9 x- Z( v% o: H# W) S) B- SPI_Init(SPI_FIRSTBIT_MSB, // 高位在前
. d; ~% ?- M4 ]1 v; n - SPI_BAUDRATEPRESCALER_2, // 传输速率为主时钟 1/2. }' y$ T# ], M
- SPI_MODE_MASTER, // 主机模式
1 Y8 G& Q5 W$ G1 o6 X0 F - SPI_CLOCKPOLARITY_LOW, // CPOL = 08 a! t1 T) w+ F1 G# w
- SPI_CLOCKPHASE_1EDGE, // CPHA = 0
1 _6 p& Y* d, f* B - SPI_DATADIRECTION_2LINES_FULLDUPLEX, // 全双工模式
# l8 a F; s, |+ l- P* Z. ` - SPI_NSS_SOFT, // 软件管理 NSS1 Y: q+ @2 \, @8 I! |4 R
- 0x07); // CRC 校验
复制代码
& I3 k$ Y& \# c
C4 b7 l' |: \逻辑分析仪数据采集:3 F* S9 g/ X+ k6 L, b9 n
8 z! i# v' a: [. u8 \
+ f- g* H" u6 e1 @: O% K/ s
" `# w, g9 ]; D1 p* `' z# M, V在先前的实验没有留意 STM8S001J3 上电后的系统时钟缺省设定是多少?直觉上一直认为应该是内部 HSI 的 16MHz,而程序中 SPI 的传输速率设定在主时钟的 1/2,因此 SCK 频率应该是 8MHz,但是在逻辑分析仪采集的 SCK 频率却是 1MHz!: `6 P; p' t% j% T7 ^
+ k% Z4 d8 L7 {; A; G2 X9 T
; P4 t6 |; E9 c0 b) L! X4 }8 U
- E1 E+ s8 ?+ G
查询规格书看到了这样的说明:. h* D. d5 c D2 m1 O# z! p+ }
, L" Y/ p4 ?! _
1 w0 {7 I% n) a$ ^- _/ L
' a' _! p: u: P G' m( a4 m H$ b原来芯片复位 (RESET) 之后的可编程分频器设定在 8,因此主时钟频率就是 2MHz,所以我所采集到的 SCK 频率就是 1MHz 没错。为了得到比较快速的传输速率,我在 main 回圈的开头增加了对时钟设定的函数,将时钟设定在最高的 16MHz。
9 z: I) j) ^% {
& s, }! U0 l( FCLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
9 d& T1 l7 g1 Y7 u9 a5 E+ w; e: H) q
运行结果也得到了预期的 8MHz:7 ^7 g5 v* Y6 ?1 _
6 e; r" J( ~. m. F; z; `
6 e0 @3 o0 I# S2 p0 \
( \) L* F+ [8 F6 h8 X1 Q2 C7 _
6 u+ N2 J" L; [
一个错误的教训!我一开始是将 CLK_HSIPrescalerConfig() 函数放在延时 5 秒代码之前,然而编程烧录过一次之后的再次编程就失败了!难道这颗芯片变砖了?延时 5 秒的代码是官方提供的,这应该是在主频为 2MHz 的条件下计算的,然而目前在延时 5 秒前我就将主频设定在 16MHz,那是否延时的时间就只剩不到 1 秒呢?原本板子在上电后可以有足够的时间按下 IAR 上的编程动作,现在延时时间减少了,我假如按钮编程的动作快一点的话是否可以就救回这一颗芯片,让芯片可以重新再烧录呢?
1 _+ b' x: i8 N2 _( A% R1 v, T/ n& T0 \; l- e
在试了很多次之后我放弃了,还好我在 ST 天猫也买了芯片,只好换上芯片后继续后续的实验。
. U3 L* J' ]8 p5 m8 g
$ b) b! f. l) \+ k F3 omain 回圈:
: b7 H) e' W2 P7 Z! S; W* J3 } e' U! P* C }4 ]( \4 e. W
- void main(void)
( k- q6 n& ^2 ^, O! n - {$ _9 K- L9 d6 V* P8 b
- uint8_t Dta[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};4 m& Z J1 w4 g9 M% x# p
- uint8_t idx = 0;0 |( V! y+ Q" s- v5 d
- + @) ?9 I1 j* n# f) U* l
- /* -------------STM8S001 startup-------------- */3 c, |$ p% z) V2 \0 X6 n
- /* delay for SWIM connection: ~5seconds */2 ~$ N# ~+ u( m: j
- STARTUP_SWIM_DELAY_5S;
! Q4 W! L: ]+ A+ l' Z: [5 V - - G* s8 t+ m" [2 L1 z) p& @
- /* configure unbonded pins */1 ^6 \4 O5 ?8 t q/ J9 z
- CONFIG_UNUSED_PINS_STM8S001;+ p* f9 F" w, o2 s" l
- + w, Z6 l. V# a
- GPIO_Init(GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); // NSS+ S6 d& [2 y l
- GPIO_WriteHigh(GPIOA, GPIO_PIN_3);7 n) L4 v" r7 _5 y' H' z
- /* ------------------------------------------- */4 q7 X+ F8 f4 A0 y
- 2 K, W ~& v( A5 L* c
- /*High speed internal clock prescaler: 1*/ K. ?* M& }% C) |% l* a
- CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);$ a) d \# }3 v3 I: H
- / D. U& \% [( a
- /* SPI configuration */. T8 E; @9 l- I
- SPI_DeInit();
, x: [, o- k3 m" @, p8 M+ }
, z' ` J2 o' w3 P0 `- /* Initialize SPI in Slave mode */( {1 Z! R' K$ y
- SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_2, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_LOW,
$ X8 `. N: N* X. T! J2 x0 f - SPI_CLOCKPHASE_1EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT,0x07);
5 U+ O2 z4 V$ j- I a
2 }% ]. Y; L7 |" }' G1 [- /* Enable the SPI*/
; ]: d) W; `8 ~ - SPI_Cmd(ENABLE);
8 M; a. C1 ]( F8 j& V
$ a7 h6 r4 x/ i& w( i- Z" @( C$ _% y- while (1)
s; v# z/ Q' ]; |, C - {
4 @6 a F% _1 x2 i5 q( D) u - while(SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);% d/ b0 k. E8 D1 Y& a5 {
-
6 P# k: |* l) M; W9 M q - GPIO_WriteLow(GPIOA, GPIO_PIN_3); // NSS = 0
7 P2 X7 `2 _$ [3 w1 Q
: d) e0 v3 t1 H- SPI_SendData(Dta[idx++]);
7 e1 ?! I! w$ `% y! l% g - if(idx == 8) idx = 0;
! G! g$ ]5 O0 W' g. A7 L1 N - . w; Y9 u; K0 B, W4 \, e, e
- GPIO_WriteHigh(GPIOA, GPIO_PIN_3); // NSS = 15 L+ W9 Q1 X2 H% [2 v! X
- }9 p9 u5 _8 B; D3 U6 @1 T
- }
复制代码
/ |6 X- s5 d9 ~( {9 v/ g# H% o2 \
源代码:# P/ Z2 d# T; i) H$ i
B07.rar
(958 KB, 下载次数: 11)
|
感谢关注