├── .gitignore ├── Doc └── readme.txt ├── Hardware ├── Multi_Key │ ├── multi_button.c │ └── multi_button.h ├── Nokia5110 │ ├── fonts.h │ ├── nokia5110.c │ └── nokia5110.h ├── RotaryEncoder │ ├── rotaryEncoder.c │ └── rotaryEncoder.h ├── systick │ ├── bsp_SysTick.c │ └── bsp_SysTick.h └── zBitsView │ ├── zBitsView.c │ └── zBitsView.h ├── README.md └── User ├── main.c ├── main.h ├── stm32f10x_conf.h ├── stm32f10x_it.c ├── stm32f10x_it.h └── system_stm32f10x.c /.gitignore: -------------------------------------------------------------------------------- 1 | !*.c 2 | !*.h 3 | *.bak 4 | *.ddk 5 | *.edk 6 | *.lst 7 | *.lnp 8 | *.mpf 9 | *.mpj 10 | *.obj 11 | *.omf 12 | *.opt 13 | *.plg 14 | *.rpt 15 | *.tmp 16 | *.__i 17 | *.crf 18 | *.o 19 | *.d 20 | *.axf 21 | *.tra 22 | *.dep 23 | JLinkLog.txt 24 | *.iex 25 | *.htm 26 | *.sct 27 | *.map 28 | *.bat 29 | *.xlsx 30 | *.html 31 | *.doc 32 | *.docx 33 | *.ppt 34 | *.exe 35 | Libraries/ 36 | Output/ 37 | Project/ 38 | Listing/ -------------------------------------------------------------------------------- /Doc/readme.txt: -------------------------------------------------------------------------------- 1 | # 屏幕菜单 2 | 3 | - 时间: 2020-3-18 4 | - 作者: 张续鹏 5 | 6 | ## 功能 7 | 8 | 实现了一个多级菜单控件 9 | 10 | ## 简介 11 | 12 | 1. 编写环境:Keil μVision 5 13 | 2. 硬件设备:STM32F103C8T6、Nokia 5110屏幕,EC11旋转编码器 14 | 3. 本界面控件理论上不限制屏幕、不限制单片机型号(未验证) 15 | 4. 移植方便 16 | 17 | ## 代码分析 18 | 19 | ### 数据结构 20 | 21 | 1. 行元素结构体 22 | 23 | ```c 24 | typedef struct{ 25 | uint16_t enterViewIndex;//按下确定键跳转的界面 26 | char * text; //当前行显示的文本 27 | HandlerFunc handler; //显示函数 28 | }RowListTypeDef; 29 | ``` 30 | 31 | 数组最大长度:65536 32 | 每个元素占用12字节 33 | 因为此数据不需要修改,所以可使用`const`或`code(C51)`修饰 34 | 35 | HandlerFunc是函数指针,此函数即可作为行元素的显示函数,又可作为按键处理函数,其类型为: 36 | 37 | > ```c 38 | > typedef void(*HandlerFunc)(uint16_t index, char* p, uint8_t key); 39 | > ``` 40 | > 41 | > 三个形参的作用分别是: 42 | > 43 | > > @param index: 指向此函数的RowListTypeDef在数组中的下标 44 | > > 45 | > > @param p: 指向当前RowListTypeDef元素的text指针指向的字符串 46 | > > 47 | > > @param key: 若按下按键的值大于等于6(KEY_ADD),则此形参会是非0值(KEY_NONE);若小于6,则传入0(KEY_NONE) 48 | 49 | 2. 界面结构体 50 | 51 | ```c 52 | typedef struct { 53 | const RowListTypeDef * const list;//指向当前层所指向的行元素 54 | uint16_t lengthOfList; //指向的行元素的长度 55 | uint16_t parentViewIndex; //本元素所属层的标号 56 | uint16_t startRow; //记录在上一层时的开始行索引 57 | uint8_t currRow; //记录在上一层时的行索引 58 | }ViewListTypeDef; 59 | ``` 60 | 61 | 数组最大长度:65535(0~65534) —— 65535代表RowListTypeDef元素没有指向的ViewListTypeDef元素 62 | 63 | 每个元素占用12字节 64 | 65 | 定义ViewListTypeDef型数组是可以使用`VIEW_MEMBER_FORMAT(x)`帮助编写;如: 66 | 67 | > ```C 68 | > ViewListTypeDef menu[] = { 69 | > VIEW_MEMBER_FORMAT(rowListHome), 70 | > VIEW_MEMBER_FORMAT(rowListSettingRoot), 71 | > VIEW_MEMBER_FORMAT(rowListView1), 72 | > VIEW_MEMBER_FORMAT(rowListView2), 73 | > VIEW_MEMBER_FORMAT(rowListView3), 74 | > VIEW_MEMBER_FORMAT(rowListView1_1), 75 | > }; 76 | > ``` 77 | > 78 | > 其中`VIEW_MEMBER_FORMAT`宏定义为 79 | > 80 | > ```c 81 | > #define ROW_LENGTH(x) ((uint16_t)(sizeof(x)/sizeof(RowListTypeDef))) 82 | > #define VIEW_MEMBER_FORMAT(x) {x,ROW_LENGTH(x),0,0,0} 83 | > ``` 84 | 85 | 3. 游标结构体 86 | 87 | ```c 88 | //游标,只需要定义一个即可 ==> 8字节(byte) 89 | typedef struct { 90 | uint8_t currRow; //当前指向元素 91 | uint8_t keyval; //记录按键 92 | uint16_t currViewIndex; //当前指向层 93 | uint16_t startRow; //屏幕第一行显示的行元素索引 94 | uint16_t rowNum; //记录当前层的行元素数 95 | }CursorTypeDef; 96 | ``` 97 | 98 | ### 函数作用 99 | 100 | 本控件函数很少,只有两个,即: 101 | 102 | 1. `void View_Init(ViewListTypeDef * v, CursorTypeDef * c)` 103 | 104 | 此函数的作用是初始化界面控件:将用户定义好的`ViewListTypeDef`数组的地址和`CursorTypeDef`地址初始化到控件 105 | 106 | 2. `void View_Loop(void)` 107 | 108 | 此函数作用是在处理界面数据。注意:**需要将此函数放入主循环中,每隔一段时间调用一次** 109 | 110 | > 间隔时间典型值是100ms。 111 | > 112 | > 注意:并不是本控件消耗的时间多,而是屏幕驱动程序消耗的时间太多,本人的屏幕驱动是模拟的SPI时序而不是单片机硬件SPI,故屏幕驱动消耗的时间太多。控件每次需要不到1000个机器周期,而驱动程序是其上百倍。 113 | > 114 | > 若使用硬件外设驱动屏幕,则可以将间隔时间适当调小一点,同时注意不要低于屏幕刷新周期。 115 | 116 | ### 界面设计 117 | 118 | 设计界面时只需要定义几个数组即可。 119 | 120 | 首先定义`RowListTypeDef`类型数组,根据界面数定义数组个数,根据每个界面包含的行元素数定义每个数组的长度。 121 | 122 | 然后定义`ViewListTypeDef`类型数组,定义一个即可,数组长度是界面数决定的。 123 | 124 | 例如,设计这样一个界面: 125 | 126 | > ```mermaid 127 | > graph LR 128 | > 129 | > home{home} 130 | > root{root} 131 | > v1{view1} 132 | > v2{view2} 133 | > v3{view3} 134 | > v1_1{view1-1} 135 | > 136 | > rowhome(rowHome) 137 | > home-->rowhome 138 | > rowhome-.->root 139 | > 140 | > r1(row1) 141 | > r2(row2) 142 | > r3(row3) 143 | > root-->r1 144 | > root-->r2 145 | > root-->r3 146 | > r1-.->v1 147 | > r2-.->v2 148 | > r3-.->v3 149 | > r1_1-.->v1_1 150 | > 151 | > r1_1(row1-1) 152 | > r1_2(row1-2) 153 | > r1_3(row1-3) 154 | > r1_4(row1-4) 155 | > r1_5(row1-5) 156 | > r1_6(row1-6) 157 | > r1_7(row1-7) 158 | > r1_8(row1-8) 159 | > r1_9(row1-9) 160 | > v1-->r1_1 161 | > v1-->r1_2 162 | > v1-->r1_3 163 | > v1-->r1_4 164 | > v1-->r1_5 165 | > v1-->r1_6 166 | > v1-->r1_7 167 | > v1-->r1_8 168 | > v1-->r1_9 169 | > 170 | > 171 | > r2_1(row2-1) 172 | > r2_2(row2-2) 173 | > r2_3(row2-3) 174 | > r2_4(row2-4) 175 | > r2_5(row2-5) 176 | > r2_6(row2-6) 177 | > r2_7(row2-7) 178 | > r2_8(row2-8) 179 | > v2-->r2_1 180 | > v2-->r2_2 181 | > v2-->r2_3 182 | > v2-->r2_4 183 | > v2-->r2_5 184 | > v2-->r2_6 185 | > v2-->r2_7 186 | > v2-->r2_8 187 | > 188 | > r3_1(row3-1) 189 | > r3_2(row3-2) 190 | > r3_3(row3-3) 191 | > r3_4(row3-4) 192 | > r3_5(row3-5) 193 | > r3_6(row3-6) 194 | > r3_7(row3-7) 195 | > r3_8(row3-8) 196 | > r3_9(row3-9) 197 | > r3_10(row3-10) 198 | > r3_11(row3-11) 199 | > r3_12(row3-12) 200 | > r3_13(row3-13) 201 | > r3_14(row3-14) 202 | > r3_15(row3-15) 203 | > v3-->r3_1 204 | > v3-->r3_2 205 | > v3-->r3_3 206 | > v3-->r3_4 207 | > v3-->r3_5 208 | > v3-->r3_6 209 | > v3-->r3_7 210 | > v3-->r3_8 211 | > v3-->r3_9 212 | > v3-->r3_10 213 | > v3-->r3_11 214 | > v3-->r3_12 215 | > v3-->r3_13 216 | > v3-->r3_14 217 | > v3-->r3_15 218 | > 219 | > r1_1_1(row1-1-1) 220 | > r1_1_2(row1-1-2) 221 | > r1_1_3(row1-1-3) 222 | > r1_1_4(row1-1-4) 223 | > r1_1_5(row1-1-5) 224 | > r1_1_6(row1-1-6) 225 | > r1_1_7(row1-1-7) 226 | > r1_1_8(row1-1-8) 227 | > v1_1-->r1_1_1 228 | > v1_1-->r1_1_2 229 | > v1_1-->r1_1_3 230 | > v1_1-->r1_1_4 231 | > v1_1-->r1_1_5 232 | > v1_1-->r1_1_6 233 | > v1_1-->r1_1_7 234 | > v1_1-->r1_1_8 235 | > 236 | > ``` 237 | 238 | 则需要这样定义数组 239 | 240 | ```c 241 | const RowListTypeDef rowListHome[] = { 242 | //{.enterViewIndex | .x | .text | .handler}, 243 | {1,"home",NULL}, 244 | }; 245 | 246 | const RowListTypeDef rowListSRoot[] = { 247 | //{.enterViewIndex | .x | .text | .handler}, 248 | {2,"Row 1",NULL}, 249 | {3,"Row 2",NULL}, 250 | {4,"Row 3",NULL}, 251 | }; 252 | 253 | const RowListTypeDef rowListView1[] = { 254 | //{.enterViewIndex | .x | .text | .handler}, 255 | {5,"Row 1-1",NULL}, 256 | {VIEW_NONE,"Row 1-2",NULL}, 257 | {VIEW_NONE,"Row 1-3",NULL}, 258 | {VIEW_NONE,"Row 1-4",NULL}, 259 | {VIEW_NONE,"Row 1-5",NULL}, 260 | {VIEW_NONE,"Row 1-6",NULL}, 261 | {VIEW_NONE,"Row 1-7",NULL}, 262 | {VIEW_NONE,"Row 1-8",NULL}, 263 | {VIEW_NONE,"Row 1-9",NULL}, 264 | }; 265 | 266 | const RowListTypeDef rowListView2[] = { 267 | //{.enterViewIndex | .x | .text | .handler}, 268 | {VIEW_NONE,"Row 2-1",NULL}, 269 | {VIEW_NONE,"Row 2-2",NULL}, 270 | {VIEW_NONE,"Row 2-3",NULL}, 271 | {VIEW_NONE,"Row 2-4",NULL}, 272 | {VIEW_NONE,"Row 2-5",NULL}, 273 | {VIEW_NONE,"Row 2-6",NULL}, 274 | {VIEW_NONE,"Row 2-7",NULL}, 275 | {VIEW_NONE,"Row 2-8",NULL}, 276 | }; 277 | 278 | const RowListTypeDef rowListView3[] = { 279 | //{.enterViewIndex | .x | .text | .handler}, 280 | {VIEW_NONE,"Row 3-1",NULL}, 281 | {VIEW_NONE,"Row 3-2",NULL}, 282 | {VIEW_NONE,"Row 3-3",NULL}, 283 | {VIEW_NONE,"Row 3-4",NULL}, 284 | {VIEW_NONE,"Row 3-5",NULL}, 285 | {VIEW_NONE,"Row 3-6",NULL}, 286 | {VIEW_NONE,"Row 3-7",NULL}, 287 | {VIEW_NONE,"Row 3-8",NULL}, 288 | {VIEW_NONE,"Row 3-9",NULL}, 289 | {VIEW_NONE,"Row 3-10",NULL}, 290 | {VIEW_NONE,"Row 3-11",NULL}, 291 | {VIEW_NONE,"Row 3-12",NULL}, 292 | {VIEW_NONE,"Row 3-13",NULL}, 293 | {VIEW_NONE,"Row 3-14",NULL}, 294 | {VIEW_NONE,"Row 3-15",NULL}, 295 | }; 296 | 297 | const RowListTypeDef rowListView1_1[] = { 298 | //{.enterViewIndex | .x | .text | .handler}, 299 | {VIEW_NONE,"Row 1-1-1",NULL}, 300 | {VIEW_NONE,"Row 1-1-2",NULL}, 301 | {VIEW_NONE,"Row 1-1-3",NULL}, 302 | {VIEW_NONE,"Row 1-1-4",NULL}, 303 | {VIEW_NONE,"Row 1-1-5",NULL}, 304 | {VIEW_NONE,"Row 1-1-6",NULL}, 305 | {VIEW_NONE,"Row 1-1-7",NULL}, 306 | {VIEW_NONE,"Row 1-1-8",NULL}, 307 | }; 308 | 309 | ViewListTypeDef menu[] = { 310 | //.currIndex | .parentViewIndex | .list | .lengthOfList | .display 311 | VIEW_MEMBER_FORMAT(rowListHome), 312 | VIEW_MEMBER_FORMAT(rowListSRoot), 313 | VIEW_MEMBER_FORMAT(rowListView1), 314 | VIEW_MEMBER_FORMAT(rowListView2), 315 | VIEW_MEMBER_FORMAT(rowListView3), 316 | VIEW_MEMBER_FORMAT(rowListView1_1), 317 | }; 318 | ``` 319 | 320 | ### 程序格式 321 | 322 | 程序需要定义一个全局变量游标`CursorTypeDef`,如: 323 | 324 | ```c 325 | CursorTypeDef cursor; 326 | ``` 327 | 328 | 然后在main函数中调用控件初始化程序`View_Init` 329 | 330 | ```c 331 | View_Init(menu,&cursor); 332 | ``` 333 | 334 | 在程序主循环中每隔一段时间调用程序`View_Loop`.例如每隔100ms调用一次 335 | 336 | 当有按键按下时,只需要根据按键的不同给`cursor.keyval`变量赋不同的值即可.例如: 337 | 338 | ```c 339 | rotaryval = ReadRotaryEncoder(); 340 | if(rotaryval == ROTARY_LEFT) 341 | { 342 | cursor.keyval = KEY_UP; 343 | }else if(rotaryval == ROTARY_RIGHT) 344 | { 345 | cursor.keyval = KEY_DOWN; 346 | } 347 | ``` 348 | 349 | 其中按键值有以下: 350 | 351 | ```c 352 | #define KEY_NONE 0 //没有按下按键 353 | #define KEY_ENTER 1 //按下<确定>键 354 | #define KEY_RETURN 2 //按下<返回>键(返回上一层) 355 | #define KEY_HOME 3 //按下<首页>键 356 | #define KEY_DOWN 4 //按下<下>键 357 | #define KEY_UP 5 //按下<上>键 358 | #define KEY_ADD 6 //按下<加>键 359 | #define KEY_SUB 7 //按下<减>键 360 | ``` 361 | 362 | 363 | 364 | 365 | 366 | -------------------------------------------------------------------------------- /Hardware/Multi_Key/multi_button.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/Multi_Key/multi_button.c -------------------------------------------------------------------------------- /Hardware/Multi_Key/multi_button.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/Multi_Key/multi_button.h -------------------------------------------------------------------------------- /Hardware/Nokia5110/fonts.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/Nokia5110/fonts.h -------------------------------------------------------------------------------- /Hardware/Nokia5110/nokia5110.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/Nokia5110/nokia5110.c -------------------------------------------------------------------------------- /Hardware/Nokia5110/nokia5110.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/Nokia5110/nokia5110.h -------------------------------------------------------------------------------- /Hardware/RotaryEncoder/rotaryEncoder.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/RotaryEncoder/rotaryEncoder.c -------------------------------------------------------------------------------- /Hardware/RotaryEncoder/rotaryEncoder.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/RotaryEncoder/rotaryEncoder.h -------------------------------------------------------------------------------- /Hardware/systick/bsp_SysTick.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/systick/bsp_SysTick.c -------------------------------------------------------------------------------- /Hardware/systick/bsp_SysTick.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/systick/bsp_SysTick.h -------------------------------------------------------------------------------- /Hardware/zBitsView/zBitsView.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/zBitsView/zBitsView.c -------------------------------------------------------------------------------- /Hardware/zBitsView/zBitsView.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/Hardware/zBitsView/zBitsView.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zBitsView 2 | 3 | 4 | # 单片机实现屏幕界面,多层菜单 5 | 6 | ## 简介 7 | 8 | 1. 编写环境:Keil μVision 5 9 | 2. 硬件设备:STM32F103C8T6、Nokia 5110屏幕,EC11旋转编码器 10 | 3. 本界面控件理论上不限制屏幕、不限制单片机型号(未验证) 11 | 4. 移植方便 12 | 13 | ## 代码分析 14 | 15 | ### 数据结构 16 | 17 | 1. 行元素结构体 18 | 19 | ```c 20 | typedef struct{ 21 | uint16_t enterViewIndex;//按下确定键跳转的界面 22 | char * text; //当前行显示的文本 23 | HandlerFunc handler; //显示函数 24 | }RowListTypeDef; 25 | ``` 26 | 27 | 数组最大长度:65536 28 | 每个元素占用12字节 29 | 因为此数据不需要修改,所以可使用`const`或`code(C51)`修饰 30 | 31 | HandlerFunc是函数指针,此函数即可作为行元素的显示函数,又可作为按键处理函数,其类型为: 32 | 33 | > ```c 34 | > typedef void(*HandlerFunc)(uint16_t index, char* p, uint8_t key); 35 | > ``` 36 | > 37 | > 三个形参的作用分别是: 38 | > 39 | > > @param index: 指向此函数的RowListTypeDef在数组中的下标 40 | > > 41 | > > @param p: 指向当前RowListTypeDef元素的text指针指向的字符串 42 | > > 43 | > > @param key: 若按下按键的值大于等于6(KEY_ADD),则此形参会是非0值(KEY_NONE);若小于6,则传入0(KEY_NONE) 44 | 45 | 2. 界面结构体 46 | 47 | ```c 48 | typedef struct { 49 | const RowListTypeDef * const list;//指向当前层所指向的行元素 50 | uint16_t lengthOfList; //指向的行元素的长度 51 | uint16_t parentViewIndex; //本元素所属层的标号 52 | uint16_t startRow; //记录在上一层时的开始行索引 53 | uint8_t currRow; //记录在上一层时的行索引 54 | }ViewListTypeDef; 55 | ``` 56 | 57 | 数组最大长度:65535(0~65534) —— 65535代表RowListTypeDef元素没有指向的ViewListTypeDef元素 58 | 59 | 每个元素占用12字节 60 | 61 | 定义ViewListTypeDef型数组是可以使用`VIEW_MEMBER_FORMAT(x)`帮助编写;如: 62 | 63 | > ```C 64 | > ViewListTypeDef menu[] = { 65 | > VIEW_MEMBER_FORMAT(rowListHome), 66 | > VIEW_MEMBER_FORMAT(rowListSettingRoot), 67 | > VIEW_MEMBER_FORMAT(rowListView1), 68 | > VIEW_MEMBER_FORMAT(rowListView2), 69 | > VIEW_MEMBER_FORMAT(rowListView3), 70 | > VIEW_MEMBER_FORMAT(rowListView1_1), 71 | > }; 72 | > ``` 73 | > 74 | > 其中`VIEW_MEMBER_FORMAT`宏定义为 75 | > 76 | > ```c 77 | > #define ROW_LENGTH(x) ((uint16_t)(sizeof(x)/sizeof(RowListTypeDef))) 78 | > #define VIEW_MEMBER_FORMAT(x) {x,ROW_LENGTH(x),0,0,0} 79 | > ``` 80 | 81 | 3. 游标结构体 82 | 83 | ```c 84 | //游标,只需要定义一个即可 ==> 8字节(byte) 85 | typedef struct { 86 | uint8_t currRow; //当前指向元素 87 | uint8_t keyval; //记录按键 88 | uint16_t currViewIndex; //当前指向层 89 | uint16_t startRow; //屏幕第一行显示的行元素索引 90 | uint16_t rowNum; //记录当前层的行元素数 91 | }CursorTypeDef; 92 | ``` 93 | 94 | ### 函数作用 95 | 96 | 本控件函数很少,只有两个,即: 97 | 98 | 1. `void View_Init(ViewListTypeDef * v, CursorTypeDef * c)` 99 | 100 | 此函数的作用是初始化界面控件:将用户定义好的`ViewListTypeDef`数组的地址和`CursorTypeDef`地址初始化到控件 101 | 102 | 2. `void View_Loop(void)` 103 | 104 | 此函数作用是在处理界面数据。注意:**需要将此函数放入主循环中,每隔一段时间调用一次** 105 | 106 | > 间隔时间典型值是100ms。 107 | > 108 | > 注意:并不是本控件消耗的时间多,而是屏幕驱动程序消耗的时间太多,本人的屏幕驱动是模拟的SPI时序而不是单片机硬件SPI,故屏幕驱动消耗的时间太多。控件每次需要不到1000个机器周期,而驱动程序是其上百倍。 109 | > 110 | > 若使用硬件外设驱动屏幕,则可以将间隔时间适当调小一点,同时注意不要低于屏幕刷新周期。 111 | 112 | ### 界面设计 113 | 114 | 设计界面时只需要定义几个数组即可。 115 | 116 | 首先定义`RowListTypeDef`类型数组,根据界面数定义数组个数,根据每个界面包含的行元素数定义每个数组的长度。 117 | 118 | 然后定义`ViewListTypeDef`类型数组,定义一个即可,数组长度是界面数决定的。 119 | 120 | 例如,设计这样一个界面: 121 | 122 | > ```mermaid 123 | > graph LR 124 | > 125 | > home{home} 126 | > root{root} 127 | > v1{view1} 128 | > v2{view2} 129 | > v3{view3} 130 | > v1_1{view1-1} 131 | > 132 | > rowhome(rowHome) 133 | > home-->rowhome 134 | > rowhome-.->root 135 | > 136 | > r1(row1) 137 | > r2(row2) 138 | > r3(row3) 139 | > root-->r1 140 | > root-->r2 141 | > root-->r3 142 | > r1-.->v1 143 | > r2-.->v2 144 | > r3-.->v3 145 | > r1_1-.->v1_1 146 | > 147 | > r1_1(row1-1) 148 | > r1_2(row1-2) 149 | > r1_3(row1-3) 150 | > r1_4(row1-4) 151 | > r1_5(row1-5) 152 | > r1_6(row1-6) 153 | > r1_7(row1-7) 154 | > r1_8(row1-8) 155 | > r1_9(row1-9) 156 | > v1-->r1_1 157 | > v1-->r1_2 158 | > v1-->r1_3 159 | > v1-->r1_4 160 | > v1-->r1_5 161 | > v1-->r1_6 162 | > v1-->r1_7 163 | > v1-->r1_8 164 | > v1-->r1_9 165 | > 166 | > 167 | > r2_1(row2-1) 168 | > r2_2(row2-2) 169 | > r2_3(row2-3) 170 | > r2_4(row2-4) 171 | > r2_5(row2-5) 172 | > r2_6(row2-6) 173 | > r2_7(row2-7) 174 | > r2_8(row2-8) 175 | > v2-->r2_1 176 | > v2-->r2_2 177 | > v2-->r2_3 178 | > v2-->r2_4 179 | > v2-->r2_5 180 | > v2-->r2_6 181 | > v2-->r2_7 182 | > v2-->r2_8 183 | > 184 | > r3_1(row3-1) 185 | > r3_2(row3-2) 186 | > r3_3(row3-3) 187 | > r3_4(row3-4) 188 | > r3_5(row3-5) 189 | > r3_6(row3-6) 190 | > r3_7(row3-7) 191 | > r3_8(row3-8) 192 | > r3_9(row3-9) 193 | > r3_10(row3-10) 194 | > r3_11(row3-11) 195 | > r3_12(row3-12) 196 | > r3_13(row3-13) 197 | > r3_14(row3-14) 198 | > r3_15(row3-15) 199 | > v3-->r3_1 200 | > v3-->r3_2 201 | > v3-->r3_3 202 | > v3-->r3_4 203 | > v3-->r3_5 204 | > v3-->r3_6 205 | > v3-->r3_7 206 | > v3-->r3_8 207 | > v3-->r3_9 208 | > v3-->r3_10 209 | > v3-->r3_11 210 | > v3-->r3_12 211 | > v3-->r3_13 212 | > v3-->r3_14 213 | > v3-->r3_15 214 | > 215 | > r1_1_1(row1-1-1) 216 | > r1_1_2(row1-1-2) 217 | > r1_1_3(row1-1-3) 218 | > r1_1_4(row1-1-4) 219 | > r1_1_5(row1-1-5) 220 | > r1_1_6(row1-1-6) 221 | > r1_1_7(row1-1-7) 222 | > r1_1_8(row1-1-8) 223 | > v1_1-->r1_1_1 224 | > v1_1-->r1_1_2 225 | > v1_1-->r1_1_3 226 | > v1_1-->r1_1_4 227 | > v1_1-->r1_1_5 228 | > v1_1-->r1_1_6 229 | > v1_1-->r1_1_7 230 | > v1_1-->r1_1_8 231 | > 232 | > ``` 233 | 234 | 则需要这样定义数组 235 | 236 | ```c 237 | const RowListTypeDef rowListHome[] = { 238 | //{.enterViewIndex | .x | .text | .handler}, 239 | {1,"home",NULL}, 240 | }; 241 | 242 | const RowListTypeDef rowListSRoot[] = { 243 | //{.enterViewIndex | .x | .text | .handler}, 244 | {2,"Row 1",NULL}, 245 | {3,"Row 2",NULL}, 246 | {4,"Row 3",NULL}, 247 | }; 248 | 249 | const RowListTypeDef rowListView1[] = { 250 | //{.enterViewIndex | .x | .text | .handler}, 251 | {5,"Row 1-1",NULL}, 252 | {VIEW_NONE,"Row 1-2",NULL}, 253 | {VIEW_NONE,"Row 1-3",NULL}, 254 | {VIEW_NONE,"Row 1-4",NULL}, 255 | {VIEW_NONE,"Row 1-5",NULL}, 256 | {VIEW_NONE,"Row 1-6",NULL}, 257 | {VIEW_NONE,"Row 1-7",NULL}, 258 | {VIEW_NONE,"Row 1-8",NULL}, 259 | {VIEW_NONE,"Row 1-9",NULL}, 260 | }; 261 | 262 | const RowListTypeDef rowListView2[] = { 263 | //{.enterViewIndex | .x | .text | .handler}, 264 | {VIEW_NONE,"Row 2-1",NULL}, 265 | {VIEW_NONE,"Row 2-2",NULL}, 266 | {VIEW_NONE,"Row 2-3",NULL}, 267 | {VIEW_NONE,"Row 2-4",NULL}, 268 | {VIEW_NONE,"Row 2-5",NULL}, 269 | {VIEW_NONE,"Row 2-6",NULL}, 270 | {VIEW_NONE,"Row 2-7",NULL}, 271 | {VIEW_NONE,"Row 2-8",NULL}, 272 | }; 273 | 274 | const RowListTypeDef rowListView3[] = { 275 | //{.enterViewIndex | .x | .text | .handler}, 276 | {VIEW_NONE,"Row 3-1",NULL}, 277 | {VIEW_NONE,"Row 3-2",NULL}, 278 | {VIEW_NONE,"Row 3-3",NULL}, 279 | {VIEW_NONE,"Row 3-4",NULL}, 280 | {VIEW_NONE,"Row 3-5",NULL}, 281 | {VIEW_NONE,"Row 3-6",NULL}, 282 | {VIEW_NONE,"Row 3-7",NULL}, 283 | {VIEW_NONE,"Row 3-8",NULL}, 284 | {VIEW_NONE,"Row 3-9",NULL}, 285 | {VIEW_NONE,"Row 3-10",NULL}, 286 | {VIEW_NONE,"Row 3-11",NULL}, 287 | {VIEW_NONE,"Row 3-12",NULL}, 288 | {VIEW_NONE,"Row 3-13",NULL}, 289 | {VIEW_NONE,"Row 3-14",NULL}, 290 | {VIEW_NONE,"Row 3-15",NULL}, 291 | }; 292 | 293 | const RowListTypeDef rowListView1_1[] = { 294 | //{.enterViewIndex | .x | .text | .handler}, 295 | {VIEW_NONE,"Row 1-1-1",NULL}, 296 | {VIEW_NONE,"Row 1-1-2",NULL}, 297 | {VIEW_NONE,"Row 1-1-3",NULL}, 298 | {VIEW_NONE,"Row 1-1-4",NULL}, 299 | {VIEW_NONE,"Row 1-1-5",NULL}, 300 | {VIEW_NONE,"Row 1-1-6",NULL}, 301 | {VIEW_NONE,"Row 1-1-7",NULL}, 302 | {VIEW_NONE,"Row 1-1-8",NULL}, 303 | }; 304 | 305 | ViewListTypeDef menu[] = { 306 | //.currIndex | .parentViewIndex | .list | .lengthOfList | .display 307 | VIEW_MEMBER_FORMAT(rowListHome), 308 | VIEW_MEMBER_FORMAT(rowListSRoot), 309 | VIEW_MEMBER_FORMAT(rowListView1), 310 | VIEW_MEMBER_FORMAT(rowListView2), 311 | VIEW_MEMBER_FORMAT(rowListView3), 312 | VIEW_MEMBER_FORMAT(rowListView1_1), 313 | }; 314 | ``` 315 | 316 | ### 程序格式 317 | 318 | 程序需要定义一个全局变量游标`CursorTypeDef`,如: 319 | 320 | ```c 321 | CursorTypeDef cursor; 322 | ``` 323 | 324 | 然后在main函数中调用控件初始化程序`View_Init` 325 | 326 | ```c 327 | View_Init(menu,&cursor); 328 | ``` 329 | 330 | 在程序主循环中每隔一段时间调用程序`View_Loop`.例如每隔100ms调用一次 331 | 332 | 当有按键按下时,只需要根据按键的不同给`cursor.keyval`变量赋不同的值即可.例如: 333 | 334 | ```c 335 | rotaryval = ReadRotaryEncoder(); 336 | if(rotaryval == ROTARY_LEFT) 337 | { 338 | cursor.keyval = KEY_UP; 339 | }else if(rotaryval == ROTARY_RIGHT) 340 | { 341 | cursor.keyval = KEY_DOWN; 342 | } 343 | ``` 344 | 345 | 其中按键值有以下: 346 | 347 | ```c 348 | #define KEY_NONE 0 //没有按下按键 349 | #define KEY_ENTER 1 //按下<确定>键 350 | #define KEY_RETURN 2 //按下<返回>键(返回上一层) 351 | #define KEY_HOME 3 //按下<首页>键 352 | #define KEY_DOWN 4 //按下<下>键 353 | #define KEY_UP 5 //按下<上>键 354 | #define KEY_ADD 6 //按下<加>键 355 | #define KEY_SUB 7 //按下<减>键 356 | ``` 357 | -------------------------------------------------------------------------------- /User/main.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/figght/zBitsView/9c5a75a014e767304b13c3214cd6fb5bd7ae4dbc/User/main.c -------------------------------------------------------------------------------- /User/main.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAIN_H_ 2 | #define _MAIN_H_ 3 | 4 | #include "stm32f10x.h" 5 | #include "bsp_SysTick.h" 6 | #include "stdio.h" 7 | 8 | #define CLK_CALU(x) ((uint32_t) (0x01<<((((uint32_t)(x)&0xff00)>>8)/4))) 9 | #ifndef MIN 10 | #define MIN(x, y) ((((int32_t)(x)) < ((int32_t)(y))) ? (x) : (y)) 11 | #endif //min 12 | #ifndef MAX 13 | #define MAX(x, y) (((x) > (y)) ? (x) : (y)) 14 | #endif //max 15 | #ifndef ABS 16 | #define ABS(X) ((X) > 0 ? (X) : -(X)) 17 | #endif 18 | 19 | #endif //_MAIN_H_ 20 | 21 | 22 | -------------------------------------------------------------------------------- /User/stm32f10x_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 08-April-2011 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2011 STMicroelectronics

