1. CLK->PCKENR1 使能 CLK_PCKENR1_UART1 无效: q+ R- p) z; H/ k* [ 想降低功耗,单独打开 CLK_PCKENR1_UART1,但UART无输出。" L t2 J& Z- r& y# h 核对资料发现: 3 r! R9 r C+ m7 l' D5 g' H 解决方法: 不要使用 stm8s.h中的 CLK_PCKENR1_UART1 自己使能 bit32 k+ o+ G8 K6 t( j& g $ o3 ]4 c) q" O9 X1 A+ z! z u' D |
2 o" k k, M# B( X5 m5 a! c
. u) n5 k' T8 ]5 u J" o
2. PD4 TIM2_CH1没有反应
( Q7 _! W3 m; u" k
同样的 PD3 TIM2_CH2则完全正常。; k% d; U @3 h$ f9 E3 M# K9 r) J
经各种跳坑调试后发现,为了使用 PC7 [TIM1_CH2] 和 PC6 [TIM1_CH1]
所以在option bytes里面启动了 AFR0! z3 Y1 d# l; ^ z$ ^, _
: z6 _2 ?- |, y" G
9 m8 s& t' `9 p5 h \
数据手册对 AFR0 描述如下:
AFR0 Alternate function remapping option 0(2)
0: AFR0 remapping option inactive: Default alternate functions(1)
1: Port C5 alternate function = TIM2_CH1; port C6 alternate function =1 F" w& q; `1 p( H( Z( j2 K9 k/ j
TIM1_CH1; port C7 alternate function = TIM1_CH2.- V. V1 N4 g- v: J. i
& F5 Q1 g8 N9 C
也就是说 TIM2_CH1也被映射走了,换成 PC5 TIM2_CH1 就完全正常了。8 c* c" R- c+ @2 Y3 w. V
但刚才翻资料看到这句就懵了。" j ^7 C6 {3 c0 v% P
) w( A7 D6 _+ n J
' c# |5 _: J P4 D( F" n. l' n
. Y+ J$ L6 h7 b
这个暂时还没得到答案!为保险起见,决定不使能AFR1,还是修改电路,把 PD2 [TIM2_CH3] 还是换成PA3 TIM2_CH3。
STM8L流水灯
*. g1 o1 z4 V( J! n' ]3 s# W
* Copyright (c) 2002-2005 STMicroelectronics
*/& X" B$ C5 ] r7 i( l
. U F; F# [: B8 `3 O
#include <stm8l052c6.h>4 z* d# ]; T7 K9 Q+ ~/ ~
void delay(unsigned int time);3 b. S$ d# S1 Y! T" ]
void main(void)9 @7 C) k. e9 X# q# S( \
{
unsigned char i=0;
PD_DDR=0x02; //设置PD1为输出模式; l7 v s* O7 a" w
PD_CR1=0x02; //设置PD1为推挽输出
PD_CR2=0x02; //设置PD1输出速率为16mhz8 T0 w& W9 x$ O: B5 R. }
PB_DDR=0x1e; //设置PB1~PB4为输出模式
PB_CR1=0x1e; //设置PB1~PB4为推挽输出
PB_CR2=0x1e; //设置PB1~PB4输出速率为16mhz( H& o. B% s6 U {; w- g9 d; w2 a
CLK_CKDIVR=0x07; //对HSI进行128分频,16MHZ/128=125KHZ! S' }7 S. @0 \% R# \$ M. s9 n+ H; }
while(1)
{
PD_ODR=0xfd; //PD1(红)灭7 T t& ^. m# A( S& _# s {& q5 c
switch(i)' C, H# I5 ~- |5 G
{
case 0: PD_ODR=0xff;break; //PD1(红)亮7 Z+ L/ {6 k, o1 o6 @
case 1: PB_ODR=0x02;break; //PB1继电器启动; G- M+ l" H! D1 C- N
case 2: PB_ODR=0x04;break; //PB2继电器启动
case 3: PB_ODR=0x08;break; //PB3继电器启动
case 4: PB_ODR=0x10;break; //PB4继电器启动9 K3 @6 u* e0 `8 l# X( d3 {6 M
}2 S! I! p1 _9 V7 _: q. o: L6 M$ k% }
delay(12500); //延时1S
i++; I1 m9 S* u3 ]+ ^/ { l
if(i==5)) U, x8 W2 o A# J, C
{4 s U7 u* y) w0 Q9 c) D
i=0;
}4 @+ J% w5 q. U2 }. j! N$ T
}
}
void delay(unsigned int time)6 L R; r8 X1 Z; P
{
while(time--);
}* W- O% s+ w3 J; i! a* R" D
继电器可以换成LED灯
* Z2 F: U) w+ t$ s X
: y+ ^# o/ g: t& A9 W3 W- a
STM8的乘除法指令是8位的,做16位或以上乘法运算时,编译器实际上调用了一个函数(通用作法);
而这个函数竟然用到了几个编译器自定义的全局变量(猜测);. d |; n# v: \3 S6 Y
在进入中断时,这几个全局变量是不会被自动保存的,从而造成这个乘法运算函数不可重入;9 }9 d. ?3 h& e4 f6 v
当主程序和中断同时使用8位以上乘除法时,自然就出错。
* |9 _9 F5 M% p, @. x2 ?/ d4 O
从芯片或编译器上面想办法基本上不太可行,那么从软件上规避吧。
STM8L间隔1S闪烁
*
* Copyright (c) 2002-2005 STMicroelectronics
*/" u3 k ]5 }, W; j( m) Y
( B7 S/ Z% \" J1 a+ f" W
#include <stm8l052c6.h>
void delay(unsigned int time);
void main(void); R5 U0 j0 R2 k: z; ^' l
{
int i;4 R+ G( R% S8 S& ]
PD_DDR=0x03; //设置PD0,PD1口为输出模式$ g% t; k! v8 F
PD_CR1=0x03; //设置PD0,PD1口为推挽输出
PD_CR2=0x03; //设置PD0,PD1口输出速率为16mhz
CLK_CKDIVR=0x07; //对HSI进行128分频,16MHZ/128=125KHZ
for(i=0;i<10;i++)2 _5 R9 A! }' G2 X! u
{; y% Q- c3 R" i$ F$ f
PD_ODR=0xfe; //PD1(红)亮
delay(12500); //延时1S) J' a; b( G r$ a8 @( A4 p
PD_ODR=0xfc; //PD1(红)灭
delay(12500); //延时1S
}: E$ R: U4 j4 t' H0 K
}
void delay(unsigned int time)
{1 L# Z: {2 ]6 b% v* H4 M/ {- I. k" N
while(time--);
}
有需要的朋友可以来看看, C* p L2 G9 h* y0 F
. X6 ?3 c- m: r# {3 E
STM8S003F3P6共享资料
; y0 p/ I7 ^* w$ k# V) I! ~
% x0 z0 e& |* i' x% @: K: z4 }
$ P z" @+ l+ b; ^2 Z
* o& D6 G6 s2 i9 o
, O! r5 C* T4 o X& `+ i# ?7 R