wangkuo0203的个人空间 https://bbs.21ic.com/?697112 [收藏] [复制] [RSS]

日志

Mark First STM8S003 CODE HERE

已有 601 次阅读2016-10-8 10:18 |个人分类:仪表|系统分类:单片机| STM8, 仪表


       
  1. /*************************************************
  2. * 2015/1/7 16:55:21
  3. * SX-C-5618 main file
  4. * Copyright (c) 2009-2015 Suxin-tech
  5. ************************************************/

  6. #include "stm8s003F3P.h"
  7. #include "typedef.h"
  8. #include "config.h"
  9. #include "display_lib.h"
  10. #include "ht1621.h"

  11. void system_init(void);
  12. uint8_t f_decode, plus_code, gear, gear_bak;

  13. uint8_t control, wink_cnt_left;
  14. uint8_t count, f_second, seconds, km;
  15. uint8_t left, right, light, d1,d2,d3, error, error2;
  16. uint32_t bat_sum, speed_sum, adj_sum, temp_sum;
  17. uint16_t bat_ad, speed_ad, adj_ad, temp_ad, voltage, change_count, hall; //voltage: 0.1V
  18. uint8_t bat, ad_cnt;
  19. uint8_t speed_max, speed_vol; // speed_vol:电机最大速度对应电压
  20. uint32_t mileage; // meter单位0.1米 mileage单位0.1km
  21. uint16_t mps, meter, single_m; // single_m 单次里程,单位0.1km
  22. uint8_t pmileage;
  23. uint8_t t2_count, dis_time, count2;

  24. uint16_t speed, speed_v, dec_cnt, inc_cnt,light_change, pre_light, light_cnt, ctr_cnt;
  25. uint16_t int_count=0, hall_count=0;

  26. const uint8_t lcd1[] = {num0, num1, num2, num3, num4, num5, num6, num7, num8, num9};
  27. const uint8_t lcd2[] = {num20, num21, num22, num23, num24, num25, num26, num27, num28, num29};

  28. void delay(uint32_t a)
  29. {
  30. if(a == 0)
  31. return;
  32. while(a--);
  33. }

  34. uint8_t select;
  35. uint8_t lcd[32];
  36. void lcd_init(void)
  37. {
  38. SendCmd(BIAS); //设置偏压和占空比
  39. SendCmd(SYSEN); //打开系统振荡器
  40. SendCmd(LCDON); //打开LCD偏压发生器 
  41. WriteAll_1621(0,lcd,32);
  42. }

  43. uint16_t get_ad(uint8_t channel)
  44. {
  45. uint16_t ad_result;
  46. ADC_CSR = channel;
  47. ADC_CR1 |= 0x01;
  48. while((ADC_CSR & 0x80) == 0x00);
  49. ad_result = ADC_DRL;
  50. ad_result += ((uint16_t)ADC_DRH << 8);
  51. return ad_result;
  52. }
  53. uint8_t ee_unlock(void)
  54. {
  55. uint8_t i = 0;
  56. do
  57. {
  58. FLASH_DUKR = 0xae;
  59. FLASH_DUKR = 0x56;
  60. i++;
  61. if(i > 10)
  62. break;
  63. } while((FLASH_IAPSR & 0x08) == 0);
  64. if(i > 10)
  65. return 1;
  66. else
  67. return 0;
  68. }

  69. void ee_lock(void)
  70. {
  71. FLASH_IAPSR &= ~0x08;
  72. }
  73. uint16_t _FULL[] = { 485, 603, 645, 725, 805, 965 };
  74. uint16_t _EMPTY[] = { 425, 538, 580, 630, 705, 845 };
  75. uint16_t FULL, EMPTY, bat_per;
  76. #define DIVIDE 4

  77. uint16_t d_cnt;
  78. volatile uint8_t decode_cnt, pdecode, decode[12], ext_cnt;
  79. uint8_t plus_code;
  80. uint8_t online_count, batQuantity;
  81. void main(void)
  82. {
  83. uint8_t i, *pee;
  84. uint16_t temp;
  85. system_init();
  86. delay(5000);
  87. pee = (unsigned char *)0x4000;
  88. if(*pee == 0xa5)
  89. {
  90. pee++;
  91. pmileage = *pee;
  92. if((pmileage > 0x5c) || (pmileage < 0x10))
  93. goto reset_ee;
  94. else
  95. {
  96. pee = (unsigned char *)(0x4000+pmileage);
  97. mileage = *pee;
  98. pee++;
  99. mileage += ((uint16_t)(*pee) << 8);
  100. pee++;
  101. mileage += ((uint32_t)(*pee) << 16);
  102. pee++;
  103. mileage += ((uint32_t)(*pee) << 24);
  104. }
  105. if(mileage > 99999)
  106. mileage = 99999;
  107. pee = (unsigned char *)0x4002;
  108. select = 1;
  109. pee++;

  110. FULL = _FULL[select];
  111. EMPTY = _EMPTY[select];
  112. bat_per = ((uint8_t)((FULL-EMPTY)/DIVIDE));

  113. pee+=2;
  114. control = *pee;
  115. }
  116. else
  117. {
  118. reset_ee:
  119. pee = (unsigned char *)0x4000;
  120. if(ee_unlock() == 0) // eeprom解锁成功,写入数据
  121. {
  122. *pee++ = 0xa5;
  123. while((FLASH_IAPSR & 0x04) == 0);
  124. *pee++ = 0x10;
  125. while((FLASH_IAPSR & 0x04) == 0);
  126. *pee++ = 0x01;
  127. while((FLASH_IAPSR & 0x04) == 0);
  128. *pee++ = 0x00;
  129. while((FLASH_IAPSR & 0x04) == 0);
  130. *pee = 100;
  131. while((FLASH_IAPSR & 0x04) == 0);
  132. *pee = 0;
  133. while((FLASH_IAPSR & 0x04) == 0);
  134. pee = (unsigned char *)0x4010;
  135. for(i=0; i<4; ++i)
  136. {
  137. *pee++ = 0x00;
  138. while((FLASH_IAPSR & 0x04) == 0);
  139. }
  140. ee_lock();
  141. }
  142. pmileage = 0x10;
  143. mileage = 0;
  144. select = 0x01;
  145. FULL = _FULL[select];
  146. EMPTY = _EMPTY[select];
  147. bat_per = ((uint8_t)((FULL-EMPTY)/DIVIDE));
  148. control = 0;
  149. }
  150. speed_max = 38;
  151. speed_vol = 24;

  152. _asm("rim");
  153. delay(100000);
  154. for(i=0; i<32; ++i)
  155. lcd[i] = 0x00;
  156. bat_ad += get_ad(0x05);
  157. voltage = (bat_ad*53/50);
  158. if(voltage < EMPTY)
  159. bat = 5;
  160. else if(voltage > FULL-bat_per)
  161. bat = 0;
  162. else
  163. bat = (FULL - voltage)/bat_per;
  164. batQuantity = (5-bat) * 20;
  165. while (1)
  166. {
  167. if(f_decode)
  168. {
  169. f_decode = 0;
  170. online_count = 0;

  171. plus_code = 0;
  172. for(i=0; i<11; i++)
  173. plus_code ^= decode[i];
  174. if(plus_code == decode[11]) {
  175. plus_code = decode[10];
  176. for(i=3; i<11; i++)
  177. decode[i] -= plus_code;
  178. gear_bak = gear;
  179. gear = (decode[4] & 0x03); // 0~3 gear
  180. error2 = decode[4];
  181. error= (decode[3] & 0x7f);

  182. speed = ((uint16_t)decode[7]<<8)+decode[8];
  183. speed = speed * speed_max / 50;
  184. if(speed > 990)
  185. speed = 990;
  186. mps = speed * 10 / 36;
  187. }

  188. bat_sum += get_ad(0x05);
  189. speed_sum += get_ad(0x04);
  190. adj_sum += get_ad(0x03);
  191. if(online_count >= 50)
  192. {
  193. online_count = 0;
  194. gear = 0;
  195. gear_bak = 0;
  196. hall = 0;
  197. speed = 0;
  198. error2 = 0;
  199. error = 0;
  200. }
  201. if(++ad_cnt ==0)
  202. {
  203. speed_ad = speed_sum >> 8;
  204. bat_ad = bat_sum >> 8;
  205. adj_ad = adj_sum >> 8;
  206. adj_ad /= 17;
  207. adj_ad += 15; // adj 0-1023: 15-75
  208. speed_max = adj_ad;
  209. speed_sum = 0;
  210. bat_sum = 0;
  211. adj_sum = 0;
  212. ad_cnt = 0;

  213. voltage *= 1;
  214. voltage += (1*bat_ad*53/50); //bat_ad/1023*5*71.3/3.3*10(单位0.1V) = bat_ad * 1.056
  215. voltage >>= 1;
  216. if(voltage >= 1000)
  217. voltage = 999;
  218. }
  219. temp = speed;

  220. // speed_v = (uint32_t)speed_ad*speed_max/speed_vol; //speed_ad*5*71.3*speed_max/3.3/1023/speed_vol, mulby 10 ≈speed_ad*speed_max/speed_vol
  221. // speed = speed_v;
  222. // 
  223. // if(speed > 990)
  224. // speed = 990;
  225. // mps = speed * 10 / 36; //mps结果为整数,每秒mps/10米,即1m/s时mps=10,speed已经放大了10倍
  226. if((speed - temp < 40) || (temp - speed < 40))
  227. {
  228. if(speed > 5)
  229. speed = (speed + temp + 1) >> 1;
  230. }

  231. if(select < 6)
  232. {
  233. if(voltage < FULL-bat_per*bat-1)
  234. {
  235. if(++inc_cnt >= 1000)
  236. {
  237. inc_cnt = 0;
  238. if(bat < DIVIDE+1)
  239. {
  240. bat++;
  241. }
  242. }
  243. }
  244. else
  245. inc_cnt = 0;
  246. if(bat > 0)
  247. {
  248. if(voltage > FULL-bat_per*(bat-1))
  249. {
  250. if(++dec_cnt >= 1000)
  251. {
  252. dec_cnt = 0;
  253. bat--;
  254. }
  255. }
  256. else
  257. dec_cnt = 0;
  258. }
  259. else
  260. dec_cnt = 0;
  261. batQuantity = (5-bat) * 20;
  262. }
  263. if(f_second == 1)
  264. {
  265. f_second = 0;
  266. if(seconds < 10)
  267. seconds++;
  268. meter += mps;
  269. if(meter >= 1000) //100米 记录
  270. {
  271. meter = 0;
  272. single_m++;
  273. mileage ++;
  274. if(mileage > 999999)
  275. mileage = 999999;
  276. else
  277. {
  278. ee_unlock();
  279. if(pmileage != ((mileage / 100000) << 2) + 0x10)
  280. {
  281. pmileage = ((mileage / 100000) << 2) + 0x10;
  282. pee = (unsigned char *)(0x4001);
  283. *pee = pmileage;
  284. while((FLASH_IAPSR & 0x04) == 0);
  285. }

  286. pee = (unsigned char *)(0x4000 + pmileage);
  287. *pee++ = mileage & 0xff;
  288. while((FLASH_IAPSR & 0x04) == 0);
  289. *pee++ = mileage >> 8;
  290. while((FLASH_IAPSR & 0x04) == 0);
  291. *pee++ = mileage >> 16;
  292. while((FLASH_IAPSR & 0x04) == 0);
  293. *pee++ = mileage >> 24;
  294. while((FLASH_IAPSR & 0x04) == 0);
  295. ee_lock();
  296. }
  297. }
  298. }
  299. for(i=0; i<32; i++)
  300. lcd[i] = 0;

  301. //speed display
  302. lcd[0] = lcd1[speed / 100];
  303. lcd[1] = lcd1[speed / 100] >> 4;
  304. lcd[2] = lcd1[speed % 100 / 10];
  305. lcd[3] = lcd1[speed % 100 / 10] >> 4;
  306. lcd[3] |= 0x08;

  307. //mileage display
  308. lcd[6] = lcd1[mileage/100000]; 
  309. lcd[7] = lcd1[mileage/100000] >> 4; 
  310. lcd[16] = lcd1[mileage%100000/10000];
  311. lcd[17] = lcd1[mileage%100000/10000] >> 4;
  312. lcd[18] = lcd1[mileage%10000/1000]; 
  313. lcd[19] = lcd1[mileage%10000/1000] >> 4; 
  314. lcd[20] = lcd1[mileage%1000/100];
  315. lcd[21] = lcd1[mileage%1000/100] >> 4; 
  316. lcd[22] = lcd1[mileage%100/10];
  317. lcd[23] = lcd1[mileage%100/10] >> 4;
  318. lcd[7] |= 0x08;

  319. if(batQuantity >= 100) {
  320. lcd[24] = lcd1[0];
  321. lcd[25] = lcd1[0] >> 4;
  322. lcd[26] = lcd1[0];
  323. lcd[27] = lcd1[0] >> 4;
  324. lcd[23] |= 0x08;
  325. } else {
  326. lcd[24] = lcd1[batQuantity / 10];
  327. lcd[25] = lcd1[batQuantity / 10] >> 4;
  328. lcd[26] = lcd1[batQuantity % 10];
  329. lcd[27] = lcd1[batQuantity % 10] >> 4;
  330. }
  331. lcd[27] |= 8;
  332. switch(bat)
  333. {
  334. case 0: lcd[28] = 0x0f; lcd[17] |= 8; lcd[25] |= 8; break;
  335. case 1: lcd[28] = 0x0e; lcd[17] |= 8; lcd[25] |= 8; break;
  336. case 2: lcd[28] = 0x0c; lcd[17] |= 8; lcd[25] |= 8; break;
  337. case 3: lcd[28] = 0x08; lcd[17] |= 8; lcd[25] |= 8;break;
  338. case 4: lcd[28] = 0x08; lcd[25] |= 8;break;
  339. case 5: lcd[28] = 0x08; if(count2 > 25) lcd[25] |= 0x8;
  340. lcd[21] |= 0x08; break; // 'CA'
  341. default: break;
  342. }
  343. light = PC_IDR & (1 << 3);

  344. if(light != pre_light)
  345. {
  346. if(light_change == 0)
  347. light_cnt = 0;
  348. if(++light_change >= 10)
  349. {
  350. light_change = 0;
  351. single_m = 0;
  352. mileage = 0;
  353. ee_unlock();
  354. pee = (uint8_t*)0x4001;
  355. *pee = 0x10;
  356. while((FLASH_IAPSR & 0x04) == 0);
  357. pee = (unsigned char *)0x4010;
  358. for(i=0; i<4; ++i)
  359. {
  360. *pee++ = 0x00;
  361. while((FLASH_IAPSR & 0x04) == 0);
  362. }
  363. ee_lock();
  364. }
  365. }
  366. pre_light = light;

  367. if(light != 0)
  368. lcd[1] |= 0x8;
  369. if(gear_bak == gear)
  370. {
  371. PC_ODR |= 0xf0;
  372. if(gear > 3) gear = 0;
  373. switch(gear) {
  374. case 0: break;
  375. case 1: PC_ODR &= ~0x30; break;
  376. case 2: PC_ODR &= ~0xe0; break;
  377. case 3: PC_ODR &= ~0x70; break;
  378. default: break;
  379. }
  380. }

  381. if(speed >= 20) lcd[5] |= 0x01; 
  382. if(speed >= 60) lcd[5] |= 0x02; 
  383. if(speed >= 110) lcd[5] |= 0x04;
  384. if(speed >= 160) lcd[5] |= 0x08; 
  385. if(speed >= 210) lcd[4] |= 0x08; 
  386. if(speed >= 260) lcd[4] |= 0x04; 
  387. if(speed >= 310) lcd[4] |= 0x02; 
  388. if(speed >= 360) lcd[4] |= 0x01; 
  389. if(speed >= 410) lcd[30] |= 0x01;
  390. if(speed >= 460) lcd[30] |= 0x02;
  391. if(speed >= 510) lcd[30] |= 0x04;
  392. if(speed >= 560) lcd[30] |= 0x08;


  393. if(error & 0x41) // MOTOR ERROR
  394. lcd[29] |= 0x04;
  395. if(error & 0x2) // 助力
  396. ;// lcd[0] |= 0x04;
  397. if(error & 0x4) // 巡航
  398. ;// lcd[0] |= 0x08;
  399. if(error & 0x10) // ECU
  400. ;// lcd[30] |= 0x02;
  401. if(error & 0x20) // 转把
  402. lcd[29] |= 0x02;
  403. if(error2 & 0x08) // 充电
  404. ;// lcd[7] |= 0x04;
  405. if(error2 & 0x20) // 刹车
  406. lcd[29] |= 0x01;
  407. WriteAll_1621(0, lcd, 32);
  408. }
  409. }

  410. @far @interrupt void portb_int(void)
  411. {
  412. volatile uint16_t time;
  413. ext_cnt = 0;
  414. if(PB_IDR & 0x20) // posedge
  415. {
  416. if(TIM1_CR1 & 0x01) // TM1 already run, 
  417. {
  418. time = (TIM1_CNTRH << 8);
  419. time += TIM1_CNTRL;
  420. TIM1_CNTRH = 0;
  421. TIM1_CNTRL = 0;
  422. if((time >= 400) && (time <= 650)) // 1
  423. {
  424. decode[decode_cnt/8] <<= 1;
  425. decode[decode_cnt/8] |= 1;
  426. decode_cnt++;
  427. if(decode_cnt >= 96)
  428. {
  429. decode_cnt = 0;
  430. f_decode = 1;
  431. }
  432. pdecode++;
  433. if(pdecode >= 8)
  434. pdecode = 0;
  435. }
  436. else if((time >= 800) && (time <= 1300)) // 0
  437. {
  438. decode[decode_cnt/8] <<= 1;
  439. decode[decode_cnt/8] |= 0;
  440. decode_cnt++;
  441. if(decode_cnt >= 96)
  442. {
  443. decode_cnt = 0;
  444. f_decode = 1;
  445. }
  446. pdecode++;
  447. if(pdecode >= 8)
  448. pdecode = 0;
  449. }
  450. else
  451. {
  452. TIM1_CR1 &= ~0x01;
  453. }
  454. }
  455. }
  456. else // negative edge
  457. {
  458. if(TIM1_CR1 & 0x01) // TM1 already run
  459. {
  460. TIM1_CNTRH = 0;
  461. TIM1_CNTRL = 0;
  462. }
  463. else
  464. {
  465. TIM1_CR1 |= 0x01;
  466. pdecode = 0;
  467. decode_cnt = 0;
  468. TIM1_CNTRH = 0;
  469. TIM1_CNTRL = 0;
  470. }
  471. }
  472. }

  473. @far @interrupt void timer2Interrupt(void) /* set f = 500Hz */
  474. {
  475. TIM2_SR1 &= ~0x01;
  476. if(++ext_cnt > 10)
  477. {
  478. ext_cnt = 0;
  479. TIM1_CR1 &= ~0x01;

  480. if(++count >= 10) // 20ms
  481. {
  482. count = 0;
  483. if(++count2 >= 50)
  484. count2 = 0;
  485. if(++t2_count >= 50)
  486. {
  487. t2_count = 0;
  488. f_second = 1;

  489. if(light_cnt <5)
  490. {
  491. if(++light_cnt==5)
  492. {
  493. light_change = 0;
  494. }
  495. }
  496. }
  497. if((t2_count == 0) || (t2_count == 25))
  498. {
  499. hall_count += int_count;
  500. hall_count >>= 1;
  501. int_count = 0;

  502. if(++dis_time > 3)
  503. dis_time = 0;
  504. }
  505. if(wink_cnt_left != 0)
  506. wink_cnt_left--;
  507. else
  508. wink_cnt_left = 100;
  509. if(online_count < 50)
  510. online_count++;
  511. }
  512. }

  513. void adc_init(void)
  514. {
  515. ADC_CSR = 0x00; // disable adc interrupt
  516. ADC_CR2 = 0x08; // right alignment
  517. ADC_CR3 = 0x00; // disable data buffer
  518. // ADC_TDRL = 0x18; // Schmitt trigger disabled 
  519. ADC_CR1 = 0x71; // adc clock = fmaster / 18
  520. ADC_CR1 |= 0x01;
  521. }

  522. void port_init(void)
  523. {
  524. CFG_GCR = 0x01;
  525. _asm("nop");
  526. PA_DDR = 0x0e; // PA.123 output;
  527. PA_CR1 = 0x0e;
  528. PA_CR2 = 0x0e;
  529. PA_ODR = 0x0e;

  530. PB_DDR = 0x00; // PB.45 input;
  531. PB_CR1 = 0x00;
  532. PB_CR2 = 0x20; // PB5 input with interrupt

  533. PC_ODR = 0xf0;
  534. PC_DDR = 0xf0; // PC.34567 in
  535. PC_CR1 = 0xe0;
  536. PC_CR2 = 0x00; 

  537. PD_DDR = 0x00; // PD.123456 in 
  538. PD_CR1 = 0x00;
  539. PD_CR2 = 0x00;
  540. }
  541. void timer_init(void)
  542. {
  543. TIM2_IER = 0x01;
  544. TIM2_PSCR = 0x03; //prescaler = 2<3> = 8
  545. TIM2_ARRH = 0x07;
  546. TIM2_ARRL = 0xd0; // auto reload = 1000 @ 1ms
  547. TIM2_CR1 |= 0x01;
  548. TIM1_IER = 0x00;
  549. TIM1_PSCRL = 0x07; //prescaler = 7 + 1 = 8
  550. TIM1_ARRH = 0xff;
  551. TIM1_ARRL = 0xff; // auto reload = 65535 @ 65.5ms
  552. }

  553. void system_init(void)
  554. {
  555. uint8_t i;
  556. CLK_CKDIVR = 0x08; 
  557. _asm("nop");
  558. _asm("nop");
  559. _asm("nop");
  560. _asm("nop");
  561. CLK_PCKENR1 = 0xac;
  562. CLK_PCKENR2 = 0x08;
  563. port_init();
  564. adc_init();
  565. timer_init();
  566. // uart_init();
  567. delay(10000);
  568. EXTI_CR1 = 0x0c;
  569. for(i=0; i<32; ++i)
  570. lcd[i] = 0xff;
  571. lcd_init();
  572. }
复制代码


路过

鸡蛋

鲜花

握手

雷人

全部作者的其他最新日志

评论 (0 个评论)