19 | ****************************************************************************** 20 | */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __STM32F10x_CONF_H 24 | #define __STM32F10x_CONF_H 25 | 26 | /* Includes ------------------------------------------------------------------*/ 27 | /* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */ 28 | #include "stm32f10x_adc.h" 29 | #include "stm32f10x_bkp.h" 30 | #include "stm32f10x_can.h" 31 | #include "stm32f10x_cec.h" 32 | #include "stm32f10x_crc.h" 33 | #include "stm32f10x_dac.h" 34 | #include "stm32f10x_dbgmcu.h" 35 | #include "stm32f10x_dma.h" 36 | #include "stm32f10x_exti.h" 37 | #include "stm32f10x_flash.h" 38 | #include "stm32f10x_fsmc.h" 39 | #include "stm32f10x_gpio.h" 40 | #include "stm32f10x_i2c.h" 41 | #include "stm32f10x_iwdg.h" 42 | #include "stm32f10x_pwr.h" 43 | #include "stm32f10x_rcc.h" 44 | #include "stm32f10x_rtc.h" 45 | #include "stm32f10x_sdio.h" 46 | #include "stm32f10x_spi.h" 47 | #include "stm32f10x_tim.h" 48 | #include "stm32f10x_usart.h" 49 | #include "stm32f10x_wwdg.h" 50 | #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 51 | 52 | /* Exported types ------------------------------------------------------------*/ 53 | /* Exported constants --------------------------------------------------------*/ 54 | /* Uncomment the line below to expanse the "assert_param" macro in the 55 | Standard Peripheral Library drivers code */ 56 | /* #define USE_FULL_ASSERT 1 */ 57 | 58 | /* Exported macro ------------------------------------------------------------*/ 59 | #ifdef USE_FULL_ASSERT 60 | 61 | /** 62 | * @brief The assert_param macro is used for function's parameters check. 63 | * @param expr: If expr is false, it calls assert_failed function which reports 64 | * the name of the source file and the source line number of the call 65 | * that failed. If expr is true, it returns no value. 66 | * @retval None 67 | */ 68 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 69 | /* Exported functions ------------------------------------------------------- */ 70 | void assert_failed(uint8_t* file, uint32_t line); 71 | #else 72 | #define assert_param(expr) ((void)0) 73 | #endif /* USE_FULL_ASSERT */ 74 | 75 | #endif /* __STM32F10x_CONF_H */ 76 | 77 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 78 | -------------------------------------------------------------------------------- /User/stm32f10x_it.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 08-April-2011 7 | * @brief Main Interrupt Service Routines. 8 | * This file provides template for all exceptions handler and 9 | * peripherals interrupt service routine. 10 | ****************************************************************************** 11 | * @attention 12 | * 13 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 14 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 15 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 16 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 17 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 18 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 19 | * 20 | *

© COPYRIGHT 2011 STMicroelectronics

21 | ****************************************************************************** 22 | */ 23 | 24 | /* Includes ------------------------------------------------------------------*/ 25 | #include "stm32f10x_it.h" 26 | #include "bsp_SysTick.h" 27 | 28 | /** @addtogroup STM32F10x_StdPeriph_Template 29 | * @{ 30 | */ 31 | 32 | /* Private typedef -----------------------------------------------------------*/ 33 | /* Private define ------------------------------------------------------------*/ 34 | /* Private macro -------------------------------------------------------------*/ 35 | /* Private variables ---------------------------------------------------------*/ 36 | /* Private function prototypes -----------------------------------------------*/ 37 | /* Private functions ---------------------------------------------------------*/ 38 | 39 | /******************************************************************************/ 40 | /* Cortex-M3 Processor Exceptions Handlers */ 41 | /******************************************************************************/ 42 | 43 | /** 44 | * @brief This function handles NMI exception. 45 | * @param None 46 | * @retval None 47 | */ 48 | void NMI_Handler(void) 49 | { 50 | } 51 | 52 | /** 53 | * @brief This function handles Hard Fault exception. 54 | * @param None 55 | * @retval None 56 | */ 57 | void HardFault_Handler(void) 58 | { 59 | /* Go to infinite loop when Hard Fault exception occurs */ 60 | while (1) 61 | { 62 | } 63 | } 64 | 65 | /** 66 | * @brief This function handles Memory Manage exception. 67 | * @param None 68 | * @retval None 69 | */ 70 | void MemManage_Handler(void) 71 | { 72 | /* Go to infinite loop when Memory Manage exception occurs */ 73 | while (1) 74 | { 75 | } 76 | } 77 | 78 | /** 79 | * @brief This function handles Bus Fault exception. 80 | * @param None 81 | * @retval None 82 | */ 83 | void BusFault_Handler(void) 84 | { 85 | /* Go to infinite loop when Bus Fault exception occurs */ 86 | while (1) 87 | { 88 | } 89 | } 90 | 91 | /** 92 | * @brief This function handles Usage Fault exception. 93 | * @param None 94 | * @retval None 95 | */ 96 | void UsageFault_Handler(void) 97 | { 98 | /* Go to infinite loop when Usage Fault exception occurs */ 99 | while (1) 100 | { 101 | } 102 | } 103 | 104 | /** 105 | * @brief This function handles SVCall exception. 106 | * @param None 107 | * @retval None 108 | */ 109 | void SVC_Handler(void) 110 | { 111 | } 112 | 113 | /** 114 | * @brief This function handles Debug Monitor exception. 115 | * @param None 116 | * @retval None 117 | */ 118 | void DebugMon_Handler(void) 119 | { 120 | } 121 | 122 | /** 123 | * @brief This function handles PendSVC exception. 124 | * @param None 125 | * @retval None 126 | */ 127 | void PendSV_Handler(void) 128 | { 129 | } 130 | 131 | /** 132 | * @brief This function handles SysTick Handler. 133 | * @param None 134 | * @retval None 135 | */ 136 | void SysTick_Handler(void) 137 | { 138 | TimingDelay_Decrement();//?????? 139 | _TimeStap_APP(); 140 | } 141 | 142 | /******************************************************************************/ 143 | /* STM32F10x Peripherals Interrupt Handlers */ 144 | /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ 145 | /* available peripheral interrupt handler's name please refer to the startup */ 146 | /* file (startup_stm32f10x_xx.s). */ 147 | /******************************************************************************/ 148 | 149 | /** 150 | * @brief This function handles PPP interrupt request. 151 | * @param None 152 | * @retval None 153 | */ 154 | /*void PPP_IRQHandler(void) 155 | { 156 | }*/ 157 | 158 | /** 159 | * @} 160 | */ 161 | 162 | 163 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 164 | -------------------------------------------------------------------------------- /User/stm32f10x_it.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Project/STM32F10x_StdPeriph_Template/stm32f10x_it.h 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 08-April-2011 7 | * @brief This file contains the headers of the interrupt handlers. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2011 STMicroelectronics

19 | ****************************************************************************** 20 | */ 21 | 22 | /* Define to prevent recursive inclusion -------------------------------------*/ 23 | #ifndef __STM32F10x_IT_H 24 | #define __STM32F10x_IT_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "stm32f10x.h" 32 | 33 | /* Exported types ------------------------------------------------------------*/ 34 | /* Exported constants --------------------------------------------------------*/ 35 | /* Exported macro ------------------------------------------------------------*/ 36 | /* Exported functions ------------------------------------------------------- */ 37 | 38 | void NMI_Handler(void); 39 | void HardFault_Handler(void); 40 | void MemManage_Handler(void); 41 | void BusFault_Handler(void); 42 | void UsageFault_Handler(void); 43 | void SVC_Handler(void); 44 | void DebugMon_Handler(void); 45 | void PendSV_Handler(void); 46 | void SysTick_Handler(void); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /* __STM32F10x_IT_H */ 53 | 54 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 55 | -------------------------------------------------------------------------------- /User/system_stm32f10x.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f10x.c 4 | * @author MCD Application Team 5 | * @version V3.5.0 6 | * @date 08-April-2011 7 | * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. 8 | * 9 | * 1. This file provides two functions and one global variable to be called from 10 | * user application: 11 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 12 | * factors, AHB/APBx prescalers and Flash settings). 13 | * This function is called at startup just after reset and 14 | * before branch to main program. This call is made inside 15 | * the "startup_stm32f10x_xx.s" file. 16 | * 17 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 18 | * by the user application to setup the SysTick 19 | * timer or configure other parameters. 20 | * 21 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 22 | * be called whenever the core clock is changed 23 | * during program execution. 24 | * 25 | * 2. After each device reset the HSI (8 MHz) is used as system clock source. 26 | * Then SystemInit() function is called, in "startup_stm32f10x_xx.s" file, to 27 | * configure the system clock before to branch to main program. 28 | * 29 | * 3. If the system clock source selected by user fails to startup, the SystemInit() 30 | * function will do nothing and HSI still used as system clock source. User can 31 | * add some code to deal with this issue inside the SetSysClock() function. 32 | * 33 | * 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depedning on 34 | * the product used), refer to "HSE_VALUE" define in "stm32f10x.h" file. 35 | * When HSE is used as system clock source, directly or through PLL, and you 36 | * are using different crystal you have to adapt the HSE value to your own 37 | * configuration. 38 | * 39 | ****************************************************************************** 40 | * @attention 41 | * 42 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 43 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 44 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 45 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 46 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 47 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 48 | * 49 | *

© COPYRIGHT 2011 STMicroelectronics

50 | ****************************************************************************** 51 | */ 52 | 53 | /** @addtogroup CMSIS 54 | * @{ 55 | */ 56 | 57 | /** @addtogroup stm32f10x_system 58 | * @{ 59 | */ 60 | 61 | /** @addtogroup STM32F10x_System_Private_Includes 62 | * @{ 63 | */ 64 | 65 | #include "stm32f10x.h" 66 | 67 | /** 68 | * @} 69 | */ 70 | 71 | /** @addtogroup STM32F10x_System_Private_TypesDefinitions 72 | * @{ 73 | */ 74 | 75 | /** 76 | * @} 77 | */ 78 | 79 | /** @addtogroup STM32F10x_System_Private_Defines 80 | * @{ 81 | */ 82 | 83 | /*!< Uncomment the line corresponding to the desired System clock (SYSCLK) 84 | frequency (after reset the HSI is used as SYSCLK source) 85 | 86 | IMPORTANT NOTE: 87 | ============== 88 | 1. After each device reset the HSI is used as System clock source. 89 | 90 | 2. Please make sure that the selected System clock doesn't exceed your device's 91 | maximum frequency. 92 | 93 | 3. If none of the define below is enabled, the HSI is used as System clock 94 | source. 95 | 96 | 4. The System clock configuration functions provided within this file assume that: 97 | - For Low, Medium and High density Value line devices an external 8MHz 98 | crystal is used to drive the System clock. 99 | - For Low, Medium and High density devices an external 8MHz crystal is 100 | used to drive the System clock. 101 | - For Connectivity line devices an external 25MHz crystal is used to drive 102 | the System clock. 103 | If you are using different crystal you have to adapt those functions accordingly. 104 | */ 105 | 106 | #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 107 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */ 108 | #define SYSCLK_FREQ_24MHz 24000000 109 | #else 110 | /* #define SYSCLK_FREQ_HSE HSE_VALUE */ 111 | /* #define SYSCLK_FREQ_24MHz 24000000 */ 112 | /* #define SYSCLK_FREQ_36MHz 36000000 */ 113 | /* #define SYSCLK_FREQ_48MHz 48000000 */ 114 | /* #define SYSCLK_FREQ_56MHz 56000000 */ 115 | #define SYSCLK_FREQ_72MHz 72000000 116 | #endif 117 | 118 | /*!< Uncomment the following line if you need to use external SRAM mounted 119 | on STM3210E-EVAL board (STM32 High density and XL-density devices) or on 120 | STM32100E-EVAL board (STM32 High-density value line devices) as data memory */ 121 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 122 | /* #define DATA_IN_ExtSRAM */ 123 | #endif 124 | 125 | /*!< Uncomment the following line if you need to relocate your vector Table in 126 | Internal SRAM. */ 127 | /* #define VECT_TAB_SRAM */ 128 | #define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. 129 | This value must be a multiple of 0x200. */ 130 | 131 | 132 | /** 133 | * @} 134 | */ 135 | 136 | /** @addtogroup STM32F10x_System_Private_Macros 137 | * @{ 138 | */ 139 | 140 | /** 141 | * @} 142 | */ 143 | 144 | /** @addtogroup STM32F10x_System_Private_Variables 145 | * @{ 146 | */ 147 | 148 | /******************************************************************************* 149 | * Clock Definitions 150 | *******************************************************************************/ 151 | #ifdef SYSCLK_FREQ_HSE 152 | uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */ 153 | #elif defined SYSCLK_FREQ_24MHz 154 | uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */ 155 | #elif defined SYSCLK_FREQ_36MHz 156 | uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */ 157 | #elif defined SYSCLK_FREQ_48MHz 158 | uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */ 159 | #elif defined SYSCLK_FREQ_56MHz 160 | uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */ 161 | #elif defined SYSCLK_FREQ_72MHz 162 | uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ 163 | #else /*!< HSI Selected as System Clock source */ 164 | uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */ 165 | #endif 166 | 167 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 168 | /** 169 | * @} 170 | */ 171 | 172 | /** @addtogroup STM32F10x_System_Private_FunctionPrototypes 173 | * @{ 174 | */ 175 | 176 | static void SetSysClock(void); 177 | 178 | #ifdef SYSCLK_FREQ_HSE 179 | static void SetSysClockToHSE(void); 180 | #elif defined SYSCLK_FREQ_24MHz 181 | static void SetSysClockTo24(void); 182 | #elif defined SYSCLK_FREQ_36MHz 183 | static void SetSysClockTo36(void); 184 | #elif defined SYSCLK_FREQ_48MHz 185 | static void SetSysClockTo48(void); 186 | #elif defined SYSCLK_FREQ_56MHz 187 | static void SetSysClockTo56(void); 188 | #elif defined SYSCLK_FREQ_72MHz 189 | static void SetSysClockTo72(void); 190 | #endif 191 | 192 | #ifdef DATA_IN_ExtSRAM 193 | static void SystemInit_ExtMemCtl(void); 194 | #endif /* DATA_IN_ExtSRAM */ 195 | 196 | /** 197 | * @} 198 | */ 199 | 200 | /** @addtogroup STM32F10x_System_Private_Functions 201 | * @{ 202 | */ 203 | 204 | /** 205 | * @brief Setup the microcontroller system 206 | * Initialize the Embedded Flash Interface, the PLL and update the 207 | * SystemCoreClock variable. 208 | * @note This function should be used only after reset. 209 | * @param None 210 | * @retval None 211 | */ 212 | void SystemInit (void) 213 | { 214 | /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ 215 | /* Set HSION bit */ 216 | RCC->CR |= (uint32_t)0x00000001; 217 | 218 | /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ 219 | #ifndef STM32F10X_CL 220 | RCC->CFGR &= (uint32_t)0xF8FF0000; 221 | #else 222 | RCC->CFGR &= (uint32_t)0xF0FF0000; 223 | #endif /* STM32F10X_CL */ 224 | 225 | /* Reset HSEON, CSSON and PLLON bits */ 226 | RCC->CR &= (uint32_t)0xFEF6FFFF; 227 | 228 | /* Reset HSEBYP bit */ 229 | RCC->CR &= (uint32_t)0xFFFBFFFF; 230 | 231 | /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ 232 | RCC->CFGR &= (uint32_t)0xFF80FFFF; 233 | 234 | #ifdef STM32F10X_CL 235 | /* Reset PLL2ON and PLL3ON bits */ 236 | RCC->CR &= (uint32_t)0xEBFFFFFF; 237 | 238 | /* Disable all interrupts and clear pending bits */ 239 | RCC->CIR = 0x00FF0000; 240 | 241 | /* Reset CFGR2 register */ 242 | RCC->CFGR2 = 0x00000000; 243 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 244 | /* Disable all interrupts and clear pending bits */ 245 | RCC->CIR = 0x009F0000; 246 | 247 | /* Reset CFGR2 register */ 248 | RCC->CFGR2 = 0x00000000; 249 | #else 250 | /* Disable all interrupts and clear pending bits */ 251 | RCC->CIR = 0x009F0000; 252 | #endif /* STM32F10X_CL */ 253 | 254 | #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) 255 | #ifdef DATA_IN_ExtSRAM 256 | SystemInit_ExtMemCtl(); 257 | #endif /* DATA_IN_ExtSRAM */ 258 | #endif 259 | 260 | /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ 261 | /* Configure the Flash Latency cycles and enable prefetch buffer */ 262 | SetSysClock(); 263 | 264 | #ifdef VECT_TAB_SRAM 265 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */ 266 | #else 267 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */ 268 | #endif 269 | } 270 | 271 | /** 272 | * @brief Update SystemCoreClock variable according to Clock Register Values. 273 | * The SystemCoreClock variable contains the core clock (HCLK), it can 274 | * be used by the user application to setup the SysTick timer or configure 275 | * other parameters. 276 | * 277 | * @note Each time the core clock (HCLK) changes, this function must be called 278 | * to update SystemCoreClock variable value. Otherwise, any configuration 279 | * based on this variable will be incorrect. 280 | * 281 | * @note - The system frequency computed by this function is not the real 282 | * frequency in the chip. It is calculated based on the predefined 283 | * constant and the selected clock source: 284 | * 285 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 286 | * 287 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 288 | * 289 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 290 | * or HSI_VALUE(*) multiplied by the PLL factors. 291 | * 292 | * (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value 293 | * 8 MHz) but the real value may vary depending on the variations 294 | * in voltage and temperature. 295 | * 296 | * (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value 297 | * 8 MHz or 25 MHz, depedning on the product used), user has to ensure 298 | * that HSE_VALUE is same as the real frequency of the crystal used. 299 | * Otherwise, this function may have wrong result. 300 | * 301 | * - The result of this function could be not correct when using fractional 302 | * value for HSE crystal. 303 | * @param None 304 | * @retval None 305 | */ 306 | void SystemCoreClockUpdate (void) 307 | { 308 | uint32_t tmp = 0, pllmull = 0, pllsource = 0; 309 | 310 | #ifdef STM32F10X_CL 311 | uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0; 312 | #endif /* STM32F10X_CL */ 313 | 314 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 315 | uint32_t prediv1factor = 0; 316 | #endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */ 317 | 318 | /* Get SYSCLK source -------------------------------------------------------*/ 319 | tmp = RCC->CFGR & RCC_CFGR_SWS; 320 | 321 | switch (tmp) 322 | { 323 | case 0x00: /* HSI used as system clock */ 324 | SystemCoreClock = HSI_VALUE; 325 | break; 326 | case 0x04: /* HSE used as system clock */ 327 | SystemCoreClock = HSE_VALUE; 328 | break; 329 | case 0x08: /* PLL used as system clock */ 330 | 331 | /* Get PLL clock source and multiplication factor ----------------------*/ 332 | pllmull = RCC->CFGR & RCC_CFGR_PLLMULL; 333 | pllsource = RCC->CFGR & RCC_CFGR_PLLSRC; 334 | 335 | #ifndef STM32F10X_CL 336 | pllmull = ( pllmull >> 18) + 2; 337 | 338 | if (pllsource == 0x00) 339 | { 340 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 341 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 342 | } 343 | else 344 | { 345 | #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) 346 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 347 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 348 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 349 | #else 350 | /* HSE selected as PLL clock entry */ 351 | if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET) 352 | {/* HSE oscillator clock divided by 2 */ 353 | SystemCoreClock = (HSE_VALUE >> 1) * pllmull; 354 | } 355 | else 356 | { 357 | SystemCoreClock = HSE_VALUE * pllmull; 358 | } 359 | #endif 360 | } 361 | #else 362 | pllmull = pllmull >> 18; 363 | 364 | if (pllmull != 0x0D) 365 | { 366 | pllmull += 2; 367 | } 368 | else 369 | { /* PLL multiplication factor = PLL input clock * 6.5 */ 370 | pllmull = 13 / 2; 371 | } 372 | 373 | if (pllsource == 0x00) 374 | { 375 | /* HSI oscillator clock divided by 2 selected as PLL clock entry */ 376 | SystemCoreClock = (HSI_VALUE >> 1) * pllmull; 377 | } 378 | else 379 | {/* PREDIV1 selected as PLL clock entry */ 380 | 381 | /* Get PREDIV1 clock source and division factor */ 382 | prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC; 383 | prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1; 384 | 385 | if (prediv1source == 0) 386 | { 387 | /* HSE oscillator clock selected as PREDIV1 clock entry */ 388 | SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull; 389 | } 390 | else 391 | {/* PLL2 clock selected as PREDIV1 clock entry */ 392 | 393 | /* Get PREDIV2 division factor and PLL2 multiplication factor */ 394 | prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1; 395 | pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2; 396 | SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull; 397 | } 398 | } 399 | #endif /* STM32F10X_CL */ 400 | break; 401 | 402 | default: 403 | SystemCoreClock = HSI_VALUE; 404 | break; 405 | } 406 | 407 | /* Compute HCLK clock frequency ----------------*/ 408 | /* Get HCLK prescaler */ 409 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 410 | /* HCLK clock frequency */ 411 | SystemCoreClock >>= tmp; 412 | } 413 | 414 | /** 415 | * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. 416 | * @param None 417 | * @retval None 418 | */ 419 | static void SetSysClock(void) 420 | { 421 | #ifdef SYSCLK_FREQ_HSE 422 | SetSysClockToHSE(); 423 | #elif defined SYSCLK_FREQ_24MHz 424 | SetSysClockTo24(); 425 | #elif defined SYSCLK_FREQ_36MHz 426 | SetSysClockTo36(); 427 | #elif defined SYSCLK_FREQ_48MHz 428 | SetSysClockTo48(); 429 | #elif defined SYSCLK_FREQ_56MHz 430 | SetSysClockTo56(); 431 | #elif defined SYSCLK_FREQ_72MHz 432 | SetSysClockTo72(); 433 | #endif 434 | 435 | /* If none of the define above is enabled, the HSI is used as System clock 436 | source (default after reset) */ 437 | } 438 | 439 | /** 440 | * @brief Setup the external memory controller. Called in startup_stm32f10x.s 441 | * before jump to __main 442 | * @param None 443 | * @retval None 444 | */ 445 | #ifdef DATA_IN_ExtSRAM 446 | /** 447 | * @brief Setup the external memory controller. 448 | * Called in startup_stm32f10x_xx.s/.c before jump to main. 449 | * This function configures the external SRAM mounted on STM3210E-EVAL 450 | * board (STM32 High density devices). This SRAM will be used as program 451 | * data memory (including heap and stack). 452 | * @param None 453 | * @retval None 454 | */ 455 | void SystemInit_ExtMemCtl(void) 456 | { 457 | /*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is 458 | required, then adjust the Register Addresses */ 459 | 460 | /* Enable FSMC clock */ 461 | RCC->AHBENR = 0x00000114; 462 | 463 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */ 464 | RCC->APB2ENR = 0x000001E0; 465 | 466 | /* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/ 467 | /*---------------- SRAM Address lines configuration -------------------------*/ 468 | /*---------------- NOE and NWE configuration --------------------------------*/ 469 | /*---------------- NE3 configuration ----------------------------------------*/ 470 | /*---------------- NBL0, NBL1 configuration ---------------------------------*/ 471 | 472 | GPIOD->CRL = 0x44BB44BB; 473 | GPIOD->CRH = 0xBBBBBBBB; 474 | 475 | GPIOE->CRL = 0xB44444BB; 476 | GPIOE->CRH = 0xBBBBBBBB; 477 | 478 | GPIOF->CRL = 0x44BBBBBB; 479 | GPIOF->CRH = 0xBBBB4444; 480 | 481 | GPIOG->CRL = 0x44BBBBBB; 482 | GPIOG->CRH = 0x44444B44; 483 | 484 | /*---------------- FSMC Configuration ---------------------------------------*/ 485 | /*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/ 486 | 487 | FSMC_Bank1->BTCR[4] = 0x00001011; 488 | FSMC_Bank1->BTCR[5] = 0x00000200; 489 | } 490 | #endif /* DATA_IN_ExtSRAM */ 491 | 492 | #ifdef SYSCLK_FREQ_HSE 493 | /** 494 | * @brief Selects HSE as System clock source and configure HCLK, PCLK2 495 | * and PCLK1 prescalers. 496 | * @note This function should be used only after reset. 497 | * @param None 498 | * @retval None 499 | */ 500 | static void SetSysClockToHSE(void) 501 | { 502 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 503 | 504 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 505 | /* Enable HSE */ 506 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 507 | 508 | /* Wait till HSE is ready and if Time out is reached exit */ 509 | do 510 | { 511 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 512 | StartUpCounter++; 513 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 514 | 515 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 516 | { 517 | HSEStatus = (uint32_t)0x01; 518 | } 519 | else 520 | { 521 | HSEStatus = (uint32_t)0x00; 522 | } 523 | 524 | if (HSEStatus == (uint32_t)0x01) 525 | { 526 | 527 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 528 | /* Enable Prefetch Buffer */ 529 | FLASH->ACR |= FLASH_ACR_PRFTBE; 530 | 531 | /* Flash 0 wait state */ 532 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 533 | 534 | #ifndef STM32F10X_CL 535 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 536 | #else 537 | if (HSE_VALUE <= 24000000) 538 | { 539 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 540 | } 541 | else 542 | { 543 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 544 | } 545 | #endif /* STM32F10X_CL */ 546 | #endif 547 | 548 | /* HCLK = SYSCLK */ 549 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 550 | 551 | /* PCLK2 = HCLK */ 552 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 553 | 554 | /* PCLK1 = HCLK */ 555 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 556 | 557 | /* Select HSE as system clock source */ 558 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 559 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE; 560 | 561 | /* Wait till HSE is used as system clock source */ 562 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04) 563 | { 564 | } 565 | } 566 | else 567 | { /* If HSE fails to start-up, the application will have wrong clock 568 | configuration. User can add here some code to deal with this error */ 569 | } 570 | } 571 | #elif defined SYSCLK_FREQ_24MHz 572 | /** 573 | * @brief Sets System clock frequency to 24MHz and configure HCLK, PCLK2 574 | * and PCLK1 prescalers. 575 | * @note This function should be used only after reset. 576 | * @param None 577 | * @retval None 578 | */ 579 | static void SetSysClockTo24(void) 580 | { 581 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 582 | 583 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 584 | /* Enable HSE */ 585 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 586 | 587 | /* Wait till HSE is ready and if Time out is reached exit */ 588 | do 589 | { 590 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 591 | StartUpCounter++; 592 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 593 | 594 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 595 | { 596 | HSEStatus = (uint32_t)0x01; 597 | } 598 | else 599 | { 600 | HSEStatus = (uint32_t)0x00; 601 | } 602 | 603 | if (HSEStatus == (uint32_t)0x01) 604 | { 605 | #if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL 606 | /* Enable Prefetch Buffer */ 607 | FLASH->ACR |= FLASH_ACR_PRFTBE; 608 | 609 | /* Flash 0 wait state */ 610 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 611 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0; 612 | #endif 613 | 614 | /* HCLK = SYSCLK */ 615 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 616 | 617 | /* PCLK2 = HCLK */ 618 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 619 | 620 | /* PCLK1 = HCLK */ 621 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 622 | 623 | #ifdef STM32F10X_CL 624 | /* Configure PLLs ------------------------------------------------------*/ 625 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 24 MHz */ 626 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 627 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 628 | RCC_CFGR_PLLMULL6); 629 | 630 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 631 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ 632 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 633 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 634 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 635 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); 636 | 637 | /* Enable PLL2 */ 638 | RCC->CR |= RCC_CR_PLL2ON; 639 | /* Wait till PLL2 is ready */ 640 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 641 | { 642 | } 643 | #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) 644 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ 645 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 646 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL6); 647 | #else 648 | /* PLL configuration: = (HSE / 2) * 6 = 24 MHz */ 649 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 650 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL6); 651 | #endif /* STM32F10X_CL */ 652 | 653 | /* Enable PLL */ 654 | RCC->CR |= RCC_CR_PLLON; 655 | 656 | /* Wait till PLL is ready */ 657 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 658 | { 659 | } 660 | 661 | /* Select PLL as system clock source */ 662 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 663 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 664 | 665 | /* Wait till PLL is used as system clock source */ 666 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 667 | { 668 | } 669 | } 670 | else 671 | { /* If HSE fails to start-up, the application will have wrong clock 672 | configuration. User can add here some code to deal with this error */ 673 | } 674 | } 675 | #elif defined SYSCLK_FREQ_36MHz 676 | /** 677 | * @brief Sets System clock frequency to 36MHz and configure HCLK, PCLK2 678 | * and PCLK1 prescalers. 679 | * @note This function should be used only after reset. 680 | * @param None 681 | * @retval None 682 | */ 683 | static void SetSysClockTo36(void) 684 | { 685 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 686 | 687 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 688 | /* Enable HSE */ 689 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 690 | 691 | /* Wait till HSE is ready and if Time out is reached exit */ 692 | do 693 | { 694 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 695 | StartUpCounter++; 696 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 697 | 698 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 699 | { 700 | HSEStatus = (uint32_t)0x01; 701 | } 702 | else 703 | { 704 | HSEStatus = (uint32_t)0x00; 705 | } 706 | 707 | if (HSEStatus == (uint32_t)0x01) 708 | { 709 | /* Enable Prefetch Buffer */ 710 | FLASH->ACR |= FLASH_ACR_PRFTBE; 711 | 712 | /* Flash 1 wait state */ 713 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 714 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 715 | 716 | /* HCLK = SYSCLK */ 717 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 718 | 719 | /* PCLK2 = HCLK */ 720 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 721 | 722 | /* PCLK1 = HCLK */ 723 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1; 724 | 725 | #ifdef STM32F10X_CL 726 | /* Configure PLLs ------------------------------------------------------*/ 727 | 728 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 36 MHz */ 729 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 730 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 731 | RCC_CFGR_PLLMULL9); 732 | 733 | /*!< PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 734 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 10 = 4 MHz */ 735 | 736 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 737 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 738 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 739 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV10); 740 | 741 | /* Enable PLL2 */ 742 | RCC->CR |= RCC_CR_PLL2ON; 743 | /* Wait till PLL2 is ready */ 744 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 745 | { 746 | } 747 | 748 | #else 749 | /* PLL configuration: PLLCLK = (HSE / 2) * 9 = 36 MHz */ 750 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 751 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9); 752 | #endif /* STM32F10X_CL */ 753 | 754 | /* Enable PLL */ 755 | RCC->CR |= RCC_CR_PLLON; 756 | 757 | /* Wait till PLL is ready */ 758 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 759 | { 760 | } 761 | 762 | /* Select PLL as system clock source */ 763 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 764 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 765 | 766 | /* Wait till PLL is used as system clock source */ 767 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 768 | { 769 | } 770 | } 771 | else 772 | { /* If HSE fails to start-up, the application will have wrong clock 773 | configuration. User can add here some code to deal with this error */ 774 | } 775 | } 776 | #elif defined SYSCLK_FREQ_48MHz 777 | /** 778 | * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 779 | * and PCLK1 prescalers. 780 | * @note This function should be used only after reset. 781 | * @param None 782 | * @retval None 783 | */ 784 | static void SetSysClockTo48(void) 785 | { 786 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 787 | 788 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 789 | /* Enable HSE */ 790 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 791 | 792 | /* Wait till HSE is ready and if Time out is reached exit */ 793 | do 794 | { 795 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 796 | StartUpCounter++; 797 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 798 | 799 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 800 | { 801 | HSEStatus = (uint32_t)0x01; 802 | } 803 | else 804 | { 805 | HSEStatus = (uint32_t)0x00; 806 | } 807 | 808 | if (HSEStatus == (uint32_t)0x01) 809 | { 810 | /* Enable Prefetch Buffer */ 811 | FLASH->ACR |= FLASH_ACR_PRFTBE; 812 | 813 | /* Flash 1 wait state */ 814 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 815 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1; 816 | 817 | /* HCLK = SYSCLK */ 818 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 819 | 820 | /* PCLK2 = HCLK */ 821 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 822 | 823 | /* PCLK1 = HCLK */ 824 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 825 | 826 | #ifdef STM32F10X_CL 827 | /* Configure PLLs ------------------------------------------------------*/ 828 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 829 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 830 | 831 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 832 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 833 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 834 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 835 | 836 | /* Enable PLL2 */ 837 | RCC->CR |= RCC_CR_PLL2ON; 838 | /* Wait till PLL2 is ready */ 839 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 840 | { 841 | } 842 | 843 | 844 | /* PLL configuration: PLLCLK = PREDIV1 * 6 = 48 MHz */ 845 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 846 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 847 | RCC_CFGR_PLLMULL6); 848 | #else 849 | /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ 850 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 851 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL6); 852 | #endif /* STM32F10X_CL */ 853 | 854 | /* Enable PLL */ 855 | RCC->CR |= RCC_CR_PLLON; 856 | 857 | /* Wait till PLL is ready */ 858 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 859 | { 860 | } 861 | 862 | /* Select PLL as system clock source */ 863 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 864 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 865 | 866 | /* Wait till PLL is used as system clock source */ 867 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 868 | { 869 | } 870 | } 871 | else 872 | { /* If HSE fails to start-up, the application will have wrong clock 873 | configuration. User can add here some code to deal with this error */ 874 | } 875 | } 876 | 877 | #elif defined SYSCLK_FREQ_56MHz 878 | /** 879 | * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 880 | * and PCLK1 prescalers. 881 | * @note This function should be used only after reset. 882 | * @param None 883 | * @retval None 884 | */ 885 | static void SetSysClockTo56(void) 886 | { 887 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 888 | 889 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 890 | /* Enable HSE */ 891 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 892 | 893 | /* Wait till HSE is ready and if Time out is reached exit */ 894 | do 895 | { 896 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 897 | StartUpCounter++; 898 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 899 | 900 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 901 | { 902 | HSEStatus = (uint32_t)0x01; 903 | } 904 | else 905 | { 906 | HSEStatus = (uint32_t)0x00; 907 | } 908 | 909 | if (HSEStatus == (uint32_t)0x01) 910 | { 911 | /* Enable Prefetch Buffer */ 912 | FLASH->ACR |= FLASH_ACR_PRFTBE; 913 | 914 | /* Flash 2 wait state */ 915 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 916 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 917 | 918 | /* HCLK = SYSCLK */ 919 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 920 | 921 | /* PCLK2 = HCLK */ 922 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 923 | 924 | /* PCLK1 = HCLK */ 925 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 926 | 927 | #ifdef STM32F10X_CL 928 | /* Configure PLLs ------------------------------------------------------*/ 929 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 930 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 931 | 932 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 933 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 934 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 935 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 936 | 937 | /* Enable PLL2 */ 938 | RCC->CR |= RCC_CR_PLL2ON; 939 | /* Wait till PLL2 is ready */ 940 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 941 | { 942 | } 943 | 944 | 945 | /* PLL configuration: PLLCLK = PREDIV1 * 7 = 56 MHz */ 946 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 947 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 948 | RCC_CFGR_PLLMULL7); 949 | #else 950 | /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ 951 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); 952 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL7); 953 | 954 | #endif /* STM32F10X_CL */ 955 | 956 | /* Enable PLL */ 957 | RCC->CR |= RCC_CR_PLLON; 958 | 959 | /* Wait till PLL is ready */ 960 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 961 | { 962 | } 963 | 964 | /* Select PLL as system clock source */ 965 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 966 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 967 | 968 | /* Wait till PLL is used as system clock source */ 969 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 970 | { 971 | } 972 | } 973 | else 974 | { /* If HSE fails to start-up, the application will have wrong clock 975 | configuration. User can add here some code to deal with this error */ 976 | } 977 | } 978 | 979 | #elif defined SYSCLK_FREQ_72MHz 980 | /** 981 | * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 982 | * and PCLK1 prescalers. 983 | * @note This function should be used only after reset. 984 | * @param None 985 | * @retval None 986 | */ 987 | static void SetSysClockTo72(void) 988 | { 989 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 990 | 991 | /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ 992 | /* Enable HSE */ 993 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 994 | 995 | /* Wait till HSE is ready and if Time out is reached exit */ 996 | do 997 | { 998 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 999 | StartUpCounter++; 1000 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 1001 | 1002 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 1003 | { 1004 | HSEStatus = (uint32_t)0x01; 1005 | } 1006 | else 1007 | { 1008 | HSEStatus = (uint32_t)0x00; 1009 | } 1010 | 1011 | if (HSEStatus == (uint32_t)0x01) 1012 | { 1013 | /* Enable Prefetch Buffer */ 1014 | FLASH->ACR |= FLASH_ACR_PRFTBE; 1015 | 1016 | /* Flash 2 wait state */ 1017 | FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); 1018 | FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; 1019 | 1020 | 1021 | /* HCLK = SYSCLK */ 1022 | RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; 1023 | 1024 | /* PCLK2 = HCLK */ 1025 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; 1026 | 1027 | /* PCLK1 = HCLK */ 1028 | RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 1029 | 1030 | #ifdef STM32F10X_CL 1031 | /* Configure PLLs ------------------------------------------------------*/ 1032 | /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ 1033 | /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ 1034 | 1035 | RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 1036 | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 1037 | RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | 1038 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 1039 | 1040 | /* Enable PLL2 */ 1041 | RCC->CR |= RCC_CR_PLL2ON; 1042 | /* Wait till PLL2 is ready */ 1043 | while((RCC->CR & RCC_CR_PLL2RDY) == 0) 1044 | { 1045 | } 1046 | 1047 | 1048 | /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 1049 | RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); 1050 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 1051 | RCC_CFGR_PLLMULL9); 1052 | #else 1053 | /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ 1054 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | 1055 | RCC_CFGR_PLLMULL)); 1056 | RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); 1057 | #endif /* STM32F10X_CL */ 1058 | 1059 | /* Enable PLL */ 1060 | RCC->CR |= RCC_CR_PLLON; 1061 | 1062 | /* Wait till PLL is ready */ 1063 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 1064 | { 1065 | } 1066 | 1067 | /* Select PLL as system clock source */ 1068 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 1069 | RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 1070 | 1071 | /* Wait till PLL is used as system clock source */ 1072 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) 1073 | { 1074 | } 1075 | } 1076 | else 1077 | { /* If HSE fails to start-up, the application will have wrong clock 1078 | configuration. User can add here some code to deal with this error */ 1079 | } 1080 | } 1081 | #endif 1082 | 1083 | /** 1084 | * @} 1085 | */ 1086 | 1087 | /** 1088 | * @} 1089 | */ 1090 | 1091 | /** 1092 | * @} 1093 | */ 1094 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 1095 | --------------------------------------------------------------------------